136 lines
3.8 KiB
Go
136 lines
3.8 KiB
Go
package host_info
|
|
|
|
import (
|
|
"cmii-uav-watchdog-common/models"
|
|
"cmii-uav-watchdog-common/wdd_log"
|
|
"strconv"
|
|
"strings"
|
|
"syscall"
|
|
)
|
|
|
|
// GetDiskInfo retrieves disk information similar to df -Th.
|
|
func GetDiskInfo() []models.DiskInfo {
|
|
var diskInfos []models.DiskInfo
|
|
|
|
// Read /proc/mounts to get mounted filesystems
|
|
mountsData, err := readFileWithWarning("/proc/mounts")
|
|
if err != nil {
|
|
return diskInfos
|
|
}
|
|
|
|
mounts := strings.Split(string(mountsData), "\n")
|
|
|
|
// Read /proc/partitions to get physical disks
|
|
partitionsData, err := readFileWithWarning("/proc/partitions")
|
|
if err != nil {
|
|
return diskInfos
|
|
}
|
|
|
|
partitions := strings.Split(string(partitionsData), "\n")
|
|
physicalDevices := make(map[string]uint64)
|
|
|
|
// Map physical devices to their sizes
|
|
for _, line := range partitions {
|
|
fields := strings.Fields(line)
|
|
if len(fields) < 4 {
|
|
continue
|
|
}
|
|
device := fields[3] // The device name is in the 4th column
|
|
size, err := strconv.ParseUint(fields[2], 10, 64) // 读取大小
|
|
if err != nil {
|
|
continue
|
|
}
|
|
physicalDevices[device] = size * 1024 // 转换为字节
|
|
}
|
|
|
|
for _, mount := range mounts {
|
|
if mount == "" {
|
|
continue
|
|
}
|
|
fields := strings.Fields(mount)
|
|
if len(fields) < 3 {
|
|
continue
|
|
}
|
|
logicalDevice := fields[0] // 逻辑分区设备名
|
|
mountPoint := fields[1] // 挂载点
|
|
fstype := fields[2] // 文件系统类型
|
|
|
|
// Skip NFS mounts
|
|
if fstype == "nfs" {
|
|
continue
|
|
}
|
|
|
|
// Skip overlay mounts
|
|
if fstype == "overlay" {
|
|
continue
|
|
}
|
|
|
|
// Get disk usage information using stat
|
|
var stat syscall.Statfs_t
|
|
if err := syscall.Statfs(mountPoint, &stat); err != nil {
|
|
wdd_log.Warn("获取 %s 的statfs信息失败: %v", mountPoint, err)
|
|
continue
|
|
}
|
|
|
|
// Calculate total, used, and available space
|
|
total := stat.Blocks * uint64(stat.Bsize)
|
|
available := stat.Bavail * uint64(stat.Bsize)
|
|
used := total - available
|
|
|
|
// Skip if size is 0
|
|
if total == 0 {
|
|
continue
|
|
}
|
|
|
|
// Calculate percentage used
|
|
usePercent := "0%"
|
|
if total > 0 {
|
|
percentage := float64(used) / float64(total) * 100
|
|
usePercent = strconv.FormatFloat(percentage, 'f', 1, 64) + "%"
|
|
}
|
|
|
|
// Determine the physical device and its size
|
|
physicalDevice := ""
|
|
physicalSize := uint64(0)
|
|
|
|
// Check if the logical device is a partition (e.g., /dev/sda1)
|
|
if strings.HasPrefix(logicalDevice, "/dev/") {
|
|
// Get the corresponding physical device (e.g., /dev/sda)
|
|
physicalDevice = strings.TrimSuffix(logicalDevice, "1") // 假设逻辑分区是 /dev/sda1
|
|
if size, exists := physicalDevices[physicalDevice]; exists {
|
|
physicalSize = size
|
|
}
|
|
}
|
|
|
|
// If not found, use the logical device as the physical device
|
|
if physicalDevice == "" || physicalSize == 0 {
|
|
physicalDevice = logicalDevice
|
|
if size, exists := physicalDevices[physicalDevice]; exists {
|
|
physicalSize = size
|
|
}
|
|
}
|
|
|
|
diskInfos = append(diskInfos, models.DiskInfo{
|
|
Device: logicalDevice, // 设置逻辑分区的设备名称
|
|
Filesystem: logicalDevice, // 逻辑分区
|
|
Type: fstype, // 文件系统类型
|
|
Size: total, // 总大小
|
|
Used: used, // 已用空间
|
|
Available: available, // 可用空间
|
|
UsePercent: usePercent, // 使用百分比
|
|
MountPoint: mountPoint, // 挂载点
|
|
PhysicalDevice: physicalDevice, // 物理设备名称
|
|
PhysicalSize: physicalSize, // 物理盘大小
|
|
})
|
|
}
|
|
|
|
return diskInfos
|
|
}
|
|
|
|
/*
|
|
Device: sda, Total: 500107862016 bytes, Used: 250000000000 bytes, Available: 200000000000 bytes
|
|
Device: sdb, Total: 400107862016 bytes, Used: 150000000000 bytes, Available: 250000000000 bytes
|
|
Device: sdc, Total: 100107862016 bytes, Used: 50000000000 bytes, Available: 50000000000 bytes
|
|
Device: unknown, Total: 0 bytes, Used: 0 bytes, Available: 0 bytes
|
|
*/
|