mirror of https://github.com/hashicorp/consul
chore: upgrade to gopsutil/v3 (#9118)
* deps: update golang.org/x/sys * deps: update imports to gopsutil/v3 * chore: make update-vendorpull/9146/head
parent
6396042ba7
commit
75019baadd
|
@ -3,10 +3,10 @@ package debug
|
||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/shirou/gopsutil/cpu"
|
"github.com/shirou/gopsutil/v3/cpu"
|
||||||
"github.com/shirou/gopsutil/disk"
|
"github.com/shirou/gopsutil/v3/disk"
|
||||||
"github.com/shirou/gopsutil/host"
|
"github.com/shirou/gopsutil/v3/host"
|
||||||
"github.com/shirou/gopsutil/mem"
|
"github.com/shirou/gopsutil/v3/mem"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
|
@ -13,7 +13,7 @@ import (
|
||||||
"github.com/hashicorp/consul/types"
|
"github.com/hashicorp/consul/types"
|
||||||
"github.com/hashicorp/go-hclog"
|
"github.com/hashicorp/go-hclog"
|
||||||
"github.com/hashicorp/go-uuid"
|
"github.com/hashicorp/go-uuid"
|
||||||
"github.com/shirou/gopsutil/host"
|
"github.com/shirou/gopsutil/v3/host"
|
||||||
)
|
)
|
||||||
|
|
||||||
// newNodeIDFromConfig will pull the persisted node ID, if any, or create a random one
|
// newNodeIDFromConfig will pull the persisted node ID, if any, or create a random one
|
||||||
|
|
8
go.mod
8
go.mod
|
@ -11,7 +11,6 @@ replace launchpad.net/gocheck => github.com/go-check/check v0.0.0-20140225173054
|
||||||
require (
|
require (
|
||||||
github.com/Microsoft/go-winio v0.4.3 // indirect
|
github.com/Microsoft/go-winio v0.4.3 // indirect
|
||||||
github.com/NYTimes/gziphandler v1.0.1
|
github.com/NYTimes/gziphandler v1.0.1
|
||||||
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 // indirect
|
|
||||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e
|
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e
|
||||||
github.com/armon/go-metrics v0.3.5-0.20201104215618-6fd5a4ddf425
|
github.com/armon/go-metrics v0.3.5-0.20201104215618-6fd5a4ddf425
|
||||||
github.com/armon/go-radix v1.0.0
|
github.com/armon/go-radix v1.0.0
|
||||||
|
@ -23,7 +22,6 @@ require (
|
||||||
github.com/elazarl/go-bindata-assetfs v0.0.0-20160803192304-e1a2a7ec64b0
|
github.com/elazarl/go-bindata-assetfs v0.0.0-20160803192304-e1a2a7ec64b0
|
||||||
github.com/envoyproxy/go-control-plane v0.9.5
|
github.com/envoyproxy/go-control-plane v0.9.5
|
||||||
github.com/frankban/quicktest v1.11.0 // indirect
|
github.com/frankban/quicktest v1.11.0 // indirect
|
||||||
github.com/go-ole/go-ole v1.2.1 // indirect
|
|
||||||
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d
|
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d
|
||||||
github.com/golang/protobuf v1.3.5
|
github.com/golang/protobuf v1.3.5
|
||||||
github.com/google/go-cmp v0.5.2
|
github.com/google/go-cmp v0.5.2
|
||||||
|
@ -78,15 +76,15 @@ require (
|
||||||
github.com/prometheus/client_golang v1.4.0
|
github.com/prometheus/client_golang v1.4.0
|
||||||
github.com/rboyer/safeio v0.2.1
|
github.com/rboyer/safeio v0.2.1
|
||||||
github.com/ryanuber/columnize v2.1.0+incompatible
|
github.com/ryanuber/columnize v2.1.0+incompatible
|
||||||
github.com/shirou/gopsutil v2.20.9+incompatible
|
github.com/shirou/gopsutil/v3 v3.20.10
|
||||||
github.com/stretchr/testify v1.5.1
|
github.com/stretchr/testify v1.6.1
|
||||||
go.opencensus.io v0.22.0 // indirect
|
go.opencensus.io v0.22.0 // indirect
|
||||||
go.uber.org/goleak v1.0.0
|
go.uber.org/goleak v1.0.0
|
||||||
golang.org/x/crypto v0.0.0-20200930160638-afb6bcd081ae
|
golang.org/x/crypto v0.0.0-20200930160638-afb6bcd081ae
|
||||||
golang.org/x/net v0.0.0-20200930145003-4acb6c075d10
|
golang.org/x/net v0.0.0-20200930145003-4acb6c075d10
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
|
||||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a
|
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a
|
||||||
golang.org/x/sys v0.0.0-20201007082116-8445cc04cbdf
|
golang.org/x/sys v0.0.0-20201024232916-9f70ab9862d5
|
||||||
golang.org/x/text v0.3.3 // indirect
|
golang.org/x/text v0.3.3 // indirect
|
||||||
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e
|
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e
|
||||||
golang.org/x/tools v0.0.0-20200513154647-78b527d18275 // indirect
|
golang.org/x/tools v0.0.0-20200513154647-78b527d18275 // indirect
|
||||||
|
|
22
go.sum
22
go.sum
|
@ -45,8 +45,8 @@ github.com/NYTimes/gziphandler v1.0.1/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64
|
||||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||||
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||||
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||||
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8=
|
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk=
|
||||||
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
||||||
github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af h1:DBNMBMuMiWYu0b+8KMJuWmfCkcxl09JwdlqwDZZ6U14=
|
github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af h1:DBNMBMuMiWYu0b+8KMJuWmfCkcxl09JwdlqwDZZ6U14=
|
||||||
github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af/go.mod h1:5Jv4cbFiHJMsVxt52+i0Ha45fjshj6wxYr1r19tB9bw=
|
github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af/go.mod h1:5Jv4cbFiHJMsVxt52+i0Ha45fjshj6wxYr1r19tB9bw=
|
||||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||||
|
@ -149,8 +149,8 @@ github.com/go-ldap/ldap/v3 v3.1.3/go.mod h1:3rbOH3jRS2u6jg2rJnKAMLE/xQyCKIveG2Sa
|
||||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||||
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
||||||
github.com/go-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E=
|
github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI=
|
||||||
github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
|
github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=
|
||||||
github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0=
|
github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0=
|
||||||
github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
|
github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
|
||||||
github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc=
|
github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc=
|
||||||
|
@ -469,8 +469,8 @@ github.com/sean-/conswriter v0.0.0-20180208195008-f5ae3917a627/go.mod h1:7zjs06q
|
||||||
github.com/sean-/pager v0.0.0-20180208200047-666be9bf53b5/go.mod h1:BeybITEsBEg6qbIiqJ6/Bqeq25bCLbL7YFmpaFfJDuM=
|
github.com/sean-/pager v0.0.0-20180208200047-666be9bf53b5/go.mod h1:BeybITEsBEg6qbIiqJ6/Bqeq25bCLbL7YFmpaFfJDuM=
|
||||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I=
|
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I=
|
||||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||||
github.com/shirou/gopsutil v2.20.9+incompatible h1:msXs2frUV+O/JLva9EDLpuJ84PrFsdCTCQex8PUdtkQ=
|
github.com/shirou/gopsutil/v3 v3.20.10 h1:7zomV9HJv6UGk225YtvEa5+camNLpbua3MAz/GqiVJY=
|
||||||
github.com/shirou/gopsutil v2.20.9+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
github.com/shirou/gopsutil/v3 v3.20.10/go.mod h1:igHnfak0qnw1biGeI2qKQvu0ZkwvEkUcCLlYhZzdr/4=
|
||||||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
||||||
github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
|
github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
|
||||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||||
|
@ -499,8 +499,8 @@ github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRci
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
|
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/tencentcloud/tencentcloud-sdk-go v3.0.83+incompatible h1:8uRvJleFpqLsO77WaAh2UrasMOzd8MxXrNj20e7El+Q=
|
github.com/tencentcloud/tencentcloud-sdk-go v3.0.83+incompatible h1:8uRvJleFpqLsO77WaAh2UrasMOzd8MxXrNj20e7El+Q=
|
||||||
github.com/tencentcloud/tencentcloud-sdk-go v3.0.83+incompatible/go.mod h1:0PfYow01SHPMhKY31xa+EFz2RStxIqj6JFAJS+IkCi4=
|
github.com/tencentcloud/tencentcloud-sdk-go v3.0.83+incompatible/go.mod h1:0PfYow01SHPMhKY31xa+EFz2RStxIqj6JFAJS+IkCi4=
|
||||||
github.com/tent/http-link-go v0.0.0-20130702225549-ac974c61c2f9/go.mod h1:RHkNRtSLfOK7qBTHaeSX1D6BNpI3qw7NTxsmNr4RvN8=
|
github.com/tent/http-link-go v0.0.0-20130702225549-ac974c61c2f9/go.mod h1:RHkNRtSLfOK7qBTHaeSX1D6BNpI3qw7NTxsmNr4RvN8=
|
||||||
|
@ -613,8 +613,8 @@ golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||||
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201007082116-8445cc04cbdf h1:AvBTl0xbF/KtHyvm61X4gSPF7/dKJ/xQqJwKr1Qu9no=
|
golang.org/x/sys v0.0.0-20201024232916-9f70ab9862d5 h1:iCaAy5bMeEvwANu3YnJfWwI0kWAGkEa2RXPdweI/ysk=
|
||||||
golang.org/x/sys v0.0.0-20201007082116-8445cc04cbdf/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201024232916-9f70ab9862d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
@ -691,6 +691,8 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
||||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
|
|
|
@ -77,7 +77,7 @@ func (s *SWbemServices) process(initError chan error) {
|
||||||
//fmt.Println("process: starting background thread initialization")
|
//fmt.Println("process: starting background thread initialization")
|
||||||
//All OLE/WMI calls must happen on the same initialized thead, so lock this goroutine
|
//All OLE/WMI calls must happen on the same initialized thead, so lock this goroutine
|
||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
defer runtime.LockOSThread()
|
defer runtime.UnlockOSThread()
|
||||||
|
|
||||||
err := ole.CoInitializeEx(0, ole.COINIT_MULTITHREADED)
|
err := ole.CoInitializeEx(0, ole.COINIT_MULTITHREADED)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -285,6 +285,10 @@ func (c *Client) loadEntity(dst interface{}, src *ole.IDispatch) (errFieldMismat
|
||||||
}
|
}
|
||||||
defer prop.Clear()
|
defer prop.Clear()
|
||||||
|
|
||||||
|
if prop.VT == 0x1 { //VT_NULL
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
switch val := prop.Value().(type) {
|
switch val := prop.Value().(type) {
|
||||||
case int8, int16, int32, int64, int:
|
case int8, int16, int32, int64, int:
|
||||||
v := reflect.ValueOf(val).Int()
|
v := reflect.ValueOf(val).Int()
|
||||||
|
@ -383,7 +387,7 @@ func (c *Client) loadEntity(dst interface{}, src *ole.IDispatch) (errFieldMismat
|
||||||
}
|
}
|
||||||
f.Set(fArr)
|
f.Set(fArr)
|
||||||
}
|
}
|
||||||
case reflect.Uint8:
|
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
|
||||||
safeArray := prop.ToArray()
|
safeArray := prop.ToArray()
|
||||||
if safeArray != nil {
|
if safeArray != nil {
|
||||||
arr := safeArray.ToValueArray()
|
arr := safeArray.ToValueArray()
|
||||||
|
@ -394,6 +398,17 @@ func (c *Client) loadEntity(dst interface{}, src *ole.IDispatch) (errFieldMismat
|
||||||
}
|
}
|
||||||
f.Set(fArr)
|
f.Set(fArr)
|
||||||
}
|
}
|
||||||
|
case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
|
||||||
|
safeArray := prop.ToArray()
|
||||||
|
if safeArray != nil {
|
||||||
|
arr := safeArray.ToValueArray()
|
||||||
|
fArr := reflect.MakeSlice(f.Type(), len(arr), len(arr))
|
||||||
|
for i, v := range arr {
|
||||||
|
s := fArr.Index(i)
|
||||||
|
s.SetInt(reflect.ValueOf(v).Int())
|
||||||
|
}
|
||||||
|
f.Set(fArr)
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return &ErrFieldMismatch{
|
return &ErrFieldMismatch{
|
||||||
StructType: of.Type(),
|
StructType: of.Type(),
|
||||||
|
|
|
@ -2,8 +2,7 @@ language: go
|
||||||
sudo: false
|
sudo: false
|
||||||
|
|
||||||
go:
|
go:
|
||||||
- 1.1
|
- 1.9.x
|
||||||
- 1.2
|
- 1.10.x
|
||||||
- 1.3
|
- 1.11.x
|
||||||
- 1.4
|
|
||||||
- tip
|
- tip
|
||||||
|
|
|
@ -3,9 +3,7 @@
|
||||||
package ole
|
package ole
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
|
||||||
"unicode/utf16"
|
"unicode/utf16"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
@ -21,6 +19,7 @@ var (
|
||||||
procStringFromCLSID, _ = modole32.FindProc("StringFromCLSID")
|
procStringFromCLSID, _ = modole32.FindProc("StringFromCLSID")
|
||||||
procStringFromIID, _ = modole32.FindProc("StringFromIID")
|
procStringFromIID, _ = modole32.FindProc("StringFromIID")
|
||||||
procIIDFromString, _ = modole32.FindProc("IIDFromString")
|
procIIDFromString, _ = modole32.FindProc("IIDFromString")
|
||||||
|
procCoGetObject, _ = modole32.FindProc("CoGetObject")
|
||||||
procGetUserDefaultLCID, _ = modkernel32.FindProc("GetUserDefaultLCID")
|
procGetUserDefaultLCID, _ = modkernel32.FindProc("GetUserDefaultLCID")
|
||||||
procCopyMemory, _ = modkernel32.FindProc("RtlMoveMemory")
|
procCopyMemory, _ = modkernel32.FindProc("RtlMoveMemory")
|
||||||
procVariantInit, _ = modoleaut32.FindProc("VariantInit")
|
procVariantInit, _ = modoleaut32.FindProc("VariantInit")
|
||||||
|
@ -209,6 +208,32 @@ func GetActiveObject(clsid *GUID, iid *GUID) (unk *IUnknown, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type BindOpts struct {
|
||||||
|
CbStruct uint32
|
||||||
|
GrfFlags uint32
|
||||||
|
GrfMode uint32
|
||||||
|
TickCountDeadline uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetObject retrieves pointer to active object.
|
||||||
|
func GetObject(programID string, bindOpts *BindOpts, iid *GUID) (unk *IUnknown, err error) {
|
||||||
|
if bindOpts != nil {
|
||||||
|
bindOpts.CbStruct = uint32(unsafe.Sizeof(BindOpts{}))
|
||||||
|
}
|
||||||
|
if iid == nil {
|
||||||
|
iid = IID_IUnknown
|
||||||
|
}
|
||||||
|
hr, _, _ := procCoGetObject.Call(
|
||||||
|
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(programID))),
|
||||||
|
uintptr(unsafe.Pointer(bindOpts)),
|
||||||
|
uintptr(unsafe.Pointer(iid)),
|
||||||
|
uintptr(unsafe.Pointer(&unk)))
|
||||||
|
if hr != 0 {
|
||||||
|
err = NewError(hr)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// VariantInit initializes variant.
|
// VariantInit initializes variant.
|
||||||
func VariantInit(v *VARIANT) (err error) {
|
func VariantInit(v *VARIANT) (err error) {
|
||||||
hr, _, _ := procVariantInit.Call(uintptr(unsafe.Pointer(v)))
|
hr, _, _ := procVariantInit.Call(uintptr(unsafe.Pointer(v)))
|
||||||
|
@ -317,13 +342,3 @@ func DispatchMessage(msg *Msg) (ret int32) {
|
||||||
ret = int32(r0)
|
ret = int32(r0)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetVariantDate converts COM Variant Time value to Go time.Time.
|
|
||||||
func GetVariantDate(value float64) (time.Time, error) {
|
|
||||||
var st syscall.Systemtime
|
|
||||||
r, _, _ := procVariantTimeToSystemTime.Call(uintptr(value), uintptr(unsafe.Pointer(&st)))
|
|
||||||
if r != 0 {
|
|
||||||
return time.Date(int(st.Year), time.Month(st.Month), int(st.Day), int(st.Hour), int(st.Minute), int(st.Second), int(st.Milliseconds/1000), time.UTC), nil
|
|
||||||
}
|
|
||||||
return time.Now(), errors.New("Could not convert to time, passing current time.")
|
|
||||||
}
|
|
||||||
|
|
|
@ -169,6 +169,6 @@ func DispatchMessage(msg *Msg) int32 {
|
||||||
return int32(0)
|
return int32(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetVariantDate(value float64) (time.Time, error) {
|
func GetVariantDate(value uint64) (time.Time, error) {
|
||||||
return time.Now(), NewError(E_NOTIMPL)
|
return time.Now(), NewError(E_NOTIMPL)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
module github.com/go-ole/go-ole
|
||||||
|
|
||||||
|
go 1.12
|
|
@ -3,6 +3,7 @@
|
||||||
package ole
|
package ole
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math/big"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
@ -132,6 +133,8 @@ func invoke(disp *IDispatch, dispid int32, dispatch int16, params ...interface{}
|
||||||
vargs[n] = NewVariant(VT_R8, *(*int64)(unsafe.Pointer(&vv)))
|
vargs[n] = NewVariant(VT_R8, *(*int64)(unsafe.Pointer(&vv)))
|
||||||
case *float64:
|
case *float64:
|
||||||
vargs[n] = NewVariant(VT_R8|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*float64)))))
|
vargs[n] = NewVariant(VT_R8|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*float64)))))
|
||||||
|
case *big.Int:
|
||||||
|
vargs[n] = NewVariant(VT_DECIMAL, v.(*big.Int).Int64())
|
||||||
case string:
|
case string:
|
||||||
vargs[n] = NewVariant(VT_BSTR, int64(uintptr(unsafe.Pointer(SysAllocStringLen(v.(string))))))
|
vargs[n] = NewVariant(VT_BSTR, int64(uintptr(unsafe.Pointer(SysAllocStringLen(v.(string))))))
|
||||||
case *string:
|
case *string:
|
||||||
|
|
|
@ -124,12 +124,12 @@ func safeArrayGetElementSize(safearray *SafeArray) (*uint32, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// safeArrayGetElement retrieves element at given index.
|
// safeArrayGetElement retrieves element at given index.
|
||||||
func safeArrayGetElement(safearray *SafeArray, index int64, pv unsafe.Pointer) error {
|
func safeArrayGetElement(safearray *SafeArray, index int32, pv unsafe.Pointer) error {
|
||||||
return NewError(E_NOTIMPL)
|
return NewError(E_NOTIMPL)
|
||||||
}
|
}
|
||||||
|
|
||||||
// safeArrayGetElement retrieves element at given index and converts to string.
|
// safeArrayGetElement retrieves element at given index and converts to string.
|
||||||
func safeArrayGetElementString(safearray *SafeArray, index int64) (string, error) {
|
func safeArrayGetElementString(safearray *SafeArray, index int32) (string, error) {
|
||||||
return "", NewError(E_NOTIMPL)
|
return "", NewError(E_NOTIMPL)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,8 +146,8 @@ func safeArrayGetIID(safearray *SafeArray) (*GUID, error) {
|
||||||
// multidimensional array.
|
// multidimensional array.
|
||||||
//
|
//
|
||||||
// AKA: SafeArrayGetLBound in Windows API.
|
// AKA: SafeArrayGetLBound in Windows API.
|
||||||
func safeArrayGetLBound(safearray *SafeArray, dimension uint32) (int64, error) {
|
func safeArrayGetLBound(safearray *SafeArray, dimension uint32) (int32, error) {
|
||||||
return int64(0), NewError(E_NOTIMPL)
|
return int32(0), NewError(E_NOTIMPL)
|
||||||
}
|
}
|
||||||
|
|
||||||
// safeArrayGetUBound returns upper bounds of SafeArray.
|
// safeArrayGetUBound returns upper bounds of SafeArray.
|
||||||
|
@ -156,8 +156,8 @@ func safeArrayGetLBound(safearray *SafeArray, dimension uint32) (int64, error) {
|
||||||
// multidimensional array.
|
// multidimensional array.
|
||||||
//
|
//
|
||||||
// AKA: SafeArrayGetUBound in Windows API.
|
// AKA: SafeArrayGetUBound in Windows API.
|
||||||
func safeArrayGetUBound(safearray *SafeArray, dimension uint32) (int64, error) {
|
func safeArrayGetUBound(safearray *SafeArray, dimension uint32) (int32, error) {
|
||||||
return int64(0), NewError(E_NOTIMPL)
|
return int32(0), NewError(E_NOTIMPL)
|
||||||
}
|
}
|
||||||
|
|
||||||
// safeArrayGetVartype returns data type of SafeArray.
|
// safeArrayGetVartype returns data type of SafeArray.
|
||||||
|
|
|
@ -205,7 +205,7 @@ func safeArrayGetElementSize(safearray *SafeArray) (length *uint32, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// safeArrayGetElement retrieves element at given index.
|
// safeArrayGetElement retrieves element at given index.
|
||||||
func safeArrayGetElement(safearray *SafeArray, index int64, pv unsafe.Pointer) error {
|
func safeArrayGetElement(safearray *SafeArray, index int32, pv unsafe.Pointer) error {
|
||||||
return convertHresultToError(
|
return convertHresultToError(
|
||||||
procSafeArrayGetElement.Call(
|
procSafeArrayGetElement.Call(
|
||||||
uintptr(unsafe.Pointer(safearray)),
|
uintptr(unsafe.Pointer(safearray)),
|
||||||
|
@ -214,7 +214,7 @@ func safeArrayGetElement(safearray *SafeArray, index int64, pv unsafe.Pointer) e
|
||||||
}
|
}
|
||||||
|
|
||||||
// safeArrayGetElementString retrieves element at given index and converts to string.
|
// safeArrayGetElementString retrieves element at given index and converts to string.
|
||||||
func safeArrayGetElementString(safearray *SafeArray, index int64) (str string, err error) {
|
func safeArrayGetElementString(safearray *SafeArray, index int32) (str string, err error) {
|
||||||
var element *int16
|
var element *int16
|
||||||
err = convertHresultToError(
|
err = convertHresultToError(
|
||||||
procSafeArrayGetElement.Call(
|
procSafeArrayGetElement.Call(
|
||||||
|
@ -243,7 +243,7 @@ func safeArrayGetIID(safearray *SafeArray) (guid *GUID, err error) {
|
||||||
// multidimensional array.
|
// multidimensional array.
|
||||||
//
|
//
|
||||||
// AKA: SafeArrayGetLBound in Windows API.
|
// AKA: SafeArrayGetLBound in Windows API.
|
||||||
func safeArrayGetLBound(safearray *SafeArray, dimension uint32) (lowerBound int64, err error) {
|
func safeArrayGetLBound(safearray *SafeArray, dimension uint32) (lowerBound int32, err error) {
|
||||||
err = convertHresultToError(
|
err = convertHresultToError(
|
||||||
procSafeArrayGetLBound.Call(
|
procSafeArrayGetLBound.Call(
|
||||||
uintptr(unsafe.Pointer(safearray)),
|
uintptr(unsafe.Pointer(safearray)),
|
||||||
|
@ -258,7 +258,7 @@ func safeArrayGetLBound(safearray *SafeArray, dimension uint32) (lowerBound int6
|
||||||
// multidimensional array.
|
// multidimensional array.
|
||||||
//
|
//
|
||||||
// AKA: SafeArrayGetUBound in Windows API.
|
// AKA: SafeArrayGetUBound in Windows API.
|
||||||
func safeArrayGetUBound(safearray *SafeArray, dimension uint32) (upperBound int64, err error) {
|
func safeArrayGetUBound(safearray *SafeArray, dimension uint32) (upperBound int32, err error) {
|
||||||
err = convertHresultToError(
|
err = convertHresultToError(
|
||||||
procSafeArrayGetUBound.Call(
|
procSafeArrayGetUBound.Call(
|
||||||
uintptr(unsafe.Pointer(safearray)),
|
uintptr(unsafe.Pointer(safearray)),
|
||||||
|
|
|
@ -14,7 +14,7 @@ func (sac *SafeArrayConversion) ToStringArray() (strings []string) {
|
||||||
totalElements, _ := sac.TotalElements(0)
|
totalElements, _ := sac.TotalElements(0)
|
||||||
strings = make([]string, totalElements)
|
strings = make([]string, totalElements)
|
||||||
|
|
||||||
for i := int64(0); i < totalElements; i++ {
|
for i := int32(0); i < totalElements; i++ {
|
||||||
strings[int32(i)], _ = safeArrayGetElementString(sac.Array, i)
|
strings[int32(i)], _ = safeArrayGetElementString(sac.Array, i)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ func (sac *SafeArrayConversion) ToByteArray() (bytes []byte) {
|
||||||
totalElements, _ := sac.TotalElements(0)
|
totalElements, _ := sac.TotalElements(0)
|
||||||
bytes = make([]byte, totalElements)
|
bytes = make([]byte, totalElements)
|
||||||
|
|
||||||
for i := int64(0); i < totalElements; i++ {
|
for i := int32(0); i < totalElements; i++ {
|
||||||
safeArrayGetElement(sac.Array, i, unsafe.Pointer(&bytes[int32(i)]))
|
safeArrayGetElement(sac.Array, i, unsafe.Pointer(&bytes[int32(i)]))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,59 +37,59 @@ func (sac *SafeArrayConversion) ToValueArray() (values []interface{}) {
|
||||||
values = make([]interface{}, totalElements)
|
values = make([]interface{}, totalElements)
|
||||||
vt, _ := safeArrayGetVartype(sac.Array)
|
vt, _ := safeArrayGetVartype(sac.Array)
|
||||||
|
|
||||||
for i := 0; i < int(totalElements); i++ {
|
for i := int32(0); i < totalElements; i++ {
|
||||||
switch VT(vt) {
|
switch VT(vt) {
|
||||||
case VT_BOOL:
|
case VT_BOOL:
|
||||||
var v bool
|
var v bool
|
||||||
safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v))
|
safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v))
|
||||||
values[i] = v
|
values[i] = v
|
||||||
case VT_I1:
|
case VT_I1:
|
||||||
var v int8
|
var v int8
|
||||||
safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v))
|
safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v))
|
||||||
values[i] = v
|
values[i] = v
|
||||||
case VT_I2:
|
case VT_I2:
|
||||||
var v int16
|
var v int16
|
||||||
safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v))
|
safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v))
|
||||||
values[i] = v
|
values[i] = v
|
||||||
case VT_I4:
|
case VT_I4:
|
||||||
var v int32
|
var v int32
|
||||||
safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v))
|
safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v))
|
||||||
values[i] = v
|
values[i] = v
|
||||||
case VT_I8:
|
case VT_I8:
|
||||||
var v int64
|
var v int64
|
||||||
safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v))
|
safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v))
|
||||||
values[i] = v
|
values[i] = v
|
||||||
case VT_UI1:
|
case VT_UI1:
|
||||||
var v uint8
|
var v uint8
|
||||||
safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v))
|
safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v))
|
||||||
values[i] = v
|
values[i] = v
|
||||||
case VT_UI2:
|
case VT_UI2:
|
||||||
var v uint16
|
var v uint16
|
||||||
safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v))
|
safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v))
|
||||||
values[i] = v
|
values[i] = v
|
||||||
case VT_UI4:
|
case VT_UI4:
|
||||||
var v uint32
|
var v uint32
|
||||||
safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v))
|
safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v))
|
||||||
values[i] = v
|
values[i] = v
|
||||||
case VT_UI8:
|
case VT_UI8:
|
||||||
var v uint64
|
var v uint64
|
||||||
safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v))
|
safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v))
|
||||||
values[i] = v
|
values[i] = v
|
||||||
case VT_R4:
|
case VT_R4:
|
||||||
var v float32
|
var v float32
|
||||||
safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v))
|
safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v))
|
||||||
values[i] = v
|
values[i] = v
|
||||||
case VT_R8:
|
case VT_R8:
|
||||||
var v float64
|
var v float64
|
||||||
safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v))
|
safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v))
|
||||||
values[i] = v
|
values[i] = v
|
||||||
case VT_BSTR:
|
case VT_BSTR:
|
||||||
var v string
|
var v string
|
||||||
safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v))
|
safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v))
|
||||||
values[i] = v
|
values[i] = v
|
||||||
case VT_VARIANT:
|
case VT_VARIANT:
|
||||||
var v VARIANT
|
var v VARIANT
|
||||||
safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v))
|
safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v))
|
||||||
values[i] = v.Value()
|
values[i] = v.Value()
|
||||||
default:
|
default:
|
||||||
// TODO
|
// TODO
|
||||||
|
@ -111,14 +111,14 @@ func (sac *SafeArrayConversion) GetSize() (length *uint32, err error) {
|
||||||
return safeArrayGetElementSize(sac.Array)
|
return safeArrayGetElementSize(sac.Array)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sac *SafeArrayConversion) TotalElements(index uint32) (totalElements int64, err error) {
|
func (sac *SafeArrayConversion) TotalElements(index uint32) (totalElements int32, err error) {
|
||||||
if index < 1 {
|
if index < 1 {
|
||||||
index = 1
|
index = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get array bounds
|
// Get array bounds
|
||||||
var LowerBounds int64
|
var LowerBounds int32
|
||||||
var UpperBounds int64
|
var UpperBounds int32
|
||||||
|
|
||||||
LowerBounds, err = safeArrayGetLBound(sac.Array, index)
|
LowerBounds, err = safeArrayGetLBound(sac.Array, index)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -88,10 +88,10 @@ func (v *VARIANT) Value() interface{} {
|
||||||
return v.ToString()
|
return v.ToString()
|
||||||
case VT_DATE:
|
case VT_DATE:
|
||||||
// VT_DATE type will either return float64 or time.Time.
|
// VT_DATE type will either return float64 or time.Time.
|
||||||
d := float64(v.Val)
|
d := uint64(v.Val)
|
||||||
date, err := GetVariantDate(d)
|
date, err := GetVariantDate(d)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return d
|
return float64(v.Val)
|
||||||
}
|
}
|
||||||
return date
|
return date
|
||||||
case VT_UNKNOWN:
|
case VT_UNKNOWN:
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
// +build windows,386
|
||||||
|
|
||||||
|
package ole
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetVariantDate converts COM Variant Time value to Go time.Time.
|
||||||
|
func GetVariantDate(value uint64) (time.Time, error) {
|
||||||
|
var st syscall.Systemtime
|
||||||
|
v1 := uint32(value)
|
||||||
|
v2 := uint32(value >> 32)
|
||||||
|
r, _, _ := procVariantTimeToSystemTime.Call(uintptr(v1), uintptr(v2), uintptr(unsafe.Pointer(&st)))
|
||||||
|
if r != 0 {
|
||||||
|
return time.Date(int(st.Year), time.Month(st.Month), int(st.Day), int(st.Hour), int(st.Minute), int(st.Second), int(st.Milliseconds/1000), time.UTC), nil
|
||||||
|
}
|
||||||
|
return time.Now(), errors.New("Could not convert to time, passing current time.")
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
// +build windows,amd64
|
||||||
|
|
||||||
|
package ole
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetVariantDate converts COM Variant Time value to Go time.Time.
|
||||||
|
func GetVariantDate(value uint64) (time.Time, error) {
|
||||||
|
var st syscall.Systemtime
|
||||||
|
r, _, _ := procVariantTimeToSystemTime.Call(uintptr(value), uintptr(unsafe.Pointer(&st)))
|
||||||
|
if r != 0 {
|
||||||
|
return time.Date(int(st.Year), time.Month(st.Month), int(st.Day), int(st.Hour), int(st.Minute), int(st.Second), int(st.Milliseconds/1000), time.UTC), nil
|
||||||
|
}
|
||||||
|
return time.Now(), errors.New("Could not convert to time, passing current time.")
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
// +build ppc64le
|
||||||
|
|
||||||
|
package ole
|
||||||
|
|
||||||
|
type VARIANT struct {
|
||||||
|
VT VT // 2
|
||||||
|
wReserved1 uint16 // 4
|
||||||
|
wReserved2 uint16 // 6
|
||||||
|
wReserved3 uint16 // 8
|
||||||
|
Val int64 // 16
|
||||||
|
_ [8]byte // 24
|
||||||
|
}
|
|
@ -1,61 +0,0 @@
|
||||||
package disk
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
|
|
||||||
"github.com/shirou/gopsutil/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)
|
|
||||||
}
|
|
|
@ -1,322 +0,0 @@
|
||||||
package process
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"runtime"
|
|
||||||
"sort"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/shirou/gopsutil/cpu"
|
|
||||||
"github.com/shirou/gopsutil/internal/common"
|
|
||||||
"github.com/shirou/gopsutil/mem"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
invoke common.Invoker = common.Invoke{}
|
|
||||||
ErrorNoChildren = errors.New("process does not have children")
|
|
||||||
ErrorProcessNotRunning = errors.New("process does not exist")
|
|
||||||
)
|
|
||||||
|
|
||||||
type Process struct {
|
|
||||||
Pid int32 `json:"pid"`
|
|
||||||
name string
|
|
||||||
status string
|
|
||||||
parent int32
|
|
||||||
numCtxSwitches *NumCtxSwitchesStat
|
|
||||||
uids []int32
|
|
||||||
gids []int32
|
|
||||||
groups []int32
|
|
||||||
numThreads int32
|
|
||||||
memInfo *MemoryInfoStat
|
|
||||||
sigInfo *SignalInfoStat
|
|
||||||
createTime int64
|
|
||||||
|
|
||||||
lastCPUTimes *cpu.TimesStat
|
|
||||||
lastCPUTime time.Time
|
|
||||||
|
|
||||||
tgid int32
|
|
||||||
}
|
|
||||||
|
|
||||||
type OpenFilesStat struct {
|
|
||||||
Path string `json:"path"`
|
|
||||||
Fd uint64 `json:"fd"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type MemoryInfoStat struct {
|
|
||||||
RSS uint64 `json:"rss"` // bytes
|
|
||||||
VMS uint64 `json:"vms"` // bytes
|
|
||||||
HWM uint64 `json:"hwm"` // bytes
|
|
||||||
Data uint64 `json:"data"` // bytes
|
|
||||||
Stack uint64 `json:"stack"` // bytes
|
|
||||||
Locked uint64 `json:"locked"` // bytes
|
|
||||||
Swap uint64 `json:"swap"` // bytes
|
|
||||||
}
|
|
||||||
|
|
||||||
type SignalInfoStat struct {
|
|
||||||
PendingProcess uint64 `json:"pending_process"`
|
|
||||||
PendingThread uint64 `json:"pending_thread"`
|
|
||||||
Blocked uint64 `json:"blocked"`
|
|
||||||
Ignored uint64 `json:"ignored"`
|
|
||||||
Caught uint64 `json:"caught"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type RlimitStat struct {
|
|
||||||
Resource int32 `json:"resource"`
|
|
||||||
Soft int32 `json:"soft"` //TODO too small. needs to be uint64
|
|
||||||
Hard int32 `json:"hard"` //TODO too small. needs to be uint64
|
|
||||||
Used uint64 `json:"used"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type IOCountersStat struct {
|
|
||||||
ReadCount uint64 `json:"readCount"`
|
|
||||||
WriteCount uint64 `json:"writeCount"`
|
|
||||||
ReadBytes uint64 `json:"readBytes"`
|
|
||||||
WriteBytes uint64 `json:"writeBytes"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type NumCtxSwitchesStat struct {
|
|
||||||
Voluntary int64 `json:"voluntary"`
|
|
||||||
Involuntary int64 `json:"involuntary"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type PageFaultsStat struct {
|
|
||||||
MinorFaults uint64 `json:"minorFaults"`
|
|
||||||
MajorFaults uint64 `json:"majorFaults"`
|
|
||||||
ChildMinorFaults uint64 `json:"childMinorFaults"`
|
|
||||||
ChildMajorFaults uint64 `json:"childMajorFaults"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resource limit constants are from /usr/include/x86_64-linux-gnu/bits/resource.h
|
|
||||||
// from libc6-dev package in Ubuntu 16.10
|
|
||||||
const (
|
|
||||||
RLIMIT_CPU int32 = 0
|
|
||||||
RLIMIT_FSIZE int32 = 1
|
|
||||||
RLIMIT_DATA int32 = 2
|
|
||||||
RLIMIT_STACK int32 = 3
|
|
||||||
RLIMIT_CORE int32 = 4
|
|
||||||
RLIMIT_RSS int32 = 5
|
|
||||||
RLIMIT_NPROC int32 = 6
|
|
||||||
RLIMIT_NOFILE int32 = 7
|
|
||||||
RLIMIT_MEMLOCK int32 = 8
|
|
||||||
RLIMIT_AS int32 = 9
|
|
||||||
RLIMIT_LOCKS int32 = 10
|
|
||||||
RLIMIT_SIGPENDING int32 = 11
|
|
||||||
RLIMIT_MSGQUEUE int32 = 12
|
|
||||||
RLIMIT_NICE int32 = 13
|
|
||||||
RLIMIT_RTPRIO int32 = 14
|
|
||||||
RLIMIT_RTTIME int32 = 15
|
|
||||||
)
|
|
||||||
|
|
||||||
func (p Process) String() string {
|
|
||||||
s, _ := json.Marshal(p)
|
|
||||||
return string(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o OpenFilesStat) String() string {
|
|
||||||
s, _ := json.Marshal(o)
|
|
||||||
return string(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m MemoryInfoStat) String() string {
|
|
||||||
s, _ := json.Marshal(m)
|
|
||||||
return string(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r RlimitStat) String() string {
|
|
||||||
s, _ := json.Marshal(r)
|
|
||||||
return string(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i IOCountersStat) String() string {
|
|
||||||
s, _ := json.Marshal(i)
|
|
||||||
return string(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p NumCtxSwitchesStat) String() string {
|
|
||||||
s, _ := json.Marshal(p)
|
|
||||||
return string(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pids returns a slice of process ID list which are running now.
|
|
||||||
func Pids() ([]int32, error) {
|
|
||||||
return PidsWithContext(context.Background())
|
|
||||||
}
|
|
||||||
|
|
||||||
func PidsWithContext(ctx context.Context) ([]int32, error) {
|
|
||||||
pids, err := pidsWithContext(ctx)
|
|
||||||
sort.Slice(pids, func(i, j int) bool { return pids[i] < pids[j] })
|
|
||||||
return pids, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewProcess creates a new Process instance, it only stores the pid and
|
|
||||||
// checks that the process exists. Other method on Process can be used
|
|
||||||
// to get more information about the process. An error will be returned
|
|
||||||
// if the process does not exist.
|
|
||||||
func NewProcess(pid int32) (*Process, error) {
|
|
||||||
p := &Process{Pid: pid}
|
|
||||||
|
|
||||||
exists, err := PidExists(pid)
|
|
||||||
if err != nil {
|
|
||||||
return p, err
|
|
||||||
}
|
|
||||||
if !exists {
|
|
||||||
return p, ErrorProcessNotRunning
|
|
||||||
}
|
|
||||||
p.CreateTime()
|
|
||||||
return p, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func PidExists(pid int32) (bool, error) {
|
|
||||||
return PidExistsWithContext(context.Background(), pid)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Background returns true if the process is in background, false otherwise.
|
|
||||||
func (p *Process) Background() (bool, error) {
|
|
||||||
return p.BackgroundWithContext(context.Background())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Process) BackgroundWithContext(ctx context.Context) (bool, error) {
|
|
||||||
fg, err := p.ForegroundWithContext(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
return !fg, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// If interval is 0, return difference from last call(non-blocking).
|
|
||||||
// If interval > 0, wait interval sec and return diffrence between start and end.
|
|
||||||
func (p *Process) Percent(interval time.Duration) (float64, error) {
|
|
||||||
return p.PercentWithContext(context.Background(), interval)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Process) PercentWithContext(ctx context.Context, interval time.Duration) (float64, error) {
|
|
||||||
cpuTimes, err := p.Times()
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
now := time.Now()
|
|
||||||
|
|
||||||
if interval > 0 {
|
|
||||||
p.lastCPUTimes = cpuTimes
|
|
||||||
p.lastCPUTime = now
|
|
||||||
if err := common.Sleep(ctx, interval); err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
cpuTimes, err = p.Times()
|
|
||||||
now = time.Now()
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if p.lastCPUTimes == nil {
|
|
||||||
// invoked first time
|
|
||||||
p.lastCPUTimes = cpuTimes
|
|
||||||
p.lastCPUTime = now
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
numcpu := runtime.NumCPU()
|
|
||||||
delta := (now.Sub(p.lastCPUTime).Seconds()) * float64(numcpu)
|
|
||||||
ret := calculatePercent(p.lastCPUTimes, cpuTimes, delta, numcpu)
|
|
||||||
p.lastCPUTimes = cpuTimes
|
|
||||||
p.lastCPUTime = now
|
|
||||||
return ret, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsRunning returns whether the process is still running or not.
|
|
||||||
func (p *Process) IsRunning() (bool, error) {
|
|
||||||
return p.IsRunningWithContext(context.Background())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Process) IsRunningWithContext(ctx context.Context) (bool, error) {
|
|
||||||
createTime, err := p.CreateTimeWithContext(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
p2, err := NewProcess(p.Pid)
|
|
||||||
if err == ErrorProcessNotRunning {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
createTime2, err := p2.CreateTimeWithContext(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
return createTime == createTime2, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateTime returns created time of the process in milliseconds since the epoch, in UTC.
|
|
||||||
func (p *Process) CreateTime() (int64, error) {
|
|
||||||
return p.CreateTimeWithContext(context.Background())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Process) CreateTimeWithContext(ctx context.Context) (int64, error) {
|
|
||||||
if p.createTime != 0 {
|
|
||||||
return p.createTime, nil
|
|
||||||
}
|
|
||||||
createTime, err := p.createTimeWithContext(ctx)
|
|
||||||
p.createTime = createTime
|
|
||||||
return p.createTime, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func calculatePercent(t1, t2 *cpu.TimesStat, delta float64, numcpu int) float64 {
|
|
||||||
if delta == 0 {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
delta_proc := t2.Total() - t1.Total()
|
|
||||||
overall_percent := ((delta_proc / delta) * 100) * float64(numcpu)
|
|
||||||
return overall_percent
|
|
||||||
}
|
|
||||||
|
|
||||||
// MemoryPercent returns how many percent of the total RAM this process uses
|
|
||||||
func (p *Process) MemoryPercent() (float32, error) {
|
|
||||||
return p.MemoryPercentWithContext(context.Background())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Process) MemoryPercentWithContext(ctx context.Context) (float32, error) {
|
|
||||||
machineMemory, err := mem.VirtualMemory()
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
total := machineMemory.Total
|
|
||||||
|
|
||||||
processMemory, err := p.MemoryInfo()
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
used := processMemory.RSS
|
|
||||||
|
|
||||||
return (100 * float32(used) / float32(total)), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CPU_Percent returns how many percent of the CPU time this process uses
|
|
||||||
func (p *Process) CPUPercent() (float64, error) {
|
|
||||||
return p.CPUPercentWithContext(context.Background())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Process) CPUPercentWithContext(ctx context.Context) (float64, error) {
|
|
||||||
crt_time, err := p.CreateTime()
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
cput, err := p.Times()
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
created := time.Unix(0, crt_time*int64(time.Millisecond))
|
|
||||||
totalTime := time.Since(created).Seconds()
|
|
||||||
if totalTime <= 0 {
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return 100 * cput.Total() / totalTime, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Groups returns all group IDs(include supplementary groups) of the process as a slice of the int
|
|
||||||
func (p *Process) Groups() ([]int32, error) {
|
|
||||||
return p.GroupsWithContext(context.Background())
|
|
||||||
}
|
|
|
@ -0,0 +1,599 @@
|
||||||
|
/*
|
||||||
|
* Apple System Management Control (SMC) Tool
|
||||||
|
* Copyright (C) 2006 devnull
|
||||||
|
* Portions Copyright (C) 2013 Michael Wilber
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <IOKit/IOKitLib.h>
|
||||||
|
#include "_smc.h"
|
||||||
|
#include <libkern/OSAtomic.h>
|
||||||
|
|
||||||
|
// Cache the keyInfo to lower the energy impact of SMCReadKey() / SMCReadKey2()
|
||||||
|
#define KEY_INFO_CACHE_SIZE 100
|
||||||
|
struct {
|
||||||
|
UInt32 key;
|
||||||
|
SMCKeyData_keyInfo_t keyInfo;
|
||||||
|
} g_keyInfoCache[KEY_INFO_CACHE_SIZE];
|
||||||
|
|
||||||
|
int g_keyInfoCacheCount = 0;
|
||||||
|
OSSpinLock g_keyInfoSpinLock = 0;
|
||||||
|
|
||||||
|
kern_return_t SMCCall2(int index, SMCKeyData_t *inputStructure, SMCKeyData_t *outputStructure, io_connect_t conn);
|
||||||
|
|
||||||
|
UInt32 _strtoul(char *str, int size, int base)
|
||||||
|
{
|
||||||
|
UInt32 total = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
if (base == 16)
|
||||||
|
total += str[i] << (size - 1 - i) * 8;
|
||||||
|
else
|
||||||
|
total += ((unsigned char) (str[i]) << (size - 1 - i) * 8);
|
||||||
|
}
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _ultostr(char *str, UInt32 val)
|
||||||
|
{
|
||||||
|
str[0] = '\0';
|
||||||
|
sprintf(str, "%c%c%c%c",
|
||||||
|
(unsigned int) val >> 24,
|
||||||
|
(unsigned int) val >> 16,
|
||||||
|
(unsigned int) val >> 8,
|
||||||
|
(unsigned int) val);
|
||||||
|
}
|
||||||
|
|
||||||
|
float _strtof(unsigned char *str, int size, int e)
|
||||||
|
{
|
||||||
|
float total = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
if (i == (size - 1))
|
||||||
|
total += (str[i] & 0xff) >> e;
|
||||||
|
else
|
||||||
|
total += str[i] << (size - 1 - i) * (8 - e);
|
||||||
|
}
|
||||||
|
|
||||||
|
total += (str[size-1] & 0x03) * 0.25;
|
||||||
|
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void printFP1F(SMCVal_t val)
|
||||||
|
{
|
||||||
|
printf("%.5f ", ntohs(*(UInt16*)val.bytes) / 32768.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printFP4C(SMCVal_t val)
|
||||||
|
{
|
||||||
|
printf("%.5f ", ntohs(*(UInt16*)val.bytes) / 4096.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printFP5B(SMCVal_t val)
|
||||||
|
{
|
||||||
|
printf("%.5f ", ntohs(*(UInt16*)val.bytes) / 2048.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printFP6A(SMCVal_t val)
|
||||||
|
{
|
||||||
|
printf("%.4f ", ntohs(*(UInt16*)val.bytes) / 1024.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printFP79(SMCVal_t val)
|
||||||
|
{
|
||||||
|
printf("%.4f ", ntohs(*(UInt16*)val.bytes) / 512.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printFP88(SMCVal_t val)
|
||||||
|
{
|
||||||
|
printf("%.3f ", ntohs(*(UInt16*)val.bytes) / 256.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printFPA6(SMCVal_t val)
|
||||||
|
{
|
||||||
|
printf("%.2f ", ntohs(*(UInt16*)val.bytes) / 64.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printFPC4(SMCVal_t val)
|
||||||
|
{
|
||||||
|
printf("%.2f ", ntohs(*(UInt16*)val.bytes) / 16.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printFPE2(SMCVal_t val)
|
||||||
|
{
|
||||||
|
printf("%.2f ", ntohs(*(UInt16*)val.bytes) / 4.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printUInt(SMCVal_t val)
|
||||||
|
{
|
||||||
|
printf("%u ", (unsigned int) _strtoul((char *)val.bytes, val.dataSize, 10));
|
||||||
|
}
|
||||||
|
|
||||||
|
void printSP1E(SMCVal_t val)
|
||||||
|
{
|
||||||
|
printf("%.5f ", ((SInt16)ntohs(*(UInt16*)val.bytes)) / 16384.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printSP3C(SMCVal_t val)
|
||||||
|
{
|
||||||
|
printf("%.5f ", ((SInt16)ntohs(*(UInt16*)val.bytes)) / 4096.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printSP4B(SMCVal_t val)
|
||||||
|
{
|
||||||
|
printf("%.4f ", ((SInt16)ntohs(*(UInt16*)val.bytes)) / 2048.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printSP5A(SMCVal_t val)
|
||||||
|
{
|
||||||
|
printf("%.4f ", ((SInt16)ntohs(*(UInt16*)val.bytes)) / 1024.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printSP69(SMCVal_t val)
|
||||||
|
{
|
||||||
|
printf("%.3f ", ((SInt16)ntohs(*(UInt16*)val.bytes)) / 512.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printSP78(SMCVal_t val)
|
||||||
|
{
|
||||||
|
printf("%.3f ", ((SInt16)ntohs(*(UInt16*)val.bytes)) / 256.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printSP87(SMCVal_t val)
|
||||||
|
{
|
||||||
|
printf("%.3f ", ((SInt16)ntohs(*(UInt16*)val.bytes)) / 128.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printSP96(SMCVal_t val)
|
||||||
|
{
|
||||||
|
printf("%.2f ", ((SInt16)ntohs(*(UInt16*)val.bytes)) / 64.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printSPB4(SMCVal_t val)
|
||||||
|
{
|
||||||
|
printf("%.2f ", ((SInt16)ntohs(*(UInt16*)val.bytes)) / 16.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printSPF0(SMCVal_t val)
|
||||||
|
{
|
||||||
|
printf("%.0f ", (float)ntohs(*(UInt16*)val.bytes));
|
||||||
|
}
|
||||||
|
|
||||||
|
void printSI8(SMCVal_t val)
|
||||||
|
{
|
||||||
|
printf("%d ", (signed char)*val.bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printSI16(SMCVal_t val)
|
||||||
|
{
|
||||||
|
printf("%d ", ntohs(*(SInt16*)val.bytes));
|
||||||
|
}
|
||||||
|
|
||||||
|
void printPWM(SMCVal_t val)
|
||||||
|
{
|
||||||
|
printf("%.1f%% ", ntohs(*(UInt16*)val.bytes) * 100 / 65536.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printBytesHex(SMCVal_t val)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
printf("(bytes");
|
||||||
|
for (i = 0; i < val.dataSize; i++)
|
||||||
|
printf(" %02x", (unsigned char) val.bytes[i]);
|
||||||
|
printf(")\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void printVal(SMCVal_t val)
|
||||||
|
{
|
||||||
|
printf(" %-4s [%-4s] ", val.key, val.dataType);
|
||||||
|
if (val.dataSize > 0)
|
||||||
|
{
|
||||||
|
if ((strcmp(val.dataType, DATATYPE_UINT8) == 0) ||
|
||||||
|
(strcmp(val.dataType, DATATYPE_UINT16) == 0) ||
|
||||||
|
(strcmp(val.dataType, DATATYPE_UINT32) == 0))
|
||||||
|
printUInt(val);
|
||||||
|
else if (strcmp(val.dataType, DATATYPE_FP1F) == 0 && val.dataSize == 2)
|
||||||
|
printFP1F(val);
|
||||||
|
else if (strcmp(val.dataType, DATATYPE_FP4C) == 0 && val.dataSize == 2)
|
||||||
|
printFP4C(val);
|
||||||
|
else if (strcmp(val.dataType, DATATYPE_FP5B) == 0 && val.dataSize == 2)
|
||||||
|
printFP5B(val);
|
||||||
|
else if (strcmp(val.dataType, DATATYPE_FP6A) == 0 && val.dataSize == 2)
|
||||||
|
printFP6A(val);
|
||||||
|
else if (strcmp(val.dataType, DATATYPE_FP79) == 0 && val.dataSize == 2)
|
||||||
|
printFP79(val);
|
||||||
|
else if (strcmp(val.dataType, DATATYPE_FP88) == 0 && val.dataSize == 2)
|
||||||
|
printFP88(val);
|
||||||
|
else if (strcmp(val.dataType, DATATYPE_FPA6) == 0 && val.dataSize == 2)
|
||||||
|
printFPA6(val);
|
||||||
|
else if (strcmp(val.dataType, DATATYPE_FPC4) == 0 && val.dataSize == 2)
|
||||||
|
printFPC4(val);
|
||||||
|
else if (strcmp(val.dataType, DATATYPE_FPE2) == 0 && val.dataSize == 2)
|
||||||
|
printFPE2(val);
|
||||||
|
else if (strcmp(val.dataType, DATATYPE_SP1E) == 0 && val.dataSize == 2)
|
||||||
|
printSP1E(val);
|
||||||
|
else if (strcmp(val.dataType, DATATYPE_SP3C) == 0 && val.dataSize == 2)
|
||||||
|
printSP3C(val);
|
||||||
|
else if (strcmp(val.dataType, DATATYPE_SP4B) == 0 && val.dataSize == 2)
|
||||||
|
printSP4B(val);
|
||||||
|
else if (strcmp(val.dataType, DATATYPE_SP5A) == 0 && val.dataSize == 2)
|
||||||
|
printSP5A(val);
|
||||||
|
else if (strcmp(val.dataType, DATATYPE_SP69) == 0 && val.dataSize == 2)
|
||||||
|
printSP69(val);
|
||||||
|
else if (strcmp(val.dataType, DATATYPE_SP78) == 0 && val.dataSize == 2)
|
||||||
|
printSP78(val);
|
||||||
|
else if (strcmp(val.dataType, DATATYPE_SP87) == 0 && val.dataSize == 2)
|
||||||
|
printSP87(val);
|
||||||
|
else if (strcmp(val.dataType, DATATYPE_SP96) == 0 && val.dataSize == 2)
|
||||||
|
printSP96(val);
|
||||||
|
else if (strcmp(val.dataType, DATATYPE_SPB4) == 0 && val.dataSize == 2)
|
||||||
|
printSPB4(val);
|
||||||
|
else if (strcmp(val.dataType, DATATYPE_SPF0) == 0 && val.dataSize == 2)
|
||||||
|
printSPF0(val);
|
||||||
|
else if (strcmp(val.dataType, DATATYPE_SI8) == 0 && val.dataSize == 1)
|
||||||
|
printSI8(val);
|
||||||
|
else if (strcmp(val.dataType, DATATYPE_SI16) == 0 && val.dataSize == 2)
|
||||||
|
printSI16(val);
|
||||||
|
else if (strcmp(val.dataType, DATATYPE_PWM) == 0 && val.dataSize == 2)
|
||||||
|
printPWM(val);
|
||||||
|
|
||||||
|
printBytesHex(val);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("no data\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
kern_return_t SMCOpen(io_connect_t *conn)
|
||||||
|
{
|
||||||
|
kern_return_t result;
|
||||||
|
mach_port_t masterPort;
|
||||||
|
io_iterator_t iterator;
|
||||||
|
io_object_t device;
|
||||||
|
|
||||||
|
IOMasterPort(MACH_PORT_NULL, &masterPort);
|
||||||
|
|
||||||
|
CFMutableDictionaryRef matchingDictionary = IOServiceMatching("AppleSMC");
|
||||||
|
result = IOServiceGetMatchingServices(masterPort, matchingDictionary, &iterator);
|
||||||
|
if (result != kIOReturnSuccess)
|
||||||
|
{
|
||||||
|
printf("Error: IOServiceGetMatchingServices() = %08x\n", result);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
device = IOIteratorNext(iterator);
|
||||||
|
IOObjectRelease(iterator);
|
||||||
|
if (device == 0)
|
||||||
|
{
|
||||||
|
printf("Error: no SMC found\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = IOServiceOpen(device, mach_task_self(), 0, conn);
|
||||||
|
IOObjectRelease(device);
|
||||||
|
if (result != kIOReturnSuccess)
|
||||||
|
{
|
||||||
|
printf("Error: IOServiceOpen() = %08x\n", result);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return kIOReturnSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
kern_return_t SMCClose(io_connect_t conn)
|
||||||
|
{
|
||||||
|
return IOServiceClose(conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
kern_return_t SMCCall2(int index, SMCKeyData_t *inputStructure, SMCKeyData_t *outputStructure,io_connect_t conn)
|
||||||
|
{
|
||||||
|
size_t structureInputSize;
|
||||||
|
size_t structureOutputSize;
|
||||||
|
structureInputSize = sizeof(SMCKeyData_t);
|
||||||
|
structureOutputSize = sizeof(SMCKeyData_t);
|
||||||
|
|
||||||
|
return IOConnectCallStructMethod(conn, index, inputStructure, structureInputSize, outputStructure, &structureOutputSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Provides key info, using a cache to dramatically improve the energy impact of smcFanControl
|
||||||
|
kern_return_t SMCGetKeyInfo(UInt32 key, SMCKeyData_keyInfo_t* keyInfo, io_connect_t conn)
|
||||||
|
{
|
||||||
|
SMCKeyData_t inputStructure;
|
||||||
|
SMCKeyData_t outputStructure;
|
||||||
|
kern_return_t result = kIOReturnSuccess;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
OSSpinLockLock(&g_keyInfoSpinLock);
|
||||||
|
|
||||||
|
for (; i < g_keyInfoCacheCount; ++i)
|
||||||
|
{
|
||||||
|
if (key == g_keyInfoCache[i].key)
|
||||||
|
{
|
||||||
|
*keyInfo = g_keyInfoCache[i].keyInfo;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == g_keyInfoCacheCount)
|
||||||
|
{
|
||||||
|
// Not in cache, must look it up.
|
||||||
|
memset(&inputStructure, 0, sizeof(inputStructure));
|
||||||
|
memset(&outputStructure, 0, sizeof(outputStructure));
|
||||||
|
|
||||||
|
inputStructure.key = key;
|
||||||
|
inputStructure.data8 = SMC_CMD_READ_KEYINFO;
|
||||||
|
|
||||||
|
result = SMCCall2(KERNEL_INDEX_SMC, &inputStructure, &outputStructure, conn);
|
||||||
|
if (result == kIOReturnSuccess)
|
||||||
|
{
|
||||||
|
*keyInfo = outputStructure.keyInfo;
|
||||||
|
if (g_keyInfoCacheCount < KEY_INFO_CACHE_SIZE)
|
||||||
|
{
|
||||||
|
g_keyInfoCache[g_keyInfoCacheCount].key = key;
|
||||||
|
g_keyInfoCache[g_keyInfoCacheCount].keyInfo = outputStructure.keyInfo;
|
||||||
|
++g_keyInfoCacheCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OSSpinLockUnlock(&g_keyInfoSpinLock);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
kern_return_t SMCReadKey2(UInt32Char_t key, SMCVal_t *val,io_connect_t conn)
|
||||||
|
{
|
||||||
|
kern_return_t result;
|
||||||
|
SMCKeyData_t inputStructure;
|
||||||
|
SMCKeyData_t outputStructure;
|
||||||
|
|
||||||
|
memset(&inputStructure, 0, sizeof(SMCKeyData_t));
|
||||||
|
memset(&outputStructure, 0, sizeof(SMCKeyData_t));
|
||||||
|
memset(val, 0, sizeof(SMCVal_t));
|
||||||
|
|
||||||
|
inputStructure.key = _strtoul(key, 4, 16);
|
||||||
|
sprintf(val->key, key);
|
||||||
|
|
||||||
|
result = SMCGetKeyInfo(inputStructure.key, &outputStructure.keyInfo, conn);
|
||||||
|
if (result != kIOReturnSuccess)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
val->dataSize = outputStructure.keyInfo.dataSize;
|
||||||
|
_ultostr(val->dataType, outputStructure.keyInfo.dataType);
|
||||||
|
inputStructure.keyInfo.dataSize = val->dataSize;
|
||||||
|
inputStructure.data8 = SMC_CMD_READ_BYTES;
|
||||||
|
|
||||||
|
result = SMCCall2(KERNEL_INDEX_SMC, &inputStructure, &outputStructure,conn);
|
||||||
|
if (result != kIOReturnSuccess)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(val->bytes, outputStructure.bytes, sizeof(outputStructure.bytes));
|
||||||
|
|
||||||
|
return kIOReturnSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
io_connect_t g_conn = 0;
|
||||||
|
|
||||||
|
void smc_init(){
|
||||||
|
SMCOpen(&g_conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
void smc_close(){
|
||||||
|
SMCClose(g_conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
kern_return_t SMCCall(int index, SMCKeyData_t *inputStructure, SMCKeyData_t *outputStructure)
|
||||||
|
{
|
||||||
|
return SMCCall2(index, inputStructure, outputStructure, g_conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
kern_return_t SMCReadKey(UInt32Char_t key, SMCVal_t *val)
|
||||||
|
{
|
||||||
|
return SMCReadKey2(key, val, g_conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
kern_return_t SMCWriteKey2(SMCVal_t writeVal, io_connect_t conn)
|
||||||
|
{
|
||||||
|
kern_return_t result;
|
||||||
|
SMCKeyData_t inputStructure;
|
||||||
|
SMCKeyData_t outputStructure;
|
||||||
|
|
||||||
|
SMCVal_t readVal;
|
||||||
|
|
||||||
|
result = SMCReadKey2(writeVal.key, &readVal,conn);
|
||||||
|
if (result != kIOReturnSuccess)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
if (readVal.dataSize != writeVal.dataSize)
|
||||||
|
return kIOReturnError;
|
||||||
|
|
||||||
|
memset(&inputStructure, 0, sizeof(SMCKeyData_t));
|
||||||
|
memset(&outputStructure, 0, sizeof(SMCKeyData_t));
|
||||||
|
|
||||||
|
inputStructure.key = _strtoul(writeVal.key, 4, 16);
|
||||||
|
inputStructure.data8 = SMC_CMD_WRITE_BYTES;
|
||||||
|
inputStructure.keyInfo.dataSize = writeVal.dataSize;
|
||||||
|
memcpy(inputStructure.bytes, writeVal.bytes, sizeof(writeVal.bytes));
|
||||||
|
result = SMCCall2(KERNEL_INDEX_SMC, &inputStructure, &outputStructure,conn);
|
||||||
|
|
||||||
|
if (result != kIOReturnSuccess)
|
||||||
|
return result;
|
||||||
|
return kIOReturnSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
kern_return_t SMCWriteKey(SMCVal_t writeVal)
|
||||||
|
{
|
||||||
|
return SMCWriteKey2(writeVal, g_conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt32 SMCReadIndexCount(void)
|
||||||
|
{
|
||||||
|
SMCVal_t val;
|
||||||
|
|
||||||
|
SMCReadKey("#KEY", &val);
|
||||||
|
return _strtoul((char *)val.bytes, val.dataSize, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
kern_return_t SMCPrintAll(void)
|
||||||
|
{
|
||||||
|
kern_return_t result;
|
||||||
|
SMCKeyData_t inputStructure;
|
||||||
|
SMCKeyData_t outputStructure;
|
||||||
|
|
||||||
|
int totalKeys, i;
|
||||||
|
UInt32Char_t key;
|
||||||
|
SMCVal_t val;
|
||||||
|
|
||||||
|
totalKeys = SMCReadIndexCount();
|
||||||
|
for (i = 0; i < totalKeys; i++)
|
||||||
|
{
|
||||||
|
memset(&inputStructure, 0, sizeof(SMCKeyData_t));
|
||||||
|
memset(&outputStructure, 0, sizeof(SMCKeyData_t));
|
||||||
|
memset(&val, 0, sizeof(SMCVal_t));
|
||||||
|
|
||||||
|
inputStructure.data8 = SMC_CMD_READ_INDEX;
|
||||||
|
inputStructure.data32 = i;
|
||||||
|
|
||||||
|
result = SMCCall(KERNEL_INDEX_SMC, &inputStructure, &outputStructure);
|
||||||
|
if (result != kIOReturnSuccess)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
_ultostr(key, outputStructure.key);
|
||||||
|
|
||||||
|
SMCReadKey(key, &val);
|
||||||
|
printVal(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
return kIOReturnSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
kern_return_t SMCPrintFans(void)
|
||||||
|
{
|
||||||
|
kern_return_t result;
|
||||||
|
SMCVal_t val;
|
||||||
|
UInt32Char_t key;
|
||||||
|
int totalFans, i;
|
||||||
|
|
||||||
|
result = SMCReadKey("FNum", &val);
|
||||||
|
if (result != kIOReturnSuccess)
|
||||||
|
return kIOReturnError;
|
||||||
|
|
||||||
|
totalFans = _strtoul((char *)val.bytes, val.dataSize, 10);
|
||||||
|
printf("Total fans in system: %d\n", totalFans);
|
||||||
|
|
||||||
|
for (i = 0; i < totalFans; i++)
|
||||||
|
{
|
||||||
|
printf("\nFan #%d:\n", i);
|
||||||
|
sprintf(key, "F%dID", i);
|
||||||
|
SMCReadKey(key, &val);
|
||||||
|
printf(" Fan ID : %s\n", val.bytes+4);
|
||||||
|
sprintf(key, "F%dAc", i);
|
||||||
|
SMCReadKey(key, &val);
|
||||||
|
printf(" Actual speed : %.0f\n", _strtof(val.bytes, val.dataSize, 2));
|
||||||
|
sprintf(key, "F%dMn", i);
|
||||||
|
SMCReadKey(key, &val);
|
||||||
|
printf(" Minimum speed: %.0f\n", _strtof(val.bytes, val.dataSize, 2));
|
||||||
|
sprintf(key, "F%dMx", i);
|
||||||
|
SMCReadKey(key, &val);
|
||||||
|
printf(" Maximum speed: %.0f\n", _strtof(val.bytes, val.dataSize, 2));
|
||||||
|
sprintf(key, "F%dSf", i);
|
||||||
|
SMCReadKey(key, &val);
|
||||||
|
printf(" Safe speed : %.0f\n", _strtof(val.bytes, val.dataSize, 2));
|
||||||
|
sprintf(key, "F%dTg", i);
|
||||||
|
SMCReadKey(key, &val);
|
||||||
|
printf(" Target speed : %.0f\n", _strtof(val.bytes, val.dataSize, 2));
|
||||||
|
SMCReadKey("FS! ", &val);
|
||||||
|
if ((_strtoul((char *)val.bytes, 2, 16) & (1 << i)) == 0)
|
||||||
|
printf(" Mode : auto\n");
|
||||||
|
else
|
||||||
|
printf(" Mode : forced\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return kIOReturnSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
void usage(char* prog)
|
||||||
|
{
|
||||||
|
printf("Apple System Management Control (SMC) tool %s\n", VERSION);
|
||||||
|
printf("Usage:\n");
|
||||||
|
printf("%s [options]\n", prog);
|
||||||
|
printf(" -f : fan info decoded\n");
|
||||||
|
printf(" -h : help\n");
|
||||||
|
printf(" -k <key> : key to manipulate\n");
|
||||||
|
printf(" -l : list all keys and values\n");
|
||||||
|
printf(" -r : read the value of a key\n");
|
||||||
|
printf(" -w <value> : write the specified value to a key\n");
|
||||||
|
printf(" -v : version\n");
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
kern_return_t SMCWriteSimple(UInt32Char_t key, char *wvalue, io_connect_t conn)
|
||||||
|
{
|
||||||
|
kern_return_t result;
|
||||||
|
SMCVal_t val;
|
||||||
|
int i;
|
||||||
|
char c[3];
|
||||||
|
for (i = 0; i < strlen(wvalue); i++)
|
||||||
|
{
|
||||||
|
sprintf(c, "%c%c", wvalue[i * 2], wvalue[(i * 2) + 1]);
|
||||||
|
val.bytes[i] = (int) strtol(c, NULL, 16);
|
||||||
|
}
|
||||||
|
val.dataSize = i / 2;
|
||||||
|
sprintf(val.key, key);
|
||||||
|
result = SMCWriteKey2(val, conn);
|
||||||
|
if (result != kIOReturnSuccess)
|
||||||
|
printf("Error: SMCWriteKey() = %08x\n", result);
|
||||||
|
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
double SMCGetTemperature(char *key)
|
||||||
|
{
|
||||||
|
SMCVal_t val;
|
||||||
|
kern_return_t result;
|
||||||
|
|
||||||
|
result = SMCReadKey(key, &val);
|
||||||
|
if (result == kIOReturnSuccess) {
|
||||||
|
// read succeeded - check returned value
|
||||||
|
if (val.dataSize > 0) {
|
||||||
|
if (strcmp(val.dataType, DATATYPE_SP78) == 0) {
|
||||||
|
// convert sp78 value to temperature
|
||||||
|
int intValue = val.bytes[0] * 256 + (unsigned char)val.bytes[1];
|
||||||
|
return intValue / 256.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// read failed
|
||||||
|
return 0.0;
|
||||||
|
}
|
|
@ -0,0 +1,133 @@
|
||||||
|
/*
|
||||||
|
* Apple System Management Control (SMC) Tool
|
||||||
|
* Copyright (C) 2006 devnull
|
||||||
|
* Portions Copyright (C) 2013 Michael Wilber
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SMC_H__
|
||||||
|
#define __SMC_H__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define VERSION "0.01"
|
||||||
|
|
||||||
|
#define OP_NONE 0
|
||||||
|
#define OP_LIST 1
|
||||||
|
#define OP_READ 2
|
||||||
|
#define OP_READ_FAN 3
|
||||||
|
#define OP_WRITE 4
|
||||||
|
|
||||||
|
#define KERNEL_INDEX_SMC 2
|
||||||
|
|
||||||
|
#define SMC_CMD_READ_BYTES 5
|
||||||
|
#define SMC_CMD_WRITE_BYTES 6
|
||||||
|
#define SMC_CMD_READ_INDEX 8
|
||||||
|
#define SMC_CMD_READ_KEYINFO 9
|
||||||
|
#define SMC_CMD_READ_PLIMIT 11
|
||||||
|
#define SMC_CMD_READ_VERS 12
|
||||||
|
|
||||||
|
#define DATATYPE_FP1F "fp1f"
|
||||||
|
#define DATATYPE_FP4C "fp4c"
|
||||||
|
#define DATATYPE_FP5B "fp5b"
|
||||||
|
#define DATATYPE_FP6A "fp6a"
|
||||||
|
#define DATATYPE_FP79 "fp79"
|
||||||
|
#define DATATYPE_FP88 "fp88"
|
||||||
|
#define DATATYPE_FPA6 "fpa6"
|
||||||
|
#define DATATYPE_FPC4 "fpc4"
|
||||||
|
#define DATATYPE_FPE2 "fpe2"
|
||||||
|
|
||||||
|
#define DATATYPE_SP1E "sp1e"
|
||||||
|
#define DATATYPE_SP3C "sp3c"
|
||||||
|
#define DATATYPE_SP4B "sp4b"
|
||||||
|
#define DATATYPE_SP5A "sp5a"
|
||||||
|
#define DATATYPE_SP69 "sp69"
|
||||||
|
#define DATATYPE_SP78 "sp78"
|
||||||
|
#define DATATYPE_SP87 "sp87"
|
||||||
|
#define DATATYPE_SP96 "sp96"
|
||||||
|
#define DATATYPE_SPB4 "spb4"
|
||||||
|
#define DATATYPE_SPF0 "spf0"
|
||||||
|
|
||||||
|
#define DATATYPE_UINT8 "ui8 "
|
||||||
|
#define DATATYPE_UINT16 "ui16"
|
||||||
|
#define DATATYPE_UINT32 "ui32"
|
||||||
|
|
||||||
|
#define DATATYPE_SI8 "si8 "
|
||||||
|
#define DATATYPE_SI16 "si16"
|
||||||
|
|
||||||
|
#define DATATYPE_PWM "{pwm"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char major;
|
||||||
|
char minor;
|
||||||
|
char build;
|
||||||
|
char reserved[1];
|
||||||
|
UInt16 release;
|
||||||
|
} SMCKeyData_vers_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
UInt16 version;
|
||||||
|
UInt16 length;
|
||||||
|
UInt32 cpuPLimit;
|
||||||
|
UInt32 gpuPLimit;
|
||||||
|
UInt32 memPLimit;
|
||||||
|
} SMCKeyData_pLimitData_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
UInt32 dataSize;
|
||||||
|
UInt32 dataType;
|
||||||
|
char dataAttributes;
|
||||||
|
} SMCKeyData_keyInfo_t;
|
||||||
|
|
||||||
|
typedef unsigned char SMCBytes_t[32];
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
UInt32 key;
|
||||||
|
SMCKeyData_vers_t vers;
|
||||||
|
SMCKeyData_pLimitData_t pLimitData;
|
||||||
|
SMCKeyData_keyInfo_t keyInfo;
|
||||||
|
char result;
|
||||||
|
char status;
|
||||||
|
char data8;
|
||||||
|
UInt32 data32;
|
||||||
|
SMCBytes_t bytes;
|
||||||
|
} SMCKeyData_t;
|
||||||
|
|
||||||
|
typedef char UInt32Char_t[5];
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
UInt32Char_t key;
|
||||||
|
UInt32 dataSize;
|
||||||
|
UInt32Char_t dataType;
|
||||||
|
SMCBytes_t bytes;
|
||||||
|
} SMCVal_t;
|
||||||
|
|
||||||
|
UInt32 _strtoul(char *str, int size, int base);
|
||||||
|
float _strtof(unsigned char *str, int size, int e);
|
||||||
|
|
||||||
|
// Exclude command-line only code from smcFanControl UI
|
||||||
|
#ifdef CMD_TOOL
|
||||||
|
|
||||||
|
void smc_init();
|
||||||
|
void smc_close();
|
||||||
|
kern_return_t SMCReadKey(UInt32Char_t key, SMCVal_t *val);
|
||||||
|
kern_return_t SMCWriteSimple(UInt32Char_t key,char *wvalue,io_connect_t conn);
|
||||||
|
|
||||||
|
#endif //#ifdef CMD_TOOL
|
||||||
|
|
||||||
|
kern_return_t SMCOpen(io_connect_t *conn);
|
||||||
|
kern_return_t SMCClose(io_connect_t conn);
|
||||||
|
kern_return_t SMCReadKey2(UInt32Char_t key, SMCVal_t *val,io_connect_t conn);
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"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
|
// TimesStat contains the amounts of time the CPU has spent performing different
|
|
@ -14,11 +14,11 @@ import (
|
||||||
// sys/resource.h
|
// sys/resource.h
|
||||||
const (
|
const (
|
||||||
CPUser = 0
|
CPUser = 0
|
||||||
CPNice = 1
|
cpNice = 1
|
||||||
CPSys = 2
|
cpSys = 2
|
||||||
CPIntr = 3
|
cpIntr = 3
|
||||||
CPIdle = 4
|
cpIdle = 4
|
||||||
CPUStates = 5
|
cpUStates = 5
|
||||||
)
|
)
|
||||||
|
|
||||||
// default value. from time.h
|
// default value. from time.h
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
package cpu
|
package cpu
|
||||||
|
|
||||||
import "github.com/shirou/gopsutil/internal/common"
|
import "github.com/shirou/gopsutil/v3/internal/common"
|
||||||
|
|
||||||
func perCPUTimes() ([]TimesStat, error) {
|
func perCPUTimes() ([]TimesStat, error) {
|
||||||
return []TimesStat{}, common.ErrNotImplementedError
|
return []TimesStat{}, common.ErrNotImplementedError
|
|
@ -11,7 +11,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/shirou/gopsutil/internal/common"
|
"github.com/shirou/gopsutil/v3/internal/common"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
"github.com/shirou/gopsutil/internal/common"
|
"github.com/shirou/gopsutil/v3/internal/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Times(percpu bool) ([]TimesStat, error) {
|
func Times(percpu bool) ([]TimesStat, error) {
|
|
@ -11,7 +11,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/shirou/gopsutil/internal/common"
|
"github.com/shirou/gopsutil/v3/internal/common"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
|
@ -11,7 +11,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/shirou/gopsutil/internal/common"
|
"github.com/shirou/gopsutil/v3/internal/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
var ClocksPerSec = float64(100)
|
var ClocksPerSec = float64(100)
|
|
@ -13,27 +13,27 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/shirou/gopsutil/internal/common"
|
"github.com/shirou/gopsutil/v3/internal/common"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
// sys/sched.h
|
// sys/sched.h
|
||||||
var (
|
var (
|
||||||
CPUser = 0
|
CPUser = 0
|
||||||
CPNice = 1
|
cpNice = 1
|
||||||
CPSys = 2
|
cpSys = 2
|
||||||
CPIntr = 3
|
cpIntr = 3
|
||||||
CPIdle = 4
|
cpIdle = 4
|
||||||
CPUStates = 5
|
cpUStates = 5
|
||||||
)
|
)
|
||||||
|
|
||||||
// sys/sysctl.h
|
// sys/sysctl.h
|
||||||
const (
|
const (
|
||||||
CTLKern = 1 // "high kernel": proc, limits
|
ctlKern = 1 // "high kernel": proc, limits
|
||||||
CTLHw = 6 // CTL_HW
|
ctlHw = 6 // CTL_HW
|
||||||
SMT = 24 // HW_SMT
|
sMT = 24 // HW_sMT
|
||||||
KernCptime = 40 // KERN_CPTIME
|
kernCptime = 40 // KERN_CPTIME
|
||||||
KernCptime2 = 71 // KERN_CPTIME2
|
kernCptime2 = 71 // KERN_CPTIME2
|
||||||
)
|
)
|
||||||
|
|
||||||
var ClocksPerSec = float64(128)
|
var ClocksPerSec = float64(128)
|
||||||
|
@ -64,15 +64,15 @@ func init() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if version >= 6.4 {
|
if version >= 6.4 {
|
||||||
CPIntr = 4
|
cpIntr = 4
|
||||||
CPIdle = 5
|
cpIdle = 5
|
||||||
CPUStates = 6
|
cpUStates = 6
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
func smt() (bool, error) {
|
func smt() (bool, error) {
|
||||||
mib := []int32{CTLHw, SMT}
|
mib := []int32{ctlHw, sMT}
|
||||||
buf, _, err := common.CallSyscall(mib)
|
buf, _, err := common.CallSyscall(mib)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
|
@ -116,12 +116,12 @@ func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) {
|
||||||
j *= 2
|
j *= 2
|
||||||
}
|
}
|
||||||
|
|
||||||
var cpuTimes = make([]int32, CPUStates)
|
var cpuTimes = make([]int32, cpUStates)
|
||||||
var mib []int32
|
var mib []int32
|
||||||
if percpu {
|
if percpu {
|
||||||
mib = []int32{CTLKern, KernCptime2, int32(j)}
|
mib = []int32{ctlKern, kernCptime2, int32(j)}
|
||||||
} else {
|
} else {
|
||||||
mib = []int32{CTLKern, KernCptime}
|
mib = []int32{ctlKern, kernCptime}
|
||||||
}
|
}
|
||||||
buf, _, err := common.CallSyscall(mib)
|
buf, _, err := common.CallSyscall(mib)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -135,10 +135,10 @@ func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) {
|
||||||
}
|
}
|
||||||
c := TimesStat{
|
c := TimesStat{
|
||||||
User: float64(cpuTimes[CPUser]) / ClocksPerSec,
|
User: float64(cpuTimes[CPUser]) / ClocksPerSec,
|
||||||
Nice: float64(cpuTimes[CPNice]) / ClocksPerSec,
|
Nice: float64(cpuTimes[cpNice]) / ClocksPerSec,
|
||||||
System: float64(cpuTimes[CPSys]) / ClocksPerSec,
|
System: float64(cpuTimes[cpSys]) / ClocksPerSec,
|
||||||
Idle: float64(cpuTimes[CPIdle]) / ClocksPerSec,
|
Idle: float64(cpuTimes[cpIdle]) / ClocksPerSec,
|
||||||
Irq: float64(cpuTimes[CPIntr]) / ClocksPerSec,
|
Irq: float64(cpuTimes[cpIntr]) / ClocksPerSec,
|
||||||
}
|
}
|
||||||
if percpu {
|
if percpu {
|
||||||
c.CPU = fmt.Sprintf("cpu%d", j)
|
c.CPU = fmt.Sprintf("cpu%d", j)
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/StackExchange/wmi"
|
"github.com/StackExchange/wmi"
|
||||||
"github.com/shirou/gopsutil/internal/common"
|
"github.com/shirou/gopsutil/v3/internal/common"
|
||||||
"golang.org/x/sys/windows"
|
"golang.org/x/sys/windows"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ var (
|
||||||
procGetNativeSystemInfo = common.Modkernel32.NewProc("GetNativeSystemInfo")
|
procGetNativeSystemInfo = common.Modkernel32.NewProc("GetNativeSystemInfo")
|
||||||
)
|
)
|
||||||
|
|
||||||
type Win32_Processor struct {
|
type win32Processor struct {
|
||||||
LoadPercentage *uint16
|
LoadPercentage *uint16
|
||||||
Family uint16
|
Family uint16
|
||||||
Manufacturer string
|
Manufacturer string
|
||||||
|
@ -104,7 +104,7 @@ func Info() ([]InfoStat, error) {
|
||||||
|
|
||||||
func InfoWithContext(ctx context.Context) ([]InfoStat, error) {
|
func InfoWithContext(ctx context.Context) ([]InfoStat, error) {
|
||||||
var ret []InfoStat
|
var ret []InfoStat
|
||||||
var dst []Win32_Processor
|
var dst []win32Processor
|
||||||
q := wmi.CreateQuery(&dst, "")
|
q := wmi.CreateQuery(&dst, "")
|
||||||
if err := common.WMIQueryWithContext(ctx, q, &dst); err != nil {
|
if err := common.WMIQueryWithContext(ctx, q, &dst); err != nil {
|
||||||
return ret, err
|
return ret, err
|
||||||
|
@ -242,7 +242,7 @@ func CountsWithContext(ctx context.Context, logical bool) (int, error) {
|
||||||
}
|
}
|
||||||
// physical cores https://github.com/giampaolo/psutil/blob/d01a9eaa35a8aadf6c519839e987a49d8be2d891/psutil/_psutil_windows.c#L499
|
// 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…
|
// for the time being, try with unreliable and slow WMI call…
|
||||||
var dst []Win32_Processor
|
var dst []win32Processor
|
||||||
q := wmi.CreateQuery(&dst, "")
|
q := wmi.CreateQuery(&dst, "")
|
||||||
if err := common.WMIQueryWithContext(ctx, q, &dst); err != nil {
|
if err := common.WMIQueryWithContext(ctx, q, &dst); err != nil {
|
||||||
return 0, err
|
return 0, err
|
|
@ -0,0 +1,96 @@
|
||||||
|
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)
|
||||||
|
}
|
|
@ -4,16 +4,13 @@ package disk
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"path"
|
|
||||||
|
|
||||||
"github.com/shirou/gopsutil/internal/common"
|
"github.com/shirou/gopsutil/v3/internal/common"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Partitions(all bool) ([]PartitionStat, error) {
|
// PartitionsWithContext returns disk partition.
|
||||||
return PartitionsWithContext(context.Background(), all)
|
// 'all' argument is ignored, see: https://github.com/giampaolo/psutil/issues/906
|
||||||
}
|
|
||||||
|
|
||||||
func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) {
|
func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) {
|
||||||
var ret []PartitionStat
|
var ret []PartitionStat
|
||||||
|
|
||||||
|
@ -26,54 +23,49 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro
|
||||||
return ret, err
|
return ret, err
|
||||||
}
|
}
|
||||||
for _, stat := range fs {
|
for _, stat := range fs {
|
||||||
opts := "rw"
|
opts := []string{"rw"}
|
||||||
if stat.Flags&unix.MNT_RDONLY != 0 {
|
if stat.Flags&unix.MNT_RDONLY != 0 {
|
||||||
opts = "ro"
|
opts = []string{"ro"}
|
||||||
}
|
}
|
||||||
if stat.Flags&unix.MNT_SYNCHRONOUS != 0 {
|
if stat.Flags&unix.MNT_SYNCHRONOUS != 0 {
|
||||||
opts += ",sync"
|
opts = append(opts, "sync")
|
||||||
}
|
}
|
||||||
if stat.Flags&unix.MNT_NOEXEC != 0 {
|
if stat.Flags&unix.MNT_NOEXEC != 0 {
|
||||||
opts += ",noexec"
|
opts = append(opts, "noexec")
|
||||||
}
|
}
|
||||||
if stat.Flags&unix.MNT_NOSUID != 0 {
|
if stat.Flags&unix.MNT_NOSUID != 0 {
|
||||||
opts += ",nosuid"
|
opts = append(opts, "nosuid")
|
||||||
}
|
}
|
||||||
if stat.Flags&unix.MNT_UNION != 0 {
|
if stat.Flags&unix.MNT_UNION != 0 {
|
||||||
opts += ",union"
|
opts = append(opts, "union")
|
||||||
}
|
}
|
||||||
if stat.Flags&unix.MNT_ASYNC != 0 {
|
if stat.Flags&unix.MNT_ASYNC != 0 {
|
||||||
opts += ",async"
|
opts = append(opts, "async")
|
||||||
}
|
}
|
||||||
if stat.Flags&unix.MNT_DONTBROWSE != 0 {
|
if stat.Flags&unix.MNT_DONTBROWSE != 0 {
|
||||||
opts += ",nobrowse"
|
opts = append(opts, "nobrowse")
|
||||||
}
|
}
|
||||||
if stat.Flags&unix.MNT_AUTOMOUNTED != 0 {
|
if stat.Flags&unix.MNT_AUTOMOUNTED != 0 {
|
||||||
opts += ",automounted"
|
opts = append(opts, "automounted")
|
||||||
}
|
}
|
||||||
if stat.Flags&unix.MNT_JOURNALED != 0 {
|
if stat.Flags&unix.MNT_JOURNALED != 0 {
|
||||||
opts += ",journaled"
|
opts = append(opts, "journaled")
|
||||||
}
|
}
|
||||||
if stat.Flags&unix.MNT_MULTILABEL != 0 {
|
if stat.Flags&unix.MNT_MULTILABEL != 0 {
|
||||||
opts += ",multilabel"
|
opts = append(opts, "multilabel")
|
||||||
}
|
}
|
||||||
if stat.Flags&unix.MNT_NOATIME != 0 {
|
if stat.Flags&unix.MNT_NOATIME != 0 {
|
||||||
opts += ",noatime"
|
opts = append(opts, "noatime")
|
||||||
}
|
}
|
||||||
if stat.Flags&unix.MNT_NODEV != 0 {
|
if stat.Flags&unix.MNT_NODEV != 0 {
|
||||||
opts += ",nodev"
|
opts = append(opts, "nodev")
|
||||||
}
|
}
|
||||||
d := PartitionStat{
|
d := PartitionStat{
|
||||||
Device: common.IntToString(stat.Mntfromname[:]),
|
Device: common.ByteToString(stat.Mntfromname[:]),
|
||||||
Mountpoint: common.IntToString(stat.Mntonname[:]),
|
Mountpoint: common.ByteToString(stat.Mntonname[:]),
|
||||||
Fstype: common.IntToString(stat.Fstypename[:]),
|
Fstype: common.ByteToString(stat.Fstypename[:]),
|
||||||
Opts: opts,
|
Opts: opts,
|
||||||
}
|
}
|
||||||
if all == false {
|
|
||||||
if !path.IsAbs(d.Device) || !common.PathExists(d.Device) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = append(ret, d)
|
ret = append(ret, d)
|
||||||
}
|
}
|
||||||
|
@ -82,5 +74,13 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro
|
||||||
}
|
}
|
||||||
|
|
||||||
func getFsType(stat unix.Statfs_t) string {
|
func getFsType(stat unix.Statfs_t) string {
|
||||||
return common.IntToString(stat.Fstypename[:])
|
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
|
||||||
}
|
}
|
|
@ -14,13 +14,9 @@ import "C"
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/shirou/gopsutil/internal/common"
|
"github.com/shirou/gopsutil/v3/internal/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
func IOCounters(names ...string) (map[string]IOCountersStat, error) {
|
|
||||||
return IOCountersWithContext(context.Background(), names...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) {
|
func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) {
|
||||||
var buf [C.NDRIVE]C.DriveStats
|
var buf [C.NDRIVE]C.DriveStats
|
||||||
n, err := C.readdrivestat(&buf[0], C.int(len(buf)))
|
n, err := C.readdrivestat(&buf[0], C.int(len(buf)))
|
|
@ -6,13 +6,9 @@ package disk
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/shirou/gopsutil/internal/common"
|
"github.com/shirou/gopsutil/v3/internal/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
func IOCounters(names ...string) (map[string]IOCountersStat, error) {
|
|
||||||
return IOCountersWithContext(context.Background(), names...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) {
|
func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) {
|
||||||
return nil, common.ErrNotImplementedError
|
return nil, common.ErrNotImplementedError
|
||||||
}
|
}
|
|
@ -5,29 +5,25 @@ package disk
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/shirou/gopsutil/internal/common"
|
"github.com/shirou/gopsutil/v3/internal/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
func IOCounters(names ...string) (map[string]IOCountersStat, error) {
|
|
||||||
return IOCountersWithContext(context.Background(), names...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) {
|
func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) {
|
||||||
return nil, common.ErrNotImplementedError
|
return nil, common.ErrNotImplementedError
|
||||||
}
|
}
|
||||||
|
|
||||||
func Partitions(all bool) ([]PartitionStat, error) {
|
|
||||||
return PartitionsWithContext(context.Background(), all)
|
|
||||||
}
|
|
||||||
|
|
||||||
func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) {
|
func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) {
|
||||||
return []PartitionStat{}, common.ErrNotImplementedError
|
return []PartitionStat{}, common.ErrNotImplementedError
|
||||||
}
|
}
|
||||||
|
|
||||||
func Usage(path string) (*UsageStat, error) {
|
|
||||||
return UsageWithContext(context.Background(), path)
|
|
||||||
}
|
|
||||||
|
|
||||||
func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) {
|
func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) {
|
||||||
return nil, common.ErrNotImplementedError
|
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
|
||||||
|
}
|
|
@ -6,18 +6,15 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"path"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
|
|
||||||
"github.com/shirou/gopsutil/internal/common"
|
"github.com/shirou/gopsutil/v3/internal/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Partitions(all bool) ([]PartitionStat, error) {
|
// PartitionsWithContext returns disk partition.
|
||||||
return PartitionsWithContext(context.Background(), all)
|
// 'all' argument is ignored, see: https://github.com/giampaolo/psutil/issues/906
|
||||||
}
|
|
||||||
|
|
||||||
func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) {
|
func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) {
|
||||||
var ret []PartitionStat
|
var ret []PartitionStat
|
||||||
|
|
||||||
|
@ -33,54 +30,54 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, stat := range fs {
|
for _, stat := range fs {
|
||||||
opts := "rw"
|
opts := []string{"rw"}
|
||||||
if stat.Flags&unix.MNT_RDONLY != 0 {
|
if stat.Flags&unix.MNT_RDONLY != 0 {
|
||||||
opts = "ro"
|
opts = []string{"ro"}
|
||||||
}
|
}
|
||||||
if stat.Flags&unix.MNT_SYNCHRONOUS != 0 {
|
if stat.Flags&unix.MNT_SYNCHRONOUS != 0 {
|
||||||
opts += ",sync"
|
opts = append(opts, "sync")
|
||||||
}
|
}
|
||||||
if stat.Flags&unix.MNT_NOEXEC != 0 {
|
if stat.Flags&unix.MNT_NOEXEC != 0 {
|
||||||
opts += ",noexec"
|
opts = append(opts, "noexec")
|
||||||
}
|
}
|
||||||
if stat.Flags&unix.MNT_NOSUID != 0 {
|
if stat.Flags&unix.MNT_NOSUID != 0 {
|
||||||
opts += ",nosuid"
|
opts = append(opts, "nosuid")
|
||||||
}
|
}
|
||||||
if stat.Flags&unix.MNT_UNION != 0 {
|
if stat.Flags&unix.MNT_UNION != 0 {
|
||||||
opts += ",union"
|
opts = append(opts, "union")
|
||||||
}
|
}
|
||||||
if stat.Flags&unix.MNT_ASYNC != 0 {
|
if stat.Flags&unix.MNT_ASYNC != 0 {
|
||||||
opts += ",async"
|
opts = append(opts, "async")
|
||||||
}
|
}
|
||||||
if stat.Flags&unix.MNT_SUIDDIR != 0 {
|
if stat.Flags&unix.MNT_SUIDDIR != 0 {
|
||||||
opts += ",suiddir"
|
opts = append(opts, "suiddir")
|
||||||
}
|
}
|
||||||
if stat.Flags&unix.MNT_SOFTDEP != 0 {
|
if stat.Flags&unix.MNT_SOFTDEP != 0 {
|
||||||
opts += ",softdep"
|
opts = append(opts, "softdep")
|
||||||
}
|
}
|
||||||
if stat.Flags&unix.MNT_NOSYMFOLLOW != 0 {
|
if stat.Flags&unix.MNT_NOSYMFOLLOW != 0 {
|
||||||
opts += ",nosymfollow"
|
opts = append(opts, "nosymfollow")
|
||||||
}
|
}
|
||||||
if stat.Flags&unix.MNT_GJOURNAL != 0 {
|
if stat.Flags&unix.MNT_GJOURNAL != 0 {
|
||||||
opts += ",gjournal"
|
opts = append(opts, "gjournal")
|
||||||
}
|
}
|
||||||
if stat.Flags&unix.MNT_MULTILABEL != 0 {
|
if stat.Flags&unix.MNT_MULTILABEL != 0 {
|
||||||
opts += ",multilabel"
|
opts = append(opts, "multilabel")
|
||||||
}
|
}
|
||||||
if stat.Flags&unix.MNT_ACLS != 0 {
|
if stat.Flags&unix.MNT_ACLS != 0 {
|
||||||
opts += ",acls"
|
opts = append(opts, "acls")
|
||||||
}
|
}
|
||||||
if stat.Flags&unix.MNT_NOATIME != 0 {
|
if stat.Flags&unix.MNT_NOATIME != 0 {
|
||||||
opts += ",noatime"
|
opts = append(opts, "noatime")
|
||||||
}
|
}
|
||||||
if stat.Flags&unix.MNT_NOCLUSTERR != 0 {
|
if stat.Flags&unix.MNT_NOCLUSTERR != 0 {
|
||||||
opts += ",noclusterr"
|
opts = append(opts, "noclusterr")
|
||||||
}
|
}
|
||||||
if stat.Flags&unix.MNT_NOCLUSTERW != 0 {
|
if stat.Flags&unix.MNT_NOCLUSTERW != 0 {
|
||||||
opts += ",noclusterw"
|
opts = append(opts, "noclusterw")
|
||||||
}
|
}
|
||||||
if stat.Flags&unix.MNT_NFS4ACLS != 0 {
|
if stat.Flags&unix.MNT_NFS4ACLS != 0 {
|
||||||
opts += ",nfsv4acls"
|
opts = append(opts, "nfsv4acls")
|
||||||
}
|
}
|
||||||
|
|
||||||
d := PartitionStat{
|
d := PartitionStat{
|
||||||
|
@ -89,11 +86,6 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro
|
||||||
Fstype: common.ByteToString(stat.Fstypename[:]),
|
Fstype: common.ByteToString(stat.Fstypename[:]),
|
||||||
Opts: opts,
|
Opts: opts,
|
||||||
}
|
}
|
||||||
if all == false {
|
|
||||||
if !path.IsAbs(d.Device) || !common.PathExists(d.Device) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = append(ret, d)
|
ret = append(ret, d)
|
||||||
}
|
}
|
||||||
|
@ -101,10 +93,6 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro
|
||||||
return ret, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func IOCounters(names ...string) (map[string]IOCountersStat, error) {
|
|
||||||
return IOCountersWithContext(context.Background(), names...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) {
|
func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) {
|
||||||
// statinfo->devinfo->devstat
|
// statinfo->devinfo->devstat
|
||||||
// /usr/include/devinfo.h
|
// /usr/include/devinfo.h
|
||||||
|
@ -117,13 +105,13 @@ func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOC
|
||||||
buf := []byte(r)
|
buf := []byte(r)
|
||||||
length := len(buf)
|
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.
|
buf = buf[8:] // devstat.all has version in the head.
|
||||||
// parse buf to Devstat
|
// parse buf to devstat
|
||||||
for i := 0; i < count; i++ {
|
for i := 0; i < count; i++ {
|
||||||
b := buf[i*sizeOfDevstat : i*sizeOfDevstat+sizeOfDevstat]
|
b := buf[i*sizeOfdevstat : i*sizeOfdevstat+sizeOfdevstat]
|
||||||
d, err := parseDevstat(b)
|
d, err := parsedevstat(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -135,12 +123,12 @@ func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOC
|
||||||
}
|
}
|
||||||
|
|
||||||
ds := IOCountersStat{
|
ds := IOCountersStat{
|
||||||
ReadCount: d.Operations[DEVSTAT_READ],
|
ReadCount: d.Operations[devstat_READ],
|
||||||
WriteCount: d.Operations[DEVSTAT_WRITE],
|
WriteCount: d.Operations[devstat_WRITE],
|
||||||
ReadBytes: d.Bytes[DEVSTAT_READ],
|
ReadBytes: d.Bytes[devstat_READ],
|
||||||
WriteBytes: d.Bytes[DEVSTAT_WRITE],
|
WriteBytes: d.Bytes[devstat_WRITE],
|
||||||
ReadTime: uint64(d.Duration[DEVSTAT_READ].Compute() * 1000),
|
ReadTime: uint64(d.Duration[devstat_READ].Compute() * 1000),
|
||||||
WriteTime: uint64(d.Duration[DEVSTAT_WRITE].Compute() * 1000),
|
WriteTime: uint64(d.Duration[devstat_WRITE].Compute() * 1000),
|
||||||
IoTime: uint64(d.Busy_time.Compute() * 1000),
|
IoTime: uint64(d.Busy_time.Compute() * 1000),
|
||||||
Name: name,
|
Name: name,
|
||||||
}
|
}
|
||||||
|
@ -150,15 +138,15 @@ func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOC
|
||||||
return ret, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b Bintime) Compute() float64 {
|
func (b bintime) Compute() float64 {
|
||||||
BINTIME_SCALE := 5.42101086242752217003726400434970855712890625e-20
|
BINTIME_SCALE := 5.42101086242752217003726400434970855712890625e-20
|
||||||
return float64(b.Sec) + float64(b.Frac)*BINTIME_SCALE
|
return float64(b.Sec) + float64(b.Frac)*BINTIME_SCALE
|
||||||
}
|
}
|
||||||
|
|
||||||
// BT2LD(time) ((long double)(time).sec + (time).frac * BINTIME_SCALE)
|
// BT2LD(time) ((long double)(time).sec + (time).frac * BINTIME_SCALE)
|
||||||
|
|
||||||
func parseDevstat(buf []byte) (Devstat, error) {
|
func parsedevstat(buf []byte) (devstat, error) {
|
||||||
var ds Devstat
|
var ds devstat
|
||||||
br := bytes.NewReader(buf)
|
br := bytes.NewReader(buf)
|
||||||
// err := binary.Read(br, binary.LittleEndian, &ds)
|
// err := binary.Read(br, binary.LittleEndian, &ds)
|
||||||
err := common.Read(br, binary.LittleEndian, &ds)
|
err := common.Read(br, binary.LittleEndian, &ds)
|
||||||
|
@ -172,3 +160,11 @@ func parseDevstat(buf []byte) (Devstat, error) {
|
||||||
func getFsType(stat unix.Statfs_t) string {
|
func getFsType(stat unix.Statfs_t) string {
|
||||||
return common.ByteToString(stat.Fstypename[:])
|
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
|
||||||
|
}
|
|
@ -11,14 +11,14 @@ const (
|
||||||
sizeofLongLong = 0x8
|
sizeofLongLong = 0x8
|
||||||
sizeofLongDouble = 0x8
|
sizeofLongDouble = 0x8
|
||||||
|
|
||||||
DEVSTAT_NO_DATA = 0x00
|
devstat_NO_DATA = 0x00
|
||||||
DEVSTAT_READ = 0x01
|
devstat_READ = 0x01
|
||||||
DEVSTAT_WRITE = 0x02
|
devstat_WRITE = 0x02
|
||||||
DEVSTAT_FREE = 0x03
|
devstat_FREE = 0x03
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
sizeOfDevstat = 0xf0
|
sizeOfdevstat = 0xf0
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
|
@ -29,21 +29,21 @@ type (
|
||||||
_C_long_double int64
|
_C_long_double int64
|
||||||
)
|
)
|
||||||
|
|
||||||
type Devstat struct {
|
type devstat struct {
|
||||||
Sequence0 uint32
|
Sequence0 uint32
|
||||||
Allocated int32
|
Allocated int32
|
||||||
Start_count uint32
|
Start_count uint32
|
||||||
End_count uint32
|
End_count uint32
|
||||||
Busy_from Bintime
|
Busy_from bintime
|
||||||
Dev_links _Ctype_struct___0
|
Dev_links _Ctype_struct___0
|
||||||
Device_number uint32
|
Device_number uint32
|
||||||
Device_name [16]int8
|
Device_name [16]int8
|
||||||
Unit_number int32
|
Unit_number int32
|
||||||
Bytes [4]uint64
|
Bytes [4]uint64
|
||||||
Operations [4]uint64
|
Operations [4]uint64
|
||||||
Duration [4]Bintime
|
Duration [4]bintime
|
||||||
Busy_time Bintime
|
Busy_time bintime
|
||||||
Creation_time Bintime
|
Creation_time bintime
|
||||||
Block_size uint32
|
Block_size uint32
|
||||||
Tag_types [3]uint64
|
Tag_types [3]uint64
|
||||||
Flags uint32
|
Flags uint32
|
||||||
|
@ -52,7 +52,7 @@ type Devstat struct {
|
||||||
Id *byte
|
Id *byte
|
||||||
Sequence1 uint32
|
Sequence1 uint32
|
||||||
}
|
}
|
||||||
type Bintime struct {
|
type bintime struct {
|
||||||
Sec int32
|
Sec int32
|
||||||
Frac uint64
|
Frac uint64
|
||||||
}
|
}
|
|
@ -11,14 +11,14 @@ const (
|
||||||
sizeofLongLong = 0x8
|
sizeofLongLong = 0x8
|
||||||
sizeofLongDouble = 0x8
|
sizeofLongDouble = 0x8
|
||||||
|
|
||||||
DEVSTAT_NO_DATA = 0x00
|
devstat_NO_DATA = 0x00
|
||||||
DEVSTAT_READ = 0x01
|
devstat_READ = 0x01
|
||||||
DEVSTAT_WRITE = 0x02
|
devstat_WRITE = 0x02
|
||||||
DEVSTAT_FREE = 0x03
|
devstat_FREE = 0x03
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
sizeOfDevstat = 0x120
|
sizeOfdevstat = 0x120
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
|
@ -29,21 +29,21 @@ type (
|
||||||
_C_long_double int64
|
_C_long_double int64
|
||||||
)
|
)
|
||||||
|
|
||||||
type Devstat struct {
|
type devstat struct {
|
||||||
Sequence0 uint32
|
Sequence0 uint32
|
||||||
Allocated int32
|
Allocated int32
|
||||||
Start_count uint32
|
Start_count uint32
|
||||||
End_count uint32
|
End_count uint32
|
||||||
Busy_from Bintime
|
Busy_from bintime
|
||||||
Dev_links _Ctype_struct___0
|
Dev_links _Ctype_struct___0
|
||||||
Device_number uint32
|
Device_number uint32
|
||||||
Device_name [16]int8
|
Device_name [16]int8
|
||||||
Unit_number int32
|
Unit_number int32
|
||||||
Bytes [4]uint64
|
Bytes [4]uint64
|
||||||
Operations [4]uint64
|
Operations [4]uint64
|
||||||
Duration [4]Bintime
|
Duration [4]bintime
|
||||||
Busy_time Bintime
|
Busy_time bintime
|
||||||
Creation_time Bintime
|
Creation_time bintime
|
||||||
Block_size uint32
|
Block_size uint32
|
||||||
Pad_cgo_0 [4]byte
|
Pad_cgo_0 [4]byte
|
||||||
Tag_types [3]uint64
|
Tag_types [3]uint64
|
||||||
|
@ -55,7 +55,7 @@ type Devstat struct {
|
||||||
Sequence1 uint32
|
Sequence1 uint32
|
||||||
Pad_cgo_2 [4]byte
|
Pad_cgo_2 [4]byte
|
||||||
}
|
}
|
||||||
type Bintime struct {
|
type bintime struct {
|
||||||
Sec int64
|
Sec int64
|
||||||
Frac uint64
|
Frac uint64
|
||||||
}
|
}
|
|
@ -11,14 +11,14 @@ const (
|
||||||
sizeofLongLong = 0x8
|
sizeofLongLong = 0x8
|
||||||
sizeofLongDouble = 0x8
|
sizeofLongDouble = 0x8
|
||||||
|
|
||||||
DEVSTAT_NO_DATA = 0x00
|
devstat_NO_DATA = 0x00
|
||||||
DEVSTAT_READ = 0x01
|
devstat_READ = 0x01
|
||||||
DEVSTAT_WRITE = 0x02
|
devstat_WRITE = 0x02
|
||||||
DEVSTAT_FREE = 0x03
|
devstat_FREE = 0x03
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
sizeOfDevstat = 0xf0
|
sizeOfdevstat = 0xf0
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
|
@ -29,21 +29,21 @@ type (
|
||||||
_C_long_double int64
|
_C_long_double int64
|
||||||
)
|
)
|
||||||
|
|
||||||
type Devstat struct {
|
type devstat struct {
|
||||||
Sequence0 uint32
|
Sequence0 uint32
|
||||||
Allocated int32
|
Allocated int32
|
||||||
Start_count uint32
|
Start_count uint32
|
||||||
End_count uint32
|
End_count uint32
|
||||||
Busy_from Bintime
|
Busy_from bintime
|
||||||
Dev_links _Ctype_struct___0
|
Dev_links _Ctype_struct___0
|
||||||
Device_number uint32
|
Device_number uint32
|
||||||
Device_name [16]int8
|
Device_name [16]int8
|
||||||
Unit_number int32
|
Unit_number int32
|
||||||
Bytes [4]uint64
|
Bytes [4]uint64
|
||||||
Operations [4]uint64
|
Operations [4]uint64
|
||||||
Duration [4]Bintime
|
Duration [4]bintime
|
||||||
Busy_time Bintime
|
Busy_time bintime
|
||||||
Creation_time Bintime
|
Creation_time bintime
|
||||||
Block_size uint32
|
Block_size uint32
|
||||||
Tag_types [3]uint64
|
Tag_types [3]uint64
|
||||||
Flags uint32
|
Flags uint32
|
||||||
|
@ -52,7 +52,7 @@ type Devstat struct {
|
||||||
Id *byte
|
Id *byte
|
||||||
Sequence1 uint32
|
Sequence1 uint32
|
||||||
}
|
}
|
||||||
type Bintime struct {
|
type bintime struct {
|
||||||
Sec int32
|
Sec int32
|
||||||
Frac uint64
|
Frac uint64
|
||||||
}
|
}
|
|
@ -13,14 +13,14 @@ const (
|
||||||
sizeofLongLong = 0x8
|
sizeofLongLong = 0x8
|
||||||
sizeofLongDouble = 0x8
|
sizeofLongDouble = 0x8
|
||||||
|
|
||||||
DEVSTAT_NO_DATA = 0x00
|
devstat_NO_DATA = 0x00
|
||||||
DEVSTAT_READ = 0x01
|
devstat_READ = 0x01
|
||||||
DEVSTAT_WRITE = 0x02
|
devstat_WRITE = 0x02
|
||||||
DEVSTAT_FREE = 0x03
|
devstat_FREE = 0x03
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
sizeOfDevstat = 0x120
|
sizeOfdevstat = 0x120
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
|
@ -31,21 +31,21 @@ type (
|
||||||
_C_long_double int64
|
_C_long_double int64
|
||||||
)
|
)
|
||||||
|
|
||||||
type Devstat struct {
|
type devstat struct {
|
||||||
Sequence0 uint32
|
Sequence0 uint32
|
||||||
Allocated int32
|
Allocated int32
|
||||||
Start_count uint32
|
Start_count uint32
|
||||||
End_count uint32
|
End_count uint32
|
||||||
Busy_from Bintime
|
Busy_from bintime
|
||||||
Dev_links _Ctype_struct___0
|
Dev_links _Ctype_struct___0
|
||||||
Device_number uint32
|
Device_number uint32
|
||||||
Device_name [16]int8
|
Device_name [16]int8
|
||||||
Unit_number int32
|
Unit_number int32
|
||||||
Bytes [4]uint64
|
Bytes [4]uint64
|
||||||
Operations [4]uint64
|
Operations [4]uint64
|
||||||
Duration [4]Bintime
|
Duration [4]bintime
|
||||||
Busy_time Bintime
|
Busy_time bintime
|
||||||
Creation_time Bintime
|
Creation_time bintime
|
||||||
Block_size uint32
|
Block_size uint32
|
||||||
Tag_types [3]uint64
|
Tag_types [3]uint64
|
||||||
Flags uint32
|
Flags uint32
|
||||||
|
@ -55,7 +55,7 @@ type Devstat struct {
|
||||||
Sequence1 uint32
|
Sequence1 uint32
|
||||||
Pad_cgo_0 [4]byte
|
Pad_cgo_0 [4]byte
|
||||||
}
|
}
|
||||||
type Bintime struct {
|
type bintime struct {
|
||||||
Sec int64
|
Sec int64
|
||||||
Frac uint64
|
Frac uint64
|
||||||
}
|
}
|
|
@ -13,12 +13,12 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/shirou/gopsutil/internal/common"
|
"github.com/shirou/gopsutil/v3/internal/common"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
SectorSize = 512
|
sectorSize = 512
|
||||||
)
|
)
|
||||||
const (
|
const (
|
||||||
// man statfs
|
// man statfs
|
||||||
|
@ -218,13 +218,6 @@ var fsTypeMap = map[int64]string{
|
||||||
ZFS_SUPER_MAGIC: "zfs", /* 0x2FC12FC1 local */
|
ZFS_SUPER_MAGIC: "zfs", /* 0x2FC12FC1 local */
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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)
|
|
||||||
func Partitions(all bool) ([]PartitionStat, error) {
|
|
||||||
return PartitionsWithContext(context.Background(), all)
|
|
||||||
}
|
|
||||||
|
|
||||||
func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) {
|
func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) {
|
||||||
useMounts := false
|
useMounts := false
|
||||||
|
|
||||||
|
@ -259,7 +252,7 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro
|
||||||
Device: fields[0],
|
Device: fields[0],
|
||||||
Mountpoint: unescapeFstab(fields[1]),
|
Mountpoint: unescapeFstab(fields[1]),
|
||||||
Fstype: fields[2],
|
Fstype: fields[2],
|
||||||
Opts: fields[3],
|
Opts: strings.Fields(fields[3]),
|
||||||
}
|
}
|
||||||
|
|
||||||
if !all {
|
if !all {
|
||||||
|
@ -281,7 +274,11 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro
|
||||||
fields := strings.Fields(parts[0])
|
fields := strings.Fields(parts[0])
|
||||||
blockDeviceID := fields[2]
|
blockDeviceID := fields[2]
|
||||||
mountPoint := fields[4]
|
mountPoint := fields[4]
|
||||||
mountOpts := fields[5]
|
mountOpts := strings.Split(fields[5], ",")
|
||||||
|
|
||||||
|
if rootDir := fields[3]; rootDir != "" && rootDir != "/" {
|
||||||
|
mountOpts = append(mountOpts, "bind")
|
||||||
|
}
|
||||||
|
|
||||||
fields = strings.Fields(parts[1])
|
fields = strings.Fields(parts[1])
|
||||||
fstype := fields[0]
|
fstype := fields[0]
|
||||||
|
@ -346,10 +343,6 @@ func getFileSystems() ([]string, error) {
|
||||||
return ret, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func IOCounters(names ...string) (map[string]IOCountersStat, error) {
|
|
||||||
return IOCountersWithContext(context.Background(), names...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) {
|
func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) {
|
||||||
filename := common.HostProc("diskstats")
|
filename := common.HostProc("diskstats")
|
||||||
lines, err := common.ReadLines(filename)
|
lines, err := common.ReadLines(filename)
|
||||||
|
@ -421,8 +414,8 @@ func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOC
|
||||||
return ret, err
|
return ret, err
|
||||||
}
|
}
|
||||||
d := IOCountersStat{
|
d := IOCountersStat{
|
||||||
ReadBytes: rbytes * SectorSize,
|
ReadBytes: rbytes * sectorSize,
|
||||||
WriteBytes: wbytes * SectorSize,
|
WriteBytes: wbytes * sectorSize,
|
||||||
ReadCount: reads,
|
ReadCount: reads,
|
||||||
WriteCount: writes,
|
WriteCount: writes,
|
||||||
MergedReadCount: mergedReads,
|
MergedReadCount: mergedReads,
|
||||||
|
@ -438,25 +431,19 @@ func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOC
|
||||||
}
|
}
|
||||||
d.Name = name
|
d.Name = name
|
||||||
|
|
||||||
d.SerialNumber = GetDiskSerialNumber(name)
|
d.SerialNumber, _ = SerialNumberWithContext(ctx, name)
|
||||||
d.Label = GetLabel(name)
|
d.Label, _ = LabelWithContext(ctx, name)
|
||||||
|
|
||||||
ret[name] = d
|
ret[name] = d
|
||||||
}
|
}
|
||||||
return ret, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetDiskSerialNumber returns Serial Number of given device or empty string
|
func SerialNumberWithContext(ctx context.Context, name string) (string, error) {
|
||||||
// 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 {
|
|
||||||
var stat unix.Stat_t
|
var stat unix.Stat_t
|
||||||
err := unix.Stat(name, &stat)
|
err := unix.Stat(name, &stat)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ""
|
return "", err
|
||||||
}
|
}
|
||||||
major := unix.Major(uint64(stat.Rdev))
|
major := unix.Major(uint64(stat.Rdev))
|
||||||
minor := unix.Minor(uint64(stat.Rdev))
|
minor := unix.Minor(uint64(stat.Rdev))
|
||||||
|
@ -468,7 +455,7 @@ func GetDiskSerialNumberWithContext(ctx context.Context, name string) string {
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
values := strings.Split(scanner.Text(), "=")
|
values := strings.Split(scanner.Text(), "=")
|
||||||
if len(values) == 2 && values[0] == "E:ID_SERIAL" {
|
if len(values) == 2 && values[0] == "E:ID_SERIAL" {
|
||||||
return values[1]
|
return values[1], nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -479,28 +466,24 @@ func GetDiskSerialNumberWithContext(ctx context.Context, name string) string {
|
||||||
model, _ := ioutil.ReadFile(filepath.Join(devicePath, "model"))
|
model, _ := ioutil.ReadFile(filepath.Join(devicePath, "model"))
|
||||||
serial, _ := ioutil.ReadFile(filepath.Join(devicePath, "serial"))
|
serial, _ := ioutil.ReadFile(filepath.Join(devicePath, "serial"))
|
||||||
if len(model) > 0 && len(serial) > 0 {
|
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.
|
func LabelWithContext(ctx context.Context, name string) (string, 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 {
|
|
||||||
// Try label based on devicemapper name
|
// Try label based on devicemapper name
|
||||||
dmname_filename := common.HostSys(fmt.Sprintf("block/%s/dm/name", name))
|
dmname_filename := common.HostSys(fmt.Sprintf("block/%s/dm/name", name))
|
||||||
|
|
||||||
if !common.PathExists(dmname_filename) {
|
if !common.PathExists(dmname_filename) {
|
||||||
return ""
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
dmname, err := ioutil.ReadFile(dmname_filename)
|
dmname, err := ioutil.ReadFile(dmname_filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ""
|
return "", err
|
||||||
} else {
|
} else {
|
||||||
return strings.TrimSpace(string(dmname))
|
return strings.TrimSpace(string(dmname)), nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,16 +6,11 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"path"
|
|
||||||
|
|
||||||
"github.com/shirou/gopsutil/internal/common"
|
"github.com/shirou/gopsutil/v3/internal/common"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Partitions(all bool) ([]PartitionStat, error) {
|
|
||||||
return PartitionsWithContext(context.Background(), all)
|
|
||||||
}
|
|
||||||
|
|
||||||
func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) {
|
func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) {
|
||||||
var ret []PartitionStat
|
var ret []PartitionStat
|
||||||
|
|
||||||
|
@ -31,33 +26,33 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, stat := range fs {
|
for _, stat := range fs {
|
||||||
opts := "rw"
|
opts := []string{"rw"}
|
||||||
if stat.F_flags&unix.MNT_RDONLY != 0 {
|
if stat.F_flags&unix.MNT_RDONLY != 0 {
|
||||||
opts = "ro"
|
opts = []string{"rw"}
|
||||||
}
|
}
|
||||||
if stat.F_flags&unix.MNT_SYNCHRONOUS != 0 {
|
if stat.F_flags&unix.MNT_SYNCHRONOUS != 0 {
|
||||||
opts += ",sync"
|
opts = append(opts, "sync")
|
||||||
}
|
}
|
||||||
if stat.F_flags&unix.MNT_NOEXEC != 0 {
|
if stat.F_flags&unix.MNT_NOEXEC != 0 {
|
||||||
opts += ",noexec"
|
opts = append(opts, "noexec")
|
||||||
}
|
}
|
||||||
if stat.F_flags&unix.MNT_NOSUID != 0 {
|
if stat.F_flags&unix.MNT_NOSUID != 0 {
|
||||||
opts += ",nosuid"
|
opts = append(opts, "nosuid")
|
||||||
}
|
}
|
||||||
if stat.F_flags&unix.MNT_NODEV != 0 {
|
if stat.F_flags&unix.MNT_NODEV != 0 {
|
||||||
opts += ",nodev"
|
opts = append(opts, "nodev")
|
||||||
}
|
}
|
||||||
if stat.F_flags&unix.MNT_ASYNC != 0 {
|
if stat.F_flags&unix.MNT_ASYNC != 0 {
|
||||||
opts += ",async"
|
opts = append(opts, "async")
|
||||||
}
|
}
|
||||||
if stat.F_flags&unix.MNT_SOFTDEP != 0 {
|
if stat.F_flags&unix.MNT_SOFTDEP != 0 {
|
||||||
opts += ",softdep"
|
opts = append(opts, "softdep")
|
||||||
}
|
}
|
||||||
if stat.F_flags&unix.MNT_NOATIME != 0 {
|
if stat.F_flags&unix.MNT_NOATIME != 0 {
|
||||||
opts += ",noatime"
|
opts = append(opts, "noatime")
|
||||||
}
|
}
|
||||||
if stat.F_flags&unix.MNT_WXALLOWED != 0 {
|
if stat.F_flags&unix.MNT_WXALLOWED != 0 {
|
||||||
opts += ",wxallowed"
|
opts = append(opts, "wxallowed")
|
||||||
}
|
}
|
||||||
|
|
||||||
d := PartitionStat{
|
d := PartitionStat{
|
||||||
|
@ -66,11 +61,6 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro
|
||||||
Fstype: common.IntToString(stat.F_fstypename[:]),
|
Fstype: common.IntToString(stat.F_fstypename[:]),
|
||||||
Opts: opts,
|
Opts: opts,
|
||||||
}
|
}
|
||||||
if all == false {
|
|
||||||
if !path.IsAbs(d.Device) || !common.PathExists(d.Device) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = append(ret, d)
|
ret = append(ret, d)
|
||||||
}
|
}
|
||||||
|
@ -78,10 +68,6 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro
|
||||||
return ret, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func IOCounters(names ...string) (map[string]IOCountersStat, error) {
|
|
||||||
return IOCountersWithContext(context.Background(), names...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) {
|
func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) {
|
||||||
ret := make(map[string]IOCountersStat)
|
ret := make(map[string]IOCountersStat)
|
||||||
|
|
||||||
|
@ -134,10 +120,6 @@ func parseDiskstats(buf []byte) (Diskstats, error) {
|
||||||
return ds, nil
|
return ds, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func Usage(path string) (*UsageStat, error) {
|
|
||||||
return UsageWithContext(context.Background(), path)
|
|
||||||
}
|
|
||||||
|
|
||||||
func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) {
|
func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) {
|
||||||
stat := unix.Statfs_t{}
|
stat := unix.Statfs_t{}
|
||||||
err := unix.Statfs(path, &stat)
|
err := unix.Statfs(path, &stat)
|
||||||
|
@ -166,3 +148,11 @@ func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) {
|
||||||
func getFsType(stat unix.Statfs_t) string {
|
func getFsType(stat unix.Statfs_t) string {
|
||||||
return common.IntToString(stat.F_fstypename[:])
|
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
|
||||||
|
}
|
|
@ -6,10 +6,10 @@
|
||||||
package disk
|
package disk
|
||||||
|
|
||||||
const (
|
const (
|
||||||
DEVSTAT_NO_DATA = 0x00
|
devstat_NO_DATA = 0x00
|
||||||
DEVSTAT_READ = 0x01
|
devstat_READ = 0x01
|
||||||
DEVSTAT_WRITE = 0x02
|
devstat_WRITE = 0x02
|
||||||
DEVSTAT_FREE = 0x03
|
devstat_FREE = 0x03
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -34,4 +34,4 @@ type Timeval struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Diskstat struct{}
|
type Diskstat struct{}
|
||||||
type Bintime struct{}
|
type bintime struct{}
|
|
@ -4,10 +4,10 @@
|
||||||
package disk
|
package disk
|
||||||
|
|
||||||
const (
|
const (
|
||||||
DEVSTAT_NO_DATA = 0x00
|
devstat_NO_DATA = 0x00
|
||||||
DEVSTAT_READ = 0x01
|
devstat_READ = 0x01
|
||||||
DEVSTAT_WRITE = 0x02
|
devstat_WRITE = 0x02
|
||||||
DEVSTAT_FREE = 0x03
|
devstat_FREE = 0x03
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -33,4 +33,4 @@ type Timeval struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Diskstat struct{}
|
type Diskstat struct{}
|
||||||
type Bintime struct{}
|
type bintime struct{}
|
|
@ -10,7 +10,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/shirou/gopsutil/internal/common"
|
"github.com/shirou/gopsutil/v3/internal/common"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -38,10 +38,6 @@ var (
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func Partitions(all bool) ([]PartitionStat, error) {
|
|
||||||
return PartitionsWithContext(context.Background(), all)
|
|
||||||
}
|
|
||||||
|
|
||||||
func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) {
|
func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) {
|
||||||
ret := make([]PartitionStat, 0, _DEFAULT_NUM_MOUNTS)
|
ret := make([]PartitionStat, 0, _DEFAULT_NUM_MOUNTS)
|
||||||
|
|
||||||
|
@ -73,7 +69,7 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro
|
||||||
Device: fields[0],
|
Device: fields[0],
|
||||||
Mountpoint: fields[1],
|
Mountpoint: fields[1],
|
||||||
Fstype: fields[2],
|
Fstype: fields[2],
|
||||||
Opts: fields[3],
|
Opts: strings.Split(fields[3], ","),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if err := scanner.Err(); err != nil {
|
if err := scanner.Err(); err != nil {
|
||||||
|
@ -83,18 +79,10 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro
|
||||||
return ret, err
|
return ret, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func IOCounters(names ...string) (map[string]IOCountersStat, error) {
|
|
||||||
return IOCountersWithContext(context.Background(), names...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) {
|
func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) {
|
||||||
return nil, common.ErrNotImplementedError
|
return nil, common.ErrNotImplementedError
|
||||||
}
|
}
|
||||||
|
|
||||||
func Usage(path string) (*UsageStat, error) {
|
|
||||||
return UsageWithContext(context.Background(), path)
|
|
||||||
}
|
|
||||||
|
|
||||||
func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) {
|
func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) {
|
||||||
statvfs := unix.Statvfs_t{}
|
statvfs := unix.Statvfs_t{}
|
||||||
if err := unix.Statvfs(path, &statvfs); err != nil {
|
if err := unix.Statvfs(path, &statvfs); err != nil {
|
||||||
|
@ -125,3 +113,10 @@ func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) {
|
||||||
|
|
||||||
return usageStat, nil
|
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
|
||||||
|
}
|
|
@ -9,13 +9,6 @@ import (
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
// 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)
|
|
||||||
}
|
|
||||||
|
|
||||||
func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) {
|
func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) {
|
||||||
stat := unix.Statfs_t{}
|
stat := unix.Statfs_t{}
|
||||||
err := unix.Statfs(path, &stat)
|
err := unix.Statfs(path, &stat)
|
|
@ -9,7 +9,7 @@ import (
|
||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/shirou/gopsutil/internal/common"
|
"github.com/shirou/gopsutil/v3/internal/common"
|
||||||
"golang.org/x/sys/windows"
|
"golang.org/x/sys/windows"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -21,8 +21,8 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
FileFileCompression = int64(16) // 0x00000010
|
fileFileCompression = int64(16) // 0x00000010
|
||||||
FileReadOnlyVolume = int64(524288) // 0x00080000
|
fileReadOnlyVolume = int64(524288) // 0x00080000
|
||||||
)
|
)
|
||||||
|
|
||||||
// diskPerformance is an equivalent representation of DISK_PERFORMANCE in the Windows API.
|
// diskPerformance is an equivalent representation of DISK_PERFORMANCE in the Windows API.
|
||||||
|
@ -43,10 +43,6 @@ type diskPerformance struct {
|
||||||
alignmentPadding uint32 // necessary for 32bit support, see https://github.com/elastic/beats/pull/16553
|
alignmentPadding uint32 // necessary for 32bit support, see https://github.com/elastic/beats/pull/16553
|
||||||
}
|
}
|
||||||
|
|
||||||
func Usage(path string) (*UsageStat, error) {
|
|
||||||
return UsageWithContext(context.Background(), path)
|
|
||||||
}
|
|
||||||
|
|
||||||
func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) {
|
func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) {
|
||||||
lpFreeBytesAvailable := int64(0)
|
lpFreeBytesAvailable := int64(0)
|
||||||
lpTotalNumberOfBytes := int64(0)
|
lpTotalNumberOfBytes := int64(0)
|
||||||
|
@ -73,10 +69,6 @@ func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) {
|
||||||
return ret, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func Partitions(all bool) ([]PartitionStat, error) {
|
|
||||||
return PartitionsWithContext(context.Background(), all)
|
|
||||||
}
|
|
||||||
|
|
||||||
func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) {
|
func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) {
|
||||||
var ret []PartitionStat
|
var ret []PartitionStat
|
||||||
lpBuffer := make([]byte, 254)
|
lpBuffer := make([]byte, 254)
|
||||||
|
@ -118,12 +110,12 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro
|
||||||
}
|
}
|
||||||
return ret, err
|
return ret, err
|
||||||
}
|
}
|
||||||
opts := "rw"
|
opts := []string{"rw"}
|
||||||
if lpFileSystemFlags&FileReadOnlyVolume != 0 {
|
if lpFileSystemFlags&fileReadOnlyVolume != 0 {
|
||||||
opts = "ro"
|
opts = []string{"ro"}
|
||||||
}
|
}
|
||||||
if lpFileSystemFlags&FileFileCompression != 0 {
|
if lpFileSystemFlags&fileFileCompression != 0 {
|
||||||
opts += ".compress"
|
opts = append(opts, "compress")
|
||||||
}
|
}
|
||||||
|
|
||||||
d := PartitionStat{
|
d := PartitionStat{
|
||||||
|
@ -139,10 +131,6 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro
|
||||||
return ret, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func IOCounters(names ...string) (map[string]IOCountersStat, error) {
|
|
||||||
return IOCountersWithContext(context.Background(), names...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) {
|
func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) {
|
||||||
// https://github.com/giampaolo/psutil/blob/544e9daa4f66a9f80d7bf6c7886d693ee42f0a13/psutil/arch/windows/disk.c#L83
|
// https://github.com/giampaolo/psutil/blob/544e9daa4f66a9f80d7bf6c7886d693ee42f0a13/psutil/arch/windows/disk.c#L83
|
||||||
drivemap := make(map[string]IOCountersStat, 0)
|
drivemap := make(map[string]IOCountersStat, 0)
|
||||||
|
@ -155,7 +143,7 @@ func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOC
|
||||||
}
|
}
|
||||||
for _, v := range lpBuffer[:lpBufferLen] {
|
for _, v := range lpBuffer[:lpBufferLen] {
|
||||||
if 'A' <= v && v <= 'Z' {
|
if 'A' <= v && v <= 'Z' {
|
||||||
path := string(v) + ":"
|
path := string(rune(v)) + ":"
|
||||||
typepath, _ := windows.UTF16PtrFromString(path)
|
typepath, _ := windows.UTF16PtrFromString(path)
|
||||||
typeret := windows.GetDriveType(typepath)
|
typeret := windows.GetDriveType(typepath)
|
||||||
if typeret == 0 {
|
if typeret == 0 {
|
||||||
|
@ -193,3 +181,11 @@ func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOC
|
||||||
}
|
}
|
||||||
return drivemap, nil
|
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
|
||||||
|
}
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"runtime"
|
"runtime"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/shirou/gopsutil/internal/common"
|
"github.com/shirou/gopsutil/v3/internal/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
var invoke common.Invoker = common.Invoke{}
|
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
|
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"`
|
VirtualizationSystem string `json:"virtualizationSystem"`
|
||||||
VirtualizationRole string `json:"virtualizationRole"` // guest or host
|
VirtualizationRole string `json:"virtualizationRole"` // guest or host
|
||||||
HostID string `json:"hostid"` // ex: uuid
|
HostID string `json:"hostId"` // ex: uuid
|
||||||
}
|
}
|
||||||
|
|
||||||
type UserStat struct {
|
type UserStat struct {
|
||||||
|
@ -39,7 +39,9 @@ type UserStat struct {
|
||||||
|
|
||||||
type TemperatureStat struct {
|
type TemperatureStat struct {
|
||||||
SensorKey string `json:"sensorKey"`
|
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 {
|
func (h InfoStat) String() string {
|
|
@ -12,13 +12,13 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/shirou/gopsutil/internal/common"
|
"github.com/shirou/gopsutil/v3/internal/common"
|
||||||
"github.com/shirou/gopsutil/process"
|
"github.com/shirou/gopsutil/v3/process"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
// from utmpx.h
|
// from utmpx.h
|
||||||
const USER_PROCESS = 7
|
const user_PROCESS = 7
|
||||||
|
|
||||||
func HostIDWithContext(ctx context.Context) (string, error) {
|
func HostIDWithContext(ctx context.Context) (string, error) {
|
||||||
uuid, err := unix.Sysctl("kern.uuid")
|
uuid, err := unix.Sysctl("kern.uuid")
|
||||||
|
@ -64,7 +64,7 @@ func UsersWithContext(ctx context.Context) ([]UserStat, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if u.Type != USER_PROCESS {
|
if u.Type != user_PROCESS {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
user := UserStat{
|
user := UserStat{
|
|
@ -6,7 +6,7 @@ package host
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/shirou/gopsutil/internal/common"
|
"github.com/shirou/gopsutil/v3/internal/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) {
|
func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) {
|
|
@ -5,7 +5,7 @@ package host
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/shirou/gopsutil/internal/common"
|
"github.com/shirou/gopsutil/v3/internal/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
func HostIDWithContext(ctx context.Context) (string, error) {
|
func HostIDWithContext(ctx context.Context) (string, error) {
|
|
@ -12,8 +12,8 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/shirou/gopsutil/internal/common"
|
"github.com/shirou/gopsutil/v3/internal/common"
|
||||||
"github.com/shirou/gopsutil/process"
|
"github.com/shirou/gopsutil/v3/process"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
|
@ -15,11 +15,11 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/shirou/gopsutil/internal/common"
|
"github.com/shirou/gopsutil/v3/internal/common"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
type LSB struct {
|
type lsbStruct struct {
|
||||||
ID string
|
ID string
|
||||||
Release string
|
Release string
|
||||||
Codename string
|
Codename string
|
||||||
|
@ -27,7 +27,11 @@ type LSB struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// from utmp.h
|
// from utmp.h
|
||||||
const USER_PROCESS = 7
|
const (
|
||||||
|
user_PROCESS = 7
|
||||||
|
|
||||||
|
hostTemperatureScale = 1000.0
|
||||||
|
)
|
||||||
|
|
||||||
func HostIDWithContext(ctx context.Context) (string, error) {
|
func HostIDWithContext(ctx context.Context) (string, error) {
|
||||||
sysProductUUID := common.HostSys("class/dmi/id/product_uuid")
|
sysProductUUID := common.HostSys("class/dmi/id/product_uuid")
|
||||||
|
@ -104,7 +108,7 @@ func UsersWithContext(ctx context.Context) ([]UserStat, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if u.Type != USER_PROCESS {
|
if u.Type != user_PROCESS {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
user := UserStat{
|
user := UserStat{
|
||||||
|
@ -120,8 +124,8 @@ func UsersWithContext(ctx context.Context) ([]UserStat, error) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func getLSB() (*LSB, error) {
|
func getlsbStruct() (*lsbStruct, error) {
|
||||||
ret := &LSB{}
|
ret := &lsbStruct{}
|
||||||
if common.PathExists(common.HostEtc("lsb-release")) {
|
if common.PathExists(common.HostEtc("lsb-release")) {
|
||||||
contents, err := common.ReadLines(common.HostEtc("lsb-release"))
|
contents, err := common.ReadLines(common.HostEtc("lsb-release"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -175,9 +179,9 @@ func getLSB() (*LSB, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func PlatformInformationWithContext(ctx context.Context) (platform string, family string, version string, err error) {
|
func PlatformInformationWithContext(ctx context.Context) (platform string, family string, version string, err error) {
|
||||||
lsb, err := getLSB()
|
lsb, err := getlsbStruct()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
lsb = &LSB{}
|
lsb = &lsbStruct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
if common.PathExists(common.HostEtc("oracle-release")) {
|
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) {
|
func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) {
|
||||||
var temperatures []TemperatureStat
|
var err error
|
||||||
files, err := filepath.Glob(common.HostSys("/class/hwmon/hwmon*/temp*_*"))
|
|
||||||
if err != nil {
|
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
|
return temperatures, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(files) == 0 {
|
if len(files) == 0 {
|
||||||
// CentOS has an intermediate /device directory:
|
// CentOS has an intermediate /device directory:
|
||||||
// https://github.com/giampaolo/psutil/issues/971
|
// https://github.com/giampaolo/psutil/issues/971
|
||||||
files, err = filepath.Glob(common.HostSys("/class/hwmon/hwmon*/device/temp*_*"))
|
if files, err = filepath.Glob(common.HostSys("/class/hwmon/hwmon*/device/temp*_input")); err != nil {
|
||||||
if err != nil {
|
|
||||||
return temperatures, err
|
return temperatures, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var warns Warnings
|
var warns Warnings
|
||||||
|
|
||||||
if len(files) == 0 { // handle distributions without hwmon, like raspbian #391, parse legacy thermal_zone files
|
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()
|
return temperatures, warns.Reference()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
temperatures = make([]TemperatureStat, 0, len(files))
|
||||||
|
|
||||||
// example directory
|
// example directory
|
||||||
// device/ temp1_crit_alarm temp2_crit_alarm temp3_crit_alarm temp4_crit_alarm temp5_crit_alarm temp6_crit_alarm temp7_crit_alarm
|
// 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
|
// 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
|
// 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
|
// temp1_crit temp2_crit temp3_crit temp4_crit temp5_crit temp6_crit temp7_crit uevent
|
||||||
for _, file := range files {
|
for _, file := range files {
|
||||||
filename := strings.Split(filepath.Base(file), "_")
|
var raw []byte
|
||||||
if filename[1] == "label" {
|
|
||||||
// Do not try to read the temperature of the label file
|
var temperature float64
|
||||||
continue
|
|
||||||
}
|
// 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 <dir>/temp1
|
||||||
|
basepath := filepath.Join(directory, basename)
|
||||||
|
|
||||||
// Get the label of the temperature you are reading
|
// Get the label of the temperature you are reading
|
||||||
var label string
|
label := ""
|
||||||
c, _ := ioutil.ReadFile(filepath.Join(filepath.Dir(file), filename[0]+"_label"))
|
|
||||||
if c != nil {
|
if raw, _ = ioutil.ReadFile(basepath + "_label"); len(raw) != 0 {
|
||||||
//format the label from "Core 0" to "core0_"
|
// Format the label from "Core 0" to "core_0"
|
||||||
label = fmt.Sprintf("%s_", strings.Join(strings.Split(strings.TrimSpace(strings.ToLower(string(c))), " "), ""))
|
label = strings.Join(strings.Split(strings.TrimSpace(strings.ToLower(string(raw))), " "), "_")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the name of the temperature you are reading
|
// Get the name of the temperature you are reading
|
||||||
name, err := ioutil.ReadFile(filepath.Join(filepath.Dir(file), "name"))
|
if raw, err = ioutil.ReadFile(filepath.Join(directory, "name")); err != nil {
|
||||||
if err != nil {
|
|
||||||
warns.Add(err)
|
warns.Add(err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
name := strings.TrimSpace(string(raw))
|
||||||
|
|
||||||
|
if label != "" {
|
||||||
|
name = name + "_" + label
|
||||||
|
}
|
||||||
|
|
||||||
// Get the temperature reading
|
// Get the temperature reading
|
||||||
current, err := ioutil.ReadFile(file)
|
if raw, err = ioutil.ReadFile(file); err != nil {
|
||||||
if err != nil {
|
|
||||||
warns.Add(err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
temperature, err := strconv.ParseFloat(strings.TrimSpace(string(current)), 64)
|
|
||||||
if err != nil {
|
|
||||||
warns.Add(err)
|
warns.Add(err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
tempName := strings.TrimSpace(strings.ToLower(string(strings.Join(filename[1:], ""))))
|
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{
|
temperatures = append(temperatures, TemperatureStat{
|
||||||
SensorKey: fmt.Sprintf("%s_%s%s", strings.TrimSpace(string(name)), label, tempName),
|
SensorKey: name,
|
||||||
Temperature: temperature / 1000.0,
|
Temperature: temperature / hostTemperatureScale,
|
||||||
|
High: optionalValueReadFromFile(basepath+"_max") / hostTemperatureScale,
|
||||||
|
Critical: optionalValueReadFromFile(basepath+"_crit") / hostTemperatureScale,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return temperatures, warns.Reference()
|
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
|
||||||
|
}
|
|
@ -11,8 +11,8 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/shirou/gopsutil/internal/common"
|
"github.com/shirou/gopsutil/v3/internal/common"
|
||||||
"github.com/shirou/gopsutil/process"
|
"github.com/shirou/gopsutil/v3/process"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
|
@ -12,7 +12,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/shirou/gopsutil/internal/common"
|
"github.com/shirou/gopsutil/v3/internal/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
func HostIDWithContext(ctx context.Context) (string, error) {
|
func HostIDWithContext(ctx context.Context) (string, error) {
|
|
@ -13,8 +13,8 @@ import (
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/StackExchange/wmi"
|
"github.com/StackExchange/wmi"
|
||||||
"github.com/shirou/gopsutil/internal/common"
|
"github.com/shirou/gopsutil/v3/internal/common"
|
||||||
"github.com/shirou/gopsutil/process"
|
"github.com/shirou/gopsutil/v3/process"
|
||||||
"golang.org/x/sys/windows"
|
"golang.org/x/sys/windows"
|
||||||
)
|
)
|
||||||
|
|
|
@ -326,7 +326,6 @@ func GetEnv(key string, dfault string, combineWith ...string) string {
|
||||||
copy(all[1:], combineWith)
|
copy(all[1:], combineWith)
|
||||||
return filepath.Join(all...)
|
return filepath.Join(all...)
|
||||||
}
|
}
|
||||||
panic("invalid switch case")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func HostProc(combineWith ...string) string {
|
func HostProc(combineWith ...string) string {
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -110,16 +111,24 @@ func Virtualization() (string, string, error) {
|
||||||
return VirtualizationWithContext(context.Background())
|
return VirtualizationWithContext(context.Background())
|
||||||
}
|
}
|
||||||
|
|
||||||
var virtualizationCache map[string]string
|
// 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) {
|
func VirtualizationWithContext(ctx context.Context) (string, string, error) {
|
||||||
// if cached already, return from cache
|
var system, role string
|
||||||
if virtualizationCache != nil {
|
|
||||||
return virtualizationCache["system"], virtualizationCache["role"], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var system string
|
// if cached already, return from cache
|
||||||
var role string
|
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")
|
filename := HostProc("xen")
|
||||||
if PathExists(filename) {
|
if PathExists(filename) {
|
||||||
|
@ -240,10 +249,14 @@ func VirtualizationWithContext(ctx context.Context) (string, string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// before returning for the first time, cache the system and role
|
// before returning for the first time, cache the system and role
|
||||||
virtualizationCache = map[string]string{
|
cachedVirtOnce.Do(func() {
|
||||||
|
cachedVirtMutex.Lock()
|
||||||
|
defer cachedVirtMutex.Unlock()
|
||||||
|
cachedVirtMap = map[string]string{
|
||||||
"system": system,
|
"system": system,
|
||||||
"role": role,
|
"role": role,
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
|
||||||
return system, role, nil
|
return system, role, nil
|
||||||
}
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue