diff --git a/disk/disk_linux.go b/disk/disk_linux.go index 1b10a38..3d68936 100644 --- a/disk/disk_linux.go +++ b/disk/disk_linux.go @@ -241,7 +241,7 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro fields := strings.Fields(line) d := PartitionStat{ Device: fields[0], - Mountpoint: fields[1], + Mountpoint: unescapeFstab(fields[1]), Fstype: fields[2], Opts: fields[3], } diff --git a/disk/disk_windows.go b/disk/disk_windows.go index 326bc1f..081443b 100644 --- a/disk/disk_windows.go +++ b/disk/disk_windows.go @@ -15,7 +15,7 @@ var ( procGetDiskFreeSpaceExW = common.Modkernel32.NewProc("GetDiskFreeSpaceExW") procGetLogicalDriveStringsW = common.Modkernel32.NewProc("GetLogicalDriveStringsW") procGetDriveType = common.Modkernel32.NewProc("GetDriveTypeW") - provGetVolumeInformation = common.Modkernel32.NewProc("GetVolumeInformationW") + procGetVolumeInformation = common.Modkernel32.NewProc("GetVolumeInformationW") ) var ( @@ -83,9 +83,6 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro for _, v := range lpBuffer { if v >= 65 && v <= 90 { path := string(v) + ":" - if path == "A:" || path == "B:" { // skip floppy drives - continue - } typepath, _ := windows.UTF16PtrFromString(path) typeret, _, _ := procGetDriveType.Call(uintptr(unsafe.Pointer(typepath))) if typeret == 0 { @@ -100,7 +97,7 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro lpFileSystemFlags := int64(0) lpFileSystemNameBuffer := make([]byte, 256) volpath, _ := windows.UTF16PtrFromString(string(v) + ":/") - driveret, _, err := provGetVolumeInformation.Call( + driveret, _, err := procGetVolumeInformation.Call( uintptr(unsafe.Pointer(volpath)), uintptr(unsafe.Pointer(&lpVolumeNameBuffer[0])), uintptr(len(lpVolumeNameBuffer)), diff --git a/host/host_linux.go b/host/host_linux.go index 7ca5089..2c1ac6b 100644 --- a/host/host_linux.go +++ b/host/host_linux.go @@ -73,7 +73,10 @@ func InfoWithContext(ctx context.Context) (*InfoStat, error) { } sysProductUUID := common.HostSys("class/dmi/id/product_uuid") + machineID := common.HostEtc("machine-id") switch { + // In order to read this file, needs to be supported by kernel/arch and run as root + // so having fallback is important case common.PathExists(sysProductUUID): lines, err := common.ReadLines(sysProductUUID) if err == nil && len(lines) > 0 && lines[0] != "" { @@ -81,6 +84,16 @@ func InfoWithContext(ctx context.Context) (*InfoStat, error) { break } fallthrough + // Fallback on GNU Linux systems with systemd, readable by everyone + case common.PathExists(machineID): + lines, err := common.ReadLines(machineID) + if err == nil && len(lines) > 0 && len(lines[0]) == 32 { + st := lines[0] + ret.HostID = fmt.Sprintf("%s-%s-%s-%s-%s", st[0:8], st[8:12], st[12:16], st[16:20], st[20:32]) + break + } + fallthrough + // Not stable between reboot, but better than nothing default: values, err := common.DoSysctrl("kernel.random.boot_id") if err == nil && len(values) == 1 && values[0] != "" { diff --git a/net/net_linux.go b/net/net_linux.go index 616c10a..71842fb 100644 --- a/net/net_linux.go +++ b/net/net_linux.go @@ -393,7 +393,11 @@ func statsFromInodes(root string, pid int32, tmap []netConnectionKindType, inode var path string var connKey string var ls []connTmp - path = fmt.Sprintf("%s/net/%s", root, t.filename) + if pid == 0 { + path = fmt.Sprintf("%s/net/%s", root, t.filename) + } else { + path = fmt.Sprintf("%s/%d/net/%s", root, pid, t.filename) + } switch t.family { case syscall.AF_INET, syscall.AF_INET6: ls, err = processInet(path, t, inodes, pid) diff --git a/process/process_windows.go b/process/process_windows.go index 3879eb4..ee661a9 100644 --- a/process/process_windows.go +++ b/process/process_windows.go @@ -465,22 +465,33 @@ func (p *Process) Children() ([]*Process, error) { } func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) { - var dst []Win32_Process - query := wmi.CreateQuery(&dst, fmt.Sprintf("Where ParentProcessId = %d", p.Pid)) - err := common.WMIQueryWithContext(ctx, query, &dst) - if err != nil { - return nil, err + out := []*Process{} + snap := w32.CreateToolhelp32Snapshot(w32.TH32CS_SNAPPROCESS, uint32(0)) + if snap == 0 { + return out, windows.GetLastError() + } + defer w32.CloseHandle(snap) + var pe32 w32.PROCESSENTRY32 + pe32.DwSize = uint32(unsafe.Sizeof(pe32)) + if w32.Process32First(snap, &pe32) == false { + return out, windows.GetLastError() } - out := []*Process{} - for _, proc := range dst { - p, err := NewProcess(int32(proc.ProcessID)) - if err != nil { - continue + if pe32.Th32ParentProcessID == uint32(p.Pid) { + p, err := NewProcess(int32(pe32.Th32ProcessID)) + if err == nil { + out = append(out, p) } - out = append(out, p) } + for w32.Process32Next(snap, &pe32) { + if pe32.Th32ParentProcessID == uint32(p.Pid) { + p, err := NewProcess(int32(pe32.Th32ProcessID)) + if err == nil { + out = append(out, p) + } + } + } return out, nil }