mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-06-05 05:32:59 +00:00
build(deps): bump github.com/containerd/containerd in /src/runtime
Bumps [github.com/containerd/containerd](https://github.com/containerd/containerd) from 1.6.1 to 1.6.6. - [Release notes](https://github.com/containerd/containerd/releases) - [Changelog](https://github.com/containerd/containerd/blob/main/RELEASES.md) - [Commits](https://github.com/containerd/containerd/compare/v1.6.1...v1.6.6) --- updated-dependencies: - dependency-name: github.com/containerd/containerd dependency-type: direct:production ... Fixes: #4421 Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
parent
d0ca2fcbbc
commit
5d7fb7b7b0
@ -9,12 +9,12 @@ require (
|
||||
github.com/blang/semver/v4 v4.0.0
|
||||
github.com/containerd/cgroups v1.0.3
|
||||
github.com/containerd/console v1.0.3
|
||||
github.com/containerd/containerd v1.6.1
|
||||
github.com/containerd/containerd v1.6.6
|
||||
github.com/containerd/cri-containerd v1.11.1-0.20190125013620-4dd6735020f5
|
||||
github.com/containerd/fifo v1.0.0
|
||||
github.com/containerd/ttrpc v1.1.0
|
||||
github.com/containerd/typeurl v1.0.2
|
||||
github.com/containernetworking/plugins v1.0.1
|
||||
github.com/containernetworking/plugins v1.1.1
|
||||
github.com/coreos/go-systemd/v22 v22.3.2
|
||||
github.com/cri-o/cri-o v1.0.0-rc2.0.20170928185954-3394b3b2d6af
|
||||
github.com/docker/go-units v0.4.0
|
||||
@ -25,17 +25,16 @@ require (
|
||||
github.com/go-openapi/strfmt v0.18.0
|
||||
github.com/go-openapi/swag v0.19.14
|
||||
github.com/go-openapi/validate v0.18.0
|
||||
github.com/godbus/dbus/v5 v5.0.4
|
||||
github.com/godbus/dbus/v5 v5.0.6
|
||||
github.com/gogo/protobuf v1.3.2
|
||||
github.com/hashicorp/go-multierror v1.1.1
|
||||
github.com/intel-go/cpuid v0.0.0-20210602155658-5747e5cec0d9
|
||||
github.com/mdlayher/vsock v1.1.0
|
||||
github.com/opencontainers/image-spec v1.0.2 // indirect
|
||||
github.com/opencontainers/runc v1.1.0
|
||||
github.com/opencontainers/runc v1.1.2
|
||||
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417
|
||||
github.com/opencontainers/selinux v1.10.0
|
||||
github.com/opencontainers/selinux v1.10.1
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/prometheus/client_golang v1.11.0
|
||||
github.com/prometheus/client_golang v1.11.1
|
||||
github.com/prometheus/client_model v0.2.0
|
||||
github.com/prometheus/common v0.30.0
|
||||
github.com/prometheus/procfs v0.7.3
|
||||
@ -51,7 +50,7 @@ require (
|
||||
go.opentelemetry.io/otel/trace v1.3.0
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd
|
||||
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f
|
||||
golang.org/x/sys v0.0.0-20220204135822-1c1b9b1eba6a
|
||||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad
|
||||
google.golang.org/grpc v1.43.0
|
||||
k8s.io/apimachinery v0.22.5
|
||||
k8s.io/cri-api v0.23.1
|
||||
|
@ -82,8 +82,9 @@ github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+V
|
||||
github.com/Microsoft/hcsshim v0.8.20/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4=
|
||||
github.com/Microsoft/hcsshim v0.8.21/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4=
|
||||
github.com/Microsoft/hcsshim v0.8.23/go.mod h1:4zegtUJth7lAvFyc6cH2gGQ5B3OFQim01nnU2M8jKDg=
|
||||
github.com/Microsoft/hcsshim v0.9.2 h1:wB06W5aYFfUB3IvootYAY2WnOmIdgPGfqSI6tufQNnY=
|
||||
github.com/Microsoft/hcsshim v0.9.2/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc=
|
||||
github.com/Microsoft/hcsshim v0.9.3 h1:k371PzBuRrz2b+ebGuI2nVgVhgsVX60jMfSw80NECxo=
|
||||
github.com/Microsoft/hcsshim v0.9.3/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc=
|
||||
github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU=
|
||||
github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY=
|
||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
||||
@ -154,8 +155,9 @@ github.com/cilium/ebpf v0.0.0-20200110133405-4032b1d8aae3/go.mod h1:MA5e5Lr8slmE
|
||||
github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLIdUjrmSXlK9pkrsDlLHbO8jiB8X8JnOc=
|
||||
github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs=
|
||||
github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
|
||||
github.com/cilium/ebpf v0.6.2 h1:iHsfF/t4aW4heW2YKfeHrVPGdtYTL4C4KocpM8KTSnI=
|
||||
github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
|
||||
github.com/cilium/ebpf v0.7.0 h1:1k/q3ATgxSXRdrmPfH8d7YK0GfqVsEKZAX9dQZvs56k=
|
||||
github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
@ -208,8 +210,9 @@ github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoT
|
||||
github.com/containerd/containerd v1.5.1/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g=
|
||||
github.com/containerd/containerd v1.5.7/go.mod h1:gyvv6+ugqY25TiXxcZC3L5yOeYgEw0QMhscqVp1AR9c=
|
||||
github.com/containerd/containerd v1.5.8/go.mod h1:YdFSv5bTFLpG2HIYmfqDpSYYTDX+mc5qtSuYx1YUb/s=
|
||||
github.com/containerd/containerd v1.6.1 h1:oa2uY0/0G+JX4X7hpGCYvkp9FjUancz56kSNnb1sG3o=
|
||||
github.com/containerd/containerd v1.6.1/go.mod h1:1nJz5xCZPusx6jJU8Frfct988y0NpumIq9ODB0kLtoE=
|
||||
github.com/containerd/containerd v1.6.6 h1:xJNPhbrmz8xAMDNoVjHy9YHtWwEQNS+CDkcIRh7t8Y0=
|
||||
github.com/containerd/containerd v1.6.6/go.mod h1:ZoP1geJldzCVY3Tonoz7b1IXk8rIX0Nltt5QE4OMNk0=
|
||||
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
||||
github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
||||
github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
||||
@ -232,6 +235,7 @@ github.com/containerd/go-cni v1.0.1/go.mod h1:+vUpYxKvAF72G9i1WoDOiPGRtQpqsNW/ZH
|
||||
github.com/containerd/go-cni v1.0.2/go.mod h1:nrNABBHzu0ZwCug9Ije8hL2xBCYh/pjfMb1aZGrrohk=
|
||||
github.com/containerd/go-cni v1.1.0/go.mod h1:Rflh2EJ/++BA2/vY5ao3K6WJRR/bZKsX123aPk+kUtA=
|
||||
github.com/containerd/go-cni v1.1.3/go.mod h1:Rflh2EJ/++BA2/vY5ao3K6WJRR/bZKsX123aPk+kUtA=
|
||||
github.com/containerd/go-cni v1.1.6/go.mod h1:BWtoWl5ghVymxu6MBjg79W9NZrCRyHIdUtk4cauMe34=
|
||||
github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0=
|
||||
github.com/containerd/go-runc v0.0.0-20190911050354-e029b79d8cda/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0=
|
||||
github.com/containerd/go-runc v0.0.0-20200220073739-7016d3ce2328/go.mod h1:PpyHrqVs8FTi9vpyHwPwiNEGaACDxT/N/pLcvMSRA9g=
|
||||
@ -243,6 +247,7 @@ github.com/containerd/imgcrypt v1.0.4-0.20210301171431-0ae5c75f59ba/go.mod h1:6T
|
||||
github.com/containerd/imgcrypt v1.1.1-0.20210312161619-7ed62a527887/go.mod h1:5AZJNI6sLHJljKuI9IHnw1pWqo/F0nGDOuR9zgTs7ow=
|
||||
github.com/containerd/imgcrypt v1.1.1/go.mod h1:xpLnwiQmEUJPvQoAapeb2SNCxz7Xr6PJrXQb0Dpc4ms=
|
||||
github.com/containerd/imgcrypt v1.1.3/go.mod h1:/TPA1GIDXMzbj01yd8pIbQiLdQxed5ue1wb8bP7PQu4=
|
||||
github.com/containerd/imgcrypt v1.1.4/go.mod h1:LorQnPtzL/T0IyCeftcsMEO7AqxUDbdO8j/tSUpgxvo=
|
||||
github.com/containerd/nri v0.0.0-20201007170849-eb1350a75164/go.mod h1:+2wGSDGFYfE5+So4M5syatU0N0f0LbWpuqyMi4/BE8c=
|
||||
github.com/containerd/nri v0.0.0-20210316161719-dbaa18c31c14/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY=
|
||||
github.com/containerd/nri v0.1.0/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY=
|
||||
@ -267,16 +272,19 @@ github.com/containerd/zfs v1.0.0/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNR
|
||||
github.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
|
||||
github.com/containernetworking/cni v0.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
|
||||
github.com/containernetworking/cni v0.8.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
|
||||
github.com/containernetworking/cni v1.0.1 h1:9OIL/sZmMYDBe+G8svzILAlulUpaDTUjeAbtH/JNLBo=
|
||||
github.com/containernetworking/cni v1.0.1/go.mod h1:AKuhXbN5EzmD4yTNtfSsX3tPcmtrBI6QcRV0NiNt15Y=
|
||||
github.com/containernetworking/cni v1.1.1 h1:ky20T7c0MvKvbMOwS/FrlbNwjEoqJEUUYfsL4b0mc4k=
|
||||
github.com/containernetworking/cni v1.1.1/go.mod h1:sDpYKmGVENF3s6uvMvGgldDWeG8dMxakj/u+i9ht9vw=
|
||||
github.com/containernetworking/plugins v0.8.6/go.mod h1:qnw5mN19D8fIwkqW7oHHYDHVlzhJpcY6TQxn/fUyDDM=
|
||||
github.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRDjeJr6FLK6vuiUwoH7P8=
|
||||
github.com/containernetworking/plugins v1.0.1 h1:wwCfYbTCj5FC0EJgyzyjTXmqysOiJE9r712Z+2KVZAk=
|
||||
github.com/containernetworking/plugins v1.0.1/go.mod h1:QHCfGpaTwYTbbH+nZXKVTxNBDZcxSOplJT5ico8/FLE=
|
||||
github.com/containernetworking/plugins v1.1.1 h1:+AGfFigZ5TiQH00vhR8qPeSatj53eNGz0C1d3wVYlHE=
|
||||
github.com/containernetworking/plugins v1.1.1/go.mod h1:Sr5TH/eBsGLXK/h71HeLfX19sZPp3ry5uHSkI4LPxV8=
|
||||
github.com/containers/ocicrypt v1.0.1/go.mod h1:MeJDzk1RJHv89LjsH0Sp5KTY3ZYkjXO/C+bKAeWFIrc=
|
||||
github.com/containers/ocicrypt v1.1.0/go.mod h1:b8AOe0YR67uU8OqfVNcznfFpAzu3rdgUV4GP9qXPfu4=
|
||||
github.com/containers/ocicrypt v1.1.1/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B0oB3dj3jFxY=
|
||||
github.com/containers/ocicrypt v1.1.2/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B0oB3dj3jFxY=
|
||||
github.com/containers/ocicrypt v1.1.3/go.mod h1:xpdkbVAuaH3WzbEabUd5yDsl9SwJA5pABH85425Es2g=
|
||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
@ -445,8 +453,9 @@ github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblf
|
||||
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e h1:BWhy2j3IXJhjCbC68FptL43tDKIq8FladmaTs3Xs7Z8=
|
||||
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
|
||||
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/godbus/dbus/v5 v5.0.4 h1:9349emZab16e7zQvpmsbtjc18ykshndd8y2PG3sgJbA=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/godbus/dbus/v5 v5.0.6 h1:mkgN1ofwASrYnJ5W6U/BxG15eXXXjirgZc7CLqkcaro=
|
||||
github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU=
|
||||
github.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
@ -527,6 +536,7 @@ github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLe
|
||||
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
@ -661,6 +671,7 @@ github.com/mdlayher/vsock v1.1.0 h1:2k9udP/hUkLUOboGxXMHOk4f0GWWZwS3IuE3Ee/YYfk=
|
||||
github.com/mdlayher/vsock v1.1.0/go.mod h1:nsVhPsVuBBwAKh6i6PzdNoke6/TNYTjkxoRKAp/+pXs=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
|
||||
github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
|
||||
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
|
||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
@ -696,6 +707,7 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||
github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM=
|
||||
github.com/networkplumbing/go-nft v0.2.0/go.mod h1:HnnM+tYvlGAsMU7yoYwXEVLLiDW9gdMmb5HoGcwpuQs=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||
@ -715,6 +727,8 @@ github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1ls
|
||||
github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
|
||||
github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
|
||||
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
|
||||
github.com/onsi/ginkgo/v2 v2.1.3 h1:e/3Cwtogj0HA+25nMP1jCMDIf8RtRYbGwGGuBIFztkc=
|
||||
github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
|
||||
github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
@ -724,8 +738,9 @@ github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoT
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc=
|
||||
github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0=
|
||||
github.com/onsi/gomega v1.16.0 h1:6gjqkI8iiRHMvdccRJM8rVKjCWk6ZIm6FTm3ddIe4/c=
|
||||
github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
||||
github.com/onsi/gomega v1.17.0 h1:9Luw4uT5HTjHTN8+aNcSThgH1vdXnmdJ8xIfZ4wyTRE=
|
||||
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
||||
github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
@ -747,8 +762,9 @@ github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mo
|
||||
github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE=
|
||||
github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo=
|
||||
github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8=
|
||||
github.com/opencontainers/selinux v1.10.0 h1:rAiKF8hTcgLI3w0DHm6i0ylVVcOrlgR1kK99DRLDhyU=
|
||||
github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI=
|
||||
github.com/opencontainers/selinux v1.10.1 h1:09LIPVRP3uuZGQvgR+SgMSNBd1Eb3vlRbGqQpoHsF8w=
|
||||
github.com/opencontainers/selinux v1.10.1/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI=
|
||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g=
|
||||
@ -772,8 +788,9 @@ github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDf
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
|
||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ=
|
||||
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
|
||||
github.com/prometheus/client_golang v1.11.1 h1:+4eQaD7vAZ6DsfsxB15hbE0odUjGI5ARs9yskGu1v4s=
|
||||
github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
|
||||
github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
@ -1192,11 +1209,13 @@ golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210903071746-97244b99971b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220204135822-1c1b9b1eba6a h1:ppl5mZgokTT8uPkmYOyEUmPTr3ypaKkg5eFOGrAmxxE=
|
||||
golang.org/x/sys v0.0.0-20220204135822-1c1b9b1eba6a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad h1:ntjMns5wyP/fN65tdBD4g8J5w8n015+iIIs9rtjXkY0=
|
||||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
@ -1281,6 +1300,7 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
188
src/runtime/vendor/github.com/Microsoft/hcsshim/internal/hcs/system.go
generated
vendored
188
src/runtime/vendor/github.com/Microsoft/hcsshim/internal/hcs/system.go
generated
vendored
@ -4,17 +4,22 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/Microsoft/hcsshim/internal/cow"
|
||||
"github.com/Microsoft/hcsshim/internal/hcs/schema1"
|
||||
hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2"
|
||||
"github.com/Microsoft/hcsshim/internal/jobobject"
|
||||
"github.com/Microsoft/hcsshim/internal/log"
|
||||
"github.com/Microsoft/hcsshim/internal/logfields"
|
||||
"github.com/Microsoft/hcsshim/internal/oc"
|
||||
"github.com/Microsoft/hcsshim/internal/timeout"
|
||||
"github.com/Microsoft/hcsshim/internal/vmcompute"
|
||||
"github.com/sirupsen/logrus"
|
||||
"go.opencensus.io/trace"
|
||||
)
|
||||
|
||||
@ -28,7 +33,8 @@ type System struct {
|
||||
waitBlock chan struct{}
|
||||
waitError error
|
||||
exitError error
|
||||
os, typ string
|
||||
os, typ, owner string
|
||||
startTime time.Time
|
||||
}
|
||||
|
||||
func newSystem(id string) *System {
|
||||
@ -38,6 +44,11 @@ func newSystem(id string) *System {
|
||||
}
|
||||
}
|
||||
|
||||
// Implementation detail for silo naming, this should NOT be relied upon very heavily.
|
||||
func siloNameFmt(containerID string) string {
|
||||
return fmt.Sprintf(`\Container_%s`, containerID)
|
||||
}
|
||||
|
||||
// CreateComputeSystem creates a new compute system with the given configuration but does not start it.
|
||||
func CreateComputeSystem(ctx context.Context, id string, hcsDocumentInterface interface{}) (_ *System, err error) {
|
||||
operation := "hcs::CreateComputeSystem"
|
||||
@ -127,6 +138,7 @@ func (computeSystem *System) getCachedProperties(ctx context.Context) error {
|
||||
}
|
||||
computeSystem.typ = strings.ToLower(props.SystemType)
|
||||
computeSystem.os = strings.ToLower(props.RuntimeOSType)
|
||||
computeSystem.owner = strings.ToLower(props.Owner)
|
||||
if computeSystem.os == "" && computeSystem.typ == "container" {
|
||||
// Pre-RS5 HCS did not return the OS, but it only supported containers
|
||||
// that ran Windows.
|
||||
@ -195,7 +207,7 @@ func (computeSystem *System) Start(ctx context.Context) (err error) {
|
||||
if err != nil {
|
||||
return makeSystemError(computeSystem, operation, err, events)
|
||||
}
|
||||
|
||||
computeSystem.startTime = time.Now()
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -324,11 +336,115 @@ func (computeSystem *System) Properties(ctx context.Context, types ...schema1.Pr
|
||||
return properties, nil
|
||||
}
|
||||
|
||||
// PropertiesV2 returns the requested container properties targeting a V2 schema container.
|
||||
func (computeSystem *System) PropertiesV2(ctx context.Context, types ...hcsschema.PropertyType) (*hcsschema.Properties, error) {
|
||||
computeSystem.handleLock.RLock()
|
||||
defer computeSystem.handleLock.RUnlock()
|
||||
// queryInProc handles querying for container properties without reaching out to HCS. `props`
|
||||
// will be updated to contain any data returned from the queries present in `types`. If any properties
|
||||
// failed to be queried they will be tallied up and returned in as the first return value. Failures on
|
||||
// query are NOT considered errors; the only failure case for this method is if the containers job object
|
||||
// cannot be opened.
|
||||
func (computeSystem *System) queryInProc(ctx context.Context, props *hcsschema.Properties, types []hcsschema.PropertyType) ([]hcsschema.PropertyType, error) {
|
||||
// In the future we can make use of some new functionality in the HCS that allows you
|
||||
// to pass a job object for HCS to use for the container. Currently, the only way we'll
|
||||
// be able to open the job/silo is if we're running as SYSTEM.
|
||||
jobOptions := &jobobject.Options{
|
||||
UseNTVariant: true,
|
||||
Name: siloNameFmt(computeSystem.id),
|
||||
}
|
||||
job, err := jobobject.Open(ctx, jobOptions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer job.Close()
|
||||
|
||||
var fallbackQueryTypes []hcsschema.PropertyType
|
||||
for _, propType := range types {
|
||||
switch propType {
|
||||
case hcsschema.PTStatistics:
|
||||
// Handle a bad caller asking for the same type twice. No use in re-querying if this is
|
||||
// filled in already.
|
||||
if props.Statistics == nil {
|
||||
props.Statistics, err = computeSystem.statisticsInProc(job)
|
||||
if err != nil {
|
||||
log.G(ctx).WithError(err).Warn("failed to get statistics in-proc")
|
||||
|
||||
fallbackQueryTypes = append(fallbackQueryTypes, propType)
|
||||
}
|
||||
}
|
||||
default:
|
||||
fallbackQueryTypes = append(fallbackQueryTypes, propType)
|
||||
}
|
||||
}
|
||||
|
||||
return fallbackQueryTypes, nil
|
||||
}
|
||||
|
||||
// statisticsInProc emulates what HCS does to grab statistics for a given container with a small
|
||||
// change to make grabbing the private working set total much more efficient.
|
||||
func (computeSystem *System) statisticsInProc(job *jobobject.JobObject) (*hcsschema.Statistics, error) {
|
||||
// Start timestamp for these stats before we grab them to match HCS
|
||||
timestamp := time.Now()
|
||||
|
||||
memInfo, err := job.QueryMemoryStats()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
processorInfo, err := job.QueryProcessorStats()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
storageInfo, err := job.QueryStorageStats()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// This calculates the private working set more efficiently than HCS does. HCS calls NtQuerySystemInformation
|
||||
// with the class SystemProcessInformation which returns an array containing system information for *every*
|
||||
// process running on the machine. They then grab the pids that are running in the container and filter down
|
||||
// the entries in the array to only what's running in that silo and start tallying up the total. This doesn't
|
||||
// work well as performance should get worse if more processess are running on the machine in general and not
|
||||
// just in the container. All of the additional information besides the WorkingSetPrivateSize field is ignored
|
||||
// as well which isn't great and is wasted work to fetch.
|
||||
//
|
||||
// HCS only let's you grab statistics in an all or nothing fashion, so we can't just grab the private
|
||||
// working set ourselves and ask for everything else seperately. The optimization we can make here is
|
||||
// to open the silo ourselves and do the same queries for the rest of the info, as well as calculating
|
||||
// the private working set in a more efficient manner by:
|
||||
//
|
||||
// 1. Find the pids running in the silo
|
||||
// 2. Get a process handle for every process (only need PROCESS_QUERY_LIMITED_INFORMATION access)
|
||||
// 3. Call NtQueryInformationProcess on each process with the class ProcessVmCounters
|
||||
// 4. Tally up the total using the field PrivateWorkingSetSize in VM_COUNTERS_EX2.
|
||||
privateWorkingSet, err := job.QueryPrivateWorkingSet()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &hcsschema.Statistics{
|
||||
Timestamp: timestamp,
|
||||
ContainerStartTime: computeSystem.startTime,
|
||||
Uptime100ns: uint64(time.Since(computeSystem.startTime).Nanoseconds()) / 100,
|
||||
Memory: &hcsschema.MemoryStats{
|
||||
MemoryUsageCommitBytes: memInfo.JobMemory,
|
||||
MemoryUsageCommitPeakBytes: memInfo.PeakJobMemoryUsed,
|
||||
MemoryUsagePrivateWorkingSetBytes: privateWorkingSet,
|
||||
},
|
||||
Processor: &hcsschema.ProcessorStats{
|
||||
RuntimeKernel100ns: uint64(processorInfo.TotalKernelTime),
|
||||
RuntimeUser100ns: uint64(processorInfo.TotalUserTime),
|
||||
TotalRuntime100ns: uint64(processorInfo.TotalKernelTime + processorInfo.TotalUserTime),
|
||||
},
|
||||
Storage: &hcsschema.StorageStats{
|
||||
ReadCountNormalized: uint64(storageInfo.ReadStats.IoCount),
|
||||
ReadSizeBytes: storageInfo.ReadStats.TotalSize,
|
||||
WriteCountNormalized: uint64(storageInfo.WriteStats.IoCount),
|
||||
WriteSizeBytes: storageInfo.WriteStats.TotalSize,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// hcsPropertiesV2Query is a helper to make a HcsGetComputeSystemProperties call using the V2 schema property types.
|
||||
func (computeSystem *System) hcsPropertiesV2Query(ctx context.Context, types []hcsschema.PropertyType) (*hcsschema.Properties, error) {
|
||||
operation := "hcs::System::PropertiesV2"
|
||||
|
||||
queryBytes, err := json.Marshal(hcsschema.PropertyQuery{PropertyTypes: types})
|
||||
@ -345,12 +461,66 @@ func (computeSystem *System) PropertiesV2(ctx context.Context, types ...hcsschem
|
||||
if propertiesJSON == "" {
|
||||
return nil, ErrUnexpectedValue
|
||||
}
|
||||
properties := &hcsschema.Properties{}
|
||||
if err := json.Unmarshal([]byte(propertiesJSON), properties); err != nil {
|
||||
props := &hcsschema.Properties{}
|
||||
if err := json.Unmarshal([]byte(propertiesJSON), props); err != nil {
|
||||
return nil, makeSystemError(computeSystem, operation, err, nil)
|
||||
}
|
||||
|
||||
return properties, nil
|
||||
return props, nil
|
||||
}
|
||||
|
||||
// PropertiesV2 returns the requested compute systems properties targeting a V2 schema compute system.
|
||||
func (computeSystem *System) PropertiesV2(ctx context.Context, types ...hcsschema.PropertyType) (_ *hcsschema.Properties, err error) {
|
||||
computeSystem.handleLock.RLock()
|
||||
defer computeSystem.handleLock.RUnlock()
|
||||
|
||||
// Let HCS tally up the total for VM based queries instead of querying ourselves.
|
||||
if computeSystem.typ != "container" {
|
||||
return computeSystem.hcsPropertiesV2Query(ctx, types)
|
||||
}
|
||||
|
||||
// Define a starter Properties struct with the default fields returned from every
|
||||
// query. Owner is only returned from Statistics but it's harmless to include.
|
||||
properties := &hcsschema.Properties{
|
||||
Id: computeSystem.id,
|
||||
SystemType: computeSystem.typ,
|
||||
RuntimeOsType: computeSystem.os,
|
||||
Owner: computeSystem.owner,
|
||||
}
|
||||
|
||||
logEntry := log.G(ctx)
|
||||
// First lets try and query ourselves without reaching to HCS. If any of the queries fail
|
||||
// we'll take note and fallback to querying HCS for any of the failed types.
|
||||
fallbackTypes, err := computeSystem.queryInProc(ctx, properties, types)
|
||||
if err == nil && len(fallbackTypes) == 0 {
|
||||
return properties, nil
|
||||
} else if err != nil {
|
||||
logEntry.WithError(fmt.Errorf("failed to query compute system properties in-proc: %w", err))
|
||||
fallbackTypes = types
|
||||
}
|
||||
|
||||
logEntry.WithFields(logrus.Fields{
|
||||
logfields.ContainerID: computeSystem.id,
|
||||
"propertyTypes": fallbackTypes,
|
||||
}).Info("falling back to HCS for property type queries")
|
||||
|
||||
hcsProperties, err := computeSystem.hcsPropertiesV2Query(ctx, fallbackTypes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Now add in anything that we might have successfully queried in process.
|
||||
if properties.Statistics != nil {
|
||||
hcsProperties.Statistics = properties.Statistics
|
||||
hcsProperties.Owner = properties.Owner
|
||||
}
|
||||
|
||||
// For future support for querying processlist in-proc as well.
|
||||
if properties.ProcessList != nil {
|
||||
hcsProperties.ProcessList = properties.ProcessList
|
||||
}
|
||||
|
||||
return hcsProperties, nil
|
||||
}
|
||||
|
||||
// Pause pauses the execution of the computeSystem. This feature is not enabled in TP5.
|
||||
|
9
src/runtime/vendor/github.com/Microsoft/hcsshim/internal/hns/hnspolicy.go
generated
vendored
9
src/runtime/vendor/github.com/Microsoft/hcsshim/internal/hns/hnspolicy.go
generated
vendored
@ -21,10 +21,11 @@ const (
|
||||
)
|
||||
|
||||
type NatPolicy struct {
|
||||
Type PolicyType `json:"Type"`
|
||||
Protocol string `json:",omitempty"`
|
||||
InternalPort uint16 `json:",omitempty"`
|
||||
ExternalPort uint16 `json:",omitempty"`
|
||||
Type PolicyType `json:"Type"`
|
||||
Protocol string `json:",omitempty"`
|
||||
InternalPort uint16 `json:",omitempty"`
|
||||
ExternalPort uint16 `json:",omitempty"`
|
||||
ExternalPortReserved bool `json:",omitempty"`
|
||||
}
|
||||
|
||||
type QosPolicy struct {
|
||||
|
111
src/runtime/vendor/github.com/Microsoft/hcsshim/internal/jobobject/iocp.go
generated
vendored
Normal file
111
src/runtime/vendor/github.com/Microsoft/hcsshim/internal/jobobject/iocp.go
generated
vendored
Normal file
@ -0,0 +1,111 @@
|
||||
package jobobject
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
"unsafe"
|
||||
|
||||
"github.com/Microsoft/hcsshim/internal/log"
|
||||
"github.com/Microsoft/hcsshim/internal/queue"
|
||||
"github.com/Microsoft/hcsshim/internal/winapi"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
var (
|
||||
ioInitOnce sync.Once
|
||||
initIOErr error
|
||||
// Global iocp handle that will be re-used for every job object
|
||||
ioCompletionPort windows.Handle
|
||||
// Mapping of job handle to queue to place notifications in.
|
||||
jobMap sync.Map
|
||||
)
|
||||
|
||||
// MsgAllProcessesExited is a type representing a message that every process in a job has exited.
|
||||
type MsgAllProcessesExited struct{}
|
||||
|
||||
// MsgUnimplemented represents a message that we are aware of, but that isn't implemented currently.
|
||||
// This should not be treated as an error.
|
||||
type MsgUnimplemented struct{}
|
||||
|
||||
// pollIOCP polls the io completion port forever.
|
||||
func pollIOCP(ctx context.Context, iocpHandle windows.Handle) {
|
||||
var (
|
||||
overlapped uintptr
|
||||
code uint32
|
||||
key uintptr
|
||||
)
|
||||
|
||||
for {
|
||||
err := windows.GetQueuedCompletionStatus(iocpHandle, &code, &key, (**windows.Overlapped)(unsafe.Pointer(&overlapped)), windows.INFINITE)
|
||||
if err != nil {
|
||||
log.G(ctx).WithError(err).Error("failed to poll for job object message")
|
||||
continue
|
||||
}
|
||||
if val, ok := jobMap.Load(key); ok {
|
||||
msq, ok := val.(*queue.MessageQueue)
|
||||
if !ok {
|
||||
log.G(ctx).WithField("value", msq).Warn("encountered non queue type in job map")
|
||||
continue
|
||||
}
|
||||
notification, err := parseMessage(code, overlapped)
|
||||
if err != nil {
|
||||
log.G(ctx).WithFields(logrus.Fields{
|
||||
"code": code,
|
||||
"overlapped": overlapped,
|
||||
}).Warn("failed to parse job object message")
|
||||
continue
|
||||
}
|
||||
if err := msq.Write(notification); err == queue.ErrQueueClosed {
|
||||
// Write will only return an error when the queue is closed.
|
||||
// The only time a queue would ever be closed is when we call `Close` on
|
||||
// the job it belongs to which also removes it from the jobMap, so something
|
||||
// went wrong here. We can't return as this is reading messages for all jobs
|
||||
// so just log it and move on.
|
||||
log.G(ctx).WithFields(logrus.Fields{
|
||||
"code": code,
|
||||
"overlapped": overlapped,
|
||||
}).Warn("tried to write to a closed queue")
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
log.G(ctx).Warn("received a message for a job not present in the mapping")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func parseMessage(code uint32, overlapped uintptr) (interface{}, error) {
|
||||
// Check code and parse out relevant information related to that notification
|
||||
// that we care about. For now all we handle is the message that all processes
|
||||
// in the job have exited.
|
||||
switch code {
|
||||
case winapi.JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO:
|
||||
return MsgAllProcessesExited{}, nil
|
||||
// Other messages for completeness and a check to make sure that if we fall
|
||||
// into the default case that this is a code we don't know how to handle.
|
||||
case winapi.JOB_OBJECT_MSG_END_OF_JOB_TIME:
|
||||
case winapi.JOB_OBJECT_MSG_END_OF_PROCESS_TIME:
|
||||
case winapi.JOB_OBJECT_MSG_ACTIVE_PROCESS_LIMIT:
|
||||
case winapi.JOB_OBJECT_MSG_NEW_PROCESS:
|
||||
case winapi.JOB_OBJECT_MSG_EXIT_PROCESS:
|
||||
case winapi.JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS:
|
||||
case winapi.JOB_OBJECT_MSG_PROCESS_MEMORY_LIMIT:
|
||||
case winapi.JOB_OBJECT_MSG_JOB_MEMORY_LIMIT:
|
||||
case winapi.JOB_OBJECT_MSG_NOTIFICATION_LIMIT:
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown job notification type: %d", code)
|
||||
}
|
||||
return MsgUnimplemented{}, nil
|
||||
}
|
||||
|
||||
// Assigns an IO completion port to get notified of events for the registered job
|
||||
// object.
|
||||
func attachIOCP(job windows.Handle, iocp windows.Handle) error {
|
||||
info := winapi.JOBOBJECT_ASSOCIATE_COMPLETION_PORT{
|
||||
CompletionKey: job,
|
||||
CompletionPort: iocp,
|
||||
}
|
||||
_, err := windows.SetInformationJobObject(job, windows.JobObjectAssociateCompletionPortInformation, uintptr(unsafe.Pointer(&info)), uint32(unsafe.Sizeof(info)))
|
||||
return err
|
||||
}
|
499
src/runtime/vendor/github.com/Microsoft/hcsshim/internal/jobobject/jobobject.go
generated
vendored
Normal file
499
src/runtime/vendor/github.com/Microsoft/hcsshim/internal/jobobject/jobobject.go
generated
vendored
Normal file
@ -0,0 +1,499 @@
|
||||
package jobobject
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
"unsafe"
|
||||
|
||||
"github.com/Microsoft/hcsshim/internal/queue"
|
||||
"github.com/Microsoft/hcsshim/internal/winapi"
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
// This file provides higher level constructs for the win32 job object API.
|
||||
// Most of the core creation and management functions are already present in "golang.org/x/sys/windows"
|
||||
// (CreateJobObject, AssignProcessToJobObject, etc.) as well as most of the limit information
|
||||
// structs and associated limit flags. Whatever is not present from the job object API
|
||||
// in golang.org/x/sys/windows is located in /internal/winapi.
|
||||
//
|
||||
// https://docs.microsoft.com/en-us/windows/win32/procthread/job-objects
|
||||
|
||||
// JobObject is a high level wrapper around a Windows job object. Holds a handle to
|
||||
// the job, a queue to receive iocp notifications about the lifecycle
|
||||
// of the job and a mutex for synchronized handle access.
|
||||
type JobObject struct {
|
||||
handle windows.Handle
|
||||
mq *queue.MessageQueue
|
||||
handleLock sync.RWMutex
|
||||
}
|
||||
|
||||
// JobLimits represents the resource constraints that can be applied to a job object.
|
||||
type JobLimits struct {
|
||||
CPULimit uint32
|
||||
CPUWeight uint32
|
||||
MemoryLimitInBytes uint64
|
||||
MaxIOPS int64
|
||||
MaxBandwidth int64
|
||||
}
|
||||
|
||||
type CPURateControlType uint32
|
||||
|
||||
const (
|
||||
WeightBased CPURateControlType = iota
|
||||
RateBased
|
||||
)
|
||||
|
||||
// Processor resource controls
|
||||
const (
|
||||
cpuLimitMin = 1
|
||||
cpuLimitMax = 10000
|
||||
cpuWeightMin = 1
|
||||
cpuWeightMax = 9
|
||||
)
|
||||
|
||||
var (
|
||||
ErrAlreadyClosed = errors.New("the handle has already been closed")
|
||||
ErrNotRegistered = errors.New("job is not registered to receive notifications")
|
||||
)
|
||||
|
||||
// Options represents the set of configurable options when making or opening a job object.
|
||||
type Options struct {
|
||||
// `Name` specifies the name of the job object if a named job object is desired.
|
||||
Name string
|
||||
// `Notifications` specifies if the job will be registered to receive notifications.
|
||||
// Defaults to false.
|
||||
Notifications bool
|
||||
// `UseNTVariant` specifies if we should use the `Nt` variant of Open/CreateJobObject.
|
||||
// Defaults to false.
|
||||
UseNTVariant bool
|
||||
}
|
||||
|
||||
// Create creates a job object.
|
||||
//
|
||||
// If options.Name is an empty string, the job will not be assigned a name.
|
||||
//
|
||||
// If options.Notifications are not enabled `PollNotifications` will return immediately with error `errNotRegistered`.
|
||||
//
|
||||
// If `options` is nil, use default option values.
|
||||
//
|
||||
// Returns a JobObject structure and an error if there is one.
|
||||
func Create(ctx context.Context, options *Options) (_ *JobObject, err error) {
|
||||
if options == nil {
|
||||
options = &Options{}
|
||||
}
|
||||
|
||||
var jobName *winapi.UnicodeString
|
||||
if options.Name != "" {
|
||||
jobName, err = winapi.NewUnicodeString(options.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
var jobHandle windows.Handle
|
||||
if options.UseNTVariant {
|
||||
oa := winapi.ObjectAttributes{
|
||||
Length: unsafe.Sizeof(winapi.ObjectAttributes{}),
|
||||
ObjectName: jobName,
|
||||
Attributes: 0,
|
||||
}
|
||||
status := winapi.NtCreateJobObject(&jobHandle, winapi.JOB_OBJECT_ALL_ACCESS, &oa)
|
||||
if status != 0 {
|
||||
return nil, winapi.RtlNtStatusToDosError(status)
|
||||
}
|
||||
} else {
|
||||
var jobNameBuf *uint16
|
||||
if jobName != nil && jobName.Buffer != nil {
|
||||
jobNameBuf = jobName.Buffer
|
||||
}
|
||||
jobHandle, err = windows.CreateJobObject(nil, jobNameBuf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if err != nil {
|
||||
windows.Close(jobHandle)
|
||||
}
|
||||
}()
|
||||
|
||||
job := &JobObject{
|
||||
handle: jobHandle,
|
||||
}
|
||||
|
||||
// If the IOCP we'll be using to receive messages for all jobs hasn't been
|
||||
// created, create it and start polling.
|
||||
if options.Notifications {
|
||||
mq, err := setupNotifications(ctx, job)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
job.mq = mq
|
||||
}
|
||||
|
||||
return job, nil
|
||||
}
|
||||
|
||||
// Open opens an existing job object with name provided in `options`. If no name is provided
|
||||
// return an error since we need to know what job object to open.
|
||||
//
|
||||
// If options.Notifications is false `PollNotifications` will return immediately with error `errNotRegistered`.
|
||||
//
|
||||
// Returns a JobObject structure and an error if there is one.
|
||||
func Open(ctx context.Context, options *Options) (_ *JobObject, err error) {
|
||||
if options == nil || (options != nil && options.Name == "") {
|
||||
return nil, errors.New("no job object name specified to open")
|
||||
}
|
||||
|
||||
unicodeJobName, err := winapi.NewUnicodeString(options.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var jobHandle windows.Handle
|
||||
if options != nil && options.UseNTVariant {
|
||||
oa := winapi.ObjectAttributes{
|
||||
Length: unsafe.Sizeof(winapi.ObjectAttributes{}),
|
||||
ObjectName: unicodeJobName,
|
||||
Attributes: 0,
|
||||
}
|
||||
status := winapi.NtOpenJobObject(&jobHandle, winapi.JOB_OBJECT_ALL_ACCESS, &oa)
|
||||
if status != 0 {
|
||||
return nil, winapi.RtlNtStatusToDosError(status)
|
||||
}
|
||||
} else {
|
||||
jobHandle, err = winapi.OpenJobObject(winapi.JOB_OBJECT_ALL_ACCESS, false, unicodeJobName.Buffer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if err != nil {
|
||||
windows.Close(jobHandle)
|
||||
}
|
||||
}()
|
||||
|
||||
job := &JobObject{
|
||||
handle: jobHandle,
|
||||
}
|
||||
|
||||
// If the IOCP we'll be using to receive messages for all jobs hasn't been
|
||||
// created, create it and start polling.
|
||||
if options != nil && options.Notifications {
|
||||
mq, err := setupNotifications(ctx, job)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
job.mq = mq
|
||||
}
|
||||
|
||||
return job, nil
|
||||
}
|
||||
|
||||
// helper function to setup notifications for creating/opening a job object
|
||||
func setupNotifications(ctx context.Context, job *JobObject) (*queue.MessageQueue, error) {
|
||||
job.handleLock.RLock()
|
||||
defer job.handleLock.RUnlock()
|
||||
|
||||
if job.handle == 0 {
|
||||
return nil, ErrAlreadyClosed
|
||||
}
|
||||
|
||||
ioInitOnce.Do(func() {
|
||||
h, err := windows.CreateIoCompletionPort(windows.InvalidHandle, 0, 0, 0xffffffff)
|
||||
if err != nil {
|
||||
initIOErr = err
|
||||
return
|
||||
}
|
||||
ioCompletionPort = h
|
||||
go pollIOCP(ctx, h)
|
||||
})
|
||||
|
||||
if initIOErr != nil {
|
||||
return nil, initIOErr
|
||||
}
|
||||
|
||||
mq := queue.NewMessageQueue()
|
||||
jobMap.Store(uintptr(job.handle), mq)
|
||||
if err := attachIOCP(job.handle, ioCompletionPort); err != nil {
|
||||
jobMap.Delete(uintptr(job.handle))
|
||||
return nil, fmt.Errorf("failed to attach job to IO completion port: %w", err)
|
||||
}
|
||||
return mq, nil
|
||||
}
|
||||
|
||||
// PollNotification will poll for a job object notification. This call should only be called once
|
||||
// per job (ideally in a goroutine loop) and will block if there is not a notification ready.
|
||||
// This call will return immediately with error `ErrNotRegistered` if the job was not registered
|
||||
// to receive notifications during `Create`. Internally, messages will be queued and there
|
||||
// is no worry of messages being dropped.
|
||||
func (job *JobObject) PollNotification() (interface{}, error) {
|
||||
if job.mq == nil {
|
||||
return nil, ErrNotRegistered
|
||||
}
|
||||
return job.mq.ReadOrWait()
|
||||
}
|
||||
|
||||
// UpdateProcThreadAttribute updates the passed in ProcThreadAttributeList to contain what is necessary to
|
||||
// launch a process in a job at creation time. This can be used to avoid having to call Assign() after a process
|
||||
// has already started running.
|
||||
func (job *JobObject) UpdateProcThreadAttribute(attrList *windows.ProcThreadAttributeListContainer) error {
|
||||
job.handleLock.RLock()
|
||||
defer job.handleLock.RUnlock()
|
||||
|
||||
if job.handle == 0 {
|
||||
return ErrAlreadyClosed
|
||||
}
|
||||
|
||||
if err := attrList.Update(
|
||||
winapi.PROC_THREAD_ATTRIBUTE_JOB_LIST,
|
||||
unsafe.Pointer(&job.handle),
|
||||
unsafe.Sizeof(job.handle),
|
||||
); err != nil {
|
||||
return fmt.Errorf("failed to update proc thread attributes for job object: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Close closes the job object handle.
|
||||
func (job *JobObject) Close() error {
|
||||
job.handleLock.Lock()
|
||||
defer job.handleLock.Unlock()
|
||||
|
||||
if job.handle == 0 {
|
||||
return ErrAlreadyClosed
|
||||
}
|
||||
|
||||
if err := windows.Close(job.handle); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if job.mq != nil {
|
||||
job.mq.Close()
|
||||
}
|
||||
// Handles now invalid so if the map entry to receive notifications for this job still
|
||||
// exists remove it so we can stop receiving notifications.
|
||||
if _, ok := jobMap.Load(uintptr(job.handle)); ok {
|
||||
jobMap.Delete(uintptr(job.handle))
|
||||
}
|
||||
|
||||
job.handle = 0
|
||||
return nil
|
||||
}
|
||||
|
||||
// Assign assigns a process to the job object.
|
||||
func (job *JobObject) Assign(pid uint32) error {
|
||||
job.handleLock.RLock()
|
||||
defer job.handleLock.RUnlock()
|
||||
|
||||
if job.handle == 0 {
|
||||
return ErrAlreadyClosed
|
||||
}
|
||||
|
||||
if pid == 0 {
|
||||
return errors.New("invalid pid: 0")
|
||||
}
|
||||
hProc, err := windows.OpenProcess(winapi.PROCESS_ALL_ACCESS, true, pid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer windows.Close(hProc)
|
||||
return windows.AssignProcessToJobObject(job.handle, hProc)
|
||||
}
|
||||
|
||||
// Terminate terminates the job, essentially calls TerminateProcess on every process in the
|
||||
// job.
|
||||
func (job *JobObject) Terminate(exitCode uint32) error {
|
||||
job.handleLock.RLock()
|
||||
defer job.handleLock.RUnlock()
|
||||
if job.handle == 0 {
|
||||
return ErrAlreadyClosed
|
||||
}
|
||||
return windows.TerminateJobObject(job.handle, exitCode)
|
||||
}
|
||||
|
||||
// Pids returns all of the process IDs in the job object.
|
||||
func (job *JobObject) Pids() ([]uint32, error) {
|
||||
job.handleLock.RLock()
|
||||
defer job.handleLock.RUnlock()
|
||||
|
||||
if job.handle == 0 {
|
||||
return nil, ErrAlreadyClosed
|
||||
}
|
||||
|
||||
info := winapi.JOBOBJECT_BASIC_PROCESS_ID_LIST{}
|
||||
err := winapi.QueryInformationJobObject(
|
||||
job.handle,
|
||||
winapi.JobObjectBasicProcessIdList,
|
||||
uintptr(unsafe.Pointer(&info)),
|
||||
uint32(unsafe.Sizeof(info)),
|
||||
nil,
|
||||
)
|
||||
|
||||
// This is either the case where there is only one process or no processes in
|
||||
// the job. Any other case will result in ERROR_MORE_DATA. Check if info.NumberOfProcessIdsInList
|
||||
// is 1 and just return this, otherwise return an empty slice.
|
||||
if err == nil {
|
||||
if info.NumberOfProcessIdsInList == 1 {
|
||||
return []uint32{uint32(info.ProcessIdList[0])}, nil
|
||||
}
|
||||
// Return empty slice instead of nil to play well with the caller of this.
|
||||
// Do not return an error if no processes are running inside the job
|
||||
return []uint32{}, nil
|
||||
}
|
||||
|
||||
if err != winapi.ERROR_MORE_DATA {
|
||||
return nil, fmt.Errorf("failed initial query for PIDs in job object: %w", err)
|
||||
}
|
||||
|
||||
jobBasicProcessIDListSize := unsafe.Sizeof(info) + (unsafe.Sizeof(info.ProcessIdList[0]) * uintptr(info.NumberOfAssignedProcesses-1))
|
||||
buf := make([]byte, jobBasicProcessIDListSize)
|
||||
if err = winapi.QueryInformationJobObject(
|
||||
job.handle,
|
||||
winapi.JobObjectBasicProcessIdList,
|
||||
uintptr(unsafe.Pointer(&buf[0])),
|
||||
uint32(len(buf)),
|
||||
nil,
|
||||
); err != nil {
|
||||
return nil, fmt.Errorf("failed to query for PIDs in job object: %w", err)
|
||||
}
|
||||
|
||||
bufInfo := (*winapi.JOBOBJECT_BASIC_PROCESS_ID_LIST)(unsafe.Pointer(&buf[0]))
|
||||
pids := make([]uint32, bufInfo.NumberOfProcessIdsInList)
|
||||
for i, bufPid := range bufInfo.AllPids() {
|
||||
pids[i] = uint32(bufPid)
|
||||
}
|
||||
return pids, nil
|
||||
}
|
||||
|
||||
// QueryMemoryStats gets the memory stats for the job object.
|
||||
func (job *JobObject) QueryMemoryStats() (*winapi.JOBOBJECT_MEMORY_USAGE_INFORMATION, error) {
|
||||
job.handleLock.RLock()
|
||||
defer job.handleLock.RUnlock()
|
||||
|
||||
if job.handle == 0 {
|
||||
return nil, ErrAlreadyClosed
|
||||
}
|
||||
|
||||
info := winapi.JOBOBJECT_MEMORY_USAGE_INFORMATION{}
|
||||
if err := winapi.QueryInformationJobObject(
|
||||
job.handle,
|
||||
winapi.JobObjectMemoryUsageInformation,
|
||||
uintptr(unsafe.Pointer(&info)),
|
||||
uint32(unsafe.Sizeof(info)),
|
||||
nil,
|
||||
); err != nil {
|
||||
return nil, fmt.Errorf("failed to query for job object memory stats: %w", err)
|
||||
}
|
||||
return &info, nil
|
||||
}
|
||||
|
||||
// QueryProcessorStats gets the processor stats for the job object.
|
||||
func (job *JobObject) QueryProcessorStats() (*winapi.JOBOBJECT_BASIC_ACCOUNTING_INFORMATION, error) {
|
||||
job.handleLock.RLock()
|
||||
defer job.handleLock.RUnlock()
|
||||
|
||||
if job.handle == 0 {
|
||||
return nil, ErrAlreadyClosed
|
||||
}
|
||||
|
||||
info := winapi.JOBOBJECT_BASIC_ACCOUNTING_INFORMATION{}
|
||||
if err := winapi.QueryInformationJobObject(
|
||||
job.handle,
|
||||
winapi.JobObjectBasicAccountingInformation,
|
||||
uintptr(unsafe.Pointer(&info)),
|
||||
uint32(unsafe.Sizeof(info)),
|
||||
nil,
|
||||
); err != nil {
|
||||
return nil, fmt.Errorf("failed to query for job object process stats: %w", err)
|
||||
}
|
||||
return &info, nil
|
||||
}
|
||||
|
||||
// QueryStorageStats gets the storage (I/O) stats for the job object.
|
||||
func (job *JobObject) QueryStorageStats() (*winapi.JOBOBJECT_IO_ATTRIBUTION_INFORMATION, error) {
|
||||
job.handleLock.RLock()
|
||||
defer job.handleLock.RUnlock()
|
||||
|
||||
if job.handle == 0 {
|
||||
return nil, ErrAlreadyClosed
|
||||
}
|
||||
|
||||
info := winapi.JOBOBJECT_IO_ATTRIBUTION_INFORMATION{
|
||||
ControlFlags: winapi.JOBOBJECT_IO_ATTRIBUTION_CONTROL_ENABLE,
|
||||
}
|
||||
if err := winapi.QueryInformationJobObject(
|
||||
job.handle,
|
||||
winapi.JobObjectIoAttribution,
|
||||
uintptr(unsafe.Pointer(&info)),
|
||||
uint32(unsafe.Sizeof(info)),
|
||||
nil,
|
||||
); err != nil {
|
||||
return nil, fmt.Errorf("failed to query for job object storage stats: %w", err)
|
||||
}
|
||||
return &info, nil
|
||||
}
|
||||
|
||||
// QueryPrivateWorkingSet returns the private working set size for the job. This is calculated by adding up the
|
||||
// private working set for every process running in the job.
|
||||
func (job *JobObject) QueryPrivateWorkingSet() (uint64, error) {
|
||||
pids, err := job.Pids()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
openAndQueryWorkingSet := func(pid uint32) (uint64, error) {
|
||||
h, err := windows.OpenProcess(windows.PROCESS_QUERY_LIMITED_INFORMATION, false, pid)
|
||||
if err != nil {
|
||||
// Continue to the next if OpenProcess doesn't return a valid handle (fails). Handles a
|
||||
// case where one of the pids in the job exited before we open.
|
||||
return 0, nil
|
||||
}
|
||||
defer func() {
|
||||
_ = windows.Close(h)
|
||||
}()
|
||||
// Check if the process is actually running in the job still. There's a small chance
|
||||
// that the process could have exited and had its pid re-used between grabbing the pids
|
||||
// in the job and opening the handle to it above.
|
||||
var inJob int32
|
||||
if err := winapi.IsProcessInJob(h, job.handle, &inJob); err != nil {
|
||||
// This shouldn't fail unless we have incorrect access rights which we control
|
||||
// here so probably best to error out if this failed.
|
||||
return 0, err
|
||||
}
|
||||
// Don't report stats for this process as it's not running in the job. This shouldn't be
|
||||
// an error condition though.
|
||||
if inJob == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
var vmCounters winapi.VM_COUNTERS_EX2
|
||||
status := winapi.NtQueryInformationProcess(
|
||||
h,
|
||||
winapi.ProcessVmCounters,
|
||||
uintptr(unsafe.Pointer(&vmCounters)),
|
||||
uint32(unsafe.Sizeof(vmCounters)),
|
||||
nil,
|
||||
)
|
||||
if !winapi.NTSuccess(status) {
|
||||
return 0, fmt.Errorf("failed to query information for process: %w", winapi.RtlNtStatusToDosError(status))
|
||||
}
|
||||
return uint64(vmCounters.PrivateWorkingSetSize), nil
|
||||
}
|
||||
|
||||
var jobWorkingSetSize uint64
|
||||
for _, pid := range pids {
|
||||
workingSet, err := openAndQueryWorkingSet(pid)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
jobWorkingSetSize += workingSet
|
||||
}
|
||||
|
||||
return jobWorkingSetSize, nil
|
||||
}
|
315
src/runtime/vendor/github.com/Microsoft/hcsshim/internal/jobobject/limits.go
generated
vendored
Normal file
315
src/runtime/vendor/github.com/Microsoft/hcsshim/internal/jobobject/limits.go
generated
vendored
Normal file
@ -0,0 +1,315 @@
|
||||
package jobobject
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
"github.com/Microsoft/hcsshim/internal/winapi"
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
const (
|
||||
memoryLimitMax uint64 = 0xffffffffffffffff
|
||||
)
|
||||
|
||||
func isFlagSet(flag, controlFlags uint32) bool {
|
||||
return (flag & controlFlags) == flag
|
||||
}
|
||||
|
||||
// SetResourceLimits sets resource limits on the job object (cpu, memory, storage).
|
||||
func (job *JobObject) SetResourceLimits(limits *JobLimits) error {
|
||||
// Go through and check what limits were specified and apply them to the job.
|
||||
if limits.MemoryLimitInBytes != 0 {
|
||||
if err := job.SetMemoryLimit(limits.MemoryLimitInBytes); err != nil {
|
||||
return fmt.Errorf("failed to set job object memory limit: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if limits.CPULimit != 0 {
|
||||
if err := job.SetCPULimit(RateBased, limits.CPULimit); err != nil {
|
||||
return fmt.Errorf("failed to set job object cpu limit: %w", err)
|
||||
}
|
||||
} else if limits.CPUWeight != 0 {
|
||||
if err := job.SetCPULimit(WeightBased, limits.CPUWeight); err != nil {
|
||||
return fmt.Errorf("failed to set job object cpu limit: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if limits.MaxBandwidth != 0 || limits.MaxIOPS != 0 {
|
||||
if err := job.SetIOLimit(limits.MaxBandwidth, limits.MaxIOPS); err != nil {
|
||||
return fmt.Errorf("failed to set io limit on job object: %w", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetTerminateOnLastHandleClose sets the job object flag that specifies that the job should terminate
|
||||
// all processes in the job on the last open handle being closed.
|
||||
func (job *JobObject) SetTerminateOnLastHandleClose() error {
|
||||
info, err := job.getExtendedInformation()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
info.BasicLimitInformation.LimitFlags |= windows.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE
|
||||
return job.setExtendedInformation(info)
|
||||
}
|
||||
|
||||
// SetMemoryLimit sets the memory limit of the job object based on the given `memoryLimitInBytes`.
|
||||
func (job *JobObject) SetMemoryLimit(memoryLimitInBytes uint64) error {
|
||||
if memoryLimitInBytes >= memoryLimitMax {
|
||||
return errors.New("memory limit specified exceeds the max size")
|
||||
}
|
||||
|
||||
info, err := job.getExtendedInformation()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
info.JobMemoryLimit = uintptr(memoryLimitInBytes)
|
||||
info.BasicLimitInformation.LimitFlags |= windows.JOB_OBJECT_LIMIT_JOB_MEMORY
|
||||
return job.setExtendedInformation(info)
|
||||
}
|
||||
|
||||
// GetMemoryLimit gets the memory limit in bytes of the job object.
|
||||
func (job *JobObject) GetMemoryLimit() (uint64, error) {
|
||||
info, err := job.getExtendedInformation()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return uint64(info.JobMemoryLimit), nil
|
||||
}
|
||||
|
||||
// SetCPULimit sets the CPU limit depending on the specified `CPURateControlType` to
|
||||
// `rateControlValue` for the job object.
|
||||
func (job *JobObject) SetCPULimit(rateControlType CPURateControlType, rateControlValue uint32) error {
|
||||
cpuInfo, err := job.getCPURateControlInformation()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch rateControlType {
|
||||
case WeightBased:
|
||||
if rateControlValue < cpuWeightMin || rateControlValue > cpuWeightMax {
|
||||
return fmt.Errorf("processor weight value of `%d` is invalid", rateControlValue)
|
||||
}
|
||||
cpuInfo.ControlFlags |= winapi.JOB_OBJECT_CPU_RATE_CONTROL_ENABLE | winapi.JOB_OBJECT_CPU_RATE_CONTROL_WEIGHT_BASED
|
||||
cpuInfo.Value = rateControlValue
|
||||
case RateBased:
|
||||
if rateControlValue < cpuLimitMin || rateControlValue > cpuLimitMax {
|
||||
return fmt.Errorf("processor rate of `%d` is invalid", rateControlValue)
|
||||
}
|
||||
cpuInfo.ControlFlags |= winapi.JOB_OBJECT_CPU_RATE_CONTROL_ENABLE | winapi.JOB_OBJECT_CPU_RATE_CONTROL_HARD_CAP
|
||||
cpuInfo.Value = rateControlValue
|
||||
default:
|
||||
return errors.New("invalid job object cpu rate control type")
|
||||
}
|
||||
return job.setCPURateControlInfo(cpuInfo)
|
||||
}
|
||||
|
||||
// GetCPULimit gets the cpu limits for the job object.
|
||||
// `rateControlType` is used to indicate what type of cpu limit to query for.
|
||||
func (job *JobObject) GetCPULimit(rateControlType CPURateControlType) (uint32, error) {
|
||||
info, err := job.getCPURateControlInformation()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if !isFlagSet(winapi.JOB_OBJECT_CPU_RATE_CONTROL_ENABLE, info.ControlFlags) {
|
||||
return 0, errors.New("the job does not have cpu rate control enabled")
|
||||
}
|
||||
|
||||
switch rateControlType {
|
||||
case WeightBased:
|
||||
if !isFlagSet(winapi.JOB_OBJECT_CPU_RATE_CONTROL_WEIGHT_BASED, info.ControlFlags) {
|
||||
return 0, errors.New("cannot get cpu weight for job object without cpu weight option set")
|
||||
}
|
||||
case RateBased:
|
||||
if !isFlagSet(winapi.JOB_OBJECT_CPU_RATE_CONTROL_HARD_CAP, info.ControlFlags) {
|
||||
return 0, errors.New("cannot get cpu rate hard cap for job object without cpu rate hard cap option set")
|
||||
}
|
||||
default:
|
||||
return 0, errors.New("invalid job object cpu rate control type")
|
||||
}
|
||||
return info.Value, nil
|
||||
}
|
||||
|
||||
// SetCPUAffinity sets the processor affinity for the job object.
|
||||
// The affinity is passed in as a bitmask.
|
||||
func (job *JobObject) SetCPUAffinity(affinityBitMask uint64) error {
|
||||
info, err := job.getExtendedInformation()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
info.BasicLimitInformation.LimitFlags |= uint32(windows.JOB_OBJECT_LIMIT_AFFINITY)
|
||||
info.BasicLimitInformation.Affinity = uintptr(affinityBitMask)
|
||||
return job.setExtendedInformation(info)
|
||||
}
|
||||
|
||||
// GetCPUAffinity gets the processor affinity for the job object.
|
||||
// The returned affinity is a bitmask.
|
||||
func (job *JobObject) GetCPUAffinity() (uint64, error) {
|
||||
info, err := job.getExtendedInformation()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return uint64(info.BasicLimitInformation.Affinity), nil
|
||||
}
|
||||
|
||||
// SetIOLimit sets the IO limits specified on the job object.
|
||||
func (job *JobObject) SetIOLimit(maxBandwidth, maxIOPS int64) error {
|
||||
ioInfo, err := job.getIOLimit()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ioInfo.ControlFlags |= winapi.JOB_OBJECT_IO_RATE_CONTROL_ENABLE
|
||||
if maxBandwidth != 0 {
|
||||
ioInfo.MaxBandwidth = maxBandwidth
|
||||
}
|
||||
if maxIOPS != 0 {
|
||||
ioInfo.MaxIops = maxIOPS
|
||||
}
|
||||
return job.setIORateControlInfo(ioInfo)
|
||||
}
|
||||
|
||||
// GetIOMaxBandwidthLimit gets the max bandwidth for the job object.
|
||||
func (job *JobObject) GetIOMaxBandwidthLimit() (int64, error) {
|
||||
info, err := job.getIOLimit()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return info.MaxBandwidth, nil
|
||||
}
|
||||
|
||||
// GetIOMaxIopsLimit gets the max iops for the job object.
|
||||
func (job *JobObject) GetIOMaxIopsLimit() (int64, error) {
|
||||
info, err := job.getIOLimit()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return info.MaxIops, nil
|
||||
}
|
||||
|
||||
// Helper function for getting a job object's extended information.
|
||||
func (job *JobObject) getExtendedInformation() (*windows.JOBOBJECT_EXTENDED_LIMIT_INFORMATION, error) {
|
||||
job.handleLock.RLock()
|
||||
defer job.handleLock.RUnlock()
|
||||
|
||||
if job.handle == 0 {
|
||||
return nil, ErrAlreadyClosed
|
||||
}
|
||||
|
||||
info := windows.JOBOBJECT_EXTENDED_LIMIT_INFORMATION{}
|
||||
if err := winapi.QueryInformationJobObject(
|
||||
job.handle,
|
||||
windows.JobObjectExtendedLimitInformation,
|
||||
uintptr(unsafe.Pointer(&info)),
|
||||
uint32(unsafe.Sizeof(info)),
|
||||
nil,
|
||||
); err != nil {
|
||||
return nil, fmt.Errorf("query %v returned error: %w", info, err)
|
||||
}
|
||||
return &info, nil
|
||||
}
|
||||
|
||||
// Helper function for getting a job object's CPU rate control information.
|
||||
func (job *JobObject) getCPURateControlInformation() (*winapi.JOBOBJECT_CPU_RATE_CONTROL_INFORMATION, error) {
|
||||
job.handleLock.RLock()
|
||||
defer job.handleLock.RUnlock()
|
||||
|
||||
if job.handle == 0 {
|
||||
return nil, ErrAlreadyClosed
|
||||
}
|
||||
|
||||
info := winapi.JOBOBJECT_CPU_RATE_CONTROL_INFORMATION{}
|
||||
if err := winapi.QueryInformationJobObject(
|
||||
job.handle,
|
||||
windows.JobObjectCpuRateControlInformation,
|
||||
uintptr(unsafe.Pointer(&info)),
|
||||
uint32(unsafe.Sizeof(info)),
|
||||
nil,
|
||||
); err != nil {
|
||||
return nil, fmt.Errorf("query %v returned error: %w", info, err)
|
||||
}
|
||||
return &info, nil
|
||||
}
|
||||
|
||||
// Helper function for setting a job object's extended information.
|
||||
func (job *JobObject) setExtendedInformation(info *windows.JOBOBJECT_EXTENDED_LIMIT_INFORMATION) error {
|
||||
job.handleLock.RLock()
|
||||
defer job.handleLock.RUnlock()
|
||||
|
||||
if job.handle == 0 {
|
||||
return ErrAlreadyClosed
|
||||
}
|
||||
|
||||
if _, err := windows.SetInformationJobObject(
|
||||
job.handle,
|
||||
windows.JobObjectExtendedLimitInformation,
|
||||
uintptr(unsafe.Pointer(info)),
|
||||
uint32(unsafe.Sizeof(*info)),
|
||||
); err != nil {
|
||||
return fmt.Errorf("failed to set Extended info %v on job object: %w", info, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Helper function for querying job handle for IO limit information.
|
||||
func (job *JobObject) getIOLimit() (*winapi.JOBOBJECT_IO_RATE_CONTROL_INFORMATION, error) {
|
||||
job.handleLock.RLock()
|
||||
defer job.handleLock.RUnlock()
|
||||
|
||||
if job.handle == 0 {
|
||||
return nil, ErrAlreadyClosed
|
||||
}
|
||||
|
||||
ioInfo := &winapi.JOBOBJECT_IO_RATE_CONTROL_INFORMATION{}
|
||||
var blockCount uint32 = 1
|
||||
|
||||
if _, err := winapi.QueryIoRateControlInformationJobObject(
|
||||
job.handle,
|
||||
nil,
|
||||
&ioInfo,
|
||||
&blockCount,
|
||||
); err != nil {
|
||||
return nil, fmt.Errorf("query %v returned error: %w", ioInfo, err)
|
||||
}
|
||||
|
||||
if !isFlagSet(winapi.JOB_OBJECT_IO_RATE_CONTROL_ENABLE, ioInfo.ControlFlags) {
|
||||
return nil, fmt.Errorf("query %v cannot get IO limits for job object without IO rate control option set", ioInfo)
|
||||
}
|
||||
return ioInfo, nil
|
||||
}
|
||||
|
||||
// Helper function for setting a job object's IO rate control information.
|
||||
func (job *JobObject) setIORateControlInfo(ioInfo *winapi.JOBOBJECT_IO_RATE_CONTROL_INFORMATION) error {
|
||||
job.handleLock.RLock()
|
||||
defer job.handleLock.RUnlock()
|
||||
|
||||
if job.handle == 0 {
|
||||
return ErrAlreadyClosed
|
||||
}
|
||||
|
||||
if _, err := winapi.SetIoRateControlInformationJobObject(job.handle, ioInfo); err != nil {
|
||||
return fmt.Errorf("failed to set IO limit info %v on job object: %w", ioInfo, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Helper function for setting a job object's CPU rate control information.
|
||||
func (job *JobObject) setCPURateControlInfo(cpuInfo *winapi.JOBOBJECT_CPU_RATE_CONTROL_INFORMATION) error {
|
||||
job.handleLock.RLock()
|
||||
defer job.handleLock.RUnlock()
|
||||
|
||||
if job.handle == 0 {
|
||||
return ErrAlreadyClosed
|
||||
}
|
||||
if _, err := windows.SetInformationJobObject(
|
||||
job.handle,
|
||||
windows.JobObjectCpuRateControlInformation,
|
||||
uintptr(unsafe.Pointer(cpuInfo)),
|
||||
uint32(unsafe.Sizeof(cpuInfo)),
|
||||
); err != nil {
|
||||
return fmt.Errorf("failed to set cpu limit info %v on job object: %w", cpuInfo, err)
|
||||
}
|
||||
return nil
|
||||
}
|
111
src/runtime/vendor/github.com/Microsoft/hcsshim/internal/queue/mq.go
generated
vendored
Normal file
111
src/runtime/vendor/github.com/Microsoft/hcsshim/internal/queue/mq.go
generated
vendored
Normal file
@ -0,0 +1,111 @@
|
||||
package queue
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrQueueClosed = errors.New("the queue is closed for reading and writing")
|
||||
ErrQueueEmpty = errors.New("the queue is empty")
|
||||
)
|
||||
|
||||
// MessageQueue represents a threadsafe message queue to be used to retrieve or
|
||||
// write messages to.
|
||||
type MessageQueue struct {
|
||||
m *sync.RWMutex
|
||||
c *sync.Cond
|
||||
messages []interface{}
|
||||
closed bool
|
||||
}
|
||||
|
||||
// NewMessageQueue returns a new MessageQueue.
|
||||
func NewMessageQueue() *MessageQueue {
|
||||
m := &sync.RWMutex{}
|
||||
return &MessageQueue{
|
||||
m: m,
|
||||
c: sync.NewCond(m),
|
||||
messages: []interface{}{},
|
||||
}
|
||||
}
|
||||
|
||||
// Write writes `msg` to the queue.
|
||||
func (mq *MessageQueue) Write(msg interface{}) error {
|
||||
mq.m.Lock()
|
||||
defer mq.m.Unlock()
|
||||
|
||||
if mq.closed {
|
||||
return ErrQueueClosed
|
||||
}
|
||||
mq.messages = append(mq.messages, msg)
|
||||
// Signal a waiter that there is now a value available in the queue.
|
||||
mq.c.Signal()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Read will read a value from the queue if available, otherwise return an error.
|
||||
func (mq *MessageQueue) Read() (interface{}, error) {
|
||||
mq.m.Lock()
|
||||
defer mq.m.Unlock()
|
||||
if mq.closed {
|
||||
return nil, ErrQueueClosed
|
||||
}
|
||||
if mq.isEmpty() {
|
||||
return nil, ErrQueueEmpty
|
||||
}
|
||||
val := mq.messages[0]
|
||||
mq.messages[0] = nil
|
||||
mq.messages = mq.messages[1:]
|
||||
return val, nil
|
||||
}
|
||||
|
||||
// ReadOrWait will read a value from the queue if available, else it will wait for a
|
||||
// value to become available. This will block forever if nothing gets written or until
|
||||
// the queue gets closed.
|
||||
func (mq *MessageQueue) ReadOrWait() (interface{}, error) {
|
||||
mq.m.Lock()
|
||||
if mq.closed {
|
||||
mq.m.Unlock()
|
||||
return nil, ErrQueueClosed
|
||||
}
|
||||
if mq.isEmpty() {
|
||||
for !mq.closed && mq.isEmpty() {
|
||||
mq.c.Wait()
|
||||
}
|
||||
mq.m.Unlock()
|
||||
return mq.Read()
|
||||
}
|
||||
val := mq.messages[0]
|
||||
mq.messages[0] = nil
|
||||
mq.messages = mq.messages[1:]
|
||||
mq.m.Unlock()
|
||||
return val, nil
|
||||
}
|
||||
|
||||
// IsEmpty returns if the queue is empty
|
||||
func (mq *MessageQueue) IsEmpty() bool {
|
||||
mq.m.RLock()
|
||||
defer mq.m.RUnlock()
|
||||
return len(mq.messages) == 0
|
||||
}
|
||||
|
||||
// Nonexported empty check that doesn't lock so we can call this in Read and Write.
|
||||
func (mq *MessageQueue) isEmpty() bool {
|
||||
return len(mq.messages) == 0
|
||||
}
|
||||
|
||||
// Close closes the queue for future writes or reads. Any attempts to read or write from the
|
||||
// queue after close will return ErrQueueClosed. This is safe to call multiple times.
|
||||
func (mq *MessageQueue) Close() {
|
||||
mq.m.Lock()
|
||||
defer mq.m.Unlock()
|
||||
// Already closed
|
||||
if mq.closed {
|
||||
return
|
||||
}
|
||||
mq.messages = nil
|
||||
mq.closed = true
|
||||
// If there's anybody currently waiting on a value from ReadOrWait, we need to
|
||||
// broadcast so the read(s) can return ErrQueueClosed.
|
||||
mq.c.Broadcast()
|
||||
}
|
3
src/runtime/vendor/github.com/Microsoft/hcsshim/internal/winapi/iocp.go
generated
vendored
3
src/runtime/vendor/github.com/Microsoft/hcsshim/internal/winapi/iocp.go
generated
vendored
@ -1,3 +0,0 @@
|
||||
package winapi
|
||||
|
||||
//sys GetQueuedCompletionStatus(cphandle windows.Handle, qty *uint32, key *uintptr, overlapped **windows.Overlapped, timeout uint32) (err error)
|
9
src/runtime/vendor/github.com/Microsoft/hcsshim/internal/winapi/jobobject.go
generated
vendored
9
src/runtime/vendor/github.com/Microsoft/hcsshim/internal/winapi/jobobject.go
generated
vendored
@ -24,7 +24,10 @@ const (
|
||||
// Access rights for creating or opening job objects.
|
||||
//
|
||||
// https://docs.microsoft.com/en-us/windows/win32/procthread/job-object-security-and-access-rights
|
||||
const JOB_OBJECT_ALL_ACCESS = 0x1F001F
|
||||
const (
|
||||
JOB_OBJECT_QUERY = 0x0004
|
||||
JOB_OBJECT_ALL_ACCESS = 0x1F001F
|
||||
)
|
||||
|
||||
// IO limit flags
|
||||
//
|
||||
@ -93,7 +96,7 @@ type JOBOBJECT_BASIC_PROCESS_ID_LIST struct {
|
||||
|
||||
// AllPids returns all the process Ids in the job object.
|
||||
func (p *JOBOBJECT_BASIC_PROCESS_ID_LIST) AllPids() []uintptr {
|
||||
return (*[(1 << 27) - 1]uintptr)(unsafe.Pointer(&p.ProcessIdList[0]))[:p.NumberOfProcessIdsInList]
|
||||
return (*[(1 << 27) - 1]uintptr)(unsafe.Pointer(&p.ProcessIdList[0]))[:p.NumberOfProcessIdsInList:p.NumberOfProcessIdsInList]
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-jobobject_basic_accounting_information
|
||||
@ -162,7 +165,7 @@ type JOBOBJECT_ASSOCIATE_COMPLETION_PORT struct {
|
||||
// PBOOL Result
|
||||
// );
|
||||
//
|
||||
//sys IsProcessInJob(procHandle windows.Handle, jobHandle windows.Handle, result *bool) (err error) = kernel32.IsProcessInJob
|
||||
//sys IsProcessInJob(procHandle windows.Handle, jobHandle windows.Handle, result *int32) (err error) = kernel32.IsProcessInJob
|
||||
|
||||
// BOOL QueryInformationJobObject(
|
||||
// HANDLE hJob,
|
||||
|
57
src/runtime/vendor/github.com/Microsoft/hcsshim/internal/winapi/process.go
generated
vendored
57
src/runtime/vendor/github.com/Microsoft/hcsshim/internal/winapi/process.go
generated
vendored
@ -6,3 +6,60 @@ const (
|
||||
PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE = 0x20016
|
||||
PROC_THREAD_ATTRIBUTE_JOB_LIST = 0x2000D
|
||||
)
|
||||
|
||||
// ProcessVmCounters corresponds to the _VM_COUNTERS_EX and _VM_COUNTERS_EX2 structures.
|
||||
const ProcessVmCounters = 3
|
||||
|
||||
// __kernel_entry NTSTATUS NtQueryInformationProcess(
|
||||
// [in] HANDLE ProcessHandle,
|
||||
// [in] PROCESSINFOCLASS ProcessInformationClass,
|
||||
// [out] PVOID ProcessInformation,
|
||||
// [in] ULONG ProcessInformationLength,
|
||||
// [out, optional] PULONG ReturnLength
|
||||
// );
|
||||
//
|
||||
//sys NtQueryInformationProcess(processHandle windows.Handle, processInfoClass uint32, processInfo uintptr, processInfoLength uint32, returnLength *uint32) (status uint32) = ntdll.NtQueryInformationProcess
|
||||
|
||||
// typedef struct _VM_COUNTERS_EX
|
||||
// {
|
||||
// SIZE_T PeakVirtualSize;
|
||||
// SIZE_T VirtualSize;
|
||||
// ULONG PageFaultCount;
|
||||
// SIZE_T PeakWorkingSetSize;
|
||||
// SIZE_T WorkingSetSize;
|
||||
// SIZE_T QuotaPeakPagedPoolUsage;
|
||||
// SIZE_T QuotaPagedPoolUsage;
|
||||
// SIZE_T QuotaPeakNonPagedPoolUsage;
|
||||
// SIZE_T QuotaNonPagedPoolUsage;
|
||||
// SIZE_T PagefileUsage;
|
||||
// SIZE_T PeakPagefileUsage;
|
||||
// SIZE_T PrivateUsage;
|
||||
// } VM_COUNTERS_EX, *PVM_COUNTERS_EX;
|
||||
//
|
||||
type VM_COUNTERS_EX struct {
|
||||
PeakVirtualSize uintptr
|
||||
VirtualSize uintptr
|
||||
PageFaultCount uint32
|
||||
PeakWorkingSetSize uintptr
|
||||
WorkingSetSize uintptr
|
||||
QuotaPeakPagedPoolUsage uintptr
|
||||
QuotaPagedPoolUsage uintptr
|
||||
QuotaPeakNonPagedPoolUsage uintptr
|
||||
QuotaNonPagedPoolUsage uintptr
|
||||
PagefileUsage uintptr
|
||||
PeakPagefileUsage uintptr
|
||||
PrivateUsage uintptr
|
||||
}
|
||||
|
||||
// typedef struct _VM_COUNTERS_EX2
|
||||
// {
|
||||
// VM_COUNTERS_EX CountersEx;
|
||||
// SIZE_T PrivateWorkingSetSize;
|
||||
// SIZE_T SharedCommitUsage;
|
||||
// } VM_COUNTERS_EX2, *PVM_COUNTERS_EX2;
|
||||
//
|
||||
type VM_COUNTERS_EX2 struct {
|
||||
CountersEx VM_COUNTERS_EX
|
||||
PrivateWorkingSetSize uintptr
|
||||
SharedCommitUsage uintptr
|
||||
}
|
||||
|
2
src/runtime/vendor/github.com/Microsoft/hcsshim/internal/winapi/winapi.go
generated
vendored
2
src/runtime/vendor/github.com/Microsoft/hcsshim/internal/winapi/winapi.go
generated
vendored
@ -2,4 +2,4 @@
|
||||
// be thought of as an extension to golang.org/x/sys/windows.
|
||||
package winapi
|
||||
|
||||
//go:generate go run ..\..\mksyscall_windows.go -output zsyscall_windows.go console.go system.go net.go path.go thread.go iocp.go jobobject.go logon.go memory.go process.go processor.go devices.go filesystem.go errors.go
|
||||
//go:generate go run ..\..\mksyscall_windows.go -output zsyscall_windows.go user.go console.go system.go net.go path.go thread.go jobobject.go logon.go memory.go process.go processor.go devices.go filesystem.go errors.go
|
||||
|
22
src/runtime/vendor/github.com/Microsoft/hcsshim/internal/winapi/zsyscall_windows.go
generated
vendored
22
src/runtime/vendor/github.com/Microsoft/hcsshim/internal/winapi/zsyscall_windows.go
generated
vendored
@ -50,7 +50,6 @@ var (
|
||||
procSetJobCompartmentId = modiphlpapi.NewProc("SetJobCompartmentId")
|
||||
procSearchPathW = modkernel32.NewProc("SearchPathW")
|
||||
procCreateRemoteThread = modkernel32.NewProc("CreateRemoteThread")
|
||||
procGetQueuedCompletionStatus = modkernel32.NewProc("GetQueuedCompletionStatus")
|
||||
procIsProcessInJob = modkernel32.NewProc("IsProcessInJob")
|
||||
procQueryInformationJobObject = modkernel32.NewProc("QueryInformationJobObject")
|
||||
procOpenJobObjectW = modkernel32.NewProc("OpenJobObjectW")
|
||||
@ -61,6 +60,7 @@ var (
|
||||
procLogonUserW = modadvapi32.NewProc("LogonUserW")
|
||||
procLocalAlloc = modkernel32.NewProc("LocalAlloc")
|
||||
procLocalFree = modkernel32.NewProc("LocalFree")
|
||||
procNtQueryInformationProcess = modntdll.NewProc("NtQueryInformationProcess")
|
||||
procGetActiveProcessorCount = modkernel32.NewProc("GetActiveProcessorCount")
|
||||
procCM_Get_Device_ID_List_SizeA = modcfgmgr32.NewProc("CM_Get_Device_ID_List_SizeA")
|
||||
procCM_Get_Device_ID_ListA = modcfgmgr32.NewProc("CM_Get_Device_ID_ListA")
|
||||
@ -140,19 +140,7 @@ func CreateRemoteThread(process windows.Handle, sa *windows.SecurityAttributes,
|
||||
return
|
||||
}
|
||||
|
||||
func GetQueuedCompletionStatus(cphandle windows.Handle, qty *uint32, key *uintptr, overlapped **windows.Overlapped, timeout uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall6(procGetQueuedCompletionStatus.Addr(), 5, uintptr(cphandle), uintptr(unsafe.Pointer(qty)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(overlapped)), uintptr(timeout), 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func IsProcessInJob(procHandle windows.Handle, jobHandle windows.Handle, result *bool) (err error) {
|
||||
func IsProcessInJob(procHandle windows.Handle, jobHandle windows.Handle, result *int32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procIsProcessInJob.Addr(), 3, uintptr(procHandle), uintptr(jobHandle), uintptr(unsafe.Pointer(result)))
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
@ -256,6 +244,12 @@ func LocalFree(ptr uintptr) {
|
||||
return
|
||||
}
|
||||
|
||||
func NtQueryInformationProcess(processHandle windows.Handle, processInfoClass uint32, processInfo uintptr, processInfoLength uint32, returnLength *uint32) (status uint32) {
|
||||
r0, _, _ := syscall.Syscall6(procNtQueryInformationProcess.Addr(), 5, uintptr(processHandle), uintptr(processInfoClass), uintptr(processInfo), uintptr(processInfoLength), uintptr(unsafe.Pointer(returnLength)), 0)
|
||||
status = uint32(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func GetActiveProcessorCount(groupNumber uint16) (amount uint32) {
|
||||
r0, _, _ := syscall.Syscall(procGetActiveProcessorCount.Addr(), 1, uintptr(groupNumber), 0, 0)
|
||||
amount = uint32(r0)
|
||||
|
1
src/runtime/vendor/github.com/cilium/ebpf/.gitignore
generated
vendored
1
src/runtime/vendor/github.com/cilium/ebpf/.gitignore
generated
vendored
@ -5,6 +5,7 @@
|
||||
*.so
|
||||
*.dylib
|
||||
*.o
|
||||
!*_bpf*.o
|
||||
|
||||
# Test binary, build with `go test -c`
|
||||
*.test
|
||||
|
1
src/runtime/vendor/github.com/cilium/ebpf/.golangci.yaml
generated
vendored
1
src/runtime/vendor/github.com/cilium/ebpf/.golangci.yaml
generated
vendored
@ -24,6 +24,5 @@ linters:
|
||||
|
||||
# Could be enabled later:
|
||||
# - gocyclo
|
||||
# - prealloc
|
||||
# - maligned
|
||||
# - gosec
|
||||
|
4
src/runtime/vendor/github.com/cilium/ebpf/ARCHITECTURE.md
generated
vendored
4
src/runtime/vendor/github.com/cilium/ebpf/ARCHITECTURE.md
generated
vendored
@ -57,7 +57,7 @@ Objects
|
||||
loading a spec will fail because the kernel is too old, or a feature is not
|
||||
enabled. There are multiple ways the library deals with that:
|
||||
|
||||
* Fallback: older kernels don't allowing naming programs and maps. The library
|
||||
* Fallback: older kernels don't allow naming programs and maps. The library
|
||||
automatically detects support for names, and omits them during load if
|
||||
necessary. This works since name is primarily a debug aid.
|
||||
|
||||
@ -68,7 +68,7 @@ enabled. There are multiple ways the library deals with that:
|
||||
Once program and map objects are loaded they expose the kernel's low-level API,
|
||||
e.g. `NextKey`. Often this API is awkward to use in Go, so there are safer
|
||||
wrappers on top of the low-level API, like `MapIterator`. The low-level API is
|
||||
useful as an out when our higher-level API doesn't support a particular use case.
|
||||
useful when our higher-level API doesn't support a particular use case.
|
||||
|
||||
Links
|
||||
---
|
||||
|
4
src/runtime/vendor/github.com/cilium/ebpf/CONTRIBUTING.md
generated
vendored
4
src/runtime/vendor/github.com/cilium/ebpf/CONTRIBUTING.md
generated
vendored
@ -6,8 +6,8 @@ are welcome. Please take a look at [the architecture](ARCHITECTURE.md) to get
|
||||
a better understanding for the high-level goals.
|
||||
|
||||
New features must be accompanied by tests. Before starting work on any large
|
||||
feature, please [join](https://cilium.herokuapp.com/) the
|
||||
[#libbpf-go](https://cilium.slack.com/messages/libbpf-go) channel on Slack to
|
||||
feature, please [join](https://ebpf.io/slack) the
|
||||
[#ebpf-go](https://cilium.slack.com/messages/ebpf-go) channel on Slack to
|
||||
discuss the design first.
|
||||
|
||||
When submitting pull requests, consider writing details about what problem you
|
||||
|
5
src/runtime/vendor/github.com/cilium/ebpf/Makefile
generated
vendored
5
src/runtime/vendor/github.com/cilium/ebpf/Makefile
generated
vendored
@ -18,11 +18,14 @@ TARGETS := \
|
||||
testdata/loader-clang-7 \
|
||||
testdata/loader-clang-9 \
|
||||
testdata/loader-$(CLANG) \
|
||||
testdata/btf_map_init \
|
||||
testdata/invalid_map \
|
||||
testdata/raw_tracepoint \
|
||||
testdata/invalid_map_static \
|
||||
testdata/initialized_btf_map \
|
||||
testdata/invalid_btf_map_init \
|
||||
testdata/strings \
|
||||
testdata/freplace \
|
||||
testdata/iproute2_map_compat \
|
||||
internal/btf/testdata/relocs
|
||||
|
||||
.PHONY: all clean docker-all docker-shell
|
||||
|
62
src/runtime/vendor/github.com/cilium/ebpf/README.md
generated
vendored
62
src/runtime/vendor/github.com/cilium/ebpf/README.md
generated
vendored
@ -2,28 +2,16 @@
|
||||
|
||||
[](https://pkg.go.dev/github.com/cilium/ebpf)
|
||||
|
||||

|
||||
|
||||
eBPF is a pure Go library that provides utilities for loading, compiling, and
|
||||
debugging eBPF programs. It has minimal external dependencies and is intended to
|
||||
be used in long running processes.
|
||||
|
||||
* [asm](https://pkg.go.dev/github.com/cilium/ebpf/asm) contains a basic
|
||||
assembler
|
||||
* [link](https://pkg.go.dev/github.com/cilium/ebpf/link) allows attaching eBPF
|
||||
to various hooks
|
||||
* [perf](https://pkg.go.dev/github.com/cilium/ebpf/perf) allows reading from a
|
||||
`PERF_EVENT_ARRAY`
|
||||
* [cmd/bpf2go](https://pkg.go.dev/github.com/cilium/ebpf/cmd/bpf2go) allows
|
||||
compiling and embedding eBPF programs in Go code
|
||||
|
||||
The library is maintained by [Cloudflare](https://www.cloudflare.com) and
|
||||
[Cilium](https://www.cilium.io). Feel free to
|
||||
[join](https://cilium.herokuapp.com/) the
|
||||
[#libbpf-go](https://cilium.slack.com/messages/libbpf-go) channel on Slack.
|
||||
[Cilium](https://www.cilium.io).
|
||||
|
||||
## Current status
|
||||
|
||||
The package is production ready, but **the API is explicitly unstable right
|
||||
now**. Expect to update your code if you want to follow along.
|
||||
See [ebpf.io](https://ebpf.io) for other projects from the eBPF ecosystem.
|
||||
|
||||
## Getting Started
|
||||
|
||||
@ -33,21 +21,37 @@ your own tools can be found under [examples/](examples/).
|
||||
Contributions are highly encouraged, as they highlight certain use cases of
|
||||
eBPF and the library, and help shape the future of the project.
|
||||
|
||||
## Getting Help
|
||||
|
||||
Please
|
||||
[join](https://ebpf.io/slack) the
|
||||
[#ebpf-go](https://cilium.slack.com/messages/ebpf-go) channel on Slack if you
|
||||
have questions regarding the library.
|
||||
|
||||
## Packages
|
||||
|
||||
This library includes the following packages:
|
||||
|
||||
* [asm](https://pkg.go.dev/github.com/cilium/ebpf/asm) contains a basic
|
||||
assembler, allowing you to write eBPF assembly instructions directly
|
||||
within your Go code. (You don't need to use this if you prefer to write your eBPF program in C.)
|
||||
* [cmd/bpf2go](https://pkg.go.dev/github.com/cilium/ebpf/cmd/bpf2go) allows
|
||||
compiling and embedding eBPF programs written in C within Go code. As well as
|
||||
compiling the C code, it auto-generates Go code for loading and manipulating
|
||||
the eBPF program and map objects.
|
||||
* [link](https://pkg.go.dev/github.com/cilium/ebpf/link) allows attaching eBPF
|
||||
to various hooks
|
||||
* [perf](https://pkg.go.dev/github.com/cilium/ebpf/perf) allows reading from a
|
||||
`PERF_EVENT_ARRAY`
|
||||
* [ringbuf](https://pkg.go.dev/github.com/cilium/ebpf/ringbuf) allows reading from a
|
||||
`BPF_MAP_TYPE_RINGBUF` map
|
||||
|
||||
|
||||
## Requirements
|
||||
|
||||
* A version of Go that is [supported by
|
||||
upstream](https://golang.org/doc/devel/release.html#policy)
|
||||
* Linux 4.9, 4.19 or 5.4 (versions in-between should work, but are not tested)
|
||||
|
||||
## Useful resources
|
||||
|
||||
* [eBPF.io](https://ebpf.io) (recommended)
|
||||
* [Cilium eBPF documentation](https://docs.cilium.io/en/latest/bpf/#bpf-guide)
|
||||
(recommended)
|
||||
* [Linux documentation on
|
||||
BPF](https://www.kernel.org/doc/html/latest/networking/filter.html)
|
||||
* [eBPF features by Linux
|
||||
version](https://github.com/iovisor/bcc/blob/master/docs/kernel-versions.md)
|
||||
* Linux >= 4.9. CI is run against LTS releases.
|
||||
|
||||
## Regenerating Testdata
|
||||
|
||||
@ -60,3 +64,7 @@ The toolchain image build files are kept in [testdata/docker/](testdata/docker/)
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
||||
### eBPF Gopher
|
||||
|
||||
The eBPF honeygopher is based on the Go gopher designed by Renee French.
|
||||
|
6
src/runtime/vendor/github.com/cilium/ebpf/asm/func.go
generated
vendored
6
src/runtime/vendor/github.com/cilium/ebpf/asm/func.go
generated
vendored
@ -184,6 +184,12 @@ const (
|
||||
FnKtimeGetCoarseNs
|
||||
FnImaInodeHash
|
||||
FnSockFromFile
|
||||
FnCheckMtu
|
||||
FnForEachMapElem
|
||||
FnSnprintf
|
||||
FnSysBpf
|
||||
FnBtfFindByNameKind
|
||||
FnSysClose
|
||||
)
|
||||
|
||||
// Call emits a function call.
|
||||
|
10
src/runtime/vendor/github.com/cilium/ebpf/asm/func_string.go
generated
vendored
10
src/runtime/vendor/github.com/cilium/ebpf/asm/func_string.go
generated
vendored
@ -171,11 +171,17 @@ func _() {
|
||||
_ = x[FnKtimeGetCoarseNs-160]
|
||||
_ = x[FnImaInodeHash-161]
|
||||
_ = x[FnSockFromFile-162]
|
||||
_ = x[FnCheckMtu-163]
|
||||
_ = x[FnForEachMapElem-164]
|
||||
_ = x[FnSnprintf-165]
|
||||
_ = x[FnSysBpf-166]
|
||||
_ = x[FnBtfFindByNameKind-167]
|
||||
_ = x[FnSysClose-168]
|
||||
}
|
||||
|
||||
const _BuiltinFunc_name = "FnUnspecFnMapLookupElemFnMapUpdateElemFnMapDeleteElemFnProbeReadFnKtimeGetNsFnTracePrintkFnGetPrandomU32FnGetSmpProcessorIdFnSkbStoreBytesFnL3CsumReplaceFnL4CsumReplaceFnTailCallFnCloneRedirectFnGetCurrentPidTgidFnGetCurrentUidGidFnGetCurrentCommFnGetCgroupClassidFnSkbVlanPushFnSkbVlanPopFnSkbGetTunnelKeyFnSkbSetTunnelKeyFnPerfEventReadFnRedirectFnGetRouteRealmFnPerfEventOutputFnSkbLoadBytesFnGetStackidFnCsumDiffFnSkbGetTunnelOptFnSkbSetTunnelOptFnSkbChangeProtoFnSkbChangeTypeFnSkbUnderCgroupFnGetHashRecalcFnGetCurrentTaskFnProbeWriteUserFnCurrentTaskUnderCgroupFnSkbChangeTailFnSkbPullDataFnCsumUpdateFnSetHashInvalidFnGetNumaNodeIdFnSkbChangeHeadFnXdpAdjustHeadFnProbeReadStrFnGetSocketCookieFnGetSocketUidFnSetHashFnSetsockoptFnSkbAdjustRoomFnRedirectMapFnSkRedirectMapFnSockMapUpdateFnXdpAdjustMetaFnPerfEventReadValueFnPerfProgReadValueFnGetsockoptFnOverrideReturnFnSockOpsCbFlagsSetFnMsgRedirectMapFnMsgApplyBytesFnMsgCorkBytesFnMsgPullDataFnBindFnXdpAdjustTailFnSkbGetXfrmStateFnGetStackFnSkbLoadBytesRelativeFnFibLookupFnSockHashUpdateFnMsgRedirectHashFnSkRedirectHashFnLwtPushEncapFnLwtSeg6StoreBytesFnLwtSeg6AdjustSrhFnLwtSeg6ActionFnRcRepeatFnRcKeydownFnSkbCgroupIdFnGetCurrentCgroupIdFnGetLocalStorageFnSkSelectReuseportFnSkbAncestorCgroupIdFnSkLookupTcpFnSkLookupUdpFnSkReleaseFnMapPushElemFnMapPopElemFnMapPeekElemFnMsgPushDataFnMsgPopDataFnRcPointerRelFnSpinLockFnSpinUnlockFnSkFullsockFnTcpSockFnSkbEcnSetCeFnGetListenerSockFnSkcLookupTcpFnTcpCheckSyncookieFnSysctlGetNameFnSysctlGetCurrentValueFnSysctlGetNewValueFnSysctlSetNewValueFnStrtolFnStrtoulFnSkStorageGetFnSkStorageDeleteFnSendSignalFnTcpGenSyncookieFnSkbOutputFnProbeReadUserFnProbeReadKernelFnProbeReadUserStrFnProbeReadKernelStrFnTcpSendAckFnSendSignalThreadFnJiffies64FnReadBranchRecordsFnGetNsCurrentPidTgidFnXdpOutputFnGetNetnsCookieFnGetCurrentAncestorCgroupIdFnSkAssignFnKtimeGetBootNsFnSeqPrintfFnSeqWriteFnSkCgroupIdFnSkAncestorCgroupIdFnRingbufOutputFnRingbufReserveFnRingbufSubmitFnRingbufDiscardFnRingbufQueryFnCsumLevelFnSkcToTcp6SockFnSkcToTcpSockFnSkcToTcpTimewaitSockFnSkcToTcpRequestSockFnSkcToUdp6SockFnGetTaskStackFnLoadHdrOptFnStoreHdrOptFnReserveHdrOptFnInodeStorageGetFnInodeStorageDeleteFnDPathFnCopyFromUserFnSnprintfBtfFnSeqPrintfBtfFnSkbCgroupClassidFnRedirectNeighFnPerCpuPtrFnThisCpuPtrFnRedirectPeerFnTaskStorageGetFnTaskStorageDeleteFnGetCurrentTaskBtfFnBprmOptsSetFnKtimeGetCoarseNsFnImaInodeHashFnSockFromFile"
|
||||
const _BuiltinFunc_name = "FnUnspecFnMapLookupElemFnMapUpdateElemFnMapDeleteElemFnProbeReadFnKtimeGetNsFnTracePrintkFnGetPrandomU32FnGetSmpProcessorIdFnSkbStoreBytesFnL3CsumReplaceFnL4CsumReplaceFnTailCallFnCloneRedirectFnGetCurrentPidTgidFnGetCurrentUidGidFnGetCurrentCommFnGetCgroupClassidFnSkbVlanPushFnSkbVlanPopFnSkbGetTunnelKeyFnSkbSetTunnelKeyFnPerfEventReadFnRedirectFnGetRouteRealmFnPerfEventOutputFnSkbLoadBytesFnGetStackidFnCsumDiffFnSkbGetTunnelOptFnSkbSetTunnelOptFnSkbChangeProtoFnSkbChangeTypeFnSkbUnderCgroupFnGetHashRecalcFnGetCurrentTaskFnProbeWriteUserFnCurrentTaskUnderCgroupFnSkbChangeTailFnSkbPullDataFnCsumUpdateFnSetHashInvalidFnGetNumaNodeIdFnSkbChangeHeadFnXdpAdjustHeadFnProbeReadStrFnGetSocketCookieFnGetSocketUidFnSetHashFnSetsockoptFnSkbAdjustRoomFnRedirectMapFnSkRedirectMapFnSockMapUpdateFnXdpAdjustMetaFnPerfEventReadValueFnPerfProgReadValueFnGetsockoptFnOverrideReturnFnSockOpsCbFlagsSetFnMsgRedirectMapFnMsgApplyBytesFnMsgCorkBytesFnMsgPullDataFnBindFnXdpAdjustTailFnSkbGetXfrmStateFnGetStackFnSkbLoadBytesRelativeFnFibLookupFnSockHashUpdateFnMsgRedirectHashFnSkRedirectHashFnLwtPushEncapFnLwtSeg6StoreBytesFnLwtSeg6AdjustSrhFnLwtSeg6ActionFnRcRepeatFnRcKeydownFnSkbCgroupIdFnGetCurrentCgroupIdFnGetLocalStorageFnSkSelectReuseportFnSkbAncestorCgroupIdFnSkLookupTcpFnSkLookupUdpFnSkReleaseFnMapPushElemFnMapPopElemFnMapPeekElemFnMsgPushDataFnMsgPopDataFnRcPointerRelFnSpinLockFnSpinUnlockFnSkFullsockFnTcpSockFnSkbEcnSetCeFnGetListenerSockFnSkcLookupTcpFnTcpCheckSyncookieFnSysctlGetNameFnSysctlGetCurrentValueFnSysctlGetNewValueFnSysctlSetNewValueFnStrtolFnStrtoulFnSkStorageGetFnSkStorageDeleteFnSendSignalFnTcpGenSyncookieFnSkbOutputFnProbeReadUserFnProbeReadKernelFnProbeReadUserStrFnProbeReadKernelStrFnTcpSendAckFnSendSignalThreadFnJiffies64FnReadBranchRecordsFnGetNsCurrentPidTgidFnXdpOutputFnGetNetnsCookieFnGetCurrentAncestorCgroupIdFnSkAssignFnKtimeGetBootNsFnSeqPrintfFnSeqWriteFnSkCgroupIdFnSkAncestorCgroupIdFnRingbufOutputFnRingbufReserveFnRingbufSubmitFnRingbufDiscardFnRingbufQueryFnCsumLevelFnSkcToTcp6SockFnSkcToTcpSockFnSkcToTcpTimewaitSockFnSkcToTcpRequestSockFnSkcToUdp6SockFnGetTaskStackFnLoadHdrOptFnStoreHdrOptFnReserveHdrOptFnInodeStorageGetFnInodeStorageDeleteFnDPathFnCopyFromUserFnSnprintfBtfFnSeqPrintfBtfFnSkbCgroupClassidFnRedirectNeighFnPerCpuPtrFnThisCpuPtrFnRedirectPeerFnTaskStorageGetFnTaskStorageDeleteFnGetCurrentTaskBtfFnBprmOptsSetFnKtimeGetCoarseNsFnImaInodeHashFnSockFromFileFnCheckMtuFnForEachMapElemFnSnprintfFnSysBpfFnBtfFindByNameKindFnSysClose"
|
||||
|
||||
var _BuiltinFunc_index = [...]uint16{0, 8, 23, 38, 53, 64, 76, 89, 104, 123, 138, 153, 168, 178, 193, 212, 230, 246, 264, 277, 289, 306, 323, 338, 348, 363, 380, 394, 406, 416, 433, 450, 466, 481, 497, 512, 528, 544, 568, 583, 596, 608, 624, 639, 654, 669, 683, 700, 714, 723, 735, 750, 763, 778, 793, 808, 828, 847, 859, 875, 894, 910, 925, 939, 952, 958, 973, 990, 1000, 1022, 1033, 1049, 1066, 1082, 1096, 1115, 1133, 1148, 1158, 1169, 1182, 1202, 1219, 1238, 1259, 1272, 1285, 1296, 1309, 1321, 1334, 1347, 1359, 1373, 1383, 1395, 1407, 1416, 1429, 1446, 1460, 1479, 1494, 1517, 1536, 1555, 1563, 1572, 1586, 1603, 1615, 1632, 1643, 1658, 1675, 1693, 1713, 1725, 1743, 1754, 1773, 1794, 1805, 1821, 1849, 1859, 1875, 1886, 1896, 1908, 1928, 1943, 1959, 1974, 1990, 2004, 2015, 2030, 2044, 2066, 2087, 2102, 2116, 2128, 2141, 2156, 2173, 2193, 2200, 2214, 2227, 2241, 2259, 2274, 2285, 2297, 2311, 2327, 2346, 2365, 2378, 2396, 2410, 2424}
|
||||
var _BuiltinFunc_index = [...]uint16{0, 8, 23, 38, 53, 64, 76, 89, 104, 123, 138, 153, 168, 178, 193, 212, 230, 246, 264, 277, 289, 306, 323, 338, 348, 363, 380, 394, 406, 416, 433, 450, 466, 481, 497, 512, 528, 544, 568, 583, 596, 608, 624, 639, 654, 669, 683, 700, 714, 723, 735, 750, 763, 778, 793, 808, 828, 847, 859, 875, 894, 910, 925, 939, 952, 958, 973, 990, 1000, 1022, 1033, 1049, 1066, 1082, 1096, 1115, 1133, 1148, 1158, 1169, 1182, 1202, 1219, 1238, 1259, 1272, 1285, 1296, 1309, 1321, 1334, 1347, 1359, 1373, 1383, 1395, 1407, 1416, 1429, 1446, 1460, 1479, 1494, 1517, 1536, 1555, 1563, 1572, 1586, 1603, 1615, 1632, 1643, 1658, 1675, 1693, 1713, 1725, 1743, 1754, 1773, 1794, 1805, 1821, 1849, 1859, 1875, 1886, 1896, 1908, 1928, 1943, 1959, 1974, 1990, 2004, 2015, 2030, 2044, 2066, 2087, 2102, 2116, 2128, 2141, 2156, 2173, 2193, 2200, 2214, 2227, 2241, 2259, 2274, 2285, 2297, 2311, 2327, 2346, 2365, 2378, 2396, 2410, 2424, 2434, 2450, 2460, 2468, 2487, 2497}
|
||||
|
||||
func (i BuiltinFunc) String() string {
|
||||
if i < 0 || i >= BuiltinFunc(len(_BuiltinFunc_index)-1) {
|
||||
|
5
src/runtime/vendor/github.com/cilium/ebpf/asm/instruction.go
generated
vendored
5
src/runtime/vendor/github.com/cilium/ebpf/asm/instruction.go
generated
vendored
@ -181,6 +181,11 @@ func (ins *Instruction) IsFunctionCall() bool {
|
||||
return ins.OpCode.JumpOp() == Call && ins.Src == PseudoCall
|
||||
}
|
||||
|
||||
// IsBuiltinCall returns true if the instruction is a built-in call, i.e. BPF helper call.
|
||||
func (ins *Instruction) IsBuiltinCall() bool {
|
||||
return ins.OpCode.JumpOp() == Call && ins.Src == R0 && ins.Dst == R0
|
||||
}
|
||||
|
||||
// IsConstantLoad returns true if the instruction loads a constant of the
|
||||
// given size.
|
||||
func (ins *Instruction) IsConstantLoad(size Size) bool {
|
||||
|
65
src/runtime/vendor/github.com/cilium/ebpf/attachtype_string.go
generated
vendored
Normal file
65
src/runtime/vendor/github.com/cilium/ebpf/attachtype_string.go
generated
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
// Code generated by "stringer -type AttachType -trimprefix Attach"; DO NOT EDIT.
|
||||
|
||||
package ebpf
|
||||
|
||||
import "strconv"
|
||||
|
||||
func _() {
|
||||
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||
// Re-run the stringer command to generate them again.
|
||||
var x [1]struct{}
|
||||
_ = x[AttachNone-0]
|
||||
_ = x[AttachCGroupInetIngress-0]
|
||||
_ = x[AttachCGroupInetEgress-1]
|
||||
_ = x[AttachCGroupInetSockCreate-2]
|
||||
_ = x[AttachCGroupSockOps-3]
|
||||
_ = x[AttachSkSKBStreamParser-4]
|
||||
_ = x[AttachSkSKBStreamVerdict-5]
|
||||
_ = x[AttachCGroupDevice-6]
|
||||
_ = x[AttachSkMsgVerdict-7]
|
||||
_ = x[AttachCGroupInet4Bind-8]
|
||||
_ = x[AttachCGroupInet6Bind-9]
|
||||
_ = x[AttachCGroupInet4Connect-10]
|
||||
_ = x[AttachCGroupInet6Connect-11]
|
||||
_ = x[AttachCGroupInet4PostBind-12]
|
||||
_ = x[AttachCGroupInet6PostBind-13]
|
||||
_ = x[AttachCGroupUDP4Sendmsg-14]
|
||||
_ = x[AttachCGroupUDP6Sendmsg-15]
|
||||
_ = x[AttachLircMode2-16]
|
||||
_ = x[AttachFlowDissector-17]
|
||||
_ = x[AttachCGroupSysctl-18]
|
||||
_ = x[AttachCGroupUDP4Recvmsg-19]
|
||||
_ = x[AttachCGroupUDP6Recvmsg-20]
|
||||
_ = x[AttachCGroupGetsockopt-21]
|
||||
_ = x[AttachCGroupSetsockopt-22]
|
||||
_ = x[AttachTraceRawTp-23]
|
||||
_ = x[AttachTraceFEntry-24]
|
||||
_ = x[AttachTraceFExit-25]
|
||||
_ = x[AttachModifyReturn-26]
|
||||
_ = x[AttachLSMMac-27]
|
||||
_ = x[AttachTraceIter-28]
|
||||
_ = x[AttachCgroupInet4GetPeername-29]
|
||||
_ = x[AttachCgroupInet6GetPeername-30]
|
||||
_ = x[AttachCgroupInet4GetSockname-31]
|
||||
_ = x[AttachCgroupInet6GetSockname-32]
|
||||
_ = x[AttachXDPDevMap-33]
|
||||
_ = x[AttachCgroupInetSockRelease-34]
|
||||
_ = x[AttachXDPCPUMap-35]
|
||||
_ = x[AttachSkLookup-36]
|
||||
_ = x[AttachXDP-37]
|
||||
_ = x[AttachSkSKBVerdict-38]
|
||||
_ = x[AttachSkReuseportSelect-39]
|
||||
_ = x[AttachSkReuseportSelectOrMigrate-40]
|
||||
_ = x[AttachPerfEvent-41]
|
||||
}
|
||||
|
||||
const _AttachType_name = "NoneCGroupInetEgressCGroupInetSockCreateCGroupSockOpsSkSKBStreamParserSkSKBStreamVerdictCGroupDeviceSkMsgVerdictCGroupInet4BindCGroupInet6BindCGroupInet4ConnectCGroupInet6ConnectCGroupInet4PostBindCGroupInet6PostBindCGroupUDP4SendmsgCGroupUDP6SendmsgLircMode2FlowDissectorCGroupSysctlCGroupUDP4RecvmsgCGroupUDP6RecvmsgCGroupGetsockoptCGroupSetsockoptTraceRawTpTraceFEntryTraceFExitModifyReturnLSMMacTraceIterCgroupInet4GetPeernameCgroupInet6GetPeernameCgroupInet4GetSocknameCgroupInet6GetSocknameXDPDevMapCgroupInetSockReleaseXDPCPUMapSkLookupXDPSkSKBVerdictSkReuseportSelectSkReuseportSelectOrMigratePerfEvent"
|
||||
|
||||
var _AttachType_index = [...]uint16{0, 4, 20, 40, 53, 70, 88, 100, 112, 127, 142, 160, 178, 197, 216, 233, 250, 259, 272, 284, 301, 318, 334, 350, 360, 371, 381, 393, 399, 408, 430, 452, 474, 496, 505, 526, 535, 543, 546, 558, 575, 601, 610}
|
||||
|
||||
func (i AttachType) String() string {
|
||||
if i >= AttachType(len(_AttachType_index)-1) {
|
||||
return "AttachType(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
return _AttachType_name[_AttachType_index[i]:_AttachType_index[i+1]]
|
||||
}
|
532
src/runtime/vendor/github.com/cilium/ebpf/collection.go
generated
vendored
532
src/runtime/vendor/github.com/cilium/ebpf/collection.go
generated
vendored
@ -1,6 +1,7 @@
|
||||
package ebpf
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
@ -25,6 +26,10 @@ type CollectionOptions struct {
|
||||
type CollectionSpec struct {
|
||||
Maps map[string]*MapSpec
|
||||
Programs map[string]*ProgramSpec
|
||||
|
||||
// ByteOrder specifies whether the ELF was compiled for
|
||||
// big-endian or little-endian architectures.
|
||||
ByteOrder binary.ByteOrder
|
||||
}
|
||||
|
||||
// Copy returns a recursive copy of the spec.
|
||||
@ -34,8 +39,9 @@ func (cs *CollectionSpec) Copy() *CollectionSpec {
|
||||
}
|
||||
|
||||
cpy := CollectionSpec{
|
||||
Maps: make(map[string]*MapSpec, len(cs.Maps)),
|
||||
Programs: make(map[string]*ProgramSpec, len(cs.Programs)),
|
||||
Maps: make(map[string]*MapSpec, len(cs.Maps)),
|
||||
Programs: make(map[string]*ProgramSpec, len(cs.Programs)),
|
||||
ByteOrder: cs.ByteOrder,
|
||||
}
|
||||
|
||||
for name, spec := range cs.Maps {
|
||||
@ -123,7 +129,7 @@ func (cs *CollectionSpec) RewriteConstants(consts map[string]interface{}) error
|
||||
buf := make([]byte, len(value))
|
||||
copy(buf, value)
|
||||
|
||||
err := patchValue(buf, btf.MapValue(rodata.BTF), consts)
|
||||
err := patchValue(buf, rodata.BTF.Value, consts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -134,15 +140,15 @@ func (cs *CollectionSpec) RewriteConstants(consts map[string]interface{}) error
|
||||
|
||||
// Assign the contents of a CollectionSpec to a struct.
|
||||
//
|
||||
// This function is a short-cut to manually checking the presence
|
||||
// of maps and programs in a collection spec. Consider using bpf2go if this
|
||||
// sounds useful.
|
||||
// This function is a shortcut to manually checking the presence
|
||||
// of maps and programs in a CollectionSpec. Consider using bpf2go
|
||||
// if this sounds useful.
|
||||
//
|
||||
// The argument to must be a pointer to a struct. A field of the
|
||||
// 'to' must be a pointer to a struct. A field of the
|
||||
// struct is updated with values from Programs or Maps if it
|
||||
// has an `ebpf` tag and its type is *ProgramSpec or *MapSpec.
|
||||
// The tag gives the name of the program or map as found in
|
||||
// the CollectionSpec.
|
||||
// The tag's value specifies the name of the program or map as
|
||||
// found in the CollectionSpec.
|
||||
//
|
||||
// struct {
|
||||
// Foo *ebpf.ProgramSpec `ebpf:"xdp_foo"`
|
||||
@ -150,42 +156,47 @@ func (cs *CollectionSpec) RewriteConstants(consts map[string]interface{}) error
|
||||
// Ignored int
|
||||
// }
|
||||
//
|
||||
// Returns an error if any of the fields can't be found, or
|
||||
// if the same map or program is assigned multiple times.
|
||||
// Returns an error if any of the eBPF objects can't be found, or
|
||||
// if the same MapSpec or ProgramSpec is assigned multiple times.
|
||||
func (cs *CollectionSpec) Assign(to interface{}) error {
|
||||
valueOf := func(typ reflect.Type, name string) (reflect.Value, error) {
|
||||
// Assign() only supports assigning ProgramSpecs and MapSpecs,
|
||||
// so doesn't load any resources into the kernel.
|
||||
getValue := func(typ reflect.Type, name string) (interface{}, error) {
|
||||
switch typ {
|
||||
|
||||
case reflect.TypeOf((*ProgramSpec)(nil)):
|
||||
p := cs.Programs[name]
|
||||
if p == nil {
|
||||
return reflect.Value{}, fmt.Errorf("missing program %q", name)
|
||||
if p := cs.Programs[name]; p != nil {
|
||||
return p, nil
|
||||
}
|
||||
return reflect.ValueOf(p), nil
|
||||
return nil, fmt.Errorf("missing program %q", name)
|
||||
|
||||
case reflect.TypeOf((*MapSpec)(nil)):
|
||||
m := cs.Maps[name]
|
||||
if m == nil {
|
||||
return reflect.Value{}, fmt.Errorf("missing map %q", name)
|
||||
if m := cs.Maps[name]; m != nil {
|
||||
return m, nil
|
||||
}
|
||||
return reflect.ValueOf(m), nil
|
||||
return nil, fmt.Errorf("missing map %q", name)
|
||||
|
||||
default:
|
||||
return reflect.Value{}, fmt.Errorf("unsupported type %s", typ)
|
||||
return nil, fmt.Errorf("unsupported type %s", typ)
|
||||
}
|
||||
}
|
||||
|
||||
return assignValues(to, valueOf)
|
||||
return assignValues(to, getValue)
|
||||
}
|
||||
|
||||
// LoadAndAssign maps and programs into the kernel and assign them to a struct.
|
||||
// LoadAndAssign loads Maps and Programs into the kernel and assigns them
|
||||
// to a struct.
|
||||
//
|
||||
// This function is a short-cut to manually checking the presence
|
||||
// of maps and programs in a collection spec. Consider using bpf2go if this
|
||||
// sounds useful.
|
||||
// This function is a shortcut to manually checking the presence
|
||||
// of maps and programs in a CollectionSpec. Consider using bpf2go
|
||||
// if this sounds useful.
|
||||
//
|
||||
// The argument to must be a pointer to a struct. A field of the
|
||||
// struct is updated with values from Programs or Maps if it
|
||||
// has an `ebpf` tag and its type is *Program or *Map.
|
||||
// The tag gives the name of the program or map as found in
|
||||
// the CollectionSpec.
|
||||
// 'to' must be a pointer to a struct. A field of the struct is updated with
|
||||
// a Program or Map if it has an `ebpf` tag and its type is *Program or *Map.
|
||||
// The tag's value specifies the name of the program or map as found in the
|
||||
// CollectionSpec. Before updating the struct, the requested objects and their
|
||||
// dependent resources are loaded into the kernel and populated with values if
|
||||
// specified.
|
||||
//
|
||||
// struct {
|
||||
// Foo *ebpf.Program `ebpf:"xdp_foo"`
|
||||
@ -196,39 +207,53 @@ func (cs *CollectionSpec) Assign(to interface{}) error {
|
||||
// opts may be nil.
|
||||
//
|
||||
// Returns an error if any of the fields can't be found, or
|
||||
// if the same map or program is assigned multiple times.
|
||||
// if the same Map or Program is assigned multiple times.
|
||||
func (cs *CollectionSpec) LoadAndAssign(to interface{}, opts *CollectionOptions) error {
|
||||
if opts == nil {
|
||||
opts = &CollectionOptions{}
|
||||
}
|
||||
loader := newCollectionLoader(cs, opts)
|
||||
defer loader.cleanup()
|
||||
|
||||
loadMap, loadProgram, done, cleanup := lazyLoadCollection(cs, opts)
|
||||
defer cleanup()
|
||||
|
||||
valueOf := func(typ reflect.Type, name string) (reflect.Value, error) {
|
||||
// Support assigning Programs and Maps, lazy-loading the required objects.
|
||||
assignedMaps := make(map[string]bool)
|
||||
getValue := func(typ reflect.Type, name string) (interface{}, error) {
|
||||
switch typ {
|
||||
|
||||
case reflect.TypeOf((*Program)(nil)):
|
||||
p, err := loadProgram(name)
|
||||
if err != nil {
|
||||
return reflect.Value{}, err
|
||||
}
|
||||
return reflect.ValueOf(p), nil
|
||||
return loader.loadProgram(name)
|
||||
|
||||
case reflect.TypeOf((*Map)(nil)):
|
||||
m, err := loadMap(name)
|
||||
if err != nil {
|
||||
return reflect.Value{}, err
|
||||
}
|
||||
return reflect.ValueOf(m), nil
|
||||
assignedMaps[name] = true
|
||||
return loader.loadMap(name)
|
||||
|
||||
default:
|
||||
return reflect.Value{}, fmt.Errorf("unsupported type %s", typ)
|
||||
return nil, fmt.Errorf("unsupported type %s", typ)
|
||||
}
|
||||
}
|
||||
|
||||
if err := assignValues(to, valueOf); err != nil {
|
||||
// Load the Maps and Programs requested by the annotated struct.
|
||||
if err := assignValues(to, getValue); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
done()
|
||||
// Populate the requested maps. Has a chance of lazy-loading other dependent maps.
|
||||
if err := loader.populateMaps(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Evaluate the loader's objects after all (lazy)loading has taken place.
|
||||
for n, m := range loader.maps {
|
||||
switch m.typ {
|
||||
case ProgramArray:
|
||||
// Require all lazy-loaded ProgramArrays to be assigned to the given object.
|
||||
// Without any references, they will be closed on the first GC and all tail
|
||||
// calls into them will miss.
|
||||
if !assignedMaps[n] {
|
||||
return fmt.Errorf("ProgramArray %s must be assigned to prevent missed tail calls", n)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
loader.finalize()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -246,24 +271,32 @@ func NewCollection(spec *CollectionSpec) (*Collection, error) {
|
||||
|
||||
// NewCollectionWithOptions creates a Collection from a specification.
|
||||
func NewCollectionWithOptions(spec *CollectionSpec, opts CollectionOptions) (*Collection, error) {
|
||||
loadMap, loadProgram, done, cleanup := lazyLoadCollection(spec, &opts)
|
||||
defer cleanup()
|
||||
loader := newCollectionLoader(spec, &opts)
|
||||
defer loader.cleanup()
|
||||
|
||||
// Create maps first, as their fds need to be linked into programs.
|
||||
for mapName := range spec.Maps {
|
||||
_, err := loadMap(mapName)
|
||||
if err != nil {
|
||||
if _, err := loader.loadMap(mapName); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
for progName := range spec.Programs {
|
||||
_, err := loadProgram(progName)
|
||||
if err != nil {
|
||||
if _, err := loader.loadProgram(progName); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
maps, progs := done()
|
||||
// Maps can contain Program and Map stubs, so populate them after
|
||||
// all Maps and Programs have been successfully loaded.
|
||||
if err := loader.populateMaps(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
maps, progs := loader.maps, loader.programs
|
||||
|
||||
loader.finalize()
|
||||
|
||||
return &Collection{
|
||||
progs,
|
||||
maps,
|
||||
@ -314,113 +347,154 @@ func (hc handleCache) close() {
|
||||
for _, handle := range hc.btfHandles {
|
||||
handle.Close()
|
||||
}
|
||||
hc.btfHandles = nil
|
||||
hc.btfSpecs = nil
|
||||
}
|
||||
|
||||
func lazyLoadCollection(coll *CollectionSpec, opts *CollectionOptions) (
|
||||
loadMap func(string) (*Map, error),
|
||||
loadProgram func(string) (*Program, error),
|
||||
done func() (map[string]*Map, map[string]*Program),
|
||||
cleanup func(),
|
||||
) {
|
||||
var (
|
||||
maps = make(map[string]*Map)
|
||||
progs = make(map[string]*Program)
|
||||
handles = newHandleCache()
|
||||
skipMapsAndProgs = false
|
||||
)
|
||||
type collectionLoader struct {
|
||||
coll *CollectionSpec
|
||||
opts *CollectionOptions
|
||||
maps map[string]*Map
|
||||
programs map[string]*Program
|
||||
handles *handleCache
|
||||
}
|
||||
|
||||
cleanup = func() {
|
||||
handles.close()
|
||||
|
||||
if skipMapsAndProgs {
|
||||
return
|
||||
}
|
||||
|
||||
for _, m := range maps {
|
||||
m.Close()
|
||||
}
|
||||
|
||||
for _, p := range progs {
|
||||
p.Close()
|
||||
}
|
||||
func newCollectionLoader(coll *CollectionSpec, opts *CollectionOptions) *collectionLoader {
|
||||
if opts == nil {
|
||||
opts = &CollectionOptions{}
|
||||
}
|
||||
|
||||
done = func() (map[string]*Map, map[string]*Program) {
|
||||
skipMapsAndProgs = true
|
||||
return maps, progs
|
||||
return &collectionLoader{
|
||||
coll,
|
||||
opts,
|
||||
make(map[string]*Map),
|
||||
make(map[string]*Program),
|
||||
newHandleCache(),
|
||||
}
|
||||
}
|
||||
|
||||
loadMap = func(mapName string) (*Map, error) {
|
||||
if m := maps[mapName]; m != nil {
|
||||
return m, nil
|
||||
}
|
||||
// finalize should be called when all the collectionLoader's resources
|
||||
// have been successfully loaded into the kernel and populated with values.
|
||||
func (cl *collectionLoader) finalize() {
|
||||
cl.maps, cl.programs = nil, nil
|
||||
}
|
||||
|
||||
mapSpec := coll.Maps[mapName]
|
||||
if mapSpec == nil {
|
||||
return nil, fmt.Errorf("missing map %s", mapName)
|
||||
}
|
||||
// cleanup cleans up all resources left over in the collectionLoader.
|
||||
// Call finalize() when Map and Program creation/population is successful
|
||||
// to prevent them from getting closed.
|
||||
func (cl *collectionLoader) cleanup() {
|
||||
cl.handles.close()
|
||||
for _, m := range cl.maps {
|
||||
m.Close()
|
||||
}
|
||||
for _, p := range cl.programs {
|
||||
p.Close()
|
||||
}
|
||||
}
|
||||
|
||||
m, err := newMapWithOptions(mapSpec, opts.Maps, handles)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("map %s: %w", mapName, err)
|
||||
}
|
||||
|
||||
maps[mapName] = m
|
||||
func (cl *collectionLoader) loadMap(mapName string) (*Map, error) {
|
||||
if m := cl.maps[mapName]; m != nil {
|
||||
return m, nil
|
||||
}
|
||||
|
||||
loadProgram = func(progName string) (*Program, error) {
|
||||
if prog := progs[progName]; prog != nil {
|
||||
return prog, nil
|
||||
mapSpec := cl.coll.Maps[mapName]
|
||||
if mapSpec == nil {
|
||||
return nil, fmt.Errorf("missing map %s", mapName)
|
||||
}
|
||||
|
||||
m, err := newMapWithOptions(mapSpec, cl.opts.Maps, cl.handles)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("map %s: %w", mapName, err)
|
||||
}
|
||||
|
||||
cl.maps[mapName] = m
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (cl *collectionLoader) loadProgram(progName string) (*Program, error) {
|
||||
if prog := cl.programs[progName]; prog != nil {
|
||||
return prog, nil
|
||||
}
|
||||
|
||||
progSpec := cl.coll.Programs[progName]
|
||||
if progSpec == nil {
|
||||
return nil, fmt.Errorf("unknown program %s", progName)
|
||||
}
|
||||
|
||||
progSpec = progSpec.Copy()
|
||||
|
||||
// Rewrite any reference to a valid map.
|
||||
for i := range progSpec.Instructions {
|
||||
ins := &progSpec.Instructions[i]
|
||||
|
||||
if !ins.IsLoadFromMap() || ins.Reference == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
progSpec := coll.Programs[progName]
|
||||
if progSpec == nil {
|
||||
return nil, fmt.Errorf("unknown program %s", progName)
|
||||
if uint32(ins.Constant) != math.MaxUint32 {
|
||||
// Don't overwrite maps already rewritten, users can
|
||||
// rewrite programs in the spec themselves
|
||||
continue
|
||||
}
|
||||
|
||||
progSpec = progSpec.Copy()
|
||||
|
||||
// Rewrite any reference to a valid map.
|
||||
for i := range progSpec.Instructions {
|
||||
ins := &progSpec.Instructions[i]
|
||||
|
||||
if !ins.IsLoadFromMap() || ins.Reference == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
if uint32(ins.Constant) != math.MaxUint32 {
|
||||
// Don't overwrite maps already rewritten, users can
|
||||
// rewrite programs in the spec themselves
|
||||
continue
|
||||
}
|
||||
|
||||
m, err := loadMap(ins.Reference)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("program %s: %w", progName, err)
|
||||
}
|
||||
|
||||
fd := m.FD()
|
||||
if fd < 0 {
|
||||
return nil, fmt.Errorf("map %s: %w", ins.Reference, internal.ErrClosedFd)
|
||||
}
|
||||
if err := ins.RewriteMapPtr(m.FD()); err != nil {
|
||||
return nil, fmt.Errorf("progam %s: map %s: %w", progName, ins.Reference, err)
|
||||
}
|
||||
}
|
||||
|
||||
prog, err := newProgramWithOptions(progSpec, opts.Programs, handles)
|
||||
m, err := cl.loadMap(ins.Reference)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("program %s: %w", progName, err)
|
||||
}
|
||||
|
||||
progs[progName] = prog
|
||||
return prog, nil
|
||||
fd := m.FD()
|
||||
if fd < 0 {
|
||||
return nil, fmt.Errorf("map %s: %w", ins.Reference, internal.ErrClosedFd)
|
||||
}
|
||||
if err := ins.RewriteMapPtr(m.FD()); err != nil {
|
||||
return nil, fmt.Errorf("program %s: map %s: %w", progName, ins.Reference, err)
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
prog, err := newProgramWithOptions(progSpec, cl.opts.Programs, cl.handles)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("program %s: %w", progName, err)
|
||||
}
|
||||
|
||||
cl.programs[progName] = prog
|
||||
return prog, nil
|
||||
}
|
||||
|
||||
func (cl *collectionLoader) populateMaps() error {
|
||||
for mapName, m := range cl.maps {
|
||||
mapSpec, ok := cl.coll.Maps[mapName]
|
||||
if !ok {
|
||||
return fmt.Errorf("missing map spec %s", mapName)
|
||||
}
|
||||
|
||||
mapSpec = mapSpec.Copy()
|
||||
|
||||
// Replace any object stubs with loaded objects.
|
||||
for i, kv := range mapSpec.Contents {
|
||||
switch v := kv.Value.(type) {
|
||||
case programStub:
|
||||
// loadProgram is idempotent and could return an existing Program.
|
||||
prog, err := cl.loadProgram(string(v))
|
||||
if err != nil {
|
||||
return fmt.Errorf("loading program %s, for map %s: %w", v, mapName, err)
|
||||
}
|
||||
mapSpec.Contents[i] = MapKV{kv.Key, prog}
|
||||
|
||||
case mapStub:
|
||||
// loadMap is idempotent and could return an existing Map.
|
||||
innerMap, err := cl.loadMap(string(v))
|
||||
if err != nil {
|
||||
return fmt.Errorf("loading inner map %s, for map %s: %w", v, mapName, err)
|
||||
}
|
||||
mapSpec.Contents[i] = MapKV{kv.Key, innerMap}
|
||||
}
|
||||
}
|
||||
|
||||
// Populate and freeze the map if specified.
|
||||
if err := m.finalize(mapSpec); err != nil {
|
||||
return fmt.Errorf("populating map %s: %w", mapName, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// LoadCollection parses an object file and converts it to a collection.
|
||||
@ -466,108 +540,81 @@ func (coll *Collection) DetachProgram(name string) *Program {
|
||||
return p
|
||||
}
|
||||
|
||||
// Assign the contents of a collection to a struct.
|
||||
//
|
||||
// Deprecated: use CollectionSpec.Assign instead. It provides the same
|
||||
// functionality but creates only the maps and programs requested.
|
||||
func (coll *Collection) Assign(to interface{}) error {
|
||||
assignedMaps := make(map[string]struct{})
|
||||
assignedPrograms := make(map[string]struct{})
|
||||
valueOf := func(typ reflect.Type, name string) (reflect.Value, error) {
|
||||
switch typ {
|
||||
case reflect.TypeOf((*Program)(nil)):
|
||||
p := coll.Programs[name]
|
||||
if p == nil {
|
||||
return reflect.Value{}, fmt.Errorf("missing program %q", name)
|
||||
}
|
||||
assignedPrograms[name] = struct{}{}
|
||||
return reflect.ValueOf(p), nil
|
||||
case reflect.TypeOf((*Map)(nil)):
|
||||
m := coll.Maps[name]
|
||||
if m == nil {
|
||||
return reflect.Value{}, fmt.Errorf("missing map %q", name)
|
||||
}
|
||||
assignedMaps[name] = struct{}{}
|
||||
return reflect.ValueOf(m), nil
|
||||
default:
|
||||
return reflect.Value{}, fmt.Errorf("unsupported type %s", typ)
|
||||
}
|
||||
}
|
||||
|
||||
if err := assignValues(to, valueOf); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for name := range assignedPrograms {
|
||||
coll.DetachProgram(name)
|
||||
}
|
||||
|
||||
for name := range assignedMaps {
|
||||
coll.DetachMap(name)
|
||||
}
|
||||
|
||||
return nil
|
||||
// structField represents a struct field containing the ebpf struct tag.
|
||||
type structField struct {
|
||||
reflect.StructField
|
||||
value reflect.Value
|
||||
}
|
||||
|
||||
func assignValues(to interface{}, valueOf func(reflect.Type, string) (reflect.Value, error)) error {
|
||||
type structField struct {
|
||||
reflect.StructField
|
||||
value reflect.Value
|
||||
// ebpfFields extracts field names tagged with 'ebpf' from a struct type.
|
||||
// Keep track of visited types to avoid infinite recursion.
|
||||
func ebpfFields(structVal reflect.Value, visited map[reflect.Type]bool) ([]structField, error) {
|
||||
if visited == nil {
|
||||
visited = make(map[reflect.Type]bool)
|
||||
}
|
||||
|
||||
var (
|
||||
fields []structField
|
||||
visitedTypes = make(map[reflect.Type]bool)
|
||||
flattenStruct func(reflect.Value) error
|
||||
)
|
||||
structType := structVal.Type()
|
||||
if structType.Kind() != reflect.Struct {
|
||||
return nil, fmt.Errorf("%s is not a struct", structType)
|
||||
}
|
||||
|
||||
flattenStruct = func(structVal reflect.Value) error {
|
||||
structType := structVal.Type()
|
||||
if structType.Kind() != reflect.Struct {
|
||||
return fmt.Errorf("%s is not a struct", structType)
|
||||
if visited[structType] {
|
||||
return nil, fmt.Errorf("recursion on type %s", structType)
|
||||
}
|
||||
|
||||
fields := make([]structField, 0, structType.NumField())
|
||||
for i := 0; i < structType.NumField(); i++ {
|
||||
field := structField{structType.Field(i), structVal.Field(i)}
|
||||
|
||||
// If the field is tagged, gather it and move on.
|
||||
name := field.Tag.Get("ebpf")
|
||||
if name != "" {
|
||||
fields = append(fields, field)
|
||||
continue
|
||||
}
|
||||
|
||||
if visitedTypes[structType] {
|
||||
return fmt.Errorf("recursion on type %s", structType)
|
||||
}
|
||||
|
||||
for i := 0; i < structType.NumField(); i++ {
|
||||
field := structField{structType.Field(i), structVal.Field(i)}
|
||||
|
||||
name := field.Tag.Get("ebpf")
|
||||
if name != "" {
|
||||
fields = append(fields, field)
|
||||
// If the field does not have an ebpf tag, but is a struct or a pointer
|
||||
// to a struct, attempt to gather its fields as well.
|
||||
var v reflect.Value
|
||||
switch field.Type.Kind() {
|
||||
case reflect.Ptr:
|
||||
if field.Type.Elem().Kind() != reflect.Struct {
|
||||
continue
|
||||
}
|
||||
|
||||
var err error
|
||||
switch field.Type.Kind() {
|
||||
case reflect.Ptr:
|
||||
if field.Type.Elem().Kind() != reflect.Struct {
|
||||
continue
|
||||
}
|
||||
|
||||
if field.value.IsNil() {
|
||||
return fmt.Errorf("nil pointer to %s", structType)
|
||||
}
|
||||
|
||||
err = flattenStruct(field.value.Elem())
|
||||
|
||||
case reflect.Struct:
|
||||
err = flattenStruct(field.value)
|
||||
|
||||
default:
|
||||
continue
|
||||
if field.value.IsNil() {
|
||||
return nil, fmt.Errorf("nil pointer to %s", structType)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("field %s: %w", field.Name, err)
|
||||
}
|
||||
// Obtain the destination type of the pointer.
|
||||
v = field.value.Elem()
|
||||
|
||||
case reflect.Struct:
|
||||
// Reference the value's type directly.
|
||||
v = field.value
|
||||
|
||||
default:
|
||||
continue
|
||||
}
|
||||
|
||||
return nil
|
||||
inner, err := ebpfFields(v, visited)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("field %s: %w", field.Name, err)
|
||||
}
|
||||
|
||||
fields = append(fields, inner...)
|
||||
}
|
||||
|
||||
return fields, nil
|
||||
}
|
||||
|
||||
// assignValues attempts to populate all fields of 'to' tagged with 'ebpf'.
|
||||
//
|
||||
// getValue is called for every tagged field of 'to' and must return the value
|
||||
// to be assigned to the field with the given typ and name.
|
||||
func assignValues(to interface{},
|
||||
getValue func(typ reflect.Type, name string) (interface{}, error)) error {
|
||||
|
||||
toValue := reflect.ValueOf(to)
|
||||
if toValue.Type().Kind() != reflect.Ptr {
|
||||
return fmt.Errorf("%T is not a pointer to struct", to)
|
||||
@ -577,7 +624,8 @@ func assignValues(to interface{}, valueOf func(reflect.Type, string) (reflect.Va
|
||||
return fmt.Errorf("nil pointer to %T", to)
|
||||
}
|
||||
|
||||
if err := flattenStruct(toValue.Elem()); err != nil {
|
||||
fields, err := ebpfFields(toValue.Elem(), nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -587,19 +635,23 @@ func assignValues(to interface{}, valueOf func(reflect.Type, string) (reflect.Va
|
||||
name string
|
||||
}
|
||||
|
||||
assignedTo := make(map[elem]string)
|
||||
assigned := make(map[elem]string)
|
||||
for _, field := range fields {
|
||||
name := field.Tag.Get("ebpf")
|
||||
if strings.Contains(name, ",") {
|
||||
// Get string value the field is tagged with.
|
||||
tag := field.Tag.Get("ebpf")
|
||||
if strings.Contains(tag, ",") {
|
||||
return fmt.Errorf("field %s: ebpf tag contains a comma", field.Name)
|
||||
}
|
||||
|
||||
e := elem{field.Type, name}
|
||||
if assignedField := assignedTo[e]; assignedField != "" {
|
||||
return fmt.Errorf("field %s: %q was already assigned to %s", field.Name, name, assignedField)
|
||||
// Check if the eBPF object with the requested
|
||||
// type and tag was already assigned elsewhere.
|
||||
e := elem{field.Type, tag}
|
||||
if af := assigned[e]; af != "" {
|
||||
return fmt.Errorf("field %s: object %q was already assigned to %s", field.Name, tag, af)
|
||||
}
|
||||
|
||||
value, err := valueOf(field.Type, name)
|
||||
// Get the eBPF object referred to by the tag.
|
||||
value, err := getValue(field.Type, tag)
|
||||
if err != nil {
|
||||
return fmt.Errorf("field %s: %w", field.Name, err)
|
||||
}
|
||||
@ -607,9 +659,9 @@ func assignValues(to interface{}, valueOf func(reflect.Type, string) (reflect.Va
|
||||
if !field.value.CanSet() {
|
||||
return fmt.Errorf("field %s: can't set value", field.Name)
|
||||
}
|
||||
field.value.Set(reflect.ValueOf(value))
|
||||
|
||||
field.value.Set(value)
|
||||
assignedTo[e] = field.Name
|
||||
assigned[e] = field.Name
|
||||
}
|
||||
|
||||
return nil
|
||||
|
180
src/runtime/vendor/github.com/cilium/ebpf/elf_reader.go
generated
vendored
180
src/runtime/vendor/github.com/cilium/ebpf/elf_reader.go
generated
vendored
@ -19,7 +19,7 @@ import (
|
||||
)
|
||||
|
||||
// elfCode is a convenience to reduce the amount of arguments that have to
|
||||
// be passed around explicitly. You should treat it's contents as immutable.
|
||||
// be passed around explicitly. You should treat its contents as immutable.
|
||||
type elfCode struct {
|
||||
*internal.SafeELFFile
|
||||
sections map[elf.SectionIndex]*elfSection
|
||||
@ -188,7 +188,7 @@ func LoadCollectionSpecFromReader(rd io.ReaderAt) (*CollectionSpec, error) {
|
||||
return nil, fmt.Errorf("load programs: %w", err)
|
||||
}
|
||||
|
||||
return &CollectionSpec{maps, progs}, nil
|
||||
return &CollectionSpec{maps, progs, ec.ByteOrder}, nil
|
||||
}
|
||||
|
||||
func loadLicense(sec *elf.Section) (string, error) {
|
||||
@ -520,8 +520,12 @@ func (ec *elfCode) loadMaps(maps map[string]*MapSpec) error {
|
||||
return fmt.Errorf("map %s: missing flags", mapName)
|
||||
}
|
||||
|
||||
if _, err := io.Copy(internal.DiscardZeroes{}, lr); err != nil {
|
||||
return fmt.Errorf("map %s: unknown and non-zero fields in definition", mapName)
|
||||
extra, err := io.ReadAll(lr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("map %s: reading map tail: %w", mapName, err)
|
||||
}
|
||||
if len(extra) > 0 {
|
||||
spec.Extra = *bytes.NewReader(extra)
|
||||
}
|
||||
|
||||
if err := spec.clampPerfEventArraySize(); err != nil {
|
||||
@ -535,6 +539,9 @@ func (ec *elfCode) loadMaps(maps map[string]*MapSpec) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// loadBTFMaps iterates over all ELF sections marked as BTF map sections
|
||||
// (like .maps) and parses them into MapSpecs. Dump the .maps section and
|
||||
// any relocations with `readelf -x .maps -r <elf_file>`.
|
||||
func (ec *elfCode) loadBTFMaps(maps map[string]*MapSpec) error {
|
||||
for _, sec := range ec.sections {
|
||||
if sec.kind != btfMapSection {
|
||||
@ -545,33 +552,46 @@ func (ec *elfCode) loadBTFMaps(maps map[string]*MapSpec) error {
|
||||
return fmt.Errorf("missing BTF")
|
||||
}
|
||||
|
||||
_, err := io.Copy(internal.DiscardZeroes{}, bufio.NewReader(sec.Open()))
|
||||
if err != nil {
|
||||
return fmt.Errorf("section %v: initializing BTF map definitions: %w", sec.Name, internal.ErrNotSupported)
|
||||
}
|
||||
|
||||
var ds btf.Datasec
|
||||
// Each section must appear as a DataSec in the ELF's BTF blob.
|
||||
var ds *btf.Datasec
|
||||
if err := ec.btf.FindType(sec.Name, &ds); err != nil {
|
||||
return fmt.Errorf("cannot find section '%s' in BTF: %w", sec.Name, err)
|
||||
}
|
||||
|
||||
// Open a Reader to the ELF's raw section bytes so we can assert that all
|
||||
// of them are zero on a per-map (per-Var) basis. For now, the section's
|
||||
// sole purpose is to receive relocations, so all must be zero.
|
||||
rs := sec.Open()
|
||||
|
||||
for _, vs := range ds.Vars {
|
||||
// BPF maps are declared as and assigned to global variables,
|
||||
// so iterate over each Var in the DataSec and validate their types.
|
||||
v, ok := vs.Type.(*btf.Var)
|
||||
if !ok {
|
||||
return fmt.Errorf("section %v: unexpected type %s", sec.Name, vs.Type)
|
||||
}
|
||||
name := string(v.Name)
|
||||
|
||||
// The BTF metadata for each Var contains the full length of the map
|
||||
// declaration, so read the corresponding amount of bytes from the ELF.
|
||||
// This way, we can pinpoint which map declaration contains unexpected
|
||||
// (and therefore unsupported) data.
|
||||
_, err := io.Copy(internal.DiscardZeroes{}, io.LimitReader(rs, int64(vs.Size)))
|
||||
if err != nil {
|
||||
return fmt.Errorf("section %v: map %s: initializing BTF map definitions: %w", sec.Name, name, internal.ErrNotSupported)
|
||||
}
|
||||
|
||||
if maps[name] != nil {
|
||||
return fmt.Errorf("section %v: map %s already exists", sec.Name, name)
|
||||
}
|
||||
|
||||
// Each Var representing a BTF map definition contains a Struct.
|
||||
mapStruct, ok := v.Type.(*btf.Struct)
|
||||
if !ok {
|
||||
return fmt.Errorf("expected struct, got %s", v.Type)
|
||||
}
|
||||
|
||||
mapSpec, err := mapSpecFromBTF(name, mapStruct, false, ec.btf)
|
||||
mapSpec, err := mapSpecFromBTF(sec, &vs, mapStruct, ec.btf, name, false)
|
||||
if err != nil {
|
||||
return fmt.Errorf("map %v: %w", name, err)
|
||||
}
|
||||
@ -582,32 +602,52 @@ func (ec *elfCode) loadBTFMaps(maps map[string]*MapSpec) error {
|
||||
|
||||
maps[name] = mapSpec
|
||||
}
|
||||
|
||||
// Drain the ELF section reader to make sure all bytes are accounted for
|
||||
// with BTF metadata.
|
||||
i, err := io.Copy(io.Discard, rs)
|
||||
if err != nil {
|
||||
return fmt.Errorf("section %v: unexpected error reading remainder of ELF section: %w", sec.Name, err)
|
||||
}
|
||||
if i > 0 {
|
||||
return fmt.Errorf("section %v: %d unexpected remaining bytes in ELF section, invalid BTF?", sec.Name, i)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// A programStub is a placeholder for a Program to be inserted at a certain map key.
|
||||
// It needs to be resolved into a Program later on in the loader process.
|
||||
type programStub string
|
||||
|
||||
// A mapStub is a placeholder for a Map to be inserted at a certain map key.
|
||||
// It needs to be resolved into a Map later on in the loader process.
|
||||
type mapStub string
|
||||
|
||||
// mapSpecFromBTF produces a MapSpec based on a btf.Struct def representing
|
||||
// a BTF map definition. The name and spec arguments will be copied to the
|
||||
// resulting MapSpec, and inner must be true on any resursive invocations.
|
||||
func mapSpecFromBTF(name string, def *btf.Struct, inner bool, spec *btf.Spec) (*MapSpec, error) {
|
||||
|
||||
func mapSpecFromBTF(es *elfSection, vs *btf.VarSecinfo, def *btf.Struct, spec *btf.Spec, name string, inner bool) (*MapSpec, error) {
|
||||
var (
|
||||
key, value btf.Type
|
||||
keySize, valueSize uint32
|
||||
mapType, flags, maxEntries uint32
|
||||
pinType PinType
|
||||
innerMapSpec *MapSpec
|
||||
err error
|
||||
key, value btf.Type
|
||||
keySize, valueSize uint32
|
||||
mapType MapType
|
||||
flags, maxEntries uint32
|
||||
pinType PinType
|
||||
innerMapSpec *MapSpec
|
||||
contents []MapKV
|
||||
err error
|
||||
)
|
||||
|
||||
for i, member := range def.Members {
|
||||
switch member.Name {
|
||||
case "type":
|
||||
mapType, err = uintFromBTF(member.Type)
|
||||
mt, err := uintFromBTF(member.Type)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't get type: %w", err)
|
||||
}
|
||||
mapType = MapType(mt)
|
||||
|
||||
case "map_flags":
|
||||
flags, err = uintFromBTF(member.Type)
|
||||
@ -717,7 +757,7 @@ func mapSpecFromBTF(name string, def *btf.Struct, inner bool, spec *btf.Spec) (*
|
||||
case *btf.Struct:
|
||||
// The values member pointing to an array of structs means we're expecting
|
||||
// a map-in-map declaration.
|
||||
if MapType(mapType) != ArrayOfMaps && MapType(mapType) != HashOfMaps {
|
||||
if mapType != ArrayOfMaps && mapType != HashOfMaps {
|
||||
return nil, errors.New("outer map needs to be an array or a hash of maps")
|
||||
}
|
||||
if inner {
|
||||
@ -731,21 +771,38 @@ func mapSpecFromBTF(name string, def *btf.Struct, inner bool, spec *btf.Spec) (*
|
||||
// on kernels 5.2 and up)
|
||||
// Pass the BTF spec from the parent object, since both parent and
|
||||
// child must be created from the same BTF blob (on kernels that support BTF).
|
||||
innerMapSpec, err = mapSpecFromBTF(name+"_inner", t, true, spec)
|
||||
innerMapSpec, err = mapSpecFromBTF(es, vs, t, spec, name+"_inner", true)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't parse BTF map definition of inner map: %w", err)
|
||||
}
|
||||
|
||||
case *btf.FuncProto:
|
||||
// The values member contains an array of function pointers, meaning an
|
||||
// autopopulated PROG_ARRAY.
|
||||
if mapType != ProgramArray {
|
||||
return nil, errors.New("map needs to be a program array")
|
||||
}
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported value type %q in 'values' field", t)
|
||||
}
|
||||
|
||||
contents, err = resolveBTFValuesContents(es, vs, member)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("resolving values contents: %w", err)
|
||||
}
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("unrecognized field %s in BTF map definition", member.Name)
|
||||
}
|
||||
}
|
||||
|
||||
bm := btf.NewMap(spec, key, value)
|
||||
if key == nil {
|
||||
key = &btf.Void{}
|
||||
}
|
||||
if value == nil {
|
||||
value = &btf.Void{}
|
||||
}
|
||||
|
||||
return &MapSpec{
|
||||
Name: SanitizeName(name, -1),
|
||||
@ -754,9 +811,10 @@ func mapSpecFromBTF(name string, def *btf.Struct, inner bool, spec *btf.Spec) (*
|
||||
ValueSize: valueSize,
|
||||
MaxEntries: maxEntries,
|
||||
Flags: flags,
|
||||
BTF: &bm,
|
||||
BTF: &btf.Map{Spec: spec, Key: key, Value: value},
|
||||
Pinning: pinType,
|
||||
InnerMap: innerMapSpec,
|
||||
Contents: contents,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -793,6 +851,64 @@ func resolveBTFArrayMacro(typ btf.Type) (btf.Type, error) {
|
||||
return ptr.Target, nil
|
||||
}
|
||||
|
||||
// resolveBTFValuesContents resolves relocations into ELF sections belonging
|
||||
// to btf.VarSecinfo's. This can be used on the 'values' member in BTF map
|
||||
// definitions to extract static declarations of map contents.
|
||||
func resolveBTFValuesContents(es *elfSection, vs *btf.VarSecinfo, member btf.Member) ([]MapKV, error) {
|
||||
// The elements of a .values pointer array are not encoded in BTF.
|
||||
// Instead, relocations are generated into each array index.
|
||||
// However, it's possible to leave certain array indices empty, so all
|
||||
// indices' offsets need to be checked for emitted relocations.
|
||||
|
||||
// The offset of the 'values' member within the _struct_ (in bits)
|
||||
// is the starting point of the array. Convert to bytes. Add VarSecinfo
|
||||
// offset to get the absolute position in the ELF blob.
|
||||
start := (member.OffsetBits / 8) + vs.Offset
|
||||
// 'values' is encoded in BTF as a zero (variable) length struct
|
||||
// member, and its contents run until the end of the VarSecinfo.
|
||||
// Add VarSecinfo offset to get the absolute position in the ELF blob.
|
||||
end := vs.Size + vs.Offset
|
||||
// The size of an address in this section. This determines the width of
|
||||
// an index in the array.
|
||||
align := uint32(es.SectionHeader.Addralign)
|
||||
|
||||
// Check if variable-length section is aligned.
|
||||
if (end-start)%align != 0 {
|
||||
return nil, errors.New("unaligned static values section")
|
||||
}
|
||||
elems := (end - start) / align
|
||||
|
||||
if elems == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
contents := make([]MapKV, 0, elems)
|
||||
|
||||
// k is the array index, off is its corresponding ELF section offset.
|
||||
for k, off := uint32(0), start; k < elems; k, off = k+1, off+align {
|
||||
r, ok := es.relocations[uint64(off)]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
// Relocation exists for the current offset in the ELF section.
|
||||
// Emit a value stub based on the type of relocation to be replaced by
|
||||
// a real fd later in the pipeline before populating the map.
|
||||
// Map keys are encoded in MapKV entries, so empty array indices are
|
||||
// skipped here.
|
||||
switch t := elf.ST_TYPE(r.Info); t {
|
||||
case elf.STT_FUNC:
|
||||
contents = append(contents, MapKV{uint32(k), programStub(r.Name)})
|
||||
case elf.STT_OBJECT:
|
||||
contents = append(contents, MapKV{uint32(k), mapStub(r.Name)})
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown relocation type %v", t)
|
||||
}
|
||||
}
|
||||
|
||||
return contents, nil
|
||||
}
|
||||
|
||||
func (ec *elfCode) loadDataSections(maps map[string]*MapSpec) error {
|
||||
for _, sec := range ec.sections {
|
||||
if sec.kind != dataSection {
|
||||
@ -809,9 +925,9 @@ func (ec *elfCode) loadDataSections(maps map[string]*MapSpec) error {
|
||||
return errors.New("data sections require BTF, make sure all consts are marked as static")
|
||||
}
|
||||
|
||||
btfMap, err := ec.btf.Datasec(sec.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
var datasec *btf.Datasec
|
||||
if err := ec.btf.FindType(sec.Name, &datasec); err != nil {
|
||||
return fmt.Errorf("data section %s: can't get BTF: %w", sec.Name, err)
|
||||
}
|
||||
|
||||
data, err := sec.Data()
|
||||
@ -830,7 +946,7 @@ func (ec *elfCode) loadDataSections(maps map[string]*MapSpec) error {
|
||||
ValueSize: uint32(len(data)),
|
||||
MaxEntries: 1,
|
||||
Contents: []MapKV{{uint32(0), data}},
|
||||
BTF: btfMap,
|
||||
BTF: &btf.Map{Spec: ec.btf, Key: &btf.Void{}, Value: datasec},
|
||||
}
|
||||
|
||||
switch sec.Name {
|
||||
@ -855,6 +971,8 @@ func getProgType(sectionName string) (ProgramType, AttachType, uint32, string) {
|
||||
}{
|
||||
// From https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tools/lib/bpf/libbpf.c
|
||||
"socket": {SocketFilter, AttachNone, 0},
|
||||
"sk_reuseport/migrate": {SkReuseport, AttachSkReuseportSelectOrMigrate, 0},
|
||||
"sk_reuseport": {SkReuseport, AttachSkReuseportSelect, 0},
|
||||
"seccomp": {SocketFilter, AttachNone, 0},
|
||||
"kprobe/": {Kprobe, AttachNone, 0},
|
||||
"uprobe/": {Kprobe, AttachNone, 0},
|
||||
@ -884,6 +1002,7 @@ func getProgType(sectionName string) (ProgramType, AttachType, uint32, string) {
|
||||
"fmod_ret.s/": {Tracing, AttachModifyReturn, unix.BPF_F_SLEEPABLE},
|
||||
"fexit.s/": {Tracing, AttachTraceFExit, unix.BPF_F_SLEEPABLE},
|
||||
"sk_lookup/": {SkLookup, AttachSkLookup, 0},
|
||||
"freplace/": {Extension, AttachNone, 0},
|
||||
"lsm/": {LSM, AttachLSMMac, 0},
|
||||
"lsm.s/": {LSM, AttachLSMMac, unix.BPF_F_SLEEPABLE},
|
||||
|
||||
@ -907,6 +1026,11 @@ func getProgType(sectionName string) (ProgramType, AttachType, uint32, string) {
|
||||
"cgroup/setsockopt": {CGroupSockopt, AttachCGroupSetsockopt, 0},
|
||||
"classifier": {SchedCLS, AttachNone, 0},
|
||||
"action": {SchedACT, AttachNone, 0},
|
||||
|
||||
"cgroup/getsockname4": {CGroupSockAddr, AttachCgroupInet4GetSockname, 0},
|
||||
"cgroup/getsockname6": {CGroupSockAddr, AttachCgroupInet6GetSockname, 0},
|
||||
"cgroup/getpeername4": {CGroupSockAddr, AttachCgroupInet4GetPeername, 0},
|
||||
"cgroup/getpeername6": {CGroupSockAddr, AttachCgroupInet6GetPeername, 0},
|
||||
}
|
||||
|
||||
for prefix, t := range types {
|
||||
|
1
src/runtime/vendor/github.com/cilium/ebpf/elf_reader_fuzz.go
generated
vendored
1
src/runtime/vendor/github.com/cilium/ebpf/elf_reader_fuzz.go
generated
vendored
@ -1,3 +1,4 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
// Use with https://github.com/dvyukov/go-fuzz
|
||||
|
4
src/runtime/vendor/github.com/cilium/ebpf/go.mod
generated
vendored
4
src/runtime/vendor/github.com/cilium/ebpf/go.mod
generated
vendored
@ -1,9 +1,9 @@
|
||||
module github.com/cilium/ebpf
|
||||
|
||||
go 1.15
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/frankban/quicktest v1.11.3
|
||||
github.com/google/go-cmp v0.5.4
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c
|
||||
golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34
|
||||
)
|
||||
|
4
src/runtime/vendor/github.com/cilium/ebpf/go.sum
generated
vendored
4
src/runtime/vendor/github.com/cilium/ebpf/go.sum
generated
vendored
@ -7,7 +7,7 @@ github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfn
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c h1:VwygUrnw9jn88c4u8GD3rZQbqrP/tgas88tPUbBxQrk=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34 h1:GkvMjFtXUmahfDtashnc1mnrCtuBVcwse5QV2lUk/tI=
|
||||
golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
36
src/runtime/vendor/github.com/cilium/ebpf/info.go
generated
vendored
36
src/runtime/vendor/github.com/cilium/ebpf/info.go
generated
vendored
@ -12,6 +12,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/cilium/ebpf/internal"
|
||||
"github.com/cilium/ebpf/internal/btf"
|
||||
)
|
||||
|
||||
// MapInfo describes a map.
|
||||
@ -87,12 +88,16 @@ type ProgramInfo struct {
|
||||
Tag string
|
||||
// Name as supplied by user space at load time.
|
||||
Name string
|
||||
// BTF for the program.
|
||||
btf btf.ID
|
||||
// IDS map ids related to program.
|
||||
ids []MapID
|
||||
|
||||
stats *programStats
|
||||
}
|
||||
|
||||
func newProgramInfoFromFd(fd *internal.FD) (*ProgramInfo, error) {
|
||||
info, err := bpfGetProgInfoByFD(fd)
|
||||
info, err := bpfGetProgInfoByFD(fd, nil)
|
||||
if errors.Is(err, syscall.EINVAL) {
|
||||
return newProgramInfoFromProc(fd)
|
||||
}
|
||||
@ -100,6 +105,15 @@ func newProgramInfoFromFd(fd *internal.FD) (*ProgramInfo, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var mapIDs []MapID
|
||||
if info.nr_map_ids > 0 {
|
||||
mapIDs = make([]MapID, info.nr_map_ids)
|
||||
info, err = bpfGetProgInfoByFD(fd, mapIDs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return &ProgramInfo{
|
||||
Type: ProgramType(info.prog_type),
|
||||
id: ProgramID(info.id),
|
||||
@ -107,6 +121,8 @@ func newProgramInfoFromFd(fd *internal.FD) (*ProgramInfo, error) {
|
||||
Tag: hex.EncodeToString(info.tag[:]),
|
||||
// name is available from 4.15.
|
||||
Name: internal.CString(info.name[:]),
|
||||
btf: btf.ID(info.btf_id),
|
||||
ids: mapIDs,
|
||||
stats: &programStats{
|
||||
runtime: time.Duration(info.run_time_ns),
|
||||
runCount: info.run_cnt,
|
||||
@ -142,6 +158,17 @@ func (pi *ProgramInfo) ID() (ProgramID, bool) {
|
||||
return pi.id, pi.id > 0
|
||||
}
|
||||
|
||||
// BTFID returns the BTF ID associated with the program.
|
||||
//
|
||||
// Available from 5.0.
|
||||
//
|
||||
// The bool return value indicates whether this optional field is available and
|
||||
// populated. (The field may be available but not populated if the kernel
|
||||
// supports the field but the program was loaded without BTF information.)
|
||||
func (pi *ProgramInfo) BTFID() (btf.ID, bool) {
|
||||
return pi.btf, pi.btf > 0
|
||||
}
|
||||
|
||||
// RunCount returns the total number of times the program was called.
|
||||
//
|
||||
// Can return 0 if the collection of statistics is not enabled. See EnableStats().
|
||||
@ -164,6 +191,13 @@ func (pi *ProgramInfo) Runtime() (time.Duration, bool) {
|
||||
return time.Duration(0), false
|
||||
}
|
||||
|
||||
// MapIDs returns the maps related to the program.
|
||||
//
|
||||
// The bool return value indicates whether this optional field is available.
|
||||
func (pi *ProgramInfo) MapIDs() ([]MapID, bool) {
|
||||
return pi.ids, pi.ids != nil
|
||||
}
|
||||
|
||||
func scanFdInfo(fd *internal.FD, fields map[string]interface{}) error {
|
||||
raw, err := fd.Value()
|
||||
if err != nil {
|
||||
|
6
src/runtime/vendor/github.com/cilium/ebpf/internal/align.go
generated
vendored
Normal file
6
src/runtime/vendor/github.com/cilium/ebpf/internal/align.go
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
package internal
|
||||
|
||||
// Align returns 'n' updated to 'alignment' boundary.
|
||||
func Align(n, alignment int) int {
|
||||
return (int(n) + alignment - 1) / alignment * alignment
|
||||
}
|
293
src/runtime/vendor/github.com/cilium/ebpf/internal/btf/btf.go
generated
vendored
293
src/runtime/vendor/github.com/cilium/ebpf/internal/btf/btf.go
generated
vendored
@ -7,7 +7,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"math"
|
||||
"os"
|
||||
"reflect"
|
||||
@ -27,12 +26,15 @@ var (
|
||||
ErrNoExtendedInfo = errors.New("no extended info")
|
||||
)
|
||||
|
||||
// ID represents the unique ID of a BTF object.
|
||||
type ID uint32
|
||||
|
||||
// Spec represents decoded BTF.
|
||||
type Spec struct {
|
||||
rawTypes []rawType
|
||||
strings stringTable
|
||||
types []Type
|
||||
namedTypes map[string][]namedType
|
||||
namedTypes map[string][]NamedType
|
||||
funcInfos map[string]extInfo
|
||||
lineInfos map[string]extInfo
|
||||
coreRelos map[string]coreRelos
|
||||
@ -61,15 +63,6 @@ func LoadSpecFromReader(rd io.ReaderAt) (*Spec, error) {
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
btfSection, btfExtSection, sectionSizes, err := findBtfSections(file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if btfSection == nil {
|
||||
return nil, fmt.Errorf("btf: %w", ErrNotFound)
|
||||
}
|
||||
|
||||
symbols, err := file.Symbols()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't read symbols: %v", err)
|
||||
@ -87,10 +80,6 @@ func LoadSpecFromReader(rd io.ReaderAt) (*Spec, error) {
|
||||
}
|
||||
|
||||
secName := file.Sections[symbol.Section].Name
|
||||
if _, ok := sectionSizes[secName]; !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
if symbol.Value > math.MaxUint32 {
|
||||
return nil, fmt.Errorf("section %s: symbol %s: size exceeds maximum", secName, symbol.Name)
|
||||
}
|
||||
@ -98,24 +87,10 @@ func LoadSpecFromReader(rd io.ReaderAt) (*Spec, error) {
|
||||
variableOffsets[variable{secName, symbol.Name}] = uint32(symbol.Value)
|
||||
}
|
||||
|
||||
spec, err := loadNakedSpec(btfSection.Open(), file.ByteOrder, sectionSizes, variableOffsets)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if btfExtSection == nil {
|
||||
return spec, nil
|
||||
}
|
||||
|
||||
spec.funcInfos, spec.lineInfos, spec.coreRelos, err = parseExtInfos(btfExtSection.Open(), file.ByteOrder, spec.strings)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't read ext info: %w", err)
|
||||
}
|
||||
|
||||
return spec, nil
|
||||
return loadSpecFromELF(file, variableOffsets)
|
||||
}
|
||||
|
||||
func findBtfSections(file *internal.SafeELFFile) (*elf.Section, *elf.Section, map[string]uint32, error) {
|
||||
func loadSpecFromELF(file *internal.SafeELFFile, variableOffsets map[variable]uint32) (*Spec, error) {
|
||||
var (
|
||||
btfSection *elf.Section
|
||||
btfExtSection *elf.Section
|
||||
@ -134,33 +109,45 @@ func findBtfSections(file *internal.SafeELFFile) (*elf.Section, *elf.Section, ma
|
||||
}
|
||||
|
||||
if sec.Size > math.MaxUint32 {
|
||||
return nil, nil, nil, fmt.Errorf("section %s exceeds maximum size", sec.Name)
|
||||
return nil, fmt.Errorf("section %s exceeds maximum size", sec.Name)
|
||||
}
|
||||
|
||||
sectionSizes[sec.Name] = uint32(sec.Size)
|
||||
}
|
||||
}
|
||||
return btfSection, btfExtSection, sectionSizes, nil
|
||||
}
|
||||
|
||||
func loadSpecFromVmlinux(rd io.ReaderAt) (*Spec, error) {
|
||||
file, err := internal.NewSafeELFFile(rd)
|
||||
if btfSection == nil {
|
||||
return nil, fmt.Errorf("btf: %w", ErrNotFound)
|
||||
}
|
||||
|
||||
spec, err := loadRawSpec(btfSection.Open(), file.ByteOrder, sectionSizes, variableOffsets)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
btfSection, _, _, err := findBtfSections(file)
|
||||
if btfExtSection == nil {
|
||||
return spec, nil
|
||||
}
|
||||
|
||||
spec.funcInfos, spec.lineInfos, spec.coreRelos, err = parseExtInfos(btfExtSection.Open(), file.ByteOrder, spec.strings)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(".BTF ELF section: %s", err)
|
||||
return nil, fmt.Errorf("can't read ext info: %w", err)
|
||||
}
|
||||
if btfSection == nil {
|
||||
return nil, fmt.Errorf("unable to find .BTF ELF section")
|
||||
}
|
||||
return loadNakedSpec(btfSection.Open(), file.ByteOrder, nil, nil)
|
||||
|
||||
return spec, nil
|
||||
}
|
||||
|
||||
func loadNakedSpec(btf io.ReadSeeker, bo binary.ByteOrder, sectionSizes map[string]uint32, variableOffsets map[variable]uint32) (*Spec, error) {
|
||||
// LoadRawSpec reads a blob of BTF data that isn't wrapped in an ELF file.
|
||||
//
|
||||
// Prefer using LoadSpecFromReader, since this function only supports a subset
|
||||
// of BTF.
|
||||
func LoadRawSpec(btf io.Reader, bo binary.ByteOrder) (*Spec, error) {
|
||||
// This will return an error if we encounter a Datasec, since we can't fix
|
||||
// it up.
|
||||
return loadRawSpec(btf, bo, nil, nil)
|
||||
}
|
||||
|
||||
func loadRawSpec(btf io.Reader, bo binary.ByteOrder, sectionSizes map[string]uint32, variableOffsets map[variable]uint32) (*Spec, error) {
|
||||
rawTypes, rawStrings, err := parseBTF(btf, bo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -217,7 +204,7 @@ func loadKernelSpec() (*Spec, error) {
|
||||
if err == nil {
|
||||
defer fh.Close()
|
||||
|
||||
return loadNakedSpec(fh, internal.NativeEndian, nil, nil)
|
||||
return LoadRawSpec(fh, internal.NativeEndian)
|
||||
}
|
||||
|
||||
// use same list of locations as libbpf
|
||||
@ -241,14 +228,20 @@ func loadKernelSpec() (*Spec, error) {
|
||||
}
|
||||
defer fh.Close()
|
||||
|
||||
return loadSpecFromVmlinux(fh)
|
||||
file, err := internal.NewSafeELFFile(fh)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
return loadSpecFromELF(file, nil)
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("no BTF for kernel version %s: %w", release, internal.ErrNotSupported)
|
||||
}
|
||||
|
||||
func parseBTF(btf io.ReadSeeker, bo binary.ByteOrder) ([]rawType, stringTable, error) {
|
||||
rawBTF, err := ioutil.ReadAll(btf)
|
||||
func parseBTF(btf io.Reader, bo binary.ByteOrder) ([]rawType, stringTable, error) {
|
||||
rawBTF, err := io.ReadAll(btf)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("can't read BTF: %v", err)
|
||||
}
|
||||
@ -357,6 +350,30 @@ func fixupDatasec(rawTypes []rawType, rawStrings stringTable, sectionSizes map[s
|
||||
return nil
|
||||
}
|
||||
|
||||
// Copy creates a copy of Spec.
|
||||
func (s *Spec) Copy() *Spec {
|
||||
types, _ := copyTypes(s.types, nil)
|
||||
namedTypes := make(map[string][]NamedType)
|
||||
for _, typ := range types {
|
||||
if named, ok := typ.(NamedType); ok {
|
||||
name := essentialName(named.TypeName())
|
||||
namedTypes[name] = append(namedTypes[name], named)
|
||||
}
|
||||
}
|
||||
|
||||
// NB: Other parts of spec are not copied since they are immutable.
|
||||
return &Spec{
|
||||
s.rawTypes,
|
||||
s.strings,
|
||||
types,
|
||||
namedTypes,
|
||||
s.funcInfos,
|
||||
s.lineInfos,
|
||||
s.coreRelos,
|
||||
s.byteOrder,
|
||||
}
|
||||
}
|
||||
|
||||
type marshalOpts struct {
|
||||
ByteOrder binary.ByteOrder
|
||||
StripFuncLinkage bool
|
||||
@ -447,36 +464,37 @@ func (s *Spec) Program(name string, length uint64) (*Program, error) {
|
||||
return &Program{s, length, funcInfos, lineInfos, relos}, nil
|
||||
}
|
||||
|
||||
// Datasec returns the BTF required to create maps which represent data sections.
|
||||
func (s *Spec) Datasec(name string) (*Map, error) {
|
||||
var datasec Datasec
|
||||
if err := s.FindType(name, &datasec); err != nil {
|
||||
return nil, fmt.Errorf("data section %s: can't get BTF: %w", name, err)
|
||||
}
|
||||
|
||||
m := NewMap(s, &Void{}, &datasec)
|
||||
return &m, nil
|
||||
}
|
||||
|
||||
// FindType searches for a type with a specific name.
|
||||
//
|
||||
// hint determines the type of the returned Type.
|
||||
// Called T a type that satisfies Type, typ must be a non-nil **T.
|
||||
// On success, the address of the found type will be copied in typ.
|
||||
//
|
||||
// Returns an error wrapping ErrNotFound if no matching
|
||||
// type exists in spec.
|
||||
func (s *Spec) FindType(name string, typ Type) error {
|
||||
var (
|
||||
wanted = reflect.TypeOf(typ)
|
||||
candidate Type
|
||||
)
|
||||
func (s *Spec) FindType(name string, typ interface{}) error {
|
||||
typValue := reflect.ValueOf(typ)
|
||||
if typValue.Kind() != reflect.Ptr {
|
||||
return fmt.Errorf("%T is not a pointer", typ)
|
||||
}
|
||||
|
||||
typPtr := typValue.Elem()
|
||||
if !typPtr.CanSet() {
|
||||
return fmt.Errorf("%T cannot be set", typ)
|
||||
}
|
||||
|
||||
wanted := typPtr.Type()
|
||||
if !wanted.AssignableTo(reflect.TypeOf((*Type)(nil)).Elem()) {
|
||||
return fmt.Errorf("%T does not satisfy Type interface", typ)
|
||||
}
|
||||
|
||||
var candidate Type
|
||||
for _, typ := range s.namedTypes[essentialName(name)] {
|
||||
if reflect.TypeOf(typ) != wanted {
|
||||
continue
|
||||
}
|
||||
|
||||
// Match against the full name, not just the essential one.
|
||||
if typ.name() != name {
|
||||
if typ.TypeName() != name {
|
||||
continue
|
||||
}
|
||||
|
||||
@ -491,15 +509,15 @@ func (s *Spec) FindType(name string, typ Type) error {
|
||||
return fmt.Errorf("type %s: %w", name, ErrNotFound)
|
||||
}
|
||||
|
||||
cpy, _ := copyType(candidate, nil)
|
||||
value := reflect.Indirect(reflect.ValueOf(cpy))
|
||||
reflect.Indirect(reflect.ValueOf(typ)).Set(value)
|
||||
typPtr.Set(reflect.ValueOf(candidate))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Handle is a reference to BTF loaded into the kernel.
|
||||
type Handle struct {
|
||||
fd *internal.FD
|
||||
spec *Spec
|
||||
fd *internal.FD
|
||||
}
|
||||
|
||||
// NewHandle loads BTF into the kernel.
|
||||
@ -541,7 +559,32 @@ func NewHandle(spec *Spec) (*Handle, error) {
|
||||
return nil, internal.ErrorWithLog(err, logBuf, logErr)
|
||||
}
|
||||
|
||||
return &Handle{fd}, nil
|
||||
return &Handle{spec.Copy(), fd}, nil
|
||||
}
|
||||
|
||||
// NewHandleFromID returns the BTF handle for a given id.
|
||||
//
|
||||
// Returns ErrNotExist, if there is no BTF with the given id.
|
||||
//
|
||||
// Requires CAP_SYS_ADMIN.
|
||||
func NewHandleFromID(id ID) (*Handle, error) {
|
||||
fd, err := internal.BPFObjGetFDByID(internal.BPF_BTF_GET_FD_BY_ID, uint32(id))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get BTF by id: %w", err)
|
||||
}
|
||||
|
||||
info, err := newInfoFromFd(fd)
|
||||
if err != nil {
|
||||
_ = fd.Close()
|
||||
return nil, fmt.Errorf("get BTF spec for handle: %w", err)
|
||||
}
|
||||
|
||||
return &Handle{info.BTF, fd}, nil
|
||||
}
|
||||
|
||||
// Spec returns the Spec that defined the BTF loaded into the kernel.
|
||||
func (h *Handle) Spec() *Spec {
|
||||
return h.spec
|
||||
}
|
||||
|
||||
// Close destroys the handle.
|
||||
@ -563,43 +606,8 @@ func (h *Handle) FD() int {
|
||||
|
||||
// Map is the BTF for a map.
|
||||
type Map struct {
|
||||
spec *Spec
|
||||
key, value Type
|
||||
}
|
||||
|
||||
// NewMap returns a new Map containing the given values.
|
||||
// The key and value arguments are initialized to Void if nil values are given.
|
||||
func NewMap(spec *Spec, key Type, value Type) Map {
|
||||
if key == nil {
|
||||
key = &Void{}
|
||||
}
|
||||
if value == nil {
|
||||
value = &Void{}
|
||||
}
|
||||
|
||||
return Map{
|
||||
spec: spec,
|
||||
key: key,
|
||||
value: value,
|
||||
}
|
||||
}
|
||||
|
||||
// MapSpec should be a method on Map, but is a free function
|
||||
// to hide it from users of the ebpf package.
|
||||
func MapSpec(m *Map) *Spec {
|
||||
return m.spec
|
||||
}
|
||||
|
||||
// MapKey should be a method on Map, but is a free function
|
||||
// to hide it from users of the ebpf package.
|
||||
func MapKey(m *Map) Type {
|
||||
return m.key
|
||||
}
|
||||
|
||||
// MapValue should be a method on Map, but is a free function
|
||||
// to hide it from users of the ebpf package.
|
||||
func MapValue(m *Map) Type {
|
||||
return m.value
|
||||
Spec *Spec
|
||||
Key, Value Type
|
||||
}
|
||||
|
||||
// Program is the BTF information for a stream of instructions.
|
||||
@ -610,68 +618,59 @@ type Program struct {
|
||||
coreRelos coreRelos
|
||||
}
|
||||
|
||||
// ProgramSpec returns the Spec needed for loading function and line infos into the kernel.
|
||||
//
|
||||
// This is a free function instead of a method to hide it from users
|
||||
// of package ebpf.
|
||||
func ProgramSpec(s *Program) *Spec {
|
||||
return s.spec
|
||||
// Spec returns the BTF spec of this program.
|
||||
func (p *Program) Spec() *Spec {
|
||||
return p.spec
|
||||
}
|
||||
|
||||
// ProgramAppend the information from other to the Program.
|
||||
//
|
||||
// This is a free function instead of a method to hide it from users
|
||||
// of package ebpf.
|
||||
func ProgramAppend(s, other *Program) error {
|
||||
funcInfos, err := s.funcInfos.append(other.funcInfos, s.length)
|
||||
// Append the information from other to the Program.
|
||||
func (p *Program) Append(other *Program) error {
|
||||
if other.spec != p.spec {
|
||||
return fmt.Errorf("can't append program with different BTF specs")
|
||||
}
|
||||
|
||||
funcInfos, err := p.funcInfos.append(other.funcInfos, p.length)
|
||||
if err != nil {
|
||||
return fmt.Errorf("func infos: %w", err)
|
||||
}
|
||||
|
||||
lineInfos, err := s.lineInfos.append(other.lineInfos, s.length)
|
||||
lineInfos, err := p.lineInfos.append(other.lineInfos, p.length)
|
||||
if err != nil {
|
||||
return fmt.Errorf("line infos: %w", err)
|
||||
}
|
||||
|
||||
s.funcInfos = funcInfos
|
||||
s.lineInfos = lineInfos
|
||||
s.coreRelos = s.coreRelos.append(other.coreRelos, s.length)
|
||||
s.length += other.length
|
||||
p.funcInfos = funcInfos
|
||||
p.lineInfos = lineInfos
|
||||
p.coreRelos = p.coreRelos.append(other.coreRelos, p.length)
|
||||
p.length += other.length
|
||||
return nil
|
||||
}
|
||||
|
||||
// ProgramFuncInfos returns the binary form of BTF function infos.
|
||||
//
|
||||
// This is a free function instead of a method to hide it from users
|
||||
// of package ebpf.
|
||||
func ProgramFuncInfos(s *Program) (recordSize uint32, bytes []byte, err error) {
|
||||
bytes, err = s.funcInfos.MarshalBinary()
|
||||
// FuncInfos returns the binary form of BTF function infos.
|
||||
func (p *Program) FuncInfos() (recordSize uint32, bytes []byte, err error) {
|
||||
bytes, err = p.funcInfos.MarshalBinary()
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
return 0, nil, fmt.Errorf("func infos: %w", err)
|
||||
}
|
||||
|
||||
return s.funcInfos.recordSize, bytes, nil
|
||||
return p.funcInfos.recordSize, bytes, nil
|
||||
}
|
||||
|
||||
// ProgramLineInfos returns the binary form of BTF line infos.
|
||||
//
|
||||
// This is a free function instead of a method to hide it from users
|
||||
// of package ebpf.
|
||||
func ProgramLineInfos(s *Program) (recordSize uint32, bytes []byte, err error) {
|
||||
bytes, err = s.lineInfos.MarshalBinary()
|
||||
// LineInfos returns the binary form of BTF line infos.
|
||||
func (p *Program) LineInfos() (recordSize uint32, bytes []byte, err error) {
|
||||
bytes, err = p.lineInfos.MarshalBinary()
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
return 0, nil, fmt.Errorf("line infos: %w", err)
|
||||
}
|
||||
|
||||
return s.lineInfos.recordSize, bytes, nil
|
||||
return p.lineInfos.recordSize, bytes, nil
|
||||
}
|
||||
|
||||
// ProgramFixups returns the changes required to adjust the program to the target.
|
||||
// Fixups returns the changes required to adjust the program to the target.
|
||||
//
|
||||
// This is a free function instead of a method to hide it from users
|
||||
// of package ebpf.
|
||||
func ProgramFixups(s *Program, target *Spec) (COREFixups, error) {
|
||||
if len(s.coreRelos) == 0 {
|
||||
// Passing a nil target will relocate against the running kernel.
|
||||
func (p *Program) Fixups(target *Spec) (COREFixups, error) {
|
||||
if len(p.coreRelos) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@ -683,7 +682,7 @@ func ProgramFixups(s *Program, target *Spec) (COREFixups, error) {
|
||||
}
|
||||
}
|
||||
|
||||
return coreRelocate(s.spec, target, s.coreRelos)
|
||||
return coreRelocate(p.spec, target, p.coreRelos)
|
||||
}
|
||||
|
||||
type bpfLoadBTFAttr struct {
|
||||
|
11
src/runtime/vendor/github.com/cilium/ebpf/internal/btf/btf_types.go
generated
vendored
11
src/runtime/vendor/github.com/cilium/ebpf/internal/btf/btf_types.go
generated
vendored
@ -31,6 +31,8 @@ const (
|
||||
// Added ~5.1
|
||||
kindVar
|
||||
kindDatasec
|
||||
// Added ~5.13
|
||||
kindFloat
|
||||
)
|
||||
|
||||
// FuncLinkage describes BTF function linkage metadata.
|
||||
@ -54,7 +56,7 @@ const (
|
||||
|
||||
const (
|
||||
btfTypeKindShift = 24
|
||||
btfTypeKindLen = 4
|
||||
btfTypeKindLen = 5
|
||||
btfTypeVlenShift = 0
|
||||
btfTypeVlenMask = 16
|
||||
btfTypeKindFlagShift = 31
|
||||
@ -67,8 +69,8 @@ type btfType struct {
|
||||
/* "info" bits arrangement
|
||||
* bits 0-15: vlen (e.g. # of struct's members), linkage
|
||||
* bits 16-23: unused
|
||||
* bits 24-27: kind (e.g. int, ptr, array...etc)
|
||||
* bits 28-30: unused
|
||||
* bits 24-28: kind (e.g. int, ptr, array...etc)
|
||||
* bits 29-30: unused
|
||||
* bit 31: kind_flag, currently used by
|
||||
* struct, union and fwd
|
||||
*/
|
||||
@ -117,6 +119,8 @@ func (k btfKind) String() string {
|
||||
return "Variable"
|
||||
case kindDatasec:
|
||||
return "Section"
|
||||
case kindFloat:
|
||||
return "Float"
|
||||
default:
|
||||
return fmt.Sprintf("Unknown (%d)", k)
|
||||
}
|
||||
@ -260,6 +264,7 @@ func readTypes(r io.Reader, bo binary.ByteOrder) ([]rawType, error) {
|
||||
data = new(btfVariable)
|
||||
case kindDatasec:
|
||||
data = make([]btfVarSecinfo, header.Vlen())
|
||||
case kindFloat:
|
||||
default:
|
||||
return nil, fmt.Errorf("type id %v: unknown kind: %v", id, header.Kind())
|
||||
}
|
||||
|
33
src/runtime/vendor/github.com/cilium/ebpf/internal/btf/core.go
generated
vendored
33
src/runtime/vendor/github.com/cilium/ebpf/internal/btf/core.go
generated
vendored
@ -234,13 +234,13 @@ func coreRelocate(local, target *Spec, relos coreRelos) (COREFixups, error) {
|
||||
}
|
||||
|
||||
localType := local.types[id]
|
||||
named, ok := localType.(namedType)
|
||||
if !ok || named.name() == "" {
|
||||
named, ok := localType.(NamedType)
|
||||
if !ok || named.TypeName() == "" {
|
||||
return nil, fmt.Errorf("relocate unnamed or anonymous type %s: %w", localType, ErrNotSupported)
|
||||
}
|
||||
|
||||
relos := relosByID[id]
|
||||
targets := target.namedTypes[named.essentialName()]
|
||||
targets := target.namedTypes[essentialName(named.TypeName())]
|
||||
fixups, err := coreCalculateFixups(localType, targets, relos)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("relocate %s: %w", localType, err)
|
||||
@ -262,7 +262,7 @@ var errImpossibleRelocation = errors.New("impossible relocation")
|
||||
//
|
||||
// The best target is determined by scoring: the less poisoning we have to do
|
||||
// the better the target is.
|
||||
func coreCalculateFixups(local Type, targets []namedType, relos coreRelos) ([]COREFixup, error) {
|
||||
func coreCalculateFixups(local Type, targets []NamedType, relos coreRelos) ([]COREFixup, error) {
|
||||
localID := local.ID()
|
||||
local, err := copyType(local, skipQualifierAndTypedef)
|
||||
if err != nil {
|
||||
@ -467,8 +467,8 @@ func parseCoreAccessor(accessor string) (coreAccessor, error) {
|
||||
return nil, fmt.Errorf("empty accessor")
|
||||
}
|
||||
|
||||
var result coreAccessor
|
||||
parts := strings.Split(accessor, ":")
|
||||
result := make(coreAccessor, 0, len(parts))
|
||||
for _, part := range parts {
|
||||
// 31 bits to avoid overflowing int on 32 bit platforms.
|
||||
index, err := strconv.ParseUint(part, 10, 31)
|
||||
@ -564,7 +564,7 @@ func coreFindField(local Type, localAcc coreAccessor, target Type) (_, _ coreFie
|
||||
|
||||
// This is an anonymous struct or union, ignore it.
|
||||
local = localMember.Type
|
||||
localOffset += localMember.Offset
|
||||
localOffset += localMember.OffsetBits
|
||||
localMaybeFlex = false
|
||||
continue
|
||||
}
|
||||
@ -585,10 +585,10 @@ func coreFindField(local Type, localAcc coreAccessor, target Type) (_, _ coreFie
|
||||
|
||||
local = localMember.Type
|
||||
localMaybeFlex = acc == len(localMembers)-1
|
||||
localOffset += localMember.Offset
|
||||
localOffset += localMember.OffsetBits
|
||||
target = targetMember.Type
|
||||
targetMaybeFlex = last
|
||||
targetOffset += targetMember.Offset
|
||||
targetOffset += targetMember.OffsetBits
|
||||
|
||||
case *Array:
|
||||
// For arrays, acc is the index in the target.
|
||||
@ -639,7 +639,7 @@ func coreFindField(local Type, localAcc coreAccessor, target Type) (_, _ coreFie
|
||||
|
||||
// coreFindMember finds a member in a composite type while handling anonymous
|
||||
// structs and unions.
|
||||
func coreFindMember(typ composite, name Name) (Member, bool, error) {
|
||||
func coreFindMember(typ composite, name string) (Member, bool, error) {
|
||||
if name == "" {
|
||||
return Member{}, false, errors.New("can't search for anonymous member")
|
||||
}
|
||||
@ -670,7 +670,7 @@ func coreFindMember(typ composite, name Name) (Member, bool, error) {
|
||||
for j, member := range members {
|
||||
if member.Name == name {
|
||||
// NB: This is safe because member is a copy.
|
||||
member.Offset += target.offset
|
||||
member.OffsetBits += target.offset
|
||||
return member, j == len(members)-1, nil
|
||||
}
|
||||
|
||||
@ -685,7 +685,7 @@ func coreFindMember(typ composite, name Name) (Member, bool, error) {
|
||||
return Member{}, false, fmt.Errorf("anonymous non-composite type %T not allowed", member.Type)
|
||||
}
|
||||
|
||||
targets = append(targets, offsetTarget{comp, target.offset + member.Offset})
|
||||
targets = append(targets, offsetTarget{comp, target.offset + member.OffsetBits})
|
||||
}
|
||||
}
|
||||
|
||||
@ -704,9 +704,9 @@ func coreFindEnumValue(local Type, localAcc coreAccessor, target Type) (localVal
|
||||
return nil, nil, errImpossibleRelocation
|
||||
}
|
||||
|
||||
localName := localValue.Name.essentialName()
|
||||
localName := essentialName(localValue.Name)
|
||||
for i, targetValue := range targetEnum.Values {
|
||||
if targetValue.Name.essentialName() != localName {
|
||||
if essentialName(targetValue.Name) != localName {
|
||||
continue
|
||||
}
|
||||
|
||||
@ -813,6 +813,7 @@ func coreAreTypesCompatible(localType Type, targetType Type) error {
|
||||
* least one of enums should be anonymous;
|
||||
* - for ENUMs, check sizes, names are ignored;
|
||||
* - for INT, size and signedness are ignored;
|
||||
* - any two FLOATs are always compatible;
|
||||
* - for ARRAY, dimensionality is ignored, element types are checked for
|
||||
* compatibility recursively;
|
||||
* [ NB: coreAreMembersCompatible doesn't recurse, this check is done
|
||||
@ -848,16 +849,16 @@ func coreAreMembersCompatible(localType Type, targetType Type) error {
|
||||
}
|
||||
|
||||
switch lv := localType.(type) {
|
||||
case *Array, *Pointer:
|
||||
case *Array, *Pointer, *Float:
|
||||
return nil
|
||||
|
||||
case *Enum:
|
||||
tv := targetType.(*Enum)
|
||||
return doNamesMatch(lv.name(), tv.name())
|
||||
return doNamesMatch(lv.Name, tv.Name)
|
||||
|
||||
case *Fwd:
|
||||
tv := targetType.(*Fwd)
|
||||
return doNamesMatch(lv.name(), tv.name())
|
||||
return doNamesMatch(lv.Name, tv.Name)
|
||||
|
||||
case *Int:
|
||||
tv := targetType.(*Int)
|
||||
|
15
src/runtime/vendor/github.com/cilium/ebpf/internal/btf/ext_info.go
generated
vendored
15
src/runtime/vendor/github.com/cilium/ebpf/internal/btf/ext_info.go
generated
vendored
@ -7,7 +7,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/cilium/ebpf/asm"
|
||||
"github.com/cilium/ebpf/internal"
|
||||
@ -64,7 +63,7 @@ func parseExtInfos(r io.ReadSeeker, bo binary.ByteOrder, strings stringTable) (f
|
||||
|
||||
// Of course, the .BTF.ext header has different semantics than the
|
||||
// .BTF ext header. We need to ignore non-null values.
|
||||
_, err = io.CopyN(ioutil.Discard, r, remainder)
|
||||
_, err = io.CopyN(io.Discard, r, remainder)
|
||||
if err != nil {
|
||||
return nil, nil, nil, fmt.Errorf("header padding: %v", err)
|
||||
}
|
||||
@ -114,11 +113,16 @@ type extInfoRecord struct {
|
||||
}
|
||||
|
||||
type extInfo struct {
|
||||
byteOrder binary.ByteOrder
|
||||
recordSize uint32
|
||||
records []extInfoRecord
|
||||
}
|
||||
|
||||
func (ei extInfo) append(other extInfo, offset uint64) (extInfo, error) {
|
||||
if other.byteOrder != ei.byteOrder {
|
||||
return extInfo{}, fmt.Errorf("ext_info byte order mismatch, want %v (got %v)", ei.byteOrder, other.byteOrder)
|
||||
}
|
||||
|
||||
if other.recordSize != ei.recordSize {
|
||||
return extInfo{}, fmt.Errorf("ext_info record size mismatch, want %d (got %d)", ei.recordSize, other.recordSize)
|
||||
}
|
||||
@ -131,10 +135,14 @@ func (ei extInfo) append(other extInfo, offset uint64) (extInfo, error) {
|
||||
Opaque: info.Opaque,
|
||||
})
|
||||
}
|
||||
return extInfo{ei.recordSize, records}, nil
|
||||
return extInfo{ei.byteOrder, ei.recordSize, records}, nil
|
||||
}
|
||||
|
||||
func (ei extInfo) MarshalBinary() ([]byte, error) {
|
||||
if ei.byteOrder != internal.NativeEndian {
|
||||
return nil, fmt.Errorf("%s is not the native byte order", ei.byteOrder)
|
||||
}
|
||||
|
||||
if len(ei.records) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
@ -197,6 +205,7 @@ func parseExtInfo(r io.Reader, bo binary.ByteOrder, strings stringTable) (map[st
|
||||
}
|
||||
|
||||
result[secName] = extInfo{
|
||||
bo,
|
||||
recordSize,
|
||||
records,
|
||||
}
|
||||
|
1
src/runtime/vendor/github.com/cilium/ebpf/internal/btf/fuzz.go
generated
vendored
1
src/runtime/vendor/github.com/cilium/ebpf/internal/btf/fuzz.go
generated
vendored
@ -1,3 +1,4 @@
|
||||
//go:build gofuzz
|
||||
// +build gofuzz
|
||||
|
||||
// Use with https://github.com/dvyukov/go-fuzz
|
||||
|
48
src/runtime/vendor/github.com/cilium/ebpf/internal/btf/info.go
generated
vendored
Normal file
48
src/runtime/vendor/github.com/cilium/ebpf/internal/btf/info.go
generated
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
package btf
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
"github.com/cilium/ebpf/internal"
|
||||
)
|
||||
|
||||
// info describes a BTF object.
|
||||
type info struct {
|
||||
BTF *Spec
|
||||
ID ID
|
||||
// Name is an identifying name for the BTF, currently only used by the
|
||||
// kernel.
|
||||
Name string
|
||||
// KernelBTF is true if the BTf originated with the kernel and not
|
||||
// userspace.
|
||||
KernelBTF bool
|
||||
}
|
||||
|
||||
func newInfoFromFd(fd *internal.FD) (*info, error) {
|
||||
// We invoke the syscall once with a empty BTF and name buffers to get size
|
||||
// information to allocate buffers. Then we invoke it a second time with
|
||||
// buffers to receive the data.
|
||||
bpfInfo, err := bpfGetBTFInfoByFD(fd, nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
btfBuffer := make([]byte, bpfInfo.btfSize)
|
||||
nameBuffer := make([]byte, bpfInfo.nameLen)
|
||||
bpfInfo, err = bpfGetBTFInfoByFD(fd, btfBuffer, nameBuffer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
spec, err := loadRawSpec(bytes.NewReader(btfBuffer), internal.NativeEndian, nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &info{
|
||||
BTF: spec,
|
||||
ID: ID(bpfInfo.id),
|
||||
Name: internal.CString(nameBuffer),
|
||||
KernelBTF: bpfInfo.kernelBTF != 0,
|
||||
}, nil
|
||||
}
|
8
src/runtime/vendor/github.com/cilium/ebpf/internal/btf/strings.go
generated
vendored
8
src/runtime/vendor/github.com/cilium/ebpf/internal/btf/strings.go
generated
vendored
@ -5,13 +5,12 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
type stringTable []byte
|
||||
|
||||
func readStringTable(r io.Reader) (stringTable, error) {
|
||||
contents, err := ioutil.ReadAll(r)
|
||||
contents, err := io.ReadAll(r)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't read string table: %v", err)
|
||||
}
|
||||
@ -53,8 +52,3 @@ func (st stringTable) Lookup(offset uint32) (string, error) {
|
||||
|
||||
return string(str[:end]), nil
|
||||
}
|
||||
|
||||
func (st stringTable) LookupName(offset uint32) (Name, error) {
|
||||
str, err := st.Lookup(offset)
|
||||
return Name(str), err
|
||||
}
|
||||
|
31
src/runtime/vendor/github.com/cilium/ebpf/internal/btf/syscalls.go
generated
vendored
Normal file
31
src/runtime/vendor/github.com/cilium/ebpf/internal/btf/syscalls.go
generated
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
package btf
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
"github.com/cilium/ebpf/internal"
|
||||
)
|
||||
|
||||
type bpfBTFInfo struct {
|
||||
btf internal.Pointer
|
||||
btfSize uint32
|
||||
id uint32
|
||||
name internal.Pointer
|
||||
nameLen uint32
|
||||
kernelBTF uint32
|
||||
}
|
||||
|
||||
func bpfGetBTFInfoByFD(fd *internal.FD, btf, name []byte) (*bpfBTFInfo, error) {
|
||||
info := bpfBTFInfo{
|
||||
btf: internal.NewSlicePointer(btf),
|
||||
btfSize: uint32(len(btf)),
|
||||
name: internal.NewSlicePointer(name),
|
||||
nameLen: uint32(len(name)),
|
||||
}
|
||||
if err := internal.BPFObjGetInfoByFD(fd, unsafe.Pointer(&info), unsafe.Sizeof(info)); err != nil {
|
||||
return nil, fmt.Errorf("can't get program info: %w", err)
|
||||
}
|
||||
|
||||
return &info, nil
|
||||
}
|
190
src/runtime/vendor/github.com/cilium/ebpf/internal/btf/types.go
generated
vendored
190
src/runtime/vendor/github.com/cilium/ebpf/internal/btf/types.go
generated
vendored
@ -30,27 +30,26 @@ type Type interface {
|
||||
walk(*typeDeque)
|
||||
}
|
||||
|
||||
// namedType is a type with a name.
|
||||
//
|
||||
// Most named types simply embed Name.
|
||||
type namedType interface {
|
||||
// NamedType is a type with a name.
|
||||
type NamedType interface {
|
||||
Type
|
||||
name() string
|
||||
essentialName() string
|
||||
|
||||
// Name of the type, empty for anonymous types.
|
||||
TypeName() string
|
||||
}
|
||||
|
||||
// Name identifies a type.
|
||||
//
|
||||
// Anonymous types have an empty name.
|
||||
type Name string
|
||||
|
||||
func (n Name) name() string {
|
||||
return string(n)
|
||||
}
|
||||
|
||||
func (n Name) essentialName() string {
|
||||
return essentialName(string(n))
|
||||
}
|
||||
var (
|
||||
_ NamedType = (*Int)(nil)
|
||||
_ NamedType = (*Struct)(nil)
|
||||
_ NamedType = (*Union)(nil)
|
||||
_ NamedType = (*Enum)(nil)
|
||||
_ NamedType = (*Fwd)(nil)
|
||||
_ NamedType = (*Func)(nil)
|
||||
_ NamedType = (*Typedef)(nil)
|
||||
_ NamedType = (*Var)(nil)
|
||||
_ NamedType = (*Datasec)(nil)
|
||||
_ NamedType = (*Float)(nil)
|
||||
)
|
||||
|
||||
// Void is the unit type of BTF.
|
||||
type Void struct{}
|
||||
@ -72,19 +71,17 @@ const (
|
||||
// Int is an integer of a given length.
|
||||
type Int struct {
|
||||
TypeID
|
||||
Name
|
||||
Name string
|
||||
|
||||
// The size of the integer in bytes.
|
||||
Size uint32
|
||||
Encoding IntEncoding
|
||||
// Offset is the starting bit offset. Currently always 0.
|
||||
// OffsetBits is the starting bit offset. Currently always 0.
|
||||
// See https://www.kernel.org/doc/html/latest/bpf/btf.html#btf-kind-int
|
||||
Offset uint32
|
||||
Bits byte
|
||||
OffsetBits uint32
|
||||
Bits byte
|
||||
}
|
||||
|
||||
var _ namedType = (*Int)(nil)
|
||||
|
||||
func (i *Int) String() string {
|
||||
var s strings.Builder
|
||||
|
||||
@ -110,15 +107,16 @@ func (i *Int) String() string {
|
||||
return s.String()
|
||||
}
|
||||
|
||||
func (i *Int) size() uint32 { return i.Size }
|
||||
func (i *Int) walk(*typeDeque) {}
|
||||
func (i *Int) TypeName() string { return i.Name }
|
||||
func (i *Int) size() uint32 { return i.Size }
|
||||
func (i *Int) walk(*typeDeque) {}
|
||||
func (i *Int) copy() Type {
|
||||
cpy := *i
|
||||
return &cpy
|
||||
}
|
||||
|
||||
func (i *Int) isBitfield() bool {
|
||||
return i.Offset > 0
|
||||
return i.OffsetBits > 0
|
||||
}
|
||||
|
||||
// Pointer is a pointer to another type.
|
||||
@ -158,7 +156,7 @@ func (arr *Array) copy() Type {
|
||||
// Struct is a compound type of consecutive members.
|
||||
type Struct struct {
|
||||
TypeID
|
||||
Name
|
||||
Name string
|
||||
// The size of the struct including padding, in bytes
|
||||
Size uint32
|
||||
Members []Member
|
||||
@ -168,6 +166,8 @@ func (s *Struct) String() string {
|
||||
return fmt.Sprintf("struct#%d[%q]", s.TypeID, s.Name)
|
||||
}
|
||||
|
||||
func (s *Struct) TypeName() string { return s.Name }
|
||||
|
||||
func (s *Struct) size() uint32 { return s.Size }
|
||||
|
||||
func (s *Struct) walk(tdq *typeDeque) {
|
||||
@ -189,7 +189,7 @@ func (s *Struct) members() []Member {
|
||||
// Union is a compound type where members occupy the same memory.
|
||||
type Union struct {
|
||||
TypeID
|
||||
Name
|
||||
Name string
|
||||
// The size of the union including padding, in bytes.
|
||||
Size uint32
|
||||
Members []Member
|
||||
@ -199,6 +199,8 @@ func (u *Union) String() string {
|
||||
return fmt.Sprintf("union#%d[%q]", u.TypeID, u.Name)
|
||||
}
|
||||
|
||||
func (u *Union) TypeName() string { return u.Name }
|
||||
|
||||
func (u *Union) size() uint32 { return u.Size }
|
||||
|
||||
func (u *Union) walk(tdq *typeDeque) {
|
||||
@ -236,17 +238,17 @@ var (
|
||||
//
|
||||
// It is not a valid Type.
|
||||
type Member struct {
|
||||
Name
|
||||
Name string
|
||||
Type Type
|
||||
// Offset is the bit offset of this member
|
||||
Offset uint32
|
||||
// OffsetBits is the bit offset of this member.
|
||||
OffsetBits uint32
|
||||
BitfieldSize uint32
|
||||
}
|
||||
|
||||
// Enum lists possible values.
|
||||
type Enum struct {
|
||||
TypeID
|
||||
Name
|
||||
Name string
|
||||
Values []EnumValue
|
||||
}
|
||||
|
||||
@ -254,11 +256,13 @@ func (e *Enum) String() string {
|
||||
return fmt.Sprintf("enum#%d[%q]", e.TypeID, e.Name)
|
||||
}
|
||||
|
||||
func (e *Enum) TypeName() string { return e.Name }
|
||||
|
||||
// EnumValue is part of an Enum
|
||||
//
|
||||
// Is is not a valid Type
|
||||
type EnumValue struct {
|
||||
Name
|
||||
Name string
|
||||
Value int32
|
||||
}
|
||||
|
||||
@ -294,7 +298,7 @@ func (fk FwdKind) String() string {
|
||||
// Fwd is a forward declaration of a Type.
|
||||
type Fwd struct {
|
||||
TypeID
|
||||
Name
|
||||
Name string
|
||||
Kind FwdKind
|
||||
}
|
||||
|
||||
@ -302,6 +306,8 @@ func (f *Fwd) String() string {
|
||||
return fmt.Sprintf("fwd#%d[%s %q]", f.TypeID, f.Kind, f.Name)
|
||||
}
|
||||
|
||||
func (f *Fwd) TypeName() string { return f.Name }
|
||||
|
||||
func (f *Fwd) walk(*typeDeque) {}
|
||||
func (f *Fwd) copy() Type {
|
||||
cpy := *f
|
||||
@ -311,7 +317,7 @@ func (f *Fwd) copy() Type {
|
||||
// Typedef is an alias of a Type.
|
||||
type Typedef struct {
|
||||
TypeID
|
||||
Name
|
||||
Name string
|
||||
Type Type
|
||||
}
|
||||
|
||||
@ -319,6 +325,8 @@ func (td *Typedef) String() string {
|
||||
return fmt.Sprintf("typedef#%d[%q #%d]", td.TypeID, td.Name, td.Type.ID())
|
||||
}
|
||||
|
||||
func (td *Typedef) TypeName() string { return td.Name }
|
||||
|
||||
func (td *Typedef) walk(tdq *typeDeque) { tdq.push(&td.Type) }
|
||||
func (td *Typedef) copy() Type {
|
||||
cpy := *td
|
||||
@ -379,7 +387,7 @@ func (r *Restrict) copy() Type {
|
||||
// Func is a function definition.
|
||||
type Func struct {
|
||||
TypeID
|
||||
Name
|
||||
Name string
|
||||
Type Type
|
||||
Linkage FuncLinkage
|
||||
}
|
||||
@ -388,6 +396,8 @@ func (f *Func) String() string {
|
||||
return fmt.Sprintf("func#%d[%s %q proto=#%d]", f.TypeID, f.Linkage, f.Name, f.Type.ID())
|
||||
}
|
||||
|
||||
func (f *Func) TypeName() string { return f.Name }
|
||||
|
||||
func (f *Func) walk(tdq *typeDeque) { tdq.push(&f.Type) }
|
||||
func (f *Func) copy() Type {
|
||||
cpy := *f
|
||||
@ -426,14 +436,14 @@ func (fp *FuncProto) copy() Type {
|
||||
}
|
||||
|
||||
type FuncParam struct {
|
||||
Name
|
||||
Name string
|
||||
Type Type
|
||||
}
|
||||
|
||||
// Var is a global variable.
|
||||
type Var struct {
|
||||
TypeID
|
||||
Name
|
||||
Name string
|
||||
Type Type
|
||||
Linkage VarLinkage
|
||||
}
|
||||
@ -442,6 +452,8 @@ func (v *Var) String() string {
|
||||
return fmt.Sprintf("var#%d[%s %q]", v.TypeID, v.Linkage, v.Name)
|
||||
}
|
||||
|
||||
func (v *Var) TypeName() string { return v.Name }
|
||||
|
||||
func (v *Var) walk(tdq *typeDeque) { tdq.push(&v.Type) }
|
||||
func (v *Var) copy() Type {
|
||||
cpy := *v
|
||||
@ -451,7 +463,7 @@ func (v *Var) copy() Type {
|
||||
// Datasec is a global program section containing data.
|
||||
type Datasec struct {
|
||||
TypeID
|
||||
Name
|
||||
Name string
|
||||
Size uint32
|
||||
Vars []VarSecinfo
|
||||
}
|
||||
@ -460,6 +472,8 @@ func (ds *Datasec) String() string {
|
||||
return fmt.Sprintf("section#%d[%q]", ds.TypeID, ds.Name)
|
||||
}
|
||||
|
||||
func (ds *Datasec) TypeName() string { return ds.Name }
|
||||
|
||||
func (ds *Datasec) size() uint32 { return ds.Size }
|
||||
|
||||
func (ds *Datasec) walk(tdq *typeDeque) {
|
||||
@ -475,7 +489,7 @@ func (ds *Datasec) copy() Type {
|
||||
return &cpy
|
||||
}
|
||||
|
||||
// VarSecinfo describes variable in a Datasec
|
||||
// VarSecinfo describes variable in a Datasec.
|
||||
//
|
||||
// It is not a valid Type.
|
||||
type VarSecinfo struct {
|
||||
@ -484,6 +498,27 @@ type VarSecinfo struct {
|
||||
Size uint32
|
||||
}
|
||||
|
||||
// Float is a float of a given length.
|
||||
type Float struct {
|
||||
TypeID
|
||||
Name string
|
||||
|
||||
// The size of the float in bytes.
|
||||
Size uint32
|
||||
}
|
||||
|
||||
func (f *Float) String() string {
|
||||
return fmt.Sprintf("float%d#%d[%q]", f.Size*8, f.TypeID, f.Name)
|
||||
}
|
||||
|
||||
func (f *Float) TypeName() string { return f.Name }
|
||||
func (f *Float) size() uint32 { return f.Size }
|
||||
func (f *Float) walk(*typeDeque) {}
|
||||
func (f *Float) copy() Type {
|
||||
cpy := *f
|
||||
return &cpy
|
||||
}
|
||||
|
||||
type sizer interface {
|
||||
size() uint32
|
||||
}
|
||||
@ -565,14 +600,36 @@ func Sizeof(typ Type) (int, error) {
|
||||
//
|
||||
// Returns any errors from transform verbatim.
|
||||
func copyType(typ Type, transform func(Type) (Type, error)) (Type, error) {
|
||||
var (
|
||||
copies = make(map[Type]Type)
|
||||
work typeDeque
|
||||
)
|
||||
copies := make(copier)
|
||||
return typ, copies.copy(&typ, transform)
|
||||
}
|
||||
|
||||
for t := &typ; t != nil; t = work.pop() {
|
||||
// copy a slice of Types recursively.
|
||||
//
|
||||
// Types may form a cycle.
|
||||
//
|
||||
// Returns any errors from transform verbatim.
|
||||
func copyTypes(types []Type, transform func(Type) (Type, error)) ([]Type, error) {
|
||||
result := make([]Type, len(types))
|
||||
copy(result, types)
|
||||
|
||||
copies := make(copier)
|
||||
for i := range result {
|
||||
if err := copies.copy(&result[i], transform); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
type copier map[Type]Type
|
||||
|
||||
func (c copier) copy(typ *Type, transform func(Type) (Type, error)) error {
|
||||
var work typeDeque
|
||||
for t := typ; t != nil; t = work.pop() {
|
||||
// *t is the identity of the type.
|
||||
if cpy := copies[*t]; cpy != nil {
|
||||
if cpy := c[*t]; cpy != nil {
|
||||
*t = cpy
|
||||
continue
|
||||
}
|
||||
@ -581,21 +638,21 @@ func copyType(typ Type, transform func(Type) (Type, error)) (Type, error) {
|
||||
if transform != nil {
|
||||
tf, err := transform(*t)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("copy %s: %w", typ, err)
|
||||
return fmt.Errorf("copy %s: %w", *t, err)
|
||||
}
|
||||
cpy = tf.copy()
|
||||
} else {
|
||||
cpy = (*t).copy()
|
||||
}
|
||||
|
||||
copies[*t] = cpy
|
||||
c[*t] = cpy
|
||||
*t = cpy
|
||||
|
||||
// Mark any nested types for copying.
|
||||
cpy.walk(&work)
|
||||
}
|
||||
|
||||
return typ, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// typeDeque keeps track of pointers to types which still
|
||||
@ -606,6 +663,10 @@ type typeDeque struct {
|
||||
mask uint64
|
||||
}
|
||||
|
||||
func (dq *typeDeque) empty() bool {
|
||||
return dq.read == dq.write
|
||||
}
|
||||
|
||||
// push adds a type to the stack.
|
||||
func (dq *typeDeque) push(t *Type) {
|
||||
if dq.write-dq.read < uint64(len(dq.types)) {
|
||||
@ -632,7 +693,7 @@ func (dq *typeDeque) push(t *Type) {
|
||||
|
||||
// shift returns the first element or null.
|
||||
func (dq *typeDeque) shift() *Type {
|
||||
if dq.read == dq.write {
|
||||
if dq.empty() {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -645,7 +706,7 @@ func (dq *typeDeque) shift() *Type {
|
||||
|
||||
// pop returns the last element or null.
|
||||
func (dq *typeDeque) pop() *Type {
|
||||
if dq.read == dq.write {
|
||||
if dq.empty() {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -674,7 +735,7 @@ func (dq *typeDeque) all() []*Type {
|
||||
// Returns a map of named types (so, where NameOff is non-zero) and a slice of types
|
||||
// indexed by TypeID. Since BTF ignores compilation units, multiple types may share
|
||||
// the same name. A Type may form a cyclic graph by pointing at itself.
|
||||
func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (types []Type, namedTypes map[string][]namedType, err error) {
|
||||
func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (types []Type, namedTypes map[string][]NamedType, err error) {
|
||||
type fixupDef struct {
|
||||
id TypeID
|
||||
expectedKind btfKind
|
||||
@ -691,17 +752,17 @@ func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (types []Type,
|
||||
// work, since otherwise append might re-allocate members.
|
||||
members := make([]Member, 0, len(raw))
|
||||
for i, btfMember := range raw {
|
||||
name, err := rawStrings.LookupName(btfMember.NameOff)
|
||||
name, err := rawStrings.Lookup(btfMember.NameOff)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't get name for member %d: %w", i, err)
|
||||
}
|
||||
m := Member{
|
||||
Name: name,
|
||||
Offset: btfMember.Offset,
|
||||
Name: name,
|
||||
OffsetBits: btfMember.Offset,
|
||||
}
|
||||
if kindFlag {
|
||||
m.BitfieldSize = btfMember.Offset >> 24
|
||||
m.Offset &= 0xffffff
|
||||
m.OffsetBits &= 0xffffff
|
||||
}
|
||||
members = append(members, m)
|
||||
}
|
||||
@ -713,7 +774,7 @@ func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (types []Type,
|
||||
|
||||
types = make([]Type, 0, len(rawTypes))
|
||||
types = append(types, (*Void)(nil))
|
||||
namedTypes = make(map[string][]namedType)
|
||||
namedTypes = make(map[string][]NamedType)
|
||||
|
||||
for i, raw := range rawTypes {
|
||||
var (
|
||||
@ -723,7 +784,7 @@ func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (types []Type,
|
||||
typ Type
|
||||
)
|
||||
|
||||
name, err := rawStrings.LookupName(raw.NameOff)
|
||||
name, err := rawStrings.Lookup(raw.NameOff)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("get name for type id %d: %w", id, err)
|
||||
}
|
||||
@ -765,7 +826,7 @@ func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (types []Type,
|
||||
rawvals := raw.data.([]btfEnum)
|
||||
vals := make([]EnumValue, 0, len(rawvals))
|
||||
for i, btfVal := range rawvals {
|
||||
name, err := rawStrings.LookupName(btfVal.NameOff)
|
||||
name, err := rawStrings.Lookup(btfVal.NameOff)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("get name for enum value %d: %s", i, err)
|
||||
}
|
||||
@ -812,7 +873,7 @@ func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (types []Type,
|
||||
rawparams := raw.data.([]btfParam)
|
||||
params := make([]FuncParam, 0, len(rawparams))
|
||||
for i, param := range rawparams {
|
||||
name, err := rawStrings.LookupName(param.NameOff)
|
||||
name, err := rawStrings.Lookup(param.NameOff)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("get name for func proto parameter %d: %s", i, err)
|
||||
}
|
||||
@ -848,14 +909,17 @@ func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (types []Type,
|
||||
}
|
||||
typ = &Datasec{id, name, raw.SizeType, vars}
|
||||
|
||||
case kindFloat:
|
||||
typ = &Float{id, name, raw.Size()}
|
||||
|
||||
default:
|
||||
return nil, nil, fmt.Errorf("type id %d: unknown kind: %v", id, raw.Kind())
|
||||
}
|
||||
|
||||
types = append(types, typ)
|
||||
|
||||
if named, ok := typ.(namedType); ok {
|
||||
if name := essentialName(named.name()); name != "" {
|
||||
if named, ok := typ.(NamedType); ok {
|
||||
if name := essentialName(named.TypeName()); name != "" {
|
||||
namedTypes[name] = append(namedTypes[name], named)
|
||||
}
|
||||
}
|
||||
|
4
src/runtime/vendor/github.com/cilium/ebpf/internal/cpu.go
generated
vendored
4
src/runtime/vendor/github.com/cilium/ebpf/internal/cpu.go
generated
vendored
@ -2,7 +2,7 @@ package internal
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
@ -24,7 +24,7 @@ func PossibleCPUs() (int, error) {
|
||||
}
|
||||
|
||||
func parseCPUsFromFile(path string) (int, error) {
|
||||
spec, err := ioutil.ReadFile(path)
|
||||
spec, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
1
src/runtime/vendor/github.com/cilium/ebpf/internal/ptr_32_be.go
generated
vendored
1
src/runtime/vendor/github.com/cilium/ebpf/internal/ptr_32_be.go
generated
vendored
@ -1,3 +1,4 @@
|
||||
//go:build armbe || mips || mips64p32
|
||||
// +build armbe mips mips64p32
|
||||
|
||||
package internal
|
||||
|
1
src/runtime/vendor/github.com/cilium/ebpf/internal/ptr_32_le.go
generated
vendored
1
src/runtime/vendor/github.com/cilium/ebpf/internal/ptr_32_le.go
generated
vendored
@ -1,3 +1,4 @@
|
||||
//go:build 386 || amd64p32 || arm || mipsle || mips64p32le
|
||||
// +build 386 amd64p32 arm mipsle mips64p32le
|
||||
|
||||
package internal
|
||||
|
4
src/runtime/vendor/github.com/cilium/ebpf/internal/ptr_64.go
generated
vendored
4
src/runtime/vendor/github.com/cilium/ebpf/internal/ptr_64.go
generated
vendored
@ -1,5 +1,5 @@
|
||||
// +build !386,!amd64p32,!arm,!mipsle,!mips64p32le
|
||||
// +build !armbe,!mips,!mips64p32
|
||||
//go:build !386 && !amd64p32 && !arm && !mipsle && !mips64p32le && !armbe && !mips && !mips64p32
|
||||
// +build !386,!amd64p32,!arm,!mipsle,!mips64p32le,!armbe,!mips,!mips64p32
|
||||
|
||||
package internal
|
||||
|
||||
|
59
src/runtime/vendor/github.com/cilium/ebpf/internal/syscall.go
generated
vendored
59
src/runtime/vendor/github.com/cilium/ebpf/internal/syscall.go
generated
vendored
@ -1,6 +1,7 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
@ -68,6 +69,48 @@ func BPF(cmd BPFCmd, attr unsafe.Pointer, size uintptr) (uintptr, error) {
|
||||
return r1, err
|
||||
}
|
||||
|
||||
type BPFProgLoadAttr struct {
|
||||
ProgType uint32
|
||||
InsCount uint32
|
||||
Instructions Pointer
|
||||
License Pointer
|
||||
LogLevel uint32
|
||||
LogSize uint32
|
||||
LogBuf Pointer
|
||||
KernelVersion uint32 // since 4.1 2541517c32be
|
||||
ProgFlags uint32 // since 4.11 e07b98d9bffe
|
||||
ProgName BPFObjName // since 4.15 067cae47771c
|
||||
ProgIfIndex uint32 // since 4.15 1f6f4cb7ba21
|
||||
ExpectedAttachType uint32 // since 4.17 5e43f899b03a
|
||||
ProgBTFFd uint32
|
||||
FuncInfoRecSize uint32
|
||||
FuncInfo Pointer
|
||||
FuncInfoCnt uint32
|
||||
LineInfoRecSize uint32
|
||||
LineInfo Pointer
|
||||
LineInfoCnt uint32
|
||||
AttachBTFID uint32
|
||||
AttachProgFd uint32
|
||||
}
|
||||
|
||||
// BPFProgLoad wraps BPF_PROG_LOAD.
|
||||
func BPFProgLoad(attr *BPFProgLoadAttr) (*FD, error) {
|
||||
for {
|
||||
fd, err := BPF(BPF_PROG_LOAD, unsafe.Pointer(attr), unsafe.Sizeof(*attr))
|
||||
// As of ~4.20 the verifier can be interrupted by a signal,
|
||||
// and returns EAGAIN in that case.
|
||||
if errors.Is(err, unix.EAGAIN) {
|
||||
continue
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewFD(uint32(fd)), nil
|
||||
}
|
||||
}
|
||||
|
||||
type BPFProgAttachAttr struct {
|
||||
TargetFd uint32
|
||||
AttachBpfFd uint32
|
||||
@ -180,6 +223,22 @@ func BPFObjGetInfoByFD(fd *FD, info unsafe.Pointer, size uintptr) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type bpfGetFDByIDAttr struct {
|
||||
id uint32
|
||||
next uint32
|
||||
}
|
||||
|
||||
// BPFObjGetInfoByFD wraps BPF_*_GET_FD_BY_ID.
|
||||
//
|
||||
// Available from 4.13.
|
||||
func BPFObjGetFDByID(cmd BPFCmd, id uint32) (*FD, error) {
|
||||
attr := bpfGetFDByIDAttr{
|
||||
id: id,
|
||||
}
|
||||
ptr, err := BPF(cmd, unsafe.Pointer(&attr), unsafe.Sizeof(attr))
|
||||
return NewFD(uint32(ptr)), err
|
||||
}
|
||||
|
||||
// BPFObjName is a null-terminated string made up of
|
||||
// 'A-Za-z0-9_' characters.
|
||||
type BPFObjName [unix.BPF_OBJ_NAME_LEN]byte
|
||||
|
16
src/runtime/vendor/github.com/cilium/ebpf/internal/unix/types_linux.go
generated
vendored
16
src/runtime/vendor/github.com/cilium/ebpf/internal/unix/types_linux.go
generated
vendored
@ -1,3 +1,4 @@
|
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
package unix
|
||||
@ -20,10 +21,11 @@ const (
|
||||
EPERM = linux.EPERM
|
||||
ESRCH = linux.ESRCH
|
||||
ENODEV = linux.ENODEV
|
||||
EBADF = linux.EBADF
|
||||
E2BIG = linux.E2BIG
|
||||
// ENOTSUPP is not the same as ENOTSUP or EOPNOTSUP
|
||||
ENOTSUPP = syscall.Errno(0x20c)
|
||||
|
||||
EBADF = linux.EBADF
|
||||
BPF_F_NO_PREALLOC = linux.BPF_F_NO_PREALLOC
|
||||
BPF_F_NUMA_NODE = linux.BPF_F_NUMA_NODE
|
||||
BPF_F_RDONLY = linux.BPF_F_RDONLY
|
||||
@ -35,6 +37,9 @@ const (
|
||||
BPF_F_INNER_MAP = linux.BPF_F_INNER_MAP
|
||||
BPF_OBJ_NAME_LEN = linux.BPF_OBJ_NAME_LEN
|
||||
BPF_TAG_SIZE = linux.BPF_TAG_SIZE
|
||||
BPF_RINGBUF_BUSY_BIT = linux.BPF_RINGBUF_BUSY_BIT
|
||||
BPF_RINGBUF_DISCARD_BIT = linux.BPF_RINGBUF_DISCARD_BIT
|
||||
BPF_RINGBUF_HDR_SZ = linux.BPF_RINGBUF_HDR_SZ
|
||||
SYS_BPF = linux.SYS_BPF
|
||||
F_DUPFD_CLOEXEC = linux.F_DUPFD_CLOEXEC
|
||||
EPOLL_CTL_ADD = linux.EPOLL_CTL_ADD
|
||||
@ -69,11 +74,6 @@ type Statfs_t = linux.Statfs_t
|
||||
// Rlimit is a wrapper
|
||||
type Rlimit = linux.Rlimit
|
||||
|
||||
// Setrlimit is a wrapper
|
||||
func Setrlimit(resource int, rlim *Rlimit) (err error) {
|
||||
return linux.Setrlimit(resource, rlim)
|
||||
}
|
||||
|
||||
// Syscall is a wrapper
|
||||
func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) {
|
||||
return linux.Syscall(trap, a1, a2, a3)
|
||||
@ -202,3 +202,7 @@ func KernelRelease() (string, error) {
|
||||
release := string(uname.Release[:end])
|
||||
return release, nil
|
||||
}
|
||||
|
||||
func Prlimit(pid, resource int, new, old *Rlimit) error {
|
||||
return linux.Prlimit(pid, resource, new, old)
|
||||
}
|
||||
|
14
src/runtime/vendor/github.com/cilium/ebpf/internal/unix/types_other.go
generated
vendored
14
src/runtime/vendor/github.com/cilium/ebpf/internal/unix/types_other.go
generated
vendored
@ -1,3 +1,4 @@
|
||||
//go:build !linux
|
||||
// +build !linux
|
||||
|
||||
package unix
|
||||
@ -21,6 +22,7 @@ const (
|
||||
ESRCH = syscall.ESRCH
|
||||
ENODEV = syscall.ENODEV
|
||||
EBADF = syscall.Errno(0)
|
||||
E2BIG = syscall.Errno(0)
|
||||
// ENOTSUPP is not the same as ENOTSUP or EOPNOTSUP
|
||||
ENOTSUPP = syscall.Errno(0x20c)
|
||||
|
||||
@ -35,6 +37,9 @@ const (
|
||||
BPF_F_INNER_MAP = 0
|
||||
BPF_OBJ_NAME_LEN = 0x10
|
||||
BPF_TAG_SIZE = 0x8
|
||||
BPF_RINGBUF_BUSY_BIT = 0
|
||||
BPF_RINGBUF_DISCARD_BIT = 0
|
||||
BPF_RINGBUF_HDR_SZ = 0
|
||||
SYS_BPF = 321
|
||||
F_DUPFD_CLOEXEC = 0x406
|
||||
EPOLLIN = 0x1
|
||||
@ -86,11 +91,6 @@ type Rlimit struct {
|
||||
Max uint64
|
||||
}
|
||||
|
||||
// Setrlimit is a wrapper
|
||||
func Setrlimit(resource int, rlim *Rlimit) (err error) {
|
||||
return errNonLinux
|
||||
}
|
||||
|
||||
// Syscall is a wrapper
|
||||
func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) {
|
||||
return 0, 0, syscall.Errno(1)
|
||||
@ -261,3 +261,7 @@ func Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags
|
||||
func KernelRelease() (string, error) {
|
||||
return "", errNonLinux
|
||||
}
|
||||
|
||||
func Prlimit(pid, resource int, new, old *Rlimit) error {
|
||||
return errNonLinux
|
||||
}
|
||||
|
4
src/runtime/vendor/github.com/cilium/ebpf/internal/version.go
generated
vendored
4
src/runtime/vendor/github.com/cilium/ebpf/internal/version.go
generated
vendored
@ -2,7 +2,7 @@ package internal
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"regexp"
|
||||
"sync"
|
||||
|
||||
@ -109,7 +109,7 @@ func detectKernelVersion() (Version, error) {
|
||||
// Example format: Ubuntu 4.15.0-91.92-generic 4.15.18
|
||||
// This method exists in the kernel itself, see d18acd15c
|
||||
// ("perf tools: Fix kernel version error in ubuntu").
|
||||
if pvs, err := ioutil.ReadFile("/proc/version_signature"); err == nil {
|
||||
if pvs, err := os.ReadFile("/proc/version_signature"); err == nil {
|
||||
// If /proc/version_signature exists, failing to parse it is an error.
|
||||
// It only exists on Ubuntu, where the real patch level is not obtainable
|
||||
// through any other method.
|
||||
|
88
src/runtime/vendor/github.com/cilium/ebpf/link/freplace.go
generated
vendored
Normal file
88
src/runtime/vendor/github.com/cilium/ebpf/link/freplace.go
generated
vendored
Normal file
@ -0,0 +1,88 @@
|
||||
package link
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/cilium/ebpf"
|
||||
"github.com/cilium/ebpf/internal/btf"
|
||||
)
|
||||
|
||||
type FreplaceLink struct {
|
||||
RawLink
|
||||
}
|
||||
|
||||
// AttachFreplace attaches the given eBPF program to the function it replaces.
|
||||
//
|
||||
// The program and name can either be provided at link time, or can be provided
|
||||
// at program load time. If they were provided at load time, they should be nil
|
||||
// and empty respectively here, as they will be ignored by the kernel.
|
||||
// Examples:
|
||||
//
|
||||
// AttachFreplace(dispatcher, "function", replacement)
|
||||
// AttachFreplace(nil, "", replacement)
|
||||
func AttachFreplace(targetProg *ebpf.Program, name string, prog *ebpf.Program) (*FreplaceLink, error) {
|
||||
if (name == "") != (targetProg == nil) {
|
||||
return nil, fmt.Errorf("must provide both or neither of name and targetProg: %w", errInvalidInput)
|
||||
}
|
||||
if prog == nil {
|
||||
return nil, fmt.Errorf("prog cannot be nil: %w", errInvalidInput)
|
||||
}
|
||||
if prog.Type() != ebpf.Extension {
|
||||
return nil, fmt.Errorf("eBPF program type %s is not an Extension: %w", prog.Type(), errInvalidInput)
|
||||
}
|
||||
|
||||
var (
|
||||
target int
|
||||
typeID btf.TypeID
|
||||
)
|
||||
if targetProg != nil {
|
||||
info, err := targetProg.Info()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
btfID, ok := info.BTFID()
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("could not get BTF ID for program %s: %w", info.Name, errInvalidInput)
|
||||
}
|
||||
btfHandle, err := btf.NewHandleFromID(btfID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer btfHandle.Close()
|
||||
|
||||
var function *btf.Func
|
||||
if err := btfHandle.Spec().FindType(name, &function); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
target = targetProg.FD()
|
||||
typeID = function.ID()
|
||||
}
|
||||
|
||||
link, err := AttachRawLink(RawLinkOptions{
|
||||
Target: target,
|
||||
Program: prog,
|
||||
Attach: ebpf.AttachNone,
|
||||
BTF: typeID,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &FreplaceLink{*link}, nil
|
||||
}
|
||||
|
||||
// Update implements the Link interface.
|
||||
func (f *FreplaceLink) Update(new *ebpf.Program) error {
|
||||
return fmt.Errorf("freplace update: %w", ErrNotSupported)
|
||||
}
|
||||
|
||||
// LoadPinnedFreplace loads a pinned iterator from a bpffs.
|
||||
func LoadPinnedFreplace(fileName string, opts *ebpf.LoadPinOptions) (*FreplaceLink, error) {
|
||||
link, err := LoadPinnedRawLink(fileName, TracingType, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &FreplaceLink{*link}, err
|
||||
}
|
38
src/runtime/vendor/github.com/cilium/ebpf/link/kprobe.go
generated
vendored
38
src/runtime/vendor/github.com/cilium/ebpf/link/kprobe.go
generated
vendored
@ -5,7 +5,6 @@ import (
|
||||
"crypto/rand"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
@ -72,10 +71,11 @@ func (pt probeType) RetprobeBit() (uint64, error) {
|
||||
// given kernel symbol starts executing. See /proc/kallsyms for available
|
||||
// symbols. For example, printk():
|
||||
//
|
||||
// Kprobe("printk", prog)
|
||||
// kp, err := Kprobe("printk", prog)
|
||||
//
|
||||
// The resulting Link must be Closed during program shutdown to avoid leaking
|
||||
// system resources.
|
||||
// Losing the reference to the resulting Link (kp) will close the Kprobe
|
||||
// and prevent further execution of prog. The Link must be Closed during
|
||||
// program shutdown to avoid leaking system resources.
|
||||
func Kprobe(symbol string, prog *ebpf.Program) (Link, error) {
|
||||
k, err := kprobe(symbol, prog, false)
|
||||
if err != nil {
|
||||
@ -95,10 +95,11 @@ func Kprobe(symbol string, prog *ebpf.Program) (Link, error) {
|
||||
// before the given kernel symbol exits, with the function stack left intact.
|
||||
// See /proc/kallsyms for available symbols. For example, printk():
|
||||
//
|
||||
// Kretprobe("printk", prog)
|
||||
// kp, err := Kretprobe("printk", prog)
|
||||
//
|
||||
// The resulting Link must be Closed during program shutdown to avoid leaking
|
||||
// system resources.
|
||||
// Losing the reference to the resulting Link (kp) will close the Kretprobe
|
||||
// and prevent further execution of prog. The Link must be Closed during
|
||||
// program shutdown to avoid leaking system resources.
|
||||
func Kretprobe(symbol string, prog *ebpf.Program) (Link, error) {
|
||||
k, err := kprobe(symbol, prog, true)
|
||||
if err != nil {
|
||||
@ -157,7 +158,7 @@ func kprobe(symbol string, prog *ebpf.Program, ret bool) (*perfEvent, error) {
|
||||
// pmuKprobe opens a perf event based on the kprobe PMU.
|
||||
// Returns os.ErrNotExist if the given symbol does not exist in the kernel.
|
||||
func pmuKprobe(symbol string, ret bool) (*perfEvent, error) {
|
||||
return pmuProbe(kprobeType, symbol, "", 0, ret)
|
||||
return pmuProbe(kprobeType, symbol, "", 0, perfAllThreads, ret)
|
||||
}
|
||||
|
||||
// pmuProbe opens a perf event based on a Performance Monitoring Unit.
|
||||
@ -167,7 +168,7 @@ func pmuKprobe(symbol string, ret bool) (*perfEvent, error) {
|
||||
// 33ea4b24277b "perf/core: Implement the 'perf_uprobe' PMU"
|
||||
//
|
||||
// Returns ErrNotSupported if the kernel doesn't support perf_[k,u]probe PMU
|
||||
func pmuProbe(typ probeType, symbol, path string, offset uint64, ret bool) (*perfEvent, error) {
|
||||
func pmuProbe(typ probeType, symbol, path string, offset uint64, pid int, ret bool) (*perfEvent, error) {
|
||||
// Getting the PMU type will fail if the kernel doesn't support
|
||||
// the perf_[k,u]probe PMU.
|
||||
et, err := getPMUEventType(typ)
|
||||
@ -191,7 +192,7 @@ func pmuProbe(typ probeType, symbol, path string, offset uint64, ret bool) (*per
|
||||
switch typ {
|
||||
case kprobeType:
|
||||
// Create a pointer to a NUL-terminated string for the kernel.
|
||||
sp, err := unsafeStringPtr(symbol)
|
||||
sp, err = unsafeStringPtr(symbol)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -202,7 +203,7 @@ func pmuProbe(typ probeType, symbol, path string, offset uint64, ret bool) (*per
|
||||
Config: config, // Retprobe flag
|
||||
}
|
||||
case uprobeType:
|
||||
sp, err := unsafeStringPtr(path)
|
||||
sp, err = unsafeStringPtr(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -220,7 +221,7 @@ func pmuProbe(typ probeType, symbol, path string, offset uint64, ret bool) (*per
|
||||
}
|
||||
}
|
||||
|
||||
fd, err := unix.PerfEventOpen(&attr, perfAllThreads, 0, -1, unix.PERF_FLAG_FD_CLOEXEC)
|
||||
fd, err := unix.PerfEventOpen(&attr, pid, 0, -1, unix.PERF_FLAG_FD_CLOEXEC)
|
||||
|
||||
// Since commit 97c753e62e6c, ENOENT is correctly returned instead of EINVAL
|
||||
// when trying to create a kretprobe for a missing symbol. Make sure ENOENT
|
||||
@ -228,6 +229,11 @@ func pmuProbe(typ probeType, symbol, path string, offset uint64, ret bool) (*per
|
||||
if errors.Is(err, os.ErrNotExist) || errors.Is(err, unix.EINVAL) {
|
||||
return nil, fmt.Errorf("symbol '%s' not found: %w", symbol, os.ErrNotExist)
|
||||
}
|
||||
// Since at least commit cb9a19fe4aa51, ENOTSUPP is returned
|
||||
// when attempting to set a uprobe on a trap instruction.
|
||||
if errors.Is(err, unix.ENOTSUPP) {
|
||||
return nil, fmt.Errorf("failed setting uprobe on offset %#x (possible trap insn): %w", offset, err)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("opening perf event: %w", err)
|
||||
}
|
||||
@ -246,7 +252,7 @@ func pmuProbe(typ probeType, symbol, path string, offset uint64, ret bool) (*per
|
||||
|
||||
// tracefsKprobe creates a Kprobe tracefs entry.
|
||||
func tracefsKprobe(symbol string, ret bool) (*perfEvent, error) {
|
||||
return tracefsProbe(kprobeType, symbol, "", 0, ret)
|
||||
return tracefsProbe(kprobeType, symbol, "", 0, perfAllThreads, ret)
|
||||
}
|
||||
|
||||
// tracefsProbe creates a trace event by writing an entry to <tracefs>/[k,u]probe_events.
|
||||
@ -255,7 +261,7 @@ func tracefsKprobe(symbol string, ret bool) (*perfEvent, error) {
|
||||
// Path and offset are only set in the case of uprobe(s) and are used to set
|
||||
// the executable/library path on the filesystem and the offset where the probe is inserted.
|
||||
// A perf event is then opened on the newly-created trace event and returned to the caller.
|
||||
func tracefsProbe(typ probeType, symbol, path string, offset uint64, ret bool) (*perfEvent, error) {
|
||||
func tracefsProbe(typ probeType, symbol, path string, offset uint64, pid int, ret bool) (*perfEvent, error) {
|
||||
// Generate a random string for each trace event we attempt to create.
|
||||
// This value is used as the 'group' token in tracefs to allow creating
|
||||
// multiple kprobe trace events with the same name.
|
||||
@ -288,7 +294,7 @@ func tracefsProbe(typ probeType, symbol, path string, offset uint64, ret bool) (
|
||||
}
|
||||
|
||||
// Kprobes are ephemeral tracepoints and share the same perf event type.
|
||||
fd, err := openTracepointPerfEvent(tid)
|
||||
fd, err := openTracepointPerfEvent(tid, pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -413,7 +419,7 @@ func probePrefix(ret bool) string {
|
||||
func determineRetprobeBit(typ probeType) (uint64, error) {
|
||||
p := filepath.Join("/sys/bus/event_source/devices/", typ.String(), "/format/retprobe")
|
||||
|
||||
data, err := ioutil.ReadFile(p)
|
||||
data, err := os.ReadFile(p)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
14
src/runtime/vendor/github.com/cilium/ebpf/link/link.go
generated
vendored
14
src/runtime/vendor/github.com/cilium/ebpf/link/link.go
generated
vendored
@ -6,6 +6,7 @@ import (
|
||||
|
||||
"github.com/cilium/ebpf"
|
||||
"github.com/cilium/ebpf/internal"
|
||||
"github.com/cilium/ebpf/internal/btf"
|
||||
)
|
||||
|
||||
var ErrNotSupported = internal.ErrNotSupported
|
||||
@ -29,8 +30,8 @@ type Link interface {
|
||||
|
||||
// Close frees resources.
|
||||
//
|
||||
// The link will be broken unless it has been pinned. A link
|
||||
// may continue past the lifetime of the process if Close is
|
||||
// The link will be broken unless it has been successfully pinned.
|
||||
// A link may continue past the lifetime of the process if Close is
|
||||
// not called.
|
||||
Close() error
|
||||
|
||||
@ -49,6 +50,8 @@ type RawLinkOptions struct {
|
||||
Program *ebpf.Program
|
||||
// Attach must match the attach type of Program.
|
||||
Attach ebpf.AttachType
|
||||
// BTF is the BTF of the attachment target.
|
||||
BTF btf.TypeID
|
||||
}
|
||||
|
||||
// RawLinkInfo contains metadata on a link.
|
||||
@ -83,9 +86,10 @@ func AttachRawLink(opts RawLinkOptions) (*RawLink, error) {
|
||||
}
|
||||
|
||||
attr := bpfLinkCreateAttr{
|
||||
targetFd: uint32(opts.Target),
|
||||
progFd: uint32(progFd),
|
||||
attachType: opts.Attach,
|
||||
targetFd: uint32(opts.Target),
|
||||
progFd: uint32(progFd),
|
||||
attachType: opts.Attach,
|
||||
targetBTFID: uint32(opts.BTF),
|
||||
}
|
||||
fd, err := bpfLinkCreate(&attr)
|
||||
if err != nil {
|
||||
|
7
src/runtime/vendor/github.com/cilium/ebpf/link/perf_event.go
generated
vendored
7
src/runtime/vendor/github.com/cilium/ebpf/link/perf_event.go
generated
vendored
@ -4,7 +4,6 @@ import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
@ -236,7 +235,7 @@ func getPMUEventType(typ probeType) (uint64, error) {
|
||||
// openTracepointPerfEvent opens a tracepoint-type perf event. System-wide
|
||||
// [k,u]probes created by writing to <tracefs>/[k,u]probe_events are tracepoints
|
||||
// behind the scenes, and can be attached to using these perf events.
|
||||
func openTracepointPerfEvent(tid uint64) (*internal.FD, error) {
|
||||
func openTracepointPerfEvent(tid uint64, pid int) (*internal.FD, error) {
|
||||
attr := unix.PerfEventAttr{
|
||||
Type: unix.PERF_TYPE_TRACEPOINT,
|
||||
Config: tid,
|
||||
@ -245,7 +244,7 @@ func openTracepointPerfEvent(tid uint64) (*internal.FD, error) {
|
||||
Wakeup: 1,
|
||||
}
|
||||
|
||||
fd, err := unix.PerfEventOpen(&attr, perfAllThreads, 0, -1, unix.PERF_FLAG_FD_CLOEXEC)
|
||||
fd, err := unix.PerfEventOpen(&attr, pid, 0, -1, unix.PERF_FLAG_FD_CLOEXEC)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("opening tracepoint perf event: %w", err)
|
||||
}
|
||||
@ -263,7 +262,7 @@ func uint64FromFile(base string, path ...string) (uint64, error) {
|
||||
return 0, fmt.Errorf("path '%s' attempts to escape base path '%s': %w", l, base, errInvalidInput)
|
||||
}
|
||||
|
||||
data, err := ioutil.ReadFile(p)
|
||||
data, err := os.ReadFile(p)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("reading file %s: %w", p, err)
|
||||
}
|
||||
|
9
src/runtime/vendor/github.com/cilium/ebpf/link/syscalls.go
generated
vendored
9
src/runtime/vendor/github.com/cilium/ebpf/link/syscalls.go
generated
vendored
@ -88,10 +88,11 @@ var haveProgAttachReplace = internal.FeatureTest("BPF_PROG_ATTACH atomic replace
|
||||
})
|
||||
|
||||
type bpfLinkCreateAttr struct {
|
||||
progFd uint32
|
||||
targetFd uint32
|
||||
attachType ebpf.AttachType
|
||||
flags uint32
|
||||
progFd uint32
|
||||
targetFd uint32
|
||||
attachType ebpf.AttachType
|
||||
flags uint32
|
||||
targetBTFID uint32
|
||||
}
|
||||
|
||||
func bpfLinkCreate(attr *bpfLinkCreateAttr) (*internal.FD, error) {
|
||||
|
8
src/runtime/vendor/github.com/cilium/ebpf/link/tracepoint.go
generated
vendored
8
src/runtime/vendor/github.com/cilium/ebpf/link/tracepoint.go
generated
vendored
@ -11,7 +11,11 @@ import (
|
||||
// tracepoints. The top-level directory is the group, the event's subdirectory
|
||||
// is the name. Example:
|
||||
//
|
||||
// Tracepoint("syscalls", "sys_enter_fork", prog)
|
||||
// tp, err := Tracepoint("syscalls", "sys_enter_fork", prog)
|
||||
//
|
||||
// Losing the reference to the resulting Link (tp) will close the Tracepoint
|
||||
// and prevent further execution of prog. The Link must be Closed during
|
||||
// program shutdown to avoid leaking system resources.
|
||||
//
|
||||
// Note that attaching eBPF programs to syscalls (sys_enter_*/sys_exit_*) is
|
||||
// only possible as of kernel 4.14 (commit cf5f5ce).
|
||||
@ -34,7 +38,7 @@ func Tracepoint(group, name string, prog *ebpf.Program) (Link, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fd, err := openTracepointPerfEvent(tid)
|
||||
fd, err := openTracepointPerfEvent(tid, perfAllThreads)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
135
src/runtime/vendor/github.com/cilium/ebpf/link/uprobe.go
generated
vendored
135
src/runtime/vendor/github.com/cilium/ebpf/link/uprobe.go
generated
vendored
@ -25,14 +25,18 @@ var (
|
||||
value uint64
|
||||
err error
|
||||
}{}
|
||||
|
||||
// ErrNoSymbol indicates that the given symbol was not found
|
||||
// in the ELF symbols table.
|
||||
ErrNoSymbol = errors.New("not found")
|
||||
)
|
||||
|
||||
// Executable defines an executable program on the filesystem.
|
||||
type Executable struct {
|
||||
// Path of the executable on the filesystem.
|
||||
path string
|
||||
// Parsed ELF symbols and dynamic symbols.
|
||||
symbols map[string]elf.Symbol
|
||||
// Parsed ELF symbols and dynamic symbols offsets.
|
||||
offsets map[string]uint64
|
||||
}
|
||||
|
||||
// UprobeOptions defines additional parameters that will be used
|
||||
@ -41,6 +45,9 @@ type UprobeOptions struct {
|
||||
// Symbol offset. Must be provided in case of external symbols (shared libs).
|
||||
// If set, overrides the offset eventually parsed from the executable.
|
||||
Offset uint64
|
||||
// Only set the uprobe on the given process ID. Useful when tracing
|
||||
// shared library calls or programs that have many running instances.
|
||||
PID int
|
||||
}
|
||||
|
||||
// To open a new Executable, use:
|
||||
@ -64,42 +71,84 @@ func OpenExecutable(path string) (*Executable, error) {
|
||||
return nil, fmt.Errorf("parse ELF file: %w", err)
|
||||
}
|
||||
|
||||
var ex = Executable{
|
||||
path: path,
|
||||
symbols: make(map[string]elf.Symbol),
|
||||
}
|
||||
if err := ex.addSymbols(se.Symbols); err != nil {
|
||||
return nil, err
|
||||
if se.Type != elf.ET_EXEC && se.Type != elf.ET_DYN {
|
||||
// ELF is not an executable or a shared object.
|
||||
return nil, errors.New("the given file is not an executable or a shared object")
|
||||
}
|
||||
|
||||
if err := ex.addSymbols(se.DynamicSymbols); err != nil {
|
||||
ex := Executable{
|
||||
path: path,
|
||||
offsets: make(map[string]uint64),
|
||||
}
|
||||
|
||||
if err := ex.load(se); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &ex, nil
|
||||
}
|
||||
|
||||
func (ex *Executable) addSymbols(f func() ([]elf.Symbol, error)) error {
|
||||
// elf.Symbols and elf.DynamicSymbols return ErrNoSymbols if the section is not found.
|
||||
syms, err := f()
|
||||
func (ex *Executable) load(f *internal.SafeELFFile) error {
|
||||
syms, err := f.Symbols()
|
||||
if err != nil && !errors.Is(err, elf.ErrNoSymbols) {
|
||||
return err
|
||||
}
|
||||
|
||||
dynsyms, err := f.DynamicSymbols()
|
||||
if err != nil && !errors.Is(err, elf.ErrNoSymbols) {
|
||||
return err
|
||||
}
|
||||
|
||||
syms = append(syms, dynsyms...)
|
||||
|
||||
for _, s := range syms {
|
||||
if elf.ST_TYPE(s.Info) != elf.STT_FUNC {
|
||||
// Symbol not associated with a function or other executable code.
|
||||
continue
|
||||
}
|
||||
ex.symbols[s.Name] = s
|
||||
|
||||
off := s.Value
|
||||
|
||||
// Loop over ELF segments.
|
||||
for _, prog := range f.Progs {
|
||||
// Skip uninteresting segments.
|
||||
if prog.Type != elf.PT_LOAD || (prog.Flags&elf.PF_X) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
if prog.Vaddr <= s.Value && s.Value < (prog.Vaddr+prog.Memsz) {
|
||||
// If the symbol value is contained in the segment, calculate
|
||||
// the symbol offset.
|
||||
//
|
||||
// fn symbol offset = fn symbol VA - .text VA + .text offset
|
||||
//
|
||||
// stackoverflow.com/a/40249502
|
||||
off = s.Value - prog.Vaddr + prog.Off
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
ex.offsets[s.Name] = off
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ex *Executable) symbol(symbol string) (*elf.Symbol, error) {
|
||||
if s, ok := ex.symbols[symbol]; ok {
|
||||
return &s, nil
|
||||
func (ex *Executable) offset(symbol string) (uint64, error) {
|
||||
if off, ok := ex.offsets[symbol]; ok {
|
||||
// Symbols with location 0 from section undef are shared library calls and
|
||||
// are relocated before the binary is executed. Dynamic linking is not
|
||||
// implemented by the library, so mark this as unsupported for now.
|
||||
//
|
||||
// Since only offset values are stored and not elf.Symbol, if the value is 0,
|
||||
// assume it's an external symbol.
|
||||
if off == 0 {
|
||||
return 0, fmt.Errorf("cannot resolve %s library call '%s', "+
|
||||
"consider providing the offset via options: %w", ex.path, symbol, ErrNotSupported)
|
||||
}
|
||||
return off, nil
|
||||
}
|
||||
return nil, fmt.Errorf("symbol %s not found", symbol)
|
||||
return 0, fmt.Errorf("symbol %s: %w", symbol, ErrNoSymbol)
|
||||
}
|
||||
|
||||
// Uprobe attaches the given eBPF program to a perf event that fires when the
|
||||
@ -112,11 +161,14 @@ func (ex *Executable) symbol(symbol string) (*elf.Symbol, error) {
|
||||
// When using symbols which belongs to shared libraries,
|
||||
// an offset must be provided via options:
|
||||
//
|
||||
// ex.Uprobe("main", prog, &UprobeOptions{Offset: 0x123})
|
||||
// up, err := ex.Uprobe("main", prog, &UprobeOptions{Offset: 0x123})
|
||||
//
|
||||
// The resulting Link must be Closed during program shutdown to avoid leaking
|
||||
// system resources. Functions provided by shared libraries can currently not
|
||||
// be traced and will result in an ErrNotSupported.
|
||||
// Losing the reference to the resulting Link (up) will close the Uprobe
|
||||
// and prevent further execution of prog. The Link must be Closed during
|
||||
// program shutdown to avoid leaking system resources.
|
||||
//
|
||||
// Functions provided by shared libraries can currently not be traced and
|
||||
// will result in an ErrNotSupported.
|
||||
func (ex *Executable) Uprobe(symbol string, prog *ebpf.Program, opts *UprobeOptions) (Link, error) {
|
||||
u, err := ex.uprobe(symbol, prog, opts, false)
|
||||
if err != nil {
|
||||
@ -141,11 +193,14 @@ func (ex *Executable) Uprobe(symbol string, prog *ebpf.Program, opts *UprobeOpti
|
||||
// When using symbols which belongs to shared libraries,
|
||||
// an offset must be provided via options:
|
||||
//
|
||||
// ex.Uretprobe("main", prog, &UprobeOptions{Offset: 0x123})
|
||||
// up, err := ex.Uretprobe("main", prog, &UprobeOptions{Offset: 0x123})
|
||||
//
|
||||
// The resulting Link must be Closed during program shutdown to avoid leaking
|
||||
// system resources. Functions provided by shared libraries can currently not
|
||||
// be traced and will result in an ErrNotSupported.
|
||||
// Losing the reference to the resulting Link (up) will close the Uprobe
|
||||
// and prevent further execution of prog. The Link must be Closed during
|
||||
// program shutdown to avoid leaking system resources.
|
||||
//
|
||||
// Functions provided by shared libraries can currently not be traced and
|
||||
// will result in an ErrNotSupported.
|
||||
func (ex *Executable) Uretprobe(symbol string, prog *ebpf.Program, opts *UprobeOptions) (Link, error) {
|
||||
u, err := ex.uprobe(symbol, prog, opts, true)
|
||||
if err != nil {
|
||||
@ -175,24 +230,20 @@ func (ex *Executable) uprobe(symbol string, prog *ebpf.Program, opts *UprobeOpti
|
||||
if opts != nil && opts.Offset != 0 {
|
||||
offset = opts.Offset
|
||||
} else {
|
||||
sym, err := ex.symbol(symbol)
|
||||
off, err := ex.offset(symbol)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("symbol '%s' not found: %w", symbol, err)
|
||||
return nil, err
|
||||
}
|
||||
offset = off
|
||||
}
|
||||
|
||||
// Symbols with location 0 from section undef are shared library calls and
|
||||
// are relocated before the binary is executed. Dynamic linking is not
|
||||
// implemented by the library, so mark this as unsupported for now.
|
||||
if sym.Section == elf.SHN_UNDEF && sym.Value == 0 {
|
||||
return nil, fmt.Errorf("cannot resolve %s library call '%s', "+
|
||||
"consider providing the offset via options: %w", ex.path, symbol, ErrNotSupported)
|
||||
}
|
||||
|
||||
offset = sym.Value
|
||||
pid := perfAllThreads
|
||||
if opts != nil && opts.PID != 0 {
|
||||
pid = opts.PID
|
||||
}
|
||||
|
||||
// Use uprobe PMU if the kernel has it available.
|
||||
tp, err := pmuUprobe(symbol, ex.path, offset, ret)
|
||||
tp, err := pmuUprobe(symbol, ex.path, offset, pid, ret)
|
||||
if err == nil {
|
||||
return tp, nil
|
||||
}
|
||||
@ -201,7 +252,7 @@ func (ex *Executable) uprobe(symbol string, prog *ebpf.Program, opts *UprobeOpti
|
||||
}
|
||||
|
||||
// Use tracefs if uprobe PMU is missing.
|
||||
tp, err = tracefsUprobe(uprobeSanitizedSymbol(symbol), ex.path, offset, ret)
|
||||
tp, err = tracefsUprobe(uprobeSanitizedSymbol(symbol), ex.path, offset, pid, ret)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("creating trace event '%s:%s' in tracefs: %w", ex.path, symbol, err)
|
||||
}
|
||||
@ -210,13 +261,13 @@ func (ex *Executable) uprobe(symbol string, prog *ebpf.Program, opts *UprobeOpti
|
||||
}
|
||||
|
||||
// pmuUprobe opens a perf event based on the uprobe PMU.
|
||||
func pmuUprobe(symbol, path string, offset uint64, ret bool) (*perfEvent, error) {
|
||||
return pmuProbe(uprobeType, symbol, path, offset, ret)
|
||||
func pmuUprobe(symbol, path string, offset uint64, pid int, ret bool) (*perfEvent, error) {
|
||||
return pmuProbe(uprobeType, symbol, path, offset, pid, ret)
|
||||
}
|
||||
|
||||
// tracefsUprobe creates a Uprobe tracefs entry.
|
||||
func tracefsUprobe(symbol, path string, offset uint64, ret bool) (*perfEvent, error) {
|
||||
return tracefsProbe(uprobeType, symbol, path, offset, ret)
|
||||
func tracefsUprobe(symbol, path string, offset uint64, pid int, ret bool) (*perfEvent, error) {
|
||||
return tracefsProbe(uprobeType, symbol, path, offset, pid, ret)
|
||||
}
|
||||
|
||||
// uprobeSanitizedSymbol replaces every invalid characted for the tracefs api with an underscore.
|
||||
|
23
src/runtime/vendor/github.com/cilium/ebpf/linker.go
generated
vendored
23
src/runtime/vendor/github.com/cilium/ebpf/linker.go
generated
vendored
@ -4,7 +4,6 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/cilium/ebpf/asm"
|
||||
"github.com/cilium/ebpf/internal/btf"
|
||||
)
|
||||
|
||||
// link resolves bpf-to-bpf calls.
|
||||
@ -40,7 +39,7 @@ func link(prog *ProgramSpec, libs []*ProgramSpec) error {
|
||||
pending = append(pending, lib.Instructions)
|
||||
|
||||
if prog.BTF != nil && lib.BTF != nil {
|
||||
if err := btf.ProgramAppend(prog.BTF, lib.BTF); err != nil {
|
||||
if err := prog.BTF.Append(lib.BTF); err != nil {
|
||||
return fmt.Errorf("linking BTF of %s: %w", lib.Name, err)
|
||||
}
|
||||
}
|
||||
@ -136,5 +135,25 @@ func fixupJumpsAndCalls(insns asm.Instructions) error {
|
||||
}
|
||||
}
|
||||
|
||||
// fixupBPFCalls replaces bpf_probe_read_{kernel,user}[_str] with bpf_probe_read[_str] on older kernels
|
||||
// https://github.com/libbpf/libbpf/blob/master/src/libbpf.c#L6009
|
||||
iter = insns.Iterate()
|
||||
for iter.Next() {
|
||||
ins := iter.Ins
|
||||
if !ins.IsBuiltinCall() {
|
||||
continue
|
||||
}
|
||||
switch asm.BuiltinFunc(ins.Constant) {
|
||||
case asm.FnProbeReadKernel, asm.FnProbeReadUser:
|
||||
if err := haveProbeReadKernel(); err != nil {
|
||||
ins.Constant = int64(asm.FnProbeRead)
|
||||
}
|
||||
case asm.FnProbeReadKernelStr, asm.FnProbeReadUserStr:
|
||||
if err := haveProbeReadKernel(); err != nil {
|
||||
ins.Constant = int64(asm.FnProbeReadStr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
95
src/runtime/vendor/github.com/cilium/ebpf/map.go
generated
vendored
95
src/runtime/vendor/github.com/cilium/ebpf/map.go
generated
vendored
@ -1,6 +1,7 @@
|
||||
package ebpf
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
@ -65,6 +66,11 @@ type MapSpec struct {
|
||||
// InnerMap is used as a template for ArrayOfMaps and HashOfMaps
|
||||
InnerMap *MapSpec
|
||||
|
||||
// Extra trailing bytes found in the ELF map definition when using structs
|
||||
// larger than libbpf's bpf_map_def. Must be empty before instantiating
|
||||
// the MapSpec into a Map.
|
||||
Extra bytes.Reader
|
||||
|
||||
// The BTF associated with this map.
|
||||
BTF *btf.Map
|
||||
}
|
||||
@ -82,9 +88,12 @@ func (ms *MapSpec) Copy() *MapSpec {
|
||||
}
|
||||
|
||||
cpy := *ms
|
||||
|
||||
cpy.Contents = make([]MapKV, len(ms.Contents))
|
||||
copy(cpy.Contents, ms.Contents)
|
||||
|
||||
cpy.InnerMap = ms.InnerMap.Copy()
|
||||
|
||||
return &cpy
|
||||
}
|
||||
|
||||
@ -188,14 +197,24 @@ func NewMap(spec *MapSpec) (*Map, error) {
|
||||
//
|
||||
// The caller is responsible for ensuring the process' rlimit is set
|
||||
// sufficiently high for locking memory during map creation. This can be done
|
||||
// by calling unix.Setrlimit with unix.RLIMIT_MEMLOCK prior to calling NewMapWithOptions.
|
||||
// by calling rlimit.RemoveMemlock() prior to calling NewMapWithOptions.
|
||||
//
|
||||
// May return an error wrapping ErrMapIncompatible.
|
||||
func NewMapWithOptions(spec *MapSpec, opts MapOptions) (*Map, error) {
|
||||
handles := newHandleCache()
|
||||
defer handles.close()
|
||||
|
||||
return newMapWithOptions(spec, opts, handles)
|
||||
m, err := newMapWithOptions(spec, opts, handles)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("creating map: %w", err)
|
||||
}
|
||||
|
||||
err = m.finalize(spec)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("populating map: %w", err)
|
||||
}
|
||||
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func newMapWithOptions(spec *MapSpec, opts MapOptions, handles *handleCache) (_ *Map, err error) {
|
||||
@ -207,8 +226,12 @@ func newMapWithOptions(spec *MapSpec, opts MapOptions, handles *handleCache) (_
|
||||
|
||||
switch spec.Pinning {
|
||||
case PinByName:
|
||||
if spec.Name == "" || opts.PinPath == "" {
|
||||
return nil, fmt.Errorf("pin by name: missing Name or PinPath")
|
||||
if spec.Name == "" {
|
||||
return nil, fmt.Errorf("pin by name: missing Name")
|
||||
}
|
||||
|
||||
if opts.PinPath == "" {
|
||||
return nil, fmt.Errorf("pin by name: missing MapOptions.PinPath")
|
||||
}
|
||||
|
||||
path := filepath.Join(opts.PinPath, spec.Name)
|
||||
@ -244,16 +267,19 @@ func newMapWithOptions(spec *MapSpec, opts MapOptions, handles *handleCache) (_
|
||||
return nil, errors.New("inner maps cannot be pinned")
|
||||
}
|
||||
|
||||
template, err := createMap(spec.InnerMap, nil, opts, handles)
|
||||
template, err := spec.InnerMap.createMap(nil, opts, handles)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, fmt.Errorf("inner map: %w", err)
|
||||
}
|
||||
defer template.Close()
|
||||
|
||||
// Intentionally skip populating and freezing (finalizing)
|
||||
// the inner map template since it will be removed shortly.
|
||||
|
||||
innerFd = template.fd
|
||||
}
|
||||
|
||||
m, err := createMap(spec, innerFd, opts, handles)
|
||||
m, err := spec.createMap(innerFd, opts, handles)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -269,7 +295,9 @@ func newMapWithOptions(spec *MapSpec, opts MapOptions, handles *handleCache) (_
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func createMap(spec *MapSpec, inner *internal.FD, opts MapOptions, handles *handleCache) (_ *Map, err error) {
|
||||
// createMap validates the spec's properties and creates the map in the kernel
|
||||
// using the given opts. It does not populate or freeze the map.
|
||||
func (spec *MapSpec) createMap(inner *internal.FD, opts MapOptions, handles *handleCache) (_ *Map, err error) {
|
||||
closeOnError := func(closer io.Closer) {
|
||||
if err != nil {
|
||||
closer.Close()
|
||||
@ -278,10 +306,16 @@ func createMap(spec *MapSpec, inner *internal.FD, opts MapOptions, handles *hand
|
||||
|
||||
spec = spec.Copy()
|
||||
|
||||
// Kernels 4.13 through 5.4 used a struct bpf_map_def that contained
|
||||
// additional 'inner_map_idx' and later 'numa_node' fields.
|
||||
// In order to support loading these definitions, tolerate the presence of
|
||||
// extra bytes, but require them to be zeroes.
|
||||
if _, err := io.Copy(internal.DiscardZeroes{}, &spec.Extra); err != nil {
|
||||
return nil, errors.New("extra contains unhandled non-zero bytes, drain before creating map")
|
||||
}
|
||||
|
||||
switch spec.Type {
|
||||
case ArrayOfMaps:
|
||||
fallthrough
|
||||
case HashOfMaps:
|
||||
case ArrayOfMaps, HashOfMaps:
|
||||
if err := haveNestedMaps(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -350,7 +384,7 @@ func createMap(spec *MapSpec, inner *internal.FD, opts MapOptions, handles *hand
|
||||
|
||||
var btfDisabled bool
|
||||
if spec.BTF != nil {
|
||||
handle, err := handles.btfHandle(btf.MapSpec(spec.BTF))
|
||||
handle, err := handles.btfHandle(spec.BTF.Spec)
|
||||
btfDisabled = errors.Is(err, btf.ErrNotSupported)
|
||||
if err != nil && !btfDisabled {
|
||||
return nil, fmt.Errorf("load BTF: %w", err)
|
||||
@ -358,15 +392,15 @@ func createMap(spec *MapSpec, inner *internal.FD, opts MapOptions, handles *hand
|
||||
|
||||
if handle != nil {
|
||||
attr.BTFFd = uint32(handle.FD())
|
||||
attr.BTFKeyTypeID = uint32(btf.MapKey(spec.BTF).ID())
|
||||
attr.BTFValueTypeID = uint32(btf.MapValue(spec.BTF).ID())
|
||||
attr.BTFKeyTypeID = uint32(spec.BTF.Key.ID())
|
||||
attr.BTFValueTypeID = uint32(spec.BTF.Value.ID())
|
||||
}
|
||||
}
|
||||
|
||||
fd, err := internal.BPFMapCreate(&attr)
|
||||
if err != nil {
|
||||
if errors.Is(err, unix.EPERM) {
|
||||
return nil, fmt.Errorf("map create: RLIMIT_MEMLOCK may be too low: %w", err)
|
||||
return nil, fmt.Errorf("map create: %w (MEMLOCK bay be too low, consider rlimit.RemoveMemlock)", err)
|
||||
}
|
||||
if btfDisabled {
|
||||
return nil, fmt.Errorf("map create without BTF: %w", err)
|
||||
@ -380,19 +414,11 @@ func createMap(spec *MapSpec, inner *internal.FD, opts MapOptions, handles *hand
|
||||
return nil, fmt.Errorf("map create: %w", err)
|
||||
}
|
||||
|
||||
if err := m.populate(spec.Contents); err != nil {
|
||||
return nil, fmt.Errorf("map create: can't set initial contents: %w", err)
|
||||
}
|
||||
|
||||
if spec.Freeze {
|
||||
if err := m.Freeze(); err != nil {
|
||||
return nil, fmt.Errorf("can't freeze map: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// newMap allocates and returns a new Map structure.
|
||||
// Sets the fullValueSize on per-CPU maps.
|
||||
func newMap(fd *internal.FD, name string, typ MapType, keySize, valueSize, maxEntries, flags uint32) (*Map, error) {
|
||||
m := &Map{
|
||||
name,
|
||||
@ -415,7 +441,7 @@ func newMap(fd *internal.FD, name string, typ MapType, keySize, valueSize, maxEn
|
||||
return nil, err
|
||||
}
|
||||
|
||||
m.fullValueSize = align(int(valueSize), 8) * possibleCPUs
|
||||
m.fullValueSize = internal.Align(int(valueSize), 8) * possibleCPUs
|
||||
return m, nil
|
||||
}
|
||||
|
||||
@ -892,12 +918,21 @@ func (m *Map) Freeze() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Map) populate(contents []MapKV) error {
|
||||
for _, kv := range contents {
|
||||
// finalize populates the Map according to the Contents specified
|
||||
// in spec and freezes the Map if requested by spec.
|
||||
func (m *Map) finalize(spec *MapSpec) error {
|
||||
for _, kv := range spec.Contents {
|
||||
if err := m.Put(kv.Key, kv.Value); err != nil {
|
||||
return fmt.Errorf("key %v: %w", kv.Key, err)
|
||||
return fmt.Errorf("putting value: key %v: %w", kv.Key, err)
|
||||
}
|
||||
}
|
||||
|
||||
if spec.Freeze {
|
||||
if err := m.Freeze(); err != nil {
|
||||
return fmt.Errorf("freezing map: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -1212,7 +1247,7 @@ func MapGetNextID(startID MapID) (MapID, error) {
|
||||
//
|
||||
// Returns ErrNotExist, if there is no eBPF map with the given id.
|
||||
func NewMapFromID(id MapID) (*Map, error) {
|
||||
fd, err := bpfObjGetFDByID(internal.BPF_MAP_GET_FD_BY_ID, uint32(id))
|
||||
fd, err := internal.BPFObjGetFDByID(internal.BPF_MAP_GET_FD_BY_ID, uint32(id))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
63
src/runtime/vendor/github.com/cilium/ebpf/marshalers.go
generated
vendored
63
src/runtime/vendor/github.com/cilium/ebpf/marshalers.go
generated
vendored
@ -8,6 +8,7 @@ import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"sync"
|
||||
"unsafe"
|
||||
|
||||
"github.com/cilium/ebpf/internal"
|
||||
@ -39,6 +40,10 @@ func marshalPtr(data interface{}, length int) (internal.Pointer, error) {
|
||||
// Returns an error if the given value isn't representable in exactly
|
||||
// length bytes.
|
||||
func marshalBytes(data interface{}, length int) (buf []byte, err error) {
|
||||
if data == nil {
|
||||
return nil, errors.New("can't marshal a nil value")
|
||||
}
|
||||
|
||||
switch value := data.(type) {
|
||||
case encoding.BinaryMarshaler:
|
||||
buf, err = value.MarshalBinary()
|
||||
@ -77,22 +82,30 @@ func makeBuffer(dst interface{}, length int) (internal.Pointer, []byte) {
|
||||
return internal.NewSlicePointer(buf), buf
|
||||
}
|
||||
|
||||
var bytesReaderPool = sync.Pool{
|
||||
New: func() interface{} {
|
||||
return new(bytes.Reader)
|
||||
},
|
||||
}
|
||||
|
||||
// unmarshalBytes converts a byte buffer into an arbitrary value.
|
||||
//
|
||||
// Prefer using Map.unmarshalKey and Map.unmarshalValue if possible, since
|
||||
// those have special cases that allow more types to be encoded.
|
||||
//
|
||||
// The common int32 and int64 types are directly handled to avoid
|
||||
// unnecessary heap allocations as happening in the default case.
|
||||
func unmarshalBytes(data interface{}, buf []byte) error {
|
||||
switch value := data.(type) {
|
||||
case unsafe.Pointer:
|
||||
// This could be solved in Go 1.17 by unsafe.Slice instead. (https://github.com/golang/go/issues/19367)
|
||||
// We could opt for removing unsafe.Pointer support in the lib as well.
|
||||
sh := &reflect.SliceHeader{ //nolint:govet
|
||||
Data: uintptr(value),
|
||||
Len: len(buf),
|
||||
Cap: len(buf),
|
||||
}
|
||||
var dst []byte
|
||||
// Use unsafe.Slice when we drop support for pre1.17 (https://github.com/golang/go/issues/19367)
|
||||
// We could opt for removing unsafe.Pointer support in the lib as well
|
||||
sh := (*reflect.SliceHeader)(unsafe.Pointer(&dst))
|
||||
sh.Data = uintptr(value)
|
||||
sh.Len = len(buf)
|
||||
sh.Cap = len(buf)
|
||||
|
||||
dst := *(*[]byte)(unsafe.Pointer(sh))
|
||||
copy(dst, buf)
|
||||
runtime.KeepAlive(value)
|
||||
return nil
|
||||
@ -106,12 +119,38 @@ func unmarshalBytes(data interface{}, buf []byte) error {
|
||||
case *[]byte:
|
||||
*value = buf
|
||||
return nil
|
||||
case *int32:
|
||||
if len(buf) < 4 {
|
||||
return errors.New("int32 requires 4 bytes")
|
||||
}
|
||||
*value = int32(internal.NativeEndian.Uint32(buf))
|
||||
return nil
|
||||
case *uint32:
|
||||
if len(buf) < 4 {
|
||||
return errors.New("uint32 requires 4 bytes")
|
||||
}
|
||||
*value = internal.NativeEndian.Uint32(buf)
|
||||
return nil
|
||||
case *int64:
|
||||
if len(buf) < 8 {
|
||||
return errors.New("int64 requires 8 bytes")
|
||||
}
|
||||
*value = int64(internal.NativeEndian.Uint64(buf))
|
||||
return nil
|
||||
case *uint64:
|
||||
if len(buf) < 8 {
|
||||
return errors.New("uint64 requires 8 bytes")
|
||||
}
|
||||
*value = internal.NativeEndian.Uint64(buf)
|
||||
return nil
|
||||
case string:
|
||||
return errors.New("require pointer to string")
|
||||
case []byte:
|
||||
return errors.New("require pointer to []byte")
|
||||
default:
|
||||
rd := bytes.NewReader(buf)
|
||||
rd := bytesReaderPool.Get().(*bytes.Reader)
|
||||
rd.Reset(buf)
|
||||
defer bytesReaderPool.Put(rd)
|
||||
if err := binary.Read(rd, internal.NativeEndian, value); err != nil {
|
||||
return fmt.Errorf("decoding %T: %v", value, err)
|
||||
}
|
||||
@ -142,7 +181,7 @@ func marshalPerCPUValue(slice interface{}, elemLength int) (internal.Pointer, er
|
||||
return internal.Pointer{}, fmt.Errorf("per-CPU value exceeds number of CPUs")
|
||||
}
|
||||
|
||||
alignedElemLength := align(elemLength, 8)
|
||||
alignedElemLength := internal.Align(elemLength, 8)
|
||||
buf := make([]byte, alignedElemLength*possibleCPUs)
|
||||
|
||||
for i := 0; i < sliceLen; i++ {
|
||||
@ -212,7 +251,3 @@ func unmarshalPerCPUValue(slicePtr interface{}, elemLength int, buf []byte) erro
|
||||
reflect.ValueOf(slicePtr).Elem().Set(slice)
|
||||
return nil
|
||||
}
|
||||
|
||||
func align(n, alignment int) int {
|
||||
return (int(n) + alignment - 1) / alignment * alignment
|
||||
}
|
||||
|
123
src/runtime/vendor/github.com/cilium/ebpf/prog.go
generated
vendored
123
src/runtime/vendor/github.com/cilium/ebpf/prog.go
generated
vendored
@ -57,16 +57,21 @@ type ProgramSpec struct {
|
||||
// Name is passed to the kernel as a debug aid. Must only contain
|
||||
// alpha numeric and '_' characters.
|
||||
Name string
|
||||
|
||||
// Type determines at which hook in the kernel a program will run.
|
||||
Type ProgramType
|
||||
AttachType AttachType
|
||||
// Name of a kernel data structure to attach to. It's interpretation
|
||||
// depends on Type and AttachType.
|
||||
AttachTo string
|
||||
// Name of a kernel data structure or function to attach to. Its
|
||||
// interpretation depends on Type and AttachType.
|
||||
AttachTo string
|
||||
// The program to attach to. Must be provided manually.
|
||||
AttachTarget *Program
|
||||
Instructions asm.Instructions
|
||||
|
||||
// Flags is passed to the kernel and specifies additional program
|
||||
// load attributes.
|
||||
Flags uint32
|
||||
|
||||
// License of the program. Some helpers are only available if
|
||||
// the license is deemed compatible with the GPL.
|
||||
//
|
||||
@ -146,7 +151,7 @@ func NewProgramWithOptions(spec *ProgramSpec, opts ProgramOptions) (*Program, er
|
||||
|
||||
func newProgramWithOptions(spec *ProgramSpec, opts ProgramOptions, handles *handleCache) (*Program, error) {
|
||||
if len(spec.Instructions) == 0 {
|
||||
return nil, errors.New("Instructions cannot be empty")
|
||||
return nil, errors.New("instructions cannot be empty")
|
||||
}
|
||||
|
||||
if spec.ByteOrder != nil && spec.ByteOrder != internal.NativeEndian {
|
||||
@ -166,16 +171,16 @@ func newProgramWithOptions(spec *ProgramSpec, opts ProgramOptions, handles *hand
|
||||
kv = v.Kernel()
|
||||
}
|
||||
|
||||
attr := &bpfProgLoadAttr{
|
||||
progType: spec.Type,
|
||||
progFlags: spec.Flags,
|
||||
expectedAttachType: spec.AttachType,
|
||||
license: internal.NewStringPointer(spec.License),
|
||||
kernelVersion: kv,
|
||||
attr := &internal.BPFProgLoadAttr{
|
||||
ProgType: uint32(spec.Type),
|
||||
ProgFlags: spec.Flags,
|
||||
ExpectedAttachType: uint32(spec.AttachType),
|
||||
License: internal.NewStringPointer(spec.License),
|
||||
KernelVersion: kv,
|
||||
}
|
||||
|
||||
if haveObjName() == nil {
|
||||
attr.progName = internal.NewBPFObjName(spec.Name)
|
||||
attr.ProgName = internal.NewBPFObjName(spec.Name)
|
||||
}
|
||||
|
||||
var err error
|
||||
@ -190,35 +195,35 @@ func newProgramWithOptions(spec *ProgramSpec, opts ProgramOptions, handles *hand
|
||||
var btfDisabled bool
|
||||
var core btf.COREFixups
|
||||
if spec.BTF != nil {
|
||||
core, err = btf.ProgramFixups(spec.BTF, targetBTF)
|
||||
core, err = spec.BTF.Fixups(targetBTF)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("CO-RE relocations: %w", err)
|
||||
}
|
||||
|
||||
handle, err := handles.btfHandle(btf.ProgramSpec(spec.BTF))
|
||||
handle, err := handles.btfHandle(spec.BTF.Spec())
|
||||
btfDisabled = errors.Is(err, btf.ErrNotSupported)
|
||||
if err != nil && !btfDisabled {
|
||||
return nil, fmt.Errorf("load BTF: %w", err)
|
||||
}
|
||||
|
||||
if handle != nil {
|
||||
attr.progBTFFd = uint32(handle.FD())
|
||||
attr.ProgBTFFd = uint32(handle.FD())
|
||||
|
||||
recSize, bytes, err := btf.ProgramLineInfos(spec.BTF)
|
||||
recSize, bytes, err := spec.BTF.LineInfos()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get BTF line infos: %w", err)
|
||||
}
|
||||
attr.lineInfoRecSize = recSize
|
||||
attr.lineInfoCnt = uint32(uint64(len(bytes)) / uint64(recSize))
|
||||
attr.lineInfo = internal.NewSlicePointer(bytes)
|
||||
attr.LineInfoRecSize = recSize
|
||||
attr.LineInfoCnt = uint32(uint64(len(bytes)) / uint64(recSize))
|
||||
attr.LineInfo = internal.NewSlicePointer(bytes)
|
||||
|
||||
recSize, bytes, err = btf.ProgramFuncInfos(spec.BTF)
|
||||
recSize, bytes, err = spec.BTF.FuncInfos()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get BTF function infos: %w", err)
|
||||
}
|
||||
attr.funcInfoRecSize = recSize
|
||||
attr.funcInfoCnt = uint32(uint64(len(bytes)) / uint64(recSize))
|
||||
attr.funcInfo = internal.NewSlicePointer(bytes)
|
||||
attr.FuncInfoRecSize = recSize
|
||||
attr.FuncInfoCnt = uint32(uint64(len(bytes)) / uint64(recSize))
|
||||
attr.FuncInfo = internal.NewSlicePointer(bytes)
|
||||
}
|
||||
}
|
||||
|
||||
@ -238,16 +243,41 @@ func newProgramWithOptions(spec *ProgramSpec, opts ProgramOptions, handles *hand
|
||||
}
|
||||
|
||||
bytecode := buf.Bytes()
|
||||
attr.instructions = internal.NewSlicePointer(bytecode)
|
||||
attr.insCount = uint32(len(bytecode) / asm.InstructionSize)
|
||||
attr.Instructions = internal.NewSlicePointer(bytecode)
|
||||
attr.InsCount = uint32(len(bytecode) / asm.InstructionSize)
|
||||
|
||||
if spec.AttachTo != "" {
|
||||
if spec.AttachTarget != nil {
|
||||
info, err := spec.AttachTarget.Info()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load target BTF: %w", err)
|
||||
}
|
||||
|
||||
btfID, ok := info.BTFID()
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("load target BTF: no BTF info available")
|
||||
}
|
||||
btfHandle, err := btf.NewHandleFromID(btfID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load target BTF: %w", err)
|
||||
}
|
||||
defer btfHandle.Close()
|
||||
|
||||
targetBTF = btfHandle.Spec()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load target BTF: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
target, err := resolveBTFType(targetBTF, spec.AttachTo, spec.Type, spec.AttachType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if target != nil {
|
||||
attr.attachBTFID = target.ID()
|
||||
attr.AttachBTFID = uint32(target.ID())
|
||||
}
|
||||
if spec.AttachTarget != nil {
|
||||
attr.AttachProgFd = uint32(spec.AttachTarget.FD())
|
||||
}
|
||||
}
|
||||
|
||||
@ -259,12 +289,12 @@ func newProgramWithOptions(spec *ProgramSpec, opts ProgramOptions, handles *hand
|
||||
var logBuf []byte
|
||||
if opts.LogLevel > 0 {
|
||||
logBuf = make([]byte, logSize)
|
||||
attr.logLevel = opts.LogLevel
|
||||
attr.logSize = uint32(len(logBuf))
|
||||
attr.logBuf = internal.NewSlicePointer(logBuf)
|
||||
attr.LogLevel = opts.LogLevel
|
||||
attr.LogSize = uint32(len(logBuf))
|
||||
attr.LogBuf = internal.NewSlicePointer(logBuf)
|
||||
}
|
||||
|
||||
fd, err := bpfProgLoad(attr)
|
||||
fd, err := internal.BPFProgLoad(attr)
|
||||
if err == nil {
|
||||
return &Program{internal.CString(logBuf), fd, spec.Name, "", spec.Type}, nil
|
||||
}
|
||||
@ -273,17 +303,20 @@ func newProgramWithOptions(spec *ProgramSpec, opts ProgramOptions, handles *hand
|
||||
if opts.LogLevel == 0 && opts.LogSize >= 0 {
|
||||
// Re-run with the verifier enabled to get better error messages.
|
||||
logBuf = make([]byte, logSize)
|
||||
attr.logLevel = 1
|
||||
attr.logSize = uint32(len(logBuf))
|
||||
attr.logBuf = internal.NewSlicePointer(logBuf)
|
||||
attr.LogLevel = 1
|
||||
attr.LogSize = uint32(len(logBuf))
|
||||
attr.LogBuf = internal.NewSlicePointer(logBuf)
|
||||
|
||||
_, logErr = bpfProgLoad(attr)
|
||||
fd, logErr = internal.BPFProgLoad(attr)
|
||||
if logErr == nil {
|
||||
fd.Close()
|
||||
}
|
||||
}
|
||||
|
||||
if errors.Is(logErr, unix.EPERM) && logBuf[0] == 0 {
|
||||
// EPERM due to RLIMIT_MEMLOCK happens before the verifier, so we can
|
||||
// check that the log is empty to reduce false positives.
|
||||
return nil, fmt.Errorf("load program: RLIMIT_MEMLOCK may be too low: %w", logErr)
|
||||
return nil, fmt.Errorf("load program: %w (MEMLOCK bay be too low, consider rlimit.RemoveMemlock)", logErr)
|
||||
}
|
||||
|
||||
err = internal.ErrorWithLog(err, logBuf, logErr)
|
||||
@ -310,7 +343,7 @@ func NewProgramFromFD(fd int) (*Program, error) {
|
||||
//
|
||||
// Returns ErrNotExist, if there is no eBPF program with the given id.
|
||||
func NewProgramFromID(id ProgramID) (*Program, error) {
|
||||
fd, err := bpfObjGetFDByID(internal.BPF_PROG_GET_FD_BY_ID, uint32(id))
|
||||
fd, err := internal.BPFObjGetFDByID(internal.BPF_PROG_GET_FD_BY_ID, uint32(id))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get program by id: %w", err)
|
||||
}
|
||||
@ -677,45 +710,44 @@ func ProgramGetNextID(startID ProgramID) (ProgramID, error) {
|
||||
//
|
||||
// Deprecated: use ProgramInfo.ID() instead.
|
||||
func (p *Program) ID() (ProgramID, error) {
|
||||
info, err := bpfGetProgInfoByFD(p.fd)
|
||||
info, err := bpfGetProgInfoByFD(p.fd, nil)
|
||||
if err != nil {
|
||||
return ProgramID(0), err
|
||||
}
|
||||
return ProgramID(info.id), nil
|
||||
}
|
||||
|
||||
func resolveBTFType(kernel *btf.Spec, name string, progType ProgramType, attachType AttachType) (btf.Type, error) {
|
||||
func resolveBTFType(spec *btf.Spec, name string, progType ProgramType, attachType AttachType) (btf.Type, error) {
|
||||
type match struct {
|
||||
p ProgramType
|
||||
a AttachType
|
||||
}
|
||||
|
||||
var target btf.Type
|
||||
var typeName, featureName string
|
||||
switch (match{progType, attachType}) {
|
||||
case match{LSM, AttachLSMMac}:
|
||||
target = new(btf.Func)
|
||||
typeName = "bpf_lsm_" + name
|
||||
featureName = name + " LSM hook"
|
||||
|
||||
case match{Tracing, AttachTraceIter}:
|
||||
target = new(btf.Func)
|
||||
typeName = "bpf_iter_" + name
|
||||
featureName = name + " iterator"
|
||||
|
||||
case match{Extension, AttachNone}:
|
||||
typeName = name
|
||||
featureName = fmt.Sprintf("freplace %s", name)
|
||||
default:
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if kernel == nil {
|
||||
if spec == nil {
|
||||
var err error
|
||||
kernel, err = btf.LoadKernelSpec()
|
||||
spec, err = btf.LoadKernelSpec()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load kernel spec: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
err := kernel.FindType(typeName, target)
|
||||
var target *btf.Func
|
||||
err := spec.FindType(typeName, &target)
|
||||
if errors.Is(err, btf.ErrNotFound) {
|
||||
return nil, &internal.UnsupportedFeatureError{
|
||||
Name: featureName,
|
||||
@ -724,5 +756,6 @@ func resolveBTFType(kernel *btf.Spec, name string, progType ProgramType, attachT
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("resolve BTF for %s: %w", featureName, err)
|
||||
}
|
||||
|
||||
return target, nil
|
||||
}
|
||||
|
22
src/runtime/vendor/github.com/cilium/ebpf/run-tests.sh
generated
vendored
22
src/runtime/vendor/github.com/cilium/ebpf/run-tests.sh
generated
vendored
@ -5,7 +5,7 @@
|
||||
# Run all tests on a 5.4 kernel
|
||||
# $ ./run-tests.sh 5.4
|
||||
# Run a subset of tests:
|
||||
# $ ./run-tests.sh 5.4 go test ./link
|
||||
# $ ./run-tests.sh 5.4 ./link
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
@ -48,15 +48,17 @@ if [[ "${1:-}" = "--exec-vm" ]]; then
|
||||
rm "${output}/fake-stdin"
|
||||
fi
|
||||
|
||||
$sudo virtme-run --kimg "${input}/bzImage" --memory 768M --pwd \
|
||||
--rwdir="${testdir}=${testdir}" \
|
||||
--rodir=/run/input="${input}" \
|
||||
--rwdir=/run/output="${output}" \
|
||||
--script-sh "PATH=\"$PATH\" \"$script\" --exec-test $cmd" \
|
||||
--qemu-opts -smp 2 # need at least two CPUs for some tests
|
||||
if ! $sudo virtme-run --kimg "${input}/bzImage" --memory 768M --pwd \
|
||||
--rwdir="${testdir}=${testdir}" \
|
||||
--rodir=/run/input="${input}" \
|
||||
--rwdir=/run/output="${output}" \
|
||||
--script-sh "PATH=\"$PATH\" \"$script\" --exec-test $cmd" \
|
||||
--kopt possible_cpus=2; then # need at least two CPUs for some tests
|
||||
exit 23
|
||||
fi
|
||||
|
||||
if [[ ! -e "${output}/success" ]]; then
|
||||
exit 1
|
||||
exit 42
|
||||
fi
|
||||
|
||||
$sudo rm -r "$output"
|
||||
@ -74,7 +76,7 @@ elif [[ "${1:-}" = "--exec-test" ]]; then
|
||||
dmesg -C
|
||||
if ! "$@"; then
|
||||
dmesg
|
||||
exit 1
|
||||
exit 1 # this return code is "swallowed" by qemu
|
||||
fi
|
||||
touch "/run/output/success"
|
||||
exit 0
|
||||
@ -108,7 +110,7 @@ else
|
||||
echo "No selftests found, disabling"
|
||||
fi
|
||||
|
||||
args=(-v -short -coverpkg=./... -coverprofile=coverage.out -count 1 ./...)
|
||||
args=(-short -coverpkg=./... -coverprofile=coverage.out -count 1 ./...)
|
||||
if (( $# > 0 )); then
|
||||
args=("$@")
|
||||
fi
|
||||
|
94
src/runtime/vendor/github.com/cilium/ebpf/syscalls.go
generated
vendored
94
src/runtime/vendor/github.com/cilium/ebpf/syscalls.go
generated
vendored
@ -1,13 +1,14 @@
|
||||
package ebpf
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"unsafe"
|
||||
|
||||
"github.com/cilium/ebpf/asm"
|
||||
"github.com/cilium/ebpf/internal"
|
||||
"github.com/cilium/ebpf/internal/btf"
|
||||
"github.com/cilium/ebpf/internal/unix"
|
||||
)
|
||||
|
||||
@ -73,30 +74,6 @@ type bpfMapInfo struct {
|
||||
btf_value_type_id uint32
|
||||
}
|
||||
|
||||
type bpfProgLoadAttr struct {
|
||||
progType ProgramType
|
||||
insCount uint32
|
||||
instructions internal.Pointer
|
||||
license internal.Pointer
|
||||
logLevel uint32
|
||||
logSize uint32
|
||||
logBuf internal.Pointer
|
||||
kernelVersion uint32 // since 4.1 2541517c32be
|
||||
progFlags uint32 // since 4.11 e07b98d9bffe
|
||||
progName internal.BPFObjName // since 4.15 067cae47771c
|
||||
progIfIndex uint32 // since 4.15 1f6f4cb7ba21
|
||||
expectedAttachType AttachType // since 4.17 5e43f899b03a
|
||||
progBTFFd uint32
|
||||
funcInfoRecSize uint32
|
||||
funcInfo internal.Pointer
|
||||
funcInfoCnt uint32
|
||||
lineInfoRecSize uint32
|
||||
lineInfo internal.Pointer
|
||||
lineInfoCnt uint32
|
||||
attachBTFID btf.TypeID
|
||||
attachProgFd uint32
|
||||
}
|
||||
|
||||
type bpfProgInfo struct {
|
||||
prog_type uint32
|
||||
id uint32
|
||||
@ -107,7 +84,7 @@ type bpfProgInfo struct {
|
||||
xlated_prog_insns internal.Pointer
|
||||
load_time uint64 // since 4.15 cb4d2b3f03d8
|
||||
created_by_uid uint32
|
||||
nr_map_ids uint32
|
||||
nr_map_ids uint32 // since 4.15 cb4d2b3f03d8
|
||||
map_ids internal.Pointer
|
||||
name internal.BPFObjName // since 4.15 067cae47771c
|
||||
ifindex uint32
|
||||
@ -145,11 +122,6 @@ type bpfProgTestRunAttr struct {
|
||||
duration uint32
|
||||
}
|
||||
|
||||
type bpfGetFDByIDAttr struct {
|
||||
id uint32
|
||||
next uint32
|
||||
}
|
||||
|
||||
type bpfMapFreezeAttr struct {
|
||||
mapFd uint32
|
||||
}
|
||||
@ -160,23 +132,6 @@ type bpfObjGetNextIDAttr struct {
|
||||
openFlags uint32
|
||||
}
|
||||
|
||||
func bpfProgLoad(attr *bpfProgLoadAttr) (*internal.FD, error) {
|
||||
for {
|
||||
fd, err := internal.BPF(internal.BPF_PROG_LOAD, unsafe.Pointer(attr), unsafe.Sizeof(*attr))
|
||||
// As of ~4.20 the verifier can be interrupted by a signal,
|
||||
// and returns EAGAIN in that case.
|
||||
if errors.Is(err, unix.EAGAIN) {
|
||||
continue
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return internal.NewFD(uint32(fd)), nil
|
||||
}
|
||||
}
|
||||
|
||||
func bpfProgTestRun(attr *bpfProgTestRunAttr) error {
|
||||
_, err := internal.BPF(internal.BPF_PROG_TEST_RUN, unsafe.Pointer(attr), unsafe.Sizeof(*attr))
|
||||
return err
|
||||
@ -372,6 +327,10 @@ func wrapMapError(err error) error {
|
||||
return internal.SyscallError(ErrNotSupported, unix.ENOTSUPP)
|
||||
}
|
||||
|
||||
if errors.Is(err, unix.E2BIG) {
|
||||
return fmt.Errorf("key too big for map: %w", err)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@ -388,8 +347,13 @@ func bpfMapFreeze(m *internal.FD) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func bpfGetProgInfoByFD(fd *internal.FD) (*bpfProgInfo, error) {
|
||||
func bpfGetProgInfoByFD(fd *internal.FD, ids []MapID) (*bpfProgInfo, error) {
|
||||
var info bpfProgInfo
|
||||
if len(ids) > 0 {
|
||||
info.nr_map_ids = uint32(len(ids))
|
||||
info.map_ids = internal.NewPointer(unsafe.Pointer(&ids[0]))
|
||||
}
|
||||
|
||||
if err := internal.BPFObjGetInfoByFD(fd, unsafe.Pointer(&info), unsafe.Sizeof(info)); err != nil {
|
||||
return nil, fmt.Errorf("can't get program info: %w", err)
|
||||
}
|
||||
@ -471,10 +435,30 @@ var haveBatchAPI = internal.FeatureTest("map batch api", "5.6", func() error {
|
||||
return nil
|
||||
})
|
||||
|
||||
func bpfObjGetFDByID(cmd internal.BPFCmd, id uint32) (*internal.FD, error) {
|
||||
attr := bpfGetFDByIDAttr{
|
||||
id: id,
|
||||
var haveProbeReadKernel = internal.FeatureTest("bpf_probe_read_kernel", "5.5", func() error {
|
||||
insns := asm.Instructions{
|
||||
asm.Mov.Reg(asm.R1, asm.R10),
|
||||
asm.Add.Imm(asm.R1, -8),
|
||||
asm.Mov.Imm(asm.R2, 8),
|
||||
asm.Mov.Imm(asm.R3, 0),
|
||||
asm.FnProbeReadKernel.Call(),
|
||||
asm.Return(),
|
||||
}
|
||||
ptr, err := internal.BPF(cmd, unsafe.Pointer(&attr), unsafe.Sizeof(attr))
|
||||
return internal.NewFD(uint32(ptr)), err
|
||||
}
|
||||
buf := bytes.NewBuffer(make([]byte, 0, len(insns)*asm.InstructionSize))
|
||||
if err := insns.Marshal(buf, internal.NativeEndian); err != nil {
|
||||
return err
|
||||
}
|
||||
bytecode := buf.Bytes()
|
||||
|
||||
fd, err := internal.BPFProgLoad(&internal.BPFProgLoadAttr{
|
||||
ProgType: uint32(Kprobe),
|
||||
License: internal.NewStringPointer("GPL"),
|
||||
Instructions: internal.NewSlicePointer(bytecode),
|
||||
InsCount: uint32(len(bytecode) / asm.InstructionSize),
|
||||
})
|
||||
if err != nil {
|
||||
return internal.ErrNotSupported
|
||||
}
|
||||
_ = fd.Close()
|
||||
return nil
|
||||
})
|
||||
|
36
src/runtime/vendor/github.com/cilium/ebpf/types.go
generated
vendored
36
src/runtime/vendor/github.com/cilium/ebpf/types.go
generated
vendored
@ -4,12 +4,17 @@ import (
|
||||
"github.com/cilium/ebpf/internal/unix"
|
||||
)
|
||||
|
||||
//go:generate stringer -output types_string.go -type=MapType,ProgramType,AttachType,PinType
|
||||
//go:generate stringer -output types_string.go -type=MapType,ProgramType,PinType
|
||||
|
||||
// MapType indicates the type map structure
|
||||
// that will be initialized in the kernel.
|
||||
type MapType uint32
|
||||
|
||||
// Max returns the latest supported MapType.
|
||||
func (_ MapType) Max() MapType {
|
||||
return maxMapType - 1
|
||||
}
|
||||
|
||||
// All the various map types that can be created
|
||||
const (
|
||||
UnspecifiedMap MapType = iota
|
||||
@ -85,15 +90,28 @@ const (
|
||||
SkStorage
|
||||
// DevMapHash - Hash-based indexing scheme for references to network devices.
|
||||
DevMapHash
|
||||
StructOpts
|
||||
// StructOpsMap - This map holds a kernel struct with its function pointer implemented in a BPF
|
||||
// program.
|
||||
StructOpsMap
|
||||
// RingBuf - Similar to PerfEventArray, but shared across all CPUs.
|
||||
RingBuf
|
||||
// InodeStorage - Specialized local storage map for inodes.
|
||||
InodeStorage
|
||||
// TaskStorage - Specialized local storage map for task_struct.
|
||||
TaskStorage
|
||||
// maxMapType - Bound enum of MapTypes, has to be last in enum.
|
||||
maxMapType
|
||||
)
|
||||
|
||||
// Deprecated: StructOpts was a typo, use StructOpsMap instead.
|
||||
//
|
||||
// Declared as a variable to prevent stringer from picking it up
|
||||
// as an enum value.
|
||||
var StructOpts MapType = StructOpsMap
|
||||
|
||||
// hasPerCPUValue returns true if the Map stores a value per CPU.
|
||||
func (mt MapType) hasPerCPUValue() bool {
|
||||
return mt == PerCPUHash || mt == PerCPUArray || mt == LRUCPUHash
|
||||
return mt == PerCPUHash || mt == PerCPUArray || mt == LRUCPUHash || mt == PerCPUCGroupStorage
|
||||
}
|
||||
|
||||
// canStoreMap returns true if the map type accepts a map fd
|
||||
@ -111,6 +129,11 @@ func (mt MapType) canStoreProgram() bool {
|
||||
// ProgramType of the eBPF program
|
||||
type ProgramType uint32
|
||||
|
||||
// Max return the latest supported ProgramType.
|
||||
func (_ ProgramType) Max() ProgramType {
|
||||
return maxProgramType - 1
|
||||
}
|
||||
|
||||
// eBPF program types
|
||||
const (
|
||||
UnspecifiedProgram ProgramType = iota
|
||||
@ -144,6 +167,7 @@ const (
|
||||
Extension
|
||||
LSM
|
||||
SkLookup
|
||||
maxProgramType
|
||||
)
|
||||
|
||||
// AttachType of the eBPF program, needed to differentiate allowed context accesses in
|
||||
@ -151,6 +175,8 @@ const (
|
||||
// Will cause invalid argument (EINVAL) at program load time if set incorrectly.
|
||||
type AttachType uint32
|
||||
|
||||
//go:generate stringer -type AttachType -trimprefix Attach
|
||||
|
||||
// AttachNone is an alias for AttachCGroupInetIngress for readability reasons.
|
||||
const AttachNone AttachType = 0
|
||||
|
||||
@ -193,6 +219,10 @@ const (
|
||||
AttachXDPCPUMap
|
||||
AttachSkLookup
|
||||
AttachXDP
|
||||
AttachSkSKBVerdict
|
||||
AttachSkReuseportSelect
|
||||
AttachSkReuseportSelectOrMigrate
|
||||
AttachPerfEvent
|
||||
)
|
||||
|
||||
// AttachFlags of the eBPF program used in BPF_PROG_ATTACH command
|
||||
|
69
src/runtime/vendor/github.com/cilium/ebpf/types_string.go
generated
vendored
69
src/runtime/vendor/github.com/cilium/ebpf/types_string.go
generated
vendored
@ -1,4 +1,4 @@
|
||||
// Code generated by "stringer -output types_string.go -type=MapType,ProgramType,AttachType,PinType"; DO NOT EDIT.
|
||||
// Code generated by "stringer -output types_string.go -type=MapType,ProgramType,PinType"; DO NOT EDIT.
|
||||
|
||||
package ebpf
|
||||
|
||||
@ -34,15 +34,16 @@ func _() {
|
||||
_ = x[Stack-23]
|
||||
_ = x[SkStorage-24]
|
||||
_ = x[DevMapHash-25]
|
||||
_ = x[StructOpts-26]
|
||||
_ = x[StructOpsMap-26]
|
||||
_ = x[RingBuf-27]
|
||||
_ = x[InodeStorage-28]
|
||||
_ = x[TaskStorage-29]
|
||||
_ = x[maxMapType-30]
|
||||
}
|
||||
|
||||
const _MapType_name = "UnspecifiedMapHashArrayProgramArrayPerfEventArrayPerCPUHashPerCPUArrayStackTraceCGroupArrayLRUHashLRUCPUHashLPMTrieArrayOfMapsHashOfMapsDevMapSockMapCPUMapXSKMapSockHashCGroupStorageReusePortSockArrayPerCPUCGroupStorageQueueStackSkStorageDevMapHashStructOptsRingBufInodeStorageTaskStorage"
|
||||
const _MapType_name = "UnspecifiedMapHashArrayProgramArrayPerfEventArrayPerCPUHashPerCPUArrayStackTraceCGroupArrayLRUHashLRUCPUHashLPMTrieArrayOfMapsHashOfMapsDevMapSockMapCPUMapXSKMapSockHashCGroupStorageReusePortSockArrayPerCPUCGroupStorageQueueStackSkStorageDevMapHashStructOpsMapRingBufInodeStorageTaskStoragemaxMapType"
|
||||
|
||||
var _MapType_index = [...]uint16{0, 14, 18, 23, 35, 49, 59, 70, 80, 91, 98, 108, 115, 126, 136, 142, 149, 155, 161, 169, 182, 200, 219, 224, 229, 238, 248, 258, 265, 277, 288}
|
||||
var _MapType_index = [...]uint16{0, 14, 18, 23, 35, 49, 59, 70, 80, 91, 98, 108, 115, 126, 136, 142, 149, 155, 161, 169, 182, 200, 219, 224, 229, 238, 248, 260, 267, 279, 290, 300}
|
||||
|
||||
func (i MapType) String() string {
|
||||
if i >= MapType(len(_MapType_index)-1) {
|
||||
@ -85,11 +86,12 @@ func _() {
|
||||
_ = x[Extension-28]
|
||||
_ = x[LSM-29]
|
||||
_ = x[SkLookup-30]
|
||||
_ = x[maxProgramType-31]
|
||||
}
|
||||
|
||||
const _ProgramType_name = "UnspecifiedProgramSocketFilterKprobeSchedCLSSchedACTTracePointXDPPerfEventCGroupSKBCGroupSockLWTInLWTOutLWTXmitSockOpsSkSKBCGroupDeviceSkMsgRawTracepointCGroupSockAddrLWTSeg6LocalLircMode2SkReuseportFlowDissectorCGroupSysctlRawTracepointWritableCGroupSockoptTracingStructOpsExtensionLSMSkLookup"
|
||||
const _ProgramType_name = "UnspecifiedProgramSocketFilterKprobeSchedCLSSchedACTTracePointXDPPerfEventCGroupSKBCGroupSockLWTInLWTOutLWTXmitSockOpsSkSKBCGroupDeviceSkMsgRawTracepointCGroupSockAddrLWTSeg6LocalLircMode2SkReuseportFlowDissectorCGroupSysctlRawTracepointWritableCGroupSockoptTracingStructOpsExtensionLSMSkLookupmaxProgramType"
|
||||
|
||||
var _ProgramType_index = [...]uint16{0, 18, 30, 36, 44, 52, 62, 65, 74, 83, 93, 98, 104, 111, 118, 123, 135, 140, 153, 167, 179, 188, 199, 212, 224, 245, 258, 265, 274, 283, 286, 294}
|
||||
var _ProgramType_index = [...]uint16{0, 18, 30, 36, 44, 52, 62, 65, 74, 83, 93, 98, 104, 111, 118, 123, 135, 140, 153, 167, 179, 188, 199, 212, 224, 245, 258, 265, 274, 283, 286, 294, 308}
|
||||
|
||||
func (i ProgramType) String() string {
|
||||
if i >= ProgramType(len(_ProgramType_index)-1) {
|
||||
@ -97,61 +99,6 @@ func (i ProgramType) String() string {
|
||||
}
|
||||
return _ProgramType_name[_ProgramType_index[i]:_ProgramType_index[i+1]]
|
||||
}
|
||||
func _() {
|
||||
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||
// Re-run the stringer command to generate them again.
|
||||
var x [1]struct{}
|
||||
_ = x[AttachNone-0]
|
||||
_ = x[AttachCGroupInetIngress-0]
|
||||
_ = x[AttachCGroupInetEgress-1]
|
||||
_ = x[AttachCGroupInetSockCreate-2]
|
||||
_ = x[AttachCGroupSockOps-3]
|
||||
_ = x[AttachSkSKBStreamParser-4]
|
||||
_ = x[AttachSkSKBStreamVerdict-5]
|
||||
_ = x[AttachCGroupDevice-6]
|
||||
_ = x[AttachSkMsgVerdict-7]
|
||||
_ = x[AttachCGroupInet4Bind-8]
|
||||
_ = x[AttachCGroupInet6Bind-9]
|
||||
_ = x[AttachCGroupInet4Connect-10]
|
||||
_ = x[AttachCGroupInet6Connect-11]
|
||||
_ = x[AttachCGroupInet4PostBind-12]
|
||||
_ = x[AttachCGroupInet6PostBind-13]
|
||||
_ = x[AttachCGroupUDP4Sendmsg-14]
|
||||
_ = x[AttachCGroupUDP6Sendmsg-15]
|
||||
_ = x[AttachLircMode2-16]
|
||||
_ = x[AttachFlowDissector-17]
|
||||
_ = x[AttachCGroupSysctl-18]
|
||||
_ = x[AttachCGroupUDP4Recvmsg-19]
|
||||
_ = x[AttachCGroupUDP6Recvmsg-20]
|
||||
_ = x[AttachCGroupGetsockopt-21]
|
||||
_ = x[AttachCGroupSetsockopt-22]
|
||||
_ = x[AttachTraceRawTp-23]
|
||||
_ = x[AttachTraceFEntry-24]
|
||||
_ = x[AttachTraceFExit-25]
|
||||
_ = x[AttachModifyReturn-26]
|
||||
_ = x[AttachLSMMac-27]
|
||||
_ = x[AttachTraceIter-28]
|
||||
_ = x[AttachCgroupInet4GetPeername-29]
|
||||
_ = x[AttachCgroupInet6GetPeername-30]
|
||||
_ = x[AttachCgroupInet4GetSockname-31]
|
||||
_ = x[AttachCgroupInet6GetSockname-32]
|
||||
_ = x[AttachXDPDevMap-33]
|
||||
_ = x[AttachCgroupInetSockRelease-34]
|
||||
_ = x[AttachXDPCPUMap-35]
|
||||
_ = x[AttachSkLookup-36]
|
||||
_ = x[AttachXDP-37]
|
||||
}
|
||||
|
||||
const _AttachType_name = "AttachNoneAttachCGroupInetEgressAttachCGroupInetSockCreateAttachCGroupSockOpsAttachSkSKBStreamParserAttachSkSKBStreamVerdictAttachCGroupDeviceAttachSkMsgVerdictAttachCGroupInet4BindAttachCGroupInet6BindAttachCGroupInet4ConnectAttachCGroupInet6ConnectAttachCGroupInet4PostBindAttachCGroupInet6PostBindAttachCGroupUDP4SendmsgAttachCGroupUDP6SendmsgAttachLircMode2AttachFlowDissectorAttachCGroupSysctlAttachCGroupUDP4RecvmsgAttachCGroupUDP6RecvmsgAttachCGroupGetsockoptAttachCGroupSetsockoptAttachTraceRawTpAttachTraceFEntryAttachTraceFExitAttachModifyReturnAttachLSMMacAttachTraceIterAttachCgroupInet4GetPeernameAttachCgroupInet6GetPeernameAttachCgroupInet4GetSocknameAttachCgroupInet6GetSocknameAttachXDPDevMapAttachCgroupInetSockReleaseAttachXDPCPUMapAttachSkLookupAttachXDP"
|
||||
|
||||
var _AttachType_index = [...]uint16{0, 10, 32, 58, 77, 100, 124, 142, 160, 181, 202, 226, 250, 275, 300, 323, 346, 361, 380, 398, 421, 444, 466, 488, 504, 521, 537, 555, 567, 582, 610, 638, 666, 694, 709, 736, 751, 765, 774}
|
||||
|
||||
func (i AttachType) String() string {
|
||||
if i >= AttachType(len(_AttachType_index)-1) {
|
||||
return "AttachType(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
return _AttachType_name[_AttachType_index[i]:_AttachType_index[i+1]]
|
||||
}
|
||||
func _() {
|
||||
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||
// Re-run the stringer command to generate them again.
|
||||
|
12
src/runtime/vendor/github.com/containerd/containerd/runtime/v2/shim/shim.go
generated
vendored
12
src/runtime/vendor/github.com/containerd/containerd/runtime/v2/shim/shim.go
generated
vendored
@ -169,7 +169,7 @@ func setLogger(ctx context.Context, id string) (context.Context, error) {
|
||||
l.Logger.SetLevel(logrus.DebugLevel)
|
||||
}
|
||||
f, err := openLog(ctx, id)
|
||||
if err != nil {
|
||||
if err != nil { //nolint:staticcheck // Ignore SA4023 as some platforms always return error
|
||||
return ctx, err
|
||||
}
|
||||
l.Logger.SetOutput(f)
|
||||
@ -255,12 +255,12 @@ func run(ctx context.Context, manager Manager, initFunc Init, name string, confi
|
||||
setRuntime()
|
||||
|
||||
signals, err := setupSignals(config)
|
||||
if err != nil {
|
||||
if err != nil { //nolint:staticcheck // Ignore SA4023 as some platforms always return error
|
||||
return err
|
||||
}
|
||||
|
||||
if !config.NoSubreaper {
|
||||
if err := subreaper(); err != nil {
|
||||
if err := subreaper(); err != nil { //nolint:staticcheck // Ignore SA4023 as some platforms always return error
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -418,7 +418,7 @@ func run(ctx context.Context, manager Manager, initFunc Init, name string, confi
|
||||
}
|
||||
|
||||
server, err := newServer()
|
||||
if err != nil {
|
||||
if err != nil { //nolint:staticcheck // Ignore SA4023 as some platforms always return error
|
||||
return fmt.Errorf("failed creating server: %w", err)
|
||||
}
|
||||
|
||||
@ -428,7 +428,7 @@ func run(ctx context.Context, manager Manager, initFunc Init, name string, confi
|
||||
}
|
||||
}
|
||||
|
||||
if err := serve(ctx, server, signals, sd.Shutdown); err != nil {
|
||||
if err := serve(ctx, server, signals, sd.Shutdown); err != nil { //nolint:staticcheck // Ignore SA4023 as some platforms always return error
|
||||
if err != shutdown.ErrShutdown {
|
||||
return err
|
||||
}
|
||||
@ -460,7 +460,7 @@ func serve(ctx context.Context, server *ttrpc.Server, signals chan os.Signal, sh
|
||||
}
|
||||
|
||||
l, err := serveListener(socketFlag)
|
||||
if err != nil {
|
||||
if err != nil { //nolint:staticcheck // Ignore SA4023 as some platforms always return error
|
||||
return err
|
||||
}
|
||||
go func() {
|
||||
|
2
src/runtime/vendor/github.com/containerd/containerd/version/version.go
generated
vendored
2
src/runtime/vendor/github.com/containerd/containerd/version/version.go
generated
vendored
@ -23,7 +23,7 @@ var (
|
||||
Package = "github.com/containerd/containerd"
|
||||
|
||||
// Version holds the complete version number. Filled in at linking time.
|
||||
Version = "1.6.1+unknown"
|
||||
Version = "1.6.6+unknown"
|
||||
|
||||
// Revision is filled with the VCS (e.g. git) revision being used to build
|
||||
// the program at linking time.
|
||||
|
6
src/runtime/vendor/github.com/containernetworking/cni/pkg/skel/skel.go
generated
vendored
6
src/runtime/vendor/github.com/containernetworking/cni/pkg/skel/skel.go
generated
vendored
@ -196,6 +196,7 @@ func (t *dispatcher) pluginMain(cmdAdd, cmdCheck, cmdDel func(_ *CmdArgs) error,
|
||||
// Print the about string to stderr when no command is set
|
||||
if err.Code == types.ErrInvalidEnvironmentVariables && t.Getenv("CNI_COMMAND") == "" && about != "" {
|
||||
_, _ = fmt.Fprintln(t.Stderr, about)
|
||||
_, _ = fmt.Fprintf(t.Stderr, "CNI protocol versions supported: %s\n", strings.Join(versionInfo.SupportedVersions(), ", "))
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
@ -248,10 +249,7 @@ func (t *dispatcher) pluginMain(cmdAdd, cmdCheck, cmdDel func(_ *CmdArgs) error,
|
||||
return types.NewError(types.ErrInvalidEnvironmentVariables, fmt.Sprintf("unknown CNI_COMMAND: %v", cmd), "")
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
// PluginMainWithError is the core "main" for a plugin. It accepts
|
||||
|
4
src/runtime/vendor/github.com/containernetworking/cni/pkg/version/plugin.go
generated
vendored
4
src/runtime/vendor/github.com/containernetworking/cni/pkg/version/plugin.go
generated
vendored
@ -86,8 +86,8 @@ func (*PluginDecoder) Decode(jsonBytes []byte) (PluginInfo, error) {
|
||||
// minor, and micro numbers or returns an error
|
||||
func ParseVersion(version string) (int, int, int, error) {
|
||||
var major, minor, micro int
|
||||
if version == "" {
|
||||
return -1, -1, -1, fmt.Errorf("invalid version %q: the version is empty", version)
|
||||
if version == "" { // special case: no version declared == v0.1.0
|
||||
return 0, 1, 0, nil
|
||||
}
|
||||
|
||||
parts := strings.Split(version, ".")
|
||||
|
4
src/runtime/vendor/github.com/containernetworking/plugins/pkg/ns/ns_linux.go
generated
vendored
4
src/runtime/vendor/github.com/containernetworking/plugins/pkg/ns/ns_linux.go
generated
vendored
@ -106,8 +106,8 @@ var _ NetNS = &netNS{}
|
||||
|
||||
const (
|
||||
// https://github.com/torvalds/linux/blob/master/include/uapi/linux/magic.h
|
||||
NSFS_MAGIC = 0x6e736673
|
||||
PROCFS_MAGIC = 0x9fa0
|
||||
NSFS_MAGIC = unix.NSFS_MAGIC
|
||||
PROCFS_MAGIC = unix.PROC_SUPER_MAGIC
|
||||
)
|
||||
|
||||
type NSPathNotExistErr struct{ msg string }
|
||||
|
@ -53,7 +53,7 @@ func NewNS() (ns.NetNS, error) {
|
||||
nsRunDir := getNsRunDir()
|
||||
|
||||
b := make([]byte, 16)
|
||||
_, err := rand.Reader.Read(b)
|
||||
_, err := rand.Read(b)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to generate random netns name: %v", err)
|
||||
}
|
||||
|
@ -14,14 +14,12 @@ D-Bus message bus system.
|
||||
|
||||
### Installation
|
||||
|
||||
This packages requires Go 1.7. If you installed it and set up your GOPATH, just run:
|
||||
This packages requires Go 1.12 or later. It can be installed by running the command below:
|
||||
|
||||
```
|
||||
go get github.com/godbus/dbus
|
||||
go get github.com/godbus/dbus/v5
|
||||
```
|
||||
|
||||
If you want to use the subpackages, you can install them the same way.
|
||||
|
||||
### Usage
|
||||
|
||||
The complete package documentation and some simple examples are available at
|
||||
@ -30,10 +28,12 @@ The complete package documentation and some simple examples are available at
|
||||
gives a short overview over the basic usage.
|
||||
|
||||
#### Projects using godbus
|
||||
- [notify](https://github.com/esiqveland/notify) provides desktop notifications over dbus into a library.
|
||||
- [fyne](https://github.com/fyne-io/fyne) a cross platform GUI in Go inspired by Material Design.
|
||||
- [fynedesk](https://github.com/fyne-io/fynedesk) a full desktop environment for Linux/Unix using Fyne.
|
||||
- [go-bluetooth](https://github.com/muka/go-bluetooth) provides a bluetooth client over bluez dbus API.
|
||||
- [playerbm](https://github.com/altdesktop/playerbm) a bookmark utility for media players.
|
||||
- [iwd](https://github.com/shibumi/iwd) go bindings for the internet wireless daemon "iwd".
|
||||
- [notify](https://github.com/esiqveland/notify) provides desktop notifications over dbus into a library.
|
||||
- [playerbm](https://github.com/altdesktop/playerbm) a bookmark utility for media players.
|
||||
|
||||
Please note that the API is considered unstable for now and may change without
|
||||
further notice.
|
15
src/runtime/vendor/github.com/godbus/dbus/v5/auth.go
generated
vendored
15
src/runtime/vendor/github.com/godbus/dbus/v5/auth.go
generated
vendored
@ -53,7 +53,7 @@ type Auth interface {
|
||||
// bus. Auth must not be called on shared connections.
|
||||
func (conn *Conn) Auth(methods []Auth) error {
|
||||
if methods == nil {
|
||||
uid := strconv.Itoa(os.Getuid())
|
||||
uid := strconv.Itoa(os.Geteuid())
|
||||
methods = []Auth{AuthExternal(uid), AuthCookieSha1(uid, getHomeDir())}
|
||||
}
|
||||
in := bufio.NewReader(conn.transport)
|
||||
@ -75,9 +75,9 @@ func (conn *Conn) Auth(methods []Auth) error {
|
||||
s = s[1:]
|
||||
for _, v := range s {
|
||||
for _, m := range methods {
|
||||
if name, data, status := m.FirstData(); bytes.Equal(v, name) {
|
||||
if name, _, status := m.FirstData(); bytes.Equal(v, name) {
|
||||
var ok bool
|
||||
err = authWriteLine(conn.transport, []byte("AUTH"), v, data)
|
||||
err = authWriteLine(conn.transport, []byte("AUTH"), v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -194,11 +194,14 @@ func (conn *Conn) tryAuth(m Auth, state authState, in *bufio.Reader) (error, boo
|
||||
}
|
||||
conn.uuid = string(s[1])
|
||||
return nil, true
|
||||
case state == waitingForOk && string(s[0]) == "DATA":
|
||||
err = authWriteLine(conn.transport, []byte("DATA"))
|
||||
if err != nil {
|
||||
return err, false
|
||||
}
|
||||
case state == waitingForOk && string(s[0]) == "REJECTED":
|
||||
return nil, false
|
||||
case state == waitingForOk && (string(s[0]) == "DATA" ||
|
||||
string(s[0]) == "ERROR"):
|
||||
|
||||
case state == waitingForOk && string(s[0]) == "ERROR":
|
||||
err = authWriteLine(conn.transport, []byte("CANCEL"))
|
||||
if err != nil {
|
||||
return err, false
|
||||
|
36
src/runtime/vendor/github.com/godbus/dbus/v5/conn.go
generated
vendored
36
src/runtime/vendor/github.com/godbus/dbus/v5/conn.go
generated
vendored
@ -73,7 +73,7 @@ func SessionBus() (conn *Conn, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func getSessionBusAddress() (string, error) {
|
||||
func getSessionBusAddress(autolaunch bool) (string, error) {
|
||||
if address := os.Getenv("DBUS_SESSION_BUS_ADDRESS"); address != "" && address != "autolaunch:" {
|
||||
return address, nil
|
||||
|
||||
@ -81,12 +81,26 @@ func getSessionBusAddress() (string, error) {
|
||||
os.Setenv("DBUS_SESSION_BUS_ADDRESS", address)
|
||||
return address, nil
|
||||
}
|
||||
if !autolaunch {
|
||||
return "", errors.New("dbus: couldn't determine address of session bus")
|
||||
}
|
||||
return getSessionBusPlatformAddress()
|
||||
}
|
||||
|
||||
// SessionBusPrivate returns a new private connection to the session bus.
|
||||
func SessionBusPrivate(opts ...ConnOption) (*Conn, error) {
|
||||
address, err := getSessionBusAddress()
|
||||
address, err := getSessionBusAddress(true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return Dial(address, opts...)
|
||||
}
|
||||
|
||||
// SessionBusPrivate returns a new private connection to the session bus. If
|
||||
// the session bus is not already open, do not attempt to launch it.
|
||||
func SessionBusPrivateNoAutoStartup(opts ...ConnOption) (*Conn, error) {
|
||||
address, err := getSessionBusAddress(false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -121,7 +135,7 @@ func SystemBus() (conn *Conn, err error) {
|
||||
|
||||
// ConnectSessionBus connects to the session bus.
|
||||
func ConnectSessionBus(opts ...ConnOption) (*Conn, error) {
|
||||
address, err := getSessionBusAddress()
|
||||
address, err := getSessionBusAddress(true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -180,7 +194,7 @@ func Dial(address string, opts ...ConnOption) (*Conn, error) {
|
||||
//
|
||||
// Deprecated: use Dial with options instead.
|
||||
func DialHandler(address string, handler Handler, signalHandler SignalHandler) (*Conn, error) {
|
||||
return Dial(address, WithSignalHandler(signalHandler))
|
||||
return Dial(address, WithHandler(handler), WithSignalHandler(signalHandler))
|
||||
}
|
||||
|
||||
// ConnOption is a connection option.
|
||||
@ -478,14 +492,24 @@ func (conn *Conn) sendMessageAndIfClosed(msg *Message, ifClosed func()) {
|
||||
conn.outInt(msg)
|
||||
}
|
||||
err := conn.outHandler.sendAndIfClosed(msg, ifClosed)
|
||||
conn.calls.handleSendError(msg, err)
|
||||
if err != nil {
|
||||
conn.serialGen.RetireSerial(msg.serial)
|
||||
conn.handleSendError(msg, err)
|
||||
} else if msg.Type != TypeMethodCall {
|
||||
conn.serialGen.RetireSerial(msg.serial)
|
||||
}
|
||||
}
|
||||
|
||||
func (conn *Conn) handleSendError(msg *Message, err error) {
|
||||
if msg.Type == TypeMethodCall {
|
||||
conn.calls.handleSendError(msg, err)
|
||||
} else if msg.Type == TypeMethodReply {
|
||||
if _, ok := err.(FormatError); ok {
|
||||
conn.sendError(err, msg.Headers[FieldDestination].value.(string), msg.Headers[FieldReplySerial].value.(uint32))
|
||||
}
|
||||
}
|
||||
conn.serialGen.RetireSerial(msg.serial)
|
||||
}
|
||||
|
||||
// Send sends the given message to the message bus. You usually don't need to
|
||||
// use this; use the higher-level equivalents (Call / Go, Emit and Export)
|
||||
// instead. If msg is a method call and NoReplyExpected is not set, a non-nil
|
||||
|
16
src/runtime/vendor/github.com/godbus/dbus/v5/decoder.go
generated
vendored
16
src/runtime/vendor/github.com/godbus/dbus/v5/decoder.go
generated
vendored
@ -10,14 +10,16 @@ type decoder struct {
|
||||
in io.Reader
|
||||
order binary.ByteOrder
|
||||
pos int
|
||||
fds []int
|
||||
}
|
||||
|
||||
// newDecoder returns a new decoder that reads values from in. The input is
|
||||
// expected to be in the given byte order.
|
||||
func newDecoder(in io.Reader, order binary.ByteOrder) *decoder {
|
||||
func newDecoder(in io.Reader, order binary.ByteOrder, fds []int) *decoder {
|
||||
dec := new(decoder)
|
||||
dec.in = in
|
||||
dec.order = order
|
||||
dec.fds = fds
|
||||
return dec
|
||||
}
|
||||
|
||||
@ -53,7 +55,7 @@ func (dec *decoder) Decode(sig Signature) (vs []interface{}, err error) {
|
||||
vs = make([]interface{}, 0)
|
||||
s := sig.str
|
||||
for s != "" {
|
||||
err, rem := validSingle(s, 0)
|
||||
err, rem := validSingle(s, &depthCounter{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -150,7 +152,7 @@ func (dec *decoder) decode(s string, depth int) interface{} {
|
||||
if len(sig.str) == 0 {
|
||||
panic(FormatError("variant signature is empty"))
|
||||
}
|
||||
err, rem := validSingle(sig.str, 0)
|
||||
err, rem := validSingle(sig.str, &depthCounter{})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -161,7 +163,11 @@ func (dec *decoder) decode(s string, depth int) interface{} {
|
||||
variant.value = dec.decode(sig.str, depth+1)
|
||||
return variant
|
||||
case 'h':
|
||||
return UnixFDIndex(dec.decode("u", depth).(uint32))
|
||||
idx := dec.decode("u", depth).(uint32)
|
||||
if int(idx) < len(dec.fds) {
|
||||
return UnixFD(dec.fds[idx])
|
||||
}
|
||||
return UnixFDIndex(idx)
|
||||
case 'a':
|
||||
if len(s) > 1 && s[1] == '{' {
|
||||
ksig := s[2:3]
|
||||
@ -219,7 +225,7 @@ func (dec *decoder) decode(s string, depth int) interface{} {
|
||||
v := make([]interface{}, 0)
|
||||
s = s[1 : len(s)-1]
|
||||
for s != "" {
|
||||
err, rem := validSingle(s, 0)
|
||||
err, rem := validSingle(s, &depthCounter{})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
61
src/runtime/vendor/github.com/godbus/dbus/v5/encoder.go
generated
vendored
61
src/runtime/vendor/github.com/godbus/dbus/v5/encoder.go
generated
vendored
@ -5,28 +5,33 @@ import (
|
||||
"encoding/binary"
|
||||
"io"
|
||||
"reflect"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// An encoder encodes values to the D-Bus wire format.
|
||||
type encoder struct {
|
||||
out io.Writer
|
||||
fds []int
|
||||
order binary.ByteOrder
|
||||
pos int
|
||||
}
|
||||
|
||||
// NewEncoder returns a new encoder that writes to out in the given byte order.
|
||||
func newEncoder(out io.Writer, order binary.ByteOrder) *encoder {
|
||||
return newEncoderAtOffset(out, 0, order)
|
||||
func newEncoder(out io.Writer, order binary.ByteOrder, fds []int) *encoder {
|
||||
enc := newEncoderAtOffset(out, 0, order, fds)
|
||||
return enc
|
||||
}
|
||||
|
||||
// newEncoderAtOffset returns a new encoder that writes to out in the given
|
||||
// byte order. Specify the offset to initialize pos for proper alignment
|
||||
// computation.
|
||||
func newEncoderAtOffset(out io.Writer, offset int, order binary.ByteOrder) *encoder {
|
||||
func newEncoderAtOffset(out io.Writer, offset int, order binary.ByteOrder, fds []int) *encoder {
|
||||
enc := new(encoder)
|
||||
enc.out = out
|
||||
enc.order = order
|
||||
enc.pos = offset
|
||||
enc.fds = fds
|
||||
return enc
|
||||
}
|
||||
|
||||
@ -75,6 +80,9 @@ func (enc *encoder) Encode(vs ...interface{}) (err error) {
|
||||
// encode encodes the given value to the writer and panics on error. depth holds
|
||||
// the depth of the container nesting.
|
||||
func (enc *encoder) encode(v reflect.Value, depth int) {
|
||||
if depth > 64 {
|
||||
panic(FormatError("input exceeds depth limitation"))
|
||||
}
|
||||
enc.align(alignment(v.Type()))
|
||||
switch v.Kind() {
|
||||
case reflect.Uint8:
|
||||
@ -97,7 +105,14 @@ func (enc *encoder) encode(v reflect.Value, depth int) {
|
||||
enc.binwrite(uint16(v.Uint()))
|
||||
enc.pos += 2
|
||||
case reflect.Int, reflect.Int32:
|
||||
enc.binwrite(int32(v.Int()))
|
||||
if v.Type() == unixFDType {
|
||||
fd := v.Int()
|
||||
idx := len(enc.fds)
|
||||
enc.fds = append(enc.fds, int(fd))
|
||||
enc.binwrite(uint32(idx))
|
||||
} else {
|
||||
enc.binwrite(int32(v.Int()))
|
||||
}
|
||||
enc.pos += 4
|
||||
case reflect.Uint, reflect.Uint32:
|
||||
enc.binwrite(uint32(v.Uint()))
|
||||
@ -112,9 +127,21 @@ func (enc *encoder) encode(v reflect.Value, depth int) {
|
||||
enc.binwrite(v.Float())
|
||||
enc.pos += 8
|
||||
case reflect.String:
|
||||
enc.encode(reflect.ValueOf(uint32(len(v.String()))), depth)
|
||||
str := v.String()
|
||||
if !utf8.ValidString(str) {
|
||||
panic(FormatError("input has a not-utf8 char in string"))
|
||||
}
|
||||
if strings.IndexByte(str, byte(0)) != -1 {
|
||||
panic(FormatError("input has a null char('\\000') in string"))
|
||||
}
|
||||
if v.Type() == objectPathType {
|
||||
if !ObjectPath(str).IsValid() {
|
||||
panic(FormatError("invalid object path"))
|
||||
}
|
||||
}
|
||||
enc.encode(reflect.ValueOf(uint32(len(str))), depth)
|
||||
b := make([]byte, v.Len()+1)
|
||||
copy(b, v.String())
|
||||
copy(b, str)
|
||||
b[len(b)-1] = 0
|
||||
n, err := enc.out.Write(b)
|
||||
if err != nil {
|
||||
@ -124,20 +151,23 @@ func (enc *encoder) encode(v reflect.Value, depth int) {
|
||||
case reflect.Ptr:
|
||||
enc.encode(v.Elem(), depth)
|
||||
case reflect.Slice, reflect.Array:
|
||||
if depth >= 64 {
|
||||
panic(FormatError("input exceeds container depth limit"))
|
||||
}
|
||||
// Lookahead offset: 4 bytes for uint32 length (with alignment),
|
||||
// plus alignment for elements.
|
||||
n := enc.padding(0, 4) + 4
|
||||
offset := enc.pos + n + enc.padding(n, alignment(v.Type().Elem()))
|
||||
|
||||
var buf bytes.Buffer
|
||||
bufenc := newEncoderAtOffset(&buf, offset, enc.order)
|
||||
bufenc := newEncoderAtOffset(&buf, offset, enc.order, enc.fds)
|
||||
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
bufenc.encode(v.Index(i), depth+1)
|
||||
}
|
||||
|
||||
if buf.Len() > 1<<26 {
|
||||
panic(FormatError("input exceeds array size limitation"))
|
||||
}
|
||||
|
||||
enc.fds = bufenc.fds
|
||||
enc.encode(reflect.ValueOf(uint32(buf.Len())), depth)
|
||||
length := buf.Len()
|
||||
enc.align(alignment(v.Type().Elem()))
|
||||
@ -146,13 +176,10 @@ func (enc *encoder) encode(v reflect.Value, depth int) {
|
||||
}
|
||||
enc.pos += length
|
||||
case reflect.Struct:
|
||||
if depth >= 64 && v.Type() != signatureType {
|
||||
panic(FormatError("input exceeds container depth limit"))
|
||||
}
|
||||
switch t := v.Type(); t {
|
||||
case signatureType:
|
||||
str := v.Field(0)
|
||||
enc.encode(reflect.ValueOf(byte(str.Len())), depth+1)
|
||||
enc.encode(reflect.ValueOf(byte(str.Len())), depth)
|
||||
b := make([]byte, str.Len()+1)
|
||||
copy(b, str.String())
|
||||
b[len(b)-1] = 0
|
||||
@ -176,9 +203,6 @@ func (enc *encoder) encode(v reflect.Value, depth int) {
|
||||
case reflect.Map:
|
||||
// Maps are arrays of structures, so they actually increase the depth by
|
||||
// 2.
|
||||
if depth >= 63 {
|
||||
panic(FormatError("input exceeds container depth limit"))
|
||||
}
|
||||
if !isKeyType(v.Type().Key()) {
|
||||
panic(InvalidTypeError{v.Type()})
|
||||
}
|
||||
@ -189,12 +213,13 @@ func (enc *encoder) encode(v reflect.Value, depth int) {
|
||||
offset := enc.pos + n + enc.padding(n, 8)
|
||||
|
||||
var buf bytes.Buffer
|
||||
bufenc := newEncoderAtOffset(&buf, offset, enc.order)
|
||||
bufenc := newEncoderAtOffset(&buf, offset, enc.order, enc.fds)
|
||||
for _, k := range keys {
|
||||
bufenc.align(8)
|
||||
bufenc.encode(k, depth+2)
|
||||
bufenc.encode(v.MapIndex(k), depth+2)
|
||||
}
|
||||
enc.fds = bufenc.fds
|
||||
enc.encode(reflect.ValueOf(uint32(buf.Len())), depth)
|
||||
length := buf.Len()
|
||||
enc.align(8)
|
||||
|
37
src/runtime/vendor/github.com/godbus/dbus/v5/export.go
generated
vendored
37
src/runtime/vendor/github.com/godbus/dbus/v5/export.go
generated
vendored
@ -26,6 +26,27 @@ var (
|
||||
}
|
||||
)
|
||||
|
||||
func MakeNoObjectError(path ObjectPath) Error {
|
||||
return Error{
|
||||
"org.freedesktop.DBus.Error.NoSuchObject",
|
||||
[]interface{}{fmt.Sprintf("No such object '%s'", string(path))},
|
||||
}
|
||||
}
|
||||
|
||||
func MakeUnknownMethodError(methodName string) Error {
|
||||
return Error{
|
||||
"org.freedesktop.DBus.Error.UnknownMethod",
|
||||
[]interface{}{fmt.Sprintf("Unknown / invalid method '%s'", methodName)},
|
||||
}
|
||||
}
|
||||
|
||||
func MakeUnknownInterfaceError(ifaceName string) Error {
|
||||
return Error{
|
||||
"org.freedesktop.DBus.Error.UnknownInterface",
|
||||
[]interface{}{fmt.Sprintf("Object does not implement the interface '%s'", ifaceName)},
|
||||
}
|
||||
}
|
||||
|
||||
func MakeFailedError(err error) *Error {
|
||||
return &Error{
|
||||
"org.freedesktop.DBus.Error.Failed",
|
||||
@ -128,6 +149,11 @@ func (conn *Conn) handleCall(msg *Message) {
|
||||
ifaceName, _ := msg.Headers[FieldInterface].value.(string)
|
||||
sender, hasSender := msg.Headers[FieldSender].value.(string)
|
||||
serial := msg.serial
|
||||
|
||||
if len(name) == 0 {
|
||||
conn.sendError(ErrMsgUnknownMethod, sender, serial)
|
||||
}
|
||||
|
||||
if ifaceName == "org.freedesktop.DBus.Peer" {
|
||||
switch name {
|
||||
case "Ping":
|
||||
@ -135,29 +161,26 @@ func (conn *Conn) handleCall(msg *Message) {
|
||||
case "GetMachineId":
|
||||
conn.sendReply(sender, serial, conn.uuid)
|
||||
default:
|
||||
conn.sendError(ErrMsgUnknownMethod, sender, serial)
|
||||
conn.sendError(MakeUnknownMethodError(name), sender, serial)
|
||||
}
|
||||
return
|
||||
}
|
||||
if len(name) == 0 {
|
||||
conn.sendError(ErrMsgUnknownMethod, sender, serial)
|
||||
}
|
||||
|
||||
object, ok := conn.handler.LookupObject(path)
|
||||
if !ok {
|
||||
conn.sendError(ErrMsgNoObject, sender, serial)
|
||||
conn.sendError(MakeNoObjectError(path), sender, serial)
|
||||
return
|
||||
}
|
||||
|
||||
iface, exists := object.LookupInterface(ifaceName)
|
||||
if !exists {
|
||||
conn.sendError(ErrMsgUnknownInterface, sender, serial)
|
||||
conn.sendError(MakeUnknownInterfaceError(ifaceName), sender, serial)
|
||||
return
|
||||
}
|
||||
|
||||
m, exists := iface.LookupMethod(name)
|
||||
if !exists {
|
||||
conn.sendError(ErrMsgUnknownMethod, sender, serial)
|
||||
conn.sendError(MakeUnknownMethodError(name), sender, serial)
|
||||
return
|
||||
}
|
||||
args, err := conn.decodeArguments(m, sender, msg)
|
||||
|
73
src/runtime/vendor/github.com/godbus/dbus/v5/message.go
generated
vendored
73
src/runtime/vendor/github.com/godbus/dbus/v5/message.go
generated
vendored
@ -118,11 +118,7 @@ type header struct {
|
||||
Variant
|
||||
}
|
||||
|
||||
// DecodeMessage tries to decode a single message in the D-Bus wire format
|
||||
// from the given reader. The byte order is figured out from the first byte.
|
||||
// The possibly returned error can be an error of the underlying reader, an
|
||||
// InvalidMessageError or a FormatError.
|
||||
func DecodeMessage(rd io.Reader) (msg *Message, err error) {
|
||||
func DecodeMessageWithFDs(rd io.Reader, fds []int) (msg *Message, err error) {
|
||||
var order binary.ByteOrder
|
||||
var hlength, length uint32
|
||||
var typ, flags, proto byte
|
||||
@ -142,7 +138,7 @@ func DecodeMessage(rd io.Reader) (msg *Message, err error) {
|
||||
return nil, InvalidMessageError("invalid byte order")
|
||||
}
|
||||
|
||||
dec := newDecoder(rd, order)
|
||||
dec := newDecoder(rd, order, fds)
|
||||
dec.pos = 1
|
||||
|
||||
msg = new(Message)
|
||||
@ -166,7 +162,7 @@ func DecodeMessage(rd io.Reader) (msg *Message, err error) {
|
||||
if hlength+length+16 > 1<<27 {
|
||||
return nil, InvalidMessageError("message is too long")
|
||||
}
|
||||
dec = newDecoder(io.MultiReader(bytes.NewBuffer(b), rd), order)
|
||||
dec = newDecoder(io.MultiReader(bytes.NewBuffer(b), rd), order, fds)
|
||||
dec.pos = 12
|
||||
vs, err = dec.Decode(Signature{"a(yv)"})
|
||||
if err != nil {
|
||||
@ -196,7 +192,7 @@ func DecodeMessage(rd io.Reader) (msg *Message, err error) {
|
||||
sig, _ := msg.Headers[FieldSignature].value.(Signature)
|
||||
if sig.str != "" {
|
||||
buf := bytes.NewBuffer(body)
|
||||
dec = newDecoder(buf, order)
|
||||
dec = newDecoder(buf, order, fds)
|
||||
vs, err := dec.Decode(sig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -207,12 +203,32 @@ func DecodeMessage(rd io.Reader) (msg *Message, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// EncodeTo encodes and sends a message to the given writer. The byte order must
|
||||
// be either binary.LittleEndian or binary.BigEndian. If the message is not
|
||||
// valid or an error occurs when writing, an error is returned.
|
||||
func (msg *Message) EncodeTo(out io.Writer, order binary.ByteOrder) error {
|
||||
// DecodeMessage tries to decode a single message in the D-Bus wire format
|
||||
// from the given reader. The byte order is figured out from the first byte.
|
||||
// The possibly returned error can be an error of the underlying reader, an
|
||||
// InvalidMessageError or a FormatError.
|
||||
func DecodeMessage(rd io.Reader) (msg *Message, err error) {
|
||||
return DecodeMessageWithFDs(rd, make([]int, 0));
|
||||
}
|
||||
|
||||
type nullwriter struct{}
|
||||
|
||||
func (nullwriter) Write(p []byte) (cnt int, err error) {
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
func (msg *Message) CountFds() (int, error) {
|
||||
if len(msg.Body) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
enc := newEncoder(nullwriter{}, nativeEndian, make([]int, 0))
|
||||
err := enc.Encode(msg.Body...)
|
||||
return len(enc.fds), err
|
||||
}
|
||||
|
||||
func (msg *Message) EncodeToWithFDs(out io.Writer, order binary.ByteOrder) (fds []int, err error) {
|
||||
if err := msg.IsValid(); err != nil {
|
||||
return err
|
||||
return make([]int, 0), err
|
||||
}
|
||||
var vs [7]interface{}
|
||||
switch order {
|
||||
@ -221,12 +237,16 @@ func (msg *Message) EncodeTo(out io.Writer, order binary.ByteOrder) error {
|
||||
case binary.BigEndian:
|
||||
vs[0] = byte('B')
|
||||
default:
|
||||
return errors.New("dbus: invalid byte order")
|
||||
return make([]int, 0), errors.New("dbus: invalid byte order")
|
||||
}
|
||||
body := new(bytes.Buffer)
|
||||
enc := newEncoder(body, order)
|
||||
fds = make([]int, 0)
|
||||
enc := newEncoder(body, order, fds)
|
||||
if len(msg.Body) != 0 {
|
||||
enc.Encode(msg.Body...)
|
||||
err = enc.Encode(msg.Body...)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
vs[1] = msg.Type
|
||||
vs[2] = msg.Flags
|
||||
@ -239,17 +259,28 @@ func (msg *Message) EncodeTo(out io.Writer, order binary.ByteOrder) error {
|
||||
}
|
||||
vs[6] = headers
|
||||
var buf bytes.Buffer
|
||||
enc = newEncoder(&buf, order)
|
||||
enc.Encode(vs[:]...)
|
||||
enc = newEncoder(&buf, order, enc.fds)
|
||||
err = enc.Encode(vs[:]...)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
enc.align(8)
|
||||
body.WriteTo(&buf)
|
||||
if buf.Len() > 1<<27 {
|
||||
return InvalidMessageError("message is too long")
|
||||
return make([]int, 0), InvalidMessageError("message is too long")
|
||||
}
|
||||
if _, err := buf.WriteTo(out); err != nil {
|
||||
return err
|
||||
return make([]int, 0), err
|
||||
}
|
||||
return nil
|
||||
return enc.fds, nil
|
||||
}
|
||||
|
||||
// EncodeTo encodes and sends a message to the given writer. The byte order must
|
||||
// be either binary.LittleEndian or binary.BigEndian. If the message is not
|
||||
// valid or an error occurs when writing, an error is returned.
|
||||
func (msg *Message) EncodeTo(out io.Writer, order binary.ByteOrder) (err error) {
|
||||
_, err = msg.EncodeToWithFDs(out, order)
|
||||
return err
|
||||
}
|
||||
|
||||
// IsValid checks whether msg is a valid message and returns an
|
||||
|
66
src/runtime/vendor/github.com/godbus/dbus/v5/sig.go
generated
vendored
66
src/runtime/vendor/github.com/godbus/dbus/v5/sig.go
generated
vendored
@ -34,7 +34,7 @@ type Signature struct {
|
||||
func SignatureOf(vs ...interface{}) Signature {
|
||||
var s string
|
||||
for _, v := range vs {
|
||||
s += getSignature(reflect.TypeOf(v))
|
||||
s += getSignature(reflect.TypeOf(v), &depthCounter{})
|
||||
}
|
||||
return Signature{s}
|
||||
}
|
||||
@ -42,11 +42,19 @@ func SignatureOf(vs ...interface{}) Signature {
|
||||
// SignatureOfType returns the signature of the given type. It panics if the
|
||||
// type is not representable in D-Bus.
|
||||
func SignatureOfType(t reflect.Type) Signature {
|
||||
return Signature{getSignature(t)}
|
||||
return Signature{getSignature(t, &depthCounter{})}
|
||||
}
|
||||
|
||||
// getSignature returns the signature of the given type and panics on unknown types.
|
||||
func getSignature(t reflect.Type) string {
|
||||
func getSignature(t reflect.Type, depth *depthCounter) (sig string) {
|
||||
if !depth.Valid() {
|
||||
panic("container nesting too deep")
|
||||
}
|
||||
defer func() {
|
||||
if len(sig) > 255 {
|
||||
panic("signature exceeds the length limitation")
|
||||
}
|
||||
}()
|
||||
// handle simple types first
|
||||
switch t.Kind() {
|
||||
case reflect.Uint8:
|
||||
@ -74,7 +82,7 @@ func getSignature(t reflect.Type) string {
|
||||
case reflect.Float64:
|
||||
return "d"
|
||||
case reflect.Ptr:
|
||||
return getSignature(t.Elem())
|
||||
return getSignature(t.Elem(), depth)
|
||||
case reflect.String:
|
||||
if t == objectPathType {
|
||||
return "o"
|
||||
@ -90,17 +98,20 @@ func getSignature(t reflect.Type) string {
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
field := t.Field(i)
|
||||
if field.PkgPath == "" && field.Tag.Get("dbus") != "-" {
|
||||
s += getSignature(t.Field(i).Type)
|
||||
s += getSignature(t.Field(i).Type, depth.EnterStruct())
|
||||
}
|
||||
}
|
||||
if len(s) == 0 {
|
||||
panic("empty struct")
|
||||
}
|
||||
return "(" + s + ")"
|
||||
case reflect.Array, reflect.Slice:
|
||||
return "a" + getSignature(t.Elem())
|
||||
return "a" + getSignature(t.Elem(), depth.EnterArray())
|
||||
case reflect.Map:
|
||||
if !isKeyType(t.Key()) {
|
||||
panic(InvalidTypeError{t})
|
||||
}
|
||||
return "a{" + getSignature(t.Key()) + getSignature(t.Elem()) + "}"
|
||||
return "a{" + getSignature(t.Key(), depth.EnterArray().EnterDictEntry()) + getSignature(t.Elem(), depth.EnterArray().EnterDictEntry()) + "}"
|
||||
case reflect.Interface:
|
||||
return "v"
|
||||
}
|
||||
@ -118,7 +129,7 @@ func ParseSignature(s string) (sig Signature, err error) {
|
||||
}
|
||||
sig.str = s
|
||||
for err == nil && len(s) != 0 {
|
||||
err, s = validSingle(s, 0)
|
||||
err, s = validSingle(s, &depthCounter{})
|
||||
}
|
||||
if err != nil {
|
||||
sig = Signature{""}
|
||||
@ -144,7 +155,7 @@ func (s Signature) Empty() bool {
|
||||
|
||||
// Single returns whether the signature represents a single, complete type.
|
||||
func (s Signature) Single() bool {
|
||||
err, r := validSingle(s.str, 0)
|
||||
err, r := validSingle(s.str, &depthCounter{})
|
||||
return err != nil && r == ""
|
||||
}
|
||||
|
||||
@ -164,15 +175,38 @@ func (e SignatureError) Error() string {
|
||||
return fmt.Sprintf("dbus: invalid signature: %q (%s)", e.Sig, e.Reason)
|
||||
}
|
||||
|
||||
type depthCounter struct {
|
||||
arrayDepth, structDepth, dictEntryDepth int
|
||||
}
|
||||
|
||||
func (cnt *depthCounter) Valid() bool {
|
||||
return cnt.arrayDepth <= 32 && cnt.structDepth <= 32 && cnt.dictEntryDepth <= 32
|
||||
}
|
||||
|
||||
func (cnt depthCounter) EnterArray() *depthCounter {
|
||||
cnt.arrayDepth++
|
||||
return &cnt
|
||||
}
|
||||
|
||||
func (cnt depthCounter) EnterStruct() *depthCounter {
|
||||
cnt.structDepth++
|
||||
return &cnt
|
||||
}
|
||||
|
||||
func (cnt depthCounter) EnterDictEntry() *depthCounter {
|
||||
cnt.dictEntryDepth++
|
||||
return &cnt
|
||||
}
|
||||
|
||||
// Try to read a single type from this string. If it was successful, err is nil
|
||||
// and rem is the remaining unparsed part. Otherwise, err is a non-nil
|
||||
// SignatureError and rem is "". depth is the current recursion depth which may
|
||||
// not be greater than 64 and should be given as 0 on the first call.
|
||||
func validSingle(s string, depth int) (err error, rem string) {
|
||||
func validSingle(s string, depth *depthCounter) (err error, rem string) {
|
||||
if s == "" {
|
||||
return SignatureError{Sig: s, Reason: "empty signature"}, ""
|
||||
}
|
||||
if depth > 64 {
|
||||
if !depth.Valid() {
|
||||
return SignatureError{Sig: s, Reason: "container nesting too deep"}, ""
|
||||
}
|
||||
switch s[0] {
|
||||
@ -187,10 +221,10 @@ func validSingle(s string, depth int) (err error, rem string) {
|
||||
i++
|
||||
rem = s[i+1:]
|
||||
s = s[2:i]
|
||||
if err, _ = validSingle(s[:1], depth+1); err != nil {
|
||||
if err, _ = validSingle(s[:1], depth.EnterArray().EnterDictEntry()); err != nil {
|
||||
return err, ""
|
||||
}
|
||||
err, nr := validSingle(s[1:], depth+1)
|
||||
err, nr := validSingle(s[1:], depth.EnterArray().EnterDictEntry())
|
||||
if err != nil {
|
||||
return err, ""
|
||||
}
|
||||
@ -199,7 +233,7 @@ func validSingle(s string, depth int) (err error, rem string) {
|
||||
}
|
||||
return nil, rem
|
||||
}
|
||||
return validSingle(s[1:], depth+1)
|
||||
return validSingle(s[1:], depth.EnterArray())
|
||||
case '(':
|
||||
i := findMatching(s, '(', ')')
|
||||
if i == -1 {
|
||||
@ -208,7 +242,7 @@ func validSingle(s string, depth int) (err error, rem string) {
|
||||
rem = s[i+1:]
|
||||
s = s[1:i]
|
||||
for err == nil && s != "" {
|
||||
err, s = validSingle(s, depth+1)
|
||||
err, s = validSingle(s, depth.EnterStruct())
|
||||
}
|
||||
if err != nil {
|
||||
rem = ""
|
||||
@ -236,7 +270,7 @@ func findMatching(s string, left, right rune) int {
|
||||
// typeFor returns the type of the given signature. It ignores any left over
|
||||
// characters and panics if s doesn't start with a valid type signature.
|
||||
func typeFor(s string) (t reflect.Type) {
|
||||
err, _ := validSingle(s, 0)
|
||||
err, _ := validSingle(s, &depthCounter{})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
10
src/runtime/vendor/github.com/godbus/dbus/v5/transport_generic.go
generated
vendored
10
src/runtime/vendor/github.com/godbus/dbus/v5/transport_generic.go
generated
vendored
@ -41,10 +41,12 @@ func (t genericTransport) ReadMessage() (*Message, error) {
|
||||
}
|
||||
|
||||
func (t genericTransport) SendMessage(msg *Message) error {
|
||||
for _, v := range msg.Body {
|
||||
if _, ok := v.(UnixFD); ok {
|
||||
return errors.New("dbus: unix fd passing not enabled")
|
||||
}
|
||||
fds, err := msg.CountFds()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if fds != 0 {
|
||||
return errors.New("dbus: unix fd passing not enabled")
|
||||
}
|
||||
return msg.EncodeTo(t, nativeEndian)
|
||||
}
|
||||
|
24
src/runtime/vendor/github.com/godbus/dbus/v5/transport_unix.go
generated
vendored
24
src/runtime/vendor/github.com/godbus/dbus/v5/transport_unix.go
generated
vendored
@ -113,7 +113,7 @@ func (t *unixTransport) ReadMessage() (*Message, error) {
|
||||
if _, err := io.ReadFull(t.rdr, headerdata[4:]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dec := newDecoder(bytes.NewBuffer(headerdata), order)
|
||||
dec := newDecoder(bytes.NewBuffer(headerdata), order, make([]int, 0))
|
||||
dec.pos = 12
|
||||
vs, err := dec.Decode(Signature{"a(yv)"})
|
||||
if err != nil {
|
||||
@ -147,7 +147,7 @@ func (t *unixTransport) ReadMessage() (*Message, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
msg, err := DecodeMessage(bytes.NewBuffer(all))
|
||||
msg, err := DecodeMessageWithFDs(bytes.NewBuffer(all), fds)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -179,21 +179,21 @@ func (t *unixTransport) ReadMessage() (*Message, error) {
|
||||
}
|
||||
|
||||
func (t *unixTransport) SendMessage(msg *Message) error {
|
||||
fds := make([]int, 0)
|
||||
for i, v := range msg.Body {
|
||||
if fd, ok := v.(UnixFD); ok {
|
||||
msg.Body[i] = UnixFDIndex(len(fds))
|
||||
fds = append(fds, int(fd))
|
||||
}
|
||||
fdcnt, err := msg.CountFds()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(fds) != 0 {
|
||||
if fdcnt != 0 {
|
||||
if !t.hasUnixFDs {
|
||||
return errors.New("dbus: unix fd passing not enabled")
|
||||
}
|
||||
msg.Headers[FieldUnixFDs] = MakeVariant(uint32(len(fds)))
|
||||
oob := syscall.UnixRights(fds...)
|
||||
msg.Headers[FieldUnixFDs] = MakeVariant(uint32(fdcnt))
|
||||
buf := new(bytes.Buffer)
|
||||
msg.EncodeTo(buf, nativeEndian)
|
||||
fds, err := msg.EncodeToWithFDs(buf, nativeEndian)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
oob := syscall.UnixRights(fds...)
|
||||
n, oobn, err := t.UnixConn.WriteMsgUnix(buf.Bytes(), oob, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
|
14
src/runtime/vendor/github.com/godbus/dbus/v5/transport_unixcred_netbsd.go
generated
vendored
Normal file
14
src/runtime/vendor/github.com/godbus/dbus/v5/transport_unixcred_netbsd.go
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
package dbus
|
||||
|
||||
import "io"
|
||||
|
||||
func (t *unixTransport) SendNullByte() error {
|
||||
n, _, err := t.UnixConn.WriteMsgUnix([]byte{0}, nil, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if n != 1 {
|
||||
return io.ErrShortWrite
|
||||
}
|
||||
return nil
|
||||
}
|
2
src/runtime/vendor/github.com/opencontainers/selinux/go-selinux/rchcon.go
generated
vendored
2
src/runtime/vendor/github.com/opencontainers/selinux/go-selinux/rchcon.go
generated
vendored
@ -12,7 +12,7 @@ import (
|
||||
|
||||
func rchcon(fpath, label string) error {
|
||||
return pwalkdir.Walk(fpath, func(p string, _ fs.DirEntry, _ error) error {
|
||||
e := setFileLabel(p, label)
|
||||
e := lSetFileLabel(p, label)
|
||||
// Walk a file tree can race with removal, so ignore ENOENT.
|
||||
if errors.Is(e, os.ErrNotExist) {
|
||||
return nil
|
||||
|
2
src/runtime/vendor/github.com/opencontainers/selinux/go-selinux/rchcon_go115.go
generated
vendored
2
src/runtime/vendor/github.com/opencontainers/selinux/go-selinux/rchcon_go115.go
generated
vendored
@ -11,7 +11,7 @@ import (
|
||||
|
||||
func rchcon(fpath, label string) error {
|
||||
return pwalk.Walk(fpath, func(p string, _ os.FileInfo, _ error) error {
|
||||
e := setFileLabel(p, label)
|
||||
e := lSetFileLabel(p, label)
|
||||
// Walk a file tree can race with removal, so ignore ENOENT.
|
||||
if errors.Is(e, os.ErrNotExist) {
|
||||
return nil
|
||||
|
54
src/runtime/vendor/golang.org/x/sys/unix/asm_linux_loong64.s
generated
vendored
Normal file
54
src/runtime/vendor/golang.org/x/sys/unix/asm_linux_loong64.s
generated
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
// Copyright 2022 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build linux && loong64 && gc
|
||||
// +build linux
|
||||
// +build loong64
|
||||
// +build gc
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·SyscallNoError(SB),NOSPLIT,$0-48
|
||||
JAL runtime·entersyscall(SB)
|
||||
MOVV a1+8(FP), R4
|
||||
MOVV a2+16(FP), R5
|
||||
MOVV a3+24(FP), R6
|
||||
MOVV R0, R7
|
||||
MOVV R0, R8
|
||||
MOVV R0, R9
|
||||
MOVV trap+0(FP), R11 // syscall entry
|
||||
SYSCALL
|
||||
MOVV R4, r1+32(FP)
|
||||
MOVV R5, r2+40(FP)
|
||||
JAL runtime·exitsyscall(SB)
|
||||
RET
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·RawSyscall6(SB)
|
||||
|
||||
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48
|
||||
MOVV a1+8(FP), R4
|
||||
MOVV a2+16(FP), R5
|
||||
MOVV a3+24(FP), R6
|
||||
MOVV R0, R7
|
||||
MOVV R0, R8
|
||||
MOVV R0, R9
|
||||
MOVV trap+0(FP), R11 // syscall entry
|
||||
SYSCALL
|
||||
MOVV R4, r1+32(FP)
|
||||
MOVV R5, r2+40(FP)
|
||||
RET
|
23
src/runtime/vendor/golang.org/x/sys/unix/ioctl_linux.go
generated
vendored
23
src/runtime/vendor/golang.org/x/sys/unix/ioctl_linux.go
generated
vendored
@ -194,3 +194,26 @@ func ioctlIfreqData(fd int, req uint, value *ifreqData) error {
|
||||
// identical so pass *IfreqData directly.
|
||||
return ioctlPtr(fd, req, unsafe.Pointer(value))
|
||||
}
|
||||
|
||||
// IoctlKCMClone attaches a new file descriptor to a multiplexor by cloning an
|
||||
// existing KCM socket, returning a structure containing the file descriptor of
|
||||
// the new socket.
|
||||
func IoctlKCMClone(fd int) (*KCMClone, error) {
|
||||
var info KCMClone
|
||||
if err := ioctlPtr(fd, SIOCKCMCLONE, unsafe.Pointer(&info)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &info, nil
|
||||
}
|
||||
|
||||
// IoctlKCMAttach attaches a TCP socket and associated BPF program file
|
||||
// descriptor to a multiplexor.
|
||||
func IoctlKCMAttach(fd int, info KCMAttach) error {
|
||||
return ioctlPtr(fd, SIOCKCMATTACH, unsafe.Pointer(&info))
|
||||
}
|
||||
|
||||
// IoctlKCMUnattach unattaches a TCP socket file descriptor from a multiplexor.
|
||||
func IoctlKCMUnattach(fd int, info KCMUnattach) error {
|
||||
return ioctlPtr(fd, SIOCKCMUNATTACH, unsafe.Pointer(&info))
|
||||
}
|
||||
|
7
src/runtime/vendor/golang.org/x/sys/unix/mkerrors.sh
generated
vendored
7
src/runtime/vendor/golang.org/x/sys/unix/mkerrors.sh
generated
vendored
@ -205,6 +205,7 @@ struct ltchars {
|
||||
#include <linux/bpf.h>
|
||||
#include <linux/can.h>
|
||||
#include <linux/can/error.h>
|
||||
#include <linux/can/netlink.h>
|
||||
#include <linux/can/raw.h>
|
||||
#include <linux/capability.h>
|
||||
#include <linux/cryptouser.h>
|
||||
@ -214,6 +215,7 @@ struct ltchars {
|
||||
#include <linux/ethtool_netlink.h>
|
||||
#include <linux/falloc.h>
|
||||
#include <linux/fanotify.h>
|
||||
#include <linux/fib_rules.h>
|
||||
#include <linux/filter.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/fscrypt.h>
|
||||
@ -231,6 +233,7 @@ struct ltchars {
|
||||
#include <linux/if_packet.h>
|
||||
#include <linux/if_xdp.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/kcm.h>
|
||||
#include <linux/kexec.h>
|
||||
#include <linux/keyctl.h>
|
||||
#include <linux/landlock.h>
|
||||
@ -503,6 +506,7 @@ ccflags="$@"
|
||||
$2 ~ /^O?XTABS$/ ||
|
||||
$2 ~ /^TC[IO](ON|OFF)$/ ||
|
||||
$2 ~ /^IN_/ ||
|
||||
$2 ~ /^KCM/ ||
|
||||
$2 ~ /^LANDLOCK_/ ||
|
||||
$2 ~ /^LOCK_(SH|EX|NB|UN)$/ ||
|
||||
$2 ~ /^LO_(KEY|NAME)_SIZE$/ ||
|
||||
@ -597,8 +601,10 @@ ccflags="$@"
|
||||
$2 ~ /^DEVLINK_/ ||
|
||||
$2 ~ /^ETHTOOL_/ ||
|
||||
$2 ~ /^LWTUNNEL_IP/ ||
|
||||
$2 ~ /^ITIMER_/ ||
|
||||
$2 !~ "WMESGLEN" &&
|
||||
$2 ~ /^W[A-Z0-9]+$/ ||
|
||||
$2 ~ /^P_/ ||
|
||||
$2 ~/^PPPIOC/ ||
|
||||
$2 ~ /^FAN_|FANOTIFY_/ ||
|
||||
$2 == "HID_MAX_DESCRIPTOR_SIZE" ||
|
||||
@ -608,6 +614,7 @@ ccflags="$@"
|
||||
$2 ~ /^OTP/ ||
|
||||
$2 ~ /^MEM/ ||
|
||||
$2 ~ /^WG/ ||
|
||||
$2 ~ /^FIB_RULE_/ ||
|
||||
$2 ~ /^BLK[A-Z]*(GET$|SET$|BUF$|PART$|SIZE)/ {printf("\t%s = C.%s\n", $2, $2)}
|
||||
$2 ~ /^__WCOREFLAG$/ {next}
|
||||
$2 ~ /^__W[A-Z0-9]+$/ {printf("\t%s = C.%s\n", substr($2,3), $2)}
|
||||
|
16
src/runtime/vendor/golang.org/x/sys/unix/syscall_aix.go
generated
vendored
16
src/runtime/vendor/golang.org/x/sys/unix/syscall_aix.go
generated
vendored
@ -215,18 +215,12 @@ func Accept(fd int) (nfd int, sa Sockaddr, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
|
||||
func recvmsgRaw(fd int, p, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
|
||||
// Recvmsg not implemented on AIX
|
||||
sa := new(SockaddrUnix)
|
||||
return -1, -1, -1, sa, ENOSYS
|
||||
return -1, -1, -1, ENOSYS
|
||||
}
|
||||
|
||||
func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
|
||||
_, err = SendmsgN(fd, p, oob, to, flags)
|
||||
return
|
||||
}
|
||||
|
||||
func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
|
||||
func sendmsgN(fd int, p, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
|
||||
// SendmsgN not implemented on AIX
|
||||
return -1, ENOSYS
|
||||
}
|
||||
@ -458,8 +452,8 @@ func Fsync(fd int) error {
|
||||
//sys Listen(s int, n int) (err error)
|
||||
//sys lstat(path string, stat *Stat_t) (err error)
|
||||
//sys Pause() (err error)
|
||||
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = pread64
|
||||
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = pwrite64
|
||||
//sys pread(fd int, p []byte, offset int64) (n int, err error) = pread64
|
||||
//sys pwrite(fd int, p []byte, offset int64) (n int, err error) = pwrite64
|
||||
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error)
|
||||
//sys Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error)
|
||||
//sysnb Setregid(rgid int, egid int) (err error)
|
||||
|
35
src/runtime/vendor/golang.org/x/sys/unix/syscall_bsd.go
generated
vendored
35
src/runtime/vendor/golang.org/x/sys/unix/syscall_bsd.go
generated
vendored
@ -325,10 +325,9 @@ func GetsockoptString(fd, level, opt int) (string, error) {
|
||||
//sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error)
|
||||
//sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error)
|
||||
|
||||
func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
|
||||
func recvmsgRaw(fd int, p, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
|
||||
var msg Msghdr
|
||||
var rsa RawSockaddrAny
|
||||
msg.Name = (*byte)(unsafe.Pointer(&rsa))
|
||||
msg.Name = (*byte)(unsafe.Pointer(rsa))
|
||||
msg.Namelen = uint32(SizeofSockaddrAny)
|
||||
var iov Iovec
|
||||
if len(p) > 0 {
|
||||
@ -352,29 +351,12 @@ func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from
|
||||
}
|
||||
oobn = int(msg.Controllen)
|
||||
recvflags = int(msg.Flags)
|
||||
// source address is only specified if the socket is unconnected
|
||||
if rsa.Addr.Family != AF_UNSPEC {
|
||||
from, err = anyToSockaddr(fd, &rsa)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error)
|
||||
|
||||
func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
|
||||
_, err = SendmsgN(fd, p, oob, to, flags)
|
||||
return
|
||||
}
|
||||
|
||||
func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
|
||||
var ptr unsafe.Pointer
|
||||
var salen _Socklen
|
||||
if to != nil {
|
||||
ptr, salen, err = to.sockaddr()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
func sendmsgN(fd int, p, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
|
||||
var msg Msghdr
|
||||
msg.Name = (*byte)(unsafe.Pointer(ptr))
|
||||
msg.Namelen = uint32(salen)
|
||||
@ -571,12 +553,7 @@ func UtimesNano(path string, ts []Timespec) error {
|
||||
if len(ts) != 2 {
|
||||
return EINVAL
|
||||
}
|
||||
// Darwin setattrlist can set nanosecond timestamps
|
||||
err := setattrlistTimes(path, ts, 0)
|
||||
if err != ENOSYS {
|
||||
return err
|
||||
}
|
||||
err = utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
|
||||
err := utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
|
||||
if err != ENOSYS {
|
||||
return err
|
||||
}
|
||||
@ -596,10 +573,6 @@ func UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error {
|
||||
if len(ts) != 2 {
|
||||
return EINVAL
|
||||
}
|
||||
err := setattrlistTimes(path, ts, flags)
|
||||
if err != ENOSYS {
|
||||
return err
|
||||
}
|
||||
return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags)
|
||||
}
|
||||
|
||||
|
45
src/runtime/vendor/golang.org/x/sys/unix/syscall_darwin.go
generated
vendored
45
src/runtime/vendor/golang.org/x/sys/unix/syscall_darwin.go
generated
vendored
@ -141,16 +141,6 @@ func direntNamlen(buf []byte) (uint64, bool) {
|
||||
func PtraceAttach(pid int) (err error) { return ptrace(PT_ATTACH, pid, 0, 0) }
|
||||
func PtraceDetach(pid int) (err error) { return ptrace(PT_DETACH, pid, 0, 0) }
|
||||
|
||||
type attrList struct {
|
||||
bitmapCount uint16
|
||||
_ uint16
|
||||
CommonAttr uint32
|
||||
VolAttr uint32
|
||||
DirAttr uint32
|
||||
FileAttr uint32
|
||||
Forkattr uint32
|
||||
}
|
||||
|
||||
//sysnb pipe(p *[2]int32) (err error)
|
||||
|
||||
func Pipe(p []int) (err error) {
|
||||
@ -282,36 +272,7 @@ func Flistxattr(fd int, dest []byte) (sz int, err error) {
|
||||
return flistxattr(fd, xattrPointer(dest), len(dest), 0)
|
||||
}
|
||||
|
||||
func setattrlistTimes(path string, times []Timespec, flags int) error {
|
||||
_p0, err := BytePtrFromString(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var attrList attrList
|
||||
attrList.bitmapCount = ATTR_BIT_MAP_COUNT
|
||||
attrList.CommonAttr = ATTR_CMN_MODTIME | ATTR_CMN_ACCTIME
|
||||
|
||||
// order is mtime, atime: the opposite of Chtimes
|
||||
attributes := [2]Timespec{times[1], times[0]}
|
||||
options := 0
|
||||
if flags&AT_SYMLINK_NOFOLLOW != 0 {
|
||||
options |= FSOPT_NOFOLLOW
|
||||
}
|
||||
return setattrlist(
|
||||
_p0,
|
||||
unsafe.Pointer(&attrList),
|
||||
unsafe.Pointer(&attributes),
|
||||
unsafe.Sizeof(attributes),
|
||||
options)
|
||||
}
|
||||
|
||||
//sys setattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintptr, options int) (err error)
|
||||
|
||||
func utimensat(dirfd int, path string, times *[2]Timespec, flags int) error {
|
||||
// Darwin doesn't support SYS_UTIMENSAT
|
||||
return ENOSYS
|
||||
}
|
||||
//sys utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error)
|
||||
|
||||
/*
|
||||
* Wrapped
|
||||
@ -546,8 +507,8 @@ func SysctlKinfoProcSlice(name string, args ...int) ([]KinfoProc, error) {
|
||||
//sys Open(path string, mode int, perm uint32) (fd int, err error)
|
||||
//sys Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error)
|
||||
//sys Pathconf(path string, name int) (val int, err error)
|
||||
//sys Pread(fd int, p []byte, offset int64) (n int, err error)
|
||||
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error)
|
||||
//sys pread(fd int, p []byte, offset int64) (n int, err error)
|
||||
//sys pwrite(fd int, p []byte, offset int64) (n int, err error)
|
||||
//sys read(fd int, p []byte) (n int, err error)
|
||||
//sys Readlink(path string, buf []byte) (n int, err error)
|
||||
//sys Readlinkat(dirfd int, path string, buf []byte) (n int, err error)
|
||||
|
9
src/runtime/vendor/golang.org/x/sys/unix/syscall_dragonfly.go
generated
vendored
9
src/runtime/vendor/golang.org/x/sys/unix/syscall_dragonfly.go
generated
vendored
@ -125,12 +125,12 @@ func Pipe2(p []int, flags int) (err error) {
|
||||
}
|
||||
|
||||
//sys extpread(fd int, p []byte, flags int, offset int64) (n int, err error)
|
||||
func Pread(fd int, p []byte, offset int64) (n int, err error) {
|
||||
func pread(fd int, p []byte, offset int64) (n int, err error) {
|
||||
return extpread(fd, p, 0, offset)
|
||||
}
|
||||
|
||||
//sys extpwrite(fd int, p []byte, flags int, offset int64) (n int, err error)
|
||||
func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
|
||||
func pwrite(fd int, p []byte, offset int64) (n int, err error) {
|
||||
return extpwrite(fd, p, 0, offset)
|
||||
}
|
||||
|
||||
@ -169,11 +169,6 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func setattrlistTimes(path string, times []Timespec, flags int) error {
|
||||
// used on Darwin for UtimesNano
|
||||
return ENOSYS
|
||||
}
|
||||
|
||||
//sys ioctl(fd int, req uint, arg uintptr) (err error)
|
||||
|
||||
//sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL
|
||||
|
9
src/runtime/vendor/golang.org/x/sys/unix/syscall_freebsd.go
generated
vendored
9
src/runtime/vendor/golang.org/x/sys/unix/syscall_freebsd.go
generated
vendored
@ -194,11 +194,6 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func setattrlistTimes(path string, times []Timespec, flags int) error {
|
||||
// used on Darwin for UtimesNano
|
||||
return ENOSYS
|
||||
}
|
||||
|
||||
//sys ioctl(fd int, req uint, arg uintptr) (err error)
|
||||
|
||||
//sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL
|
||||
@ -638,8 +633,8 @@ func PtraceSingleStep(pid int) (err error) {
|
||||
//sys Open(path string, mode int, perm uint32) (fd int, err error)
|
||||
//sys Openat(fdat int, path string, mode int, perm uint32) (fd int, err error)
|
||||
//sys Pathconf(path string, name int) (val int, err error)
|
||||
//sys Pread(fd int, p []byte, offset int64) (n int, err error)
|
||||
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error)
|
||||
//sys pread(fd int, p []byte, offset int64) (n int, err error)
|
||||
//sys pwrite(fd int, p []byte, offset int64) (n int, err error)
|
||||
//sys read(fd int, p []byte) (n int, err error)
|
||||
//sys Readlink(path string, buf []byte) (n int, err error)
|
||||
//sys Readlinkat(dirfd int, path string, buf []byte) (n int, err error)
|
||||
|
92
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux.go
generated
vendored
92
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux.go
generated
vendored
@ -14,6 +14,7 @@ package unix
|
||||
import (
|
||||
"encoding/binary"
|
||||
"syscall"
|
||||
"time"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
@ -249,6 +250,13 @@ func Getwd() (wd string, err error) {
|
||||
if n < 1 || n > len(buf) || buf[n-1] != 0 {
|
||||
return "", EINVAL
|
||||
}
|
||||
// In some cases, Linux can return a path that starts with the
|
||||
// "(unreachable)" prefix, which can potentially be a valid relative
|
||||
// path. To work around that, return ENOENT if path is not absolute.
|
||||
if buf[0] != '/' {
|
||||
return "", ENOENT
|
||||
}
|
||||
|
||||
return string(buf[0 : n-1]), nil
|
||||
}
|
||||
|
||||
@ -358,6 +366,8 @@ func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int,
|
||||
return
|
||||
}
|
||||
|
||||
//sys Waitid(idType int, id int, info *Siginfo, options int, rusage *Rusage) (err error)
|
||||
|
||||
func Mkfifo(path string, mode uint32) error {
|
||||
return Mknod(path, mode|S_IFIFO, 0)
|
||||
}
|
||||
@ -1489,10 +1499,9 @@ func KeyctlRestrictKeyring(ringid int, keyType string, restriction string) error
|
||||
//sys keyctlRestrictKeyringByType(cmd int, arg2 int, keyType string, restriction string) (err error) = SYS_KEYCTL
|
||||
//sys keyctlRestrictKeyring(cmd int, arg2 int) (err error) = SYS_KEYCTL
|
||||
|
||||
func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
|
||||
func recvmsgRaw(fd int, p, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
|
||||
var msg Msghdr
|
||||
var rsa RawSockaddrAny
|
||||
msg.Name = (*byte)(unsafe.Pointer(&rsa))
|
||||
msg.Name = (*byte)(unsafe.Pointer(rsa))
|
||||
msg.Namelen = uint32(SizeofSockaddrAny)
|
||||
var iov Iovec
|
||||
if len(p) > 0 {
|
||||
@ -1523,28 +1532,10 @@ func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from
|
||||
}
|
||||
oobn = int(msg.Controllen)
|
||||
recvflags = int(msg.Flags)
|
||||
// source address is only specified if the socket is unconnected
|
||||
if rsa.Addr.Family != AF_UNSPEC {
|
||||
from, err = anyToSockaddr(fd, &rsa)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
|
||||
_, err = SendmsgN(fd, p, oob, to, flags)
|
||||
return
|
||||
}
|
||||
|
||||
func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
|
||||
var ptr unsafe.Pointer
|
||||
var salen _Socklen
|
||||
if to != nil {
|
||||
var err error
|
||||
ptr, salen, err = to.sockaddr()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
func sendmsgN(fd int, p, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
|
||||
var msg Msghdr
|
||||
msg.Name = (*byte)(ptr)
|
||||
msg.Namelen = uint32(salen)
|
||||
@ -1838,6 +1829,9 @@ func Dup2(oldfd, newfd int) error {
|
||||
//sys Fremovexattr(fd int, attr string) (err error)
|
||||
//sys Fsetxattr(fd int, attr string, dest []byte, flags int) (err error)
|
||||
//sys Fsync(fd int) (err error)
|
||||
//sys Fsmount(fd int, flags int, mountAttrs int) (fsfd int, err error)
|
||||
//sys Fsopen(fsName string, flags int) (fd int, err error)
|
||||
//sys Fspick(dirfd int, pathName string, flags int) (fd int, err error)
|
||||
//sys Getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64
|
||||
//sysnb Getpgid(pid int) (pgid int, err error)
|
||||
|
||||
@ -1868,7 +1862,9 @@ func Getpgrp() (pid int) {
|
||||
//sys MemfdCreate(name string, flags int) (fd int, err error)
|
||||
//sys Mkdirat(dirfd int, path string, mode uint32) (err error)
|
||||
//sys Mknodat(dirfd int, path string, mode uint32, dev int) (err error)
|
||||
//sys MoveMount(fromDirfd int, fromPathName string, toDirfd int, toPathName string, flags int) (err error)
|
||||
//sys Nanosleep(time *Timespec, leftover *Timespec) (err error)
|
||||
//sys OpenTree(dfd int, fileName string, flags uint) (r int, err error)
|
||||
//sys PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error)
|
||||
//sys PivotRoot(newroot string, putold string) (err error) = SYS_PIVOT_ROOT
|
||||
//sysnb Prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) = SYS_PRLIMIT64
|
||||
@ -2193,7 +2189,7 @@ func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
|
||||
gid = Getgid()
|
||||
}
|
||||
|
||||
if uint32(gid) == st.Gid || isGroupMember(gid) {
|
||||
if uint32(gid) == st.Gid || isGroupMember(int(st.Gid)) {
|
||||
fmode = (st.Mode >> 3) & 7
|
||||
} else {
|
||||
fmode = st.Mode & 7
|
||||
@ -2308,17 +2304,63 @@ type RemoteIovec struct {
|
||||
|
||||
//sys PidfdOpen(pid int, flags int) (fd int, err error) = SYS_PIDFD_OPEN
|
||||
//sys PidfdGetfd(pidfd int, targetfd int, flags int) (fd int, err error) = SYS_PIDFD_GETFD
|
||||
//sys PidfdSendSignal(pidfd int, sig Signal, info *Siginfo, flags int) (err error) = SYS_PIDFD_SEND_SIGNAL
|
||||
|
||||
//sys shmat(id int, addr uintptr, flag int) (ret uintptr, err error)
|
||||
//sys shmctl(id int, cmd int, buf *SysvShmDesc) (result int, err error)
|
||||
//sys shmdt(addr uintptr) (err error)
|
||||
//sys shmget(key int, size int, flag int) (id int, err error)
|
||||
|
||||
//sys getitimer(which int, currValue *Itimerval) (err error)
|
||||
//sys setitimer(which int, newValue *Itimerval, oldValue *Itimerval) (err error)
|
||||
|
||||
// MakeItimerval creates an Itimerval from interval and value durations.
|
||||
func MakeItimerval(interval, value time.Duration) Itimerval {
|
||||
return Itimerval{
|
||||
Interval: NsecToTimeval(interval.Nanoseconds()),
|
||||
Value: NsecToTimeval(value.Nanoseconds()),
|
||||
}
|
||||
}
|
||||
|
||||
// A value which may be passed to the which parameter for Getitimer and
|
||||
// Setitimer.
|
||||
type ItimerWhich int
|
||||
|
||||
// Possible which values for Getitimer and Setitimer.
|
||||
const (
|
||||
ItimerReal ItimerWhich = ITIMER_REAL
|
||||
ItimerVirtual ItimerWhich = ITIMER_VIRTUAL
|
||||
ItimerProf ItimerWhich = ITIMER_PROF
|
||||
)
|
||||
|
||||
// Getitimer wraps getitimer(2) to return the current value of the timer
|
||||
// specified by which.
|
||||
func Getitimer(which ItimerWhich) (Itimerval, error) {
|
||||
var it Itimerval
|
||||
if err := getitimer(int(which), &it); err != nil {
|
||||
return Itimerval{}, err
|
||||
}
|
||||
|
||||
return it, nil
|
||||
}
|
||||
|
||||
// Setitimer wraps setitimer(2) to arm or disarm the timer specified by which.
|
||||
// It returns the previous value of the timer.
|
||||
//
|
||||
// If the Itimerval argument is the zero value, the timer will be disarmed.
|
||||
func Setitimer(which ItimerWhich, it Itimerval) (Itimerval, error) {
|
||||
var prev Itimerval
|
||||
if err := setitimer(int(which), &it, &prev); err != nil {
|
||||
return Itimerval{}, err
|
||||
}
|
||||
|
||||
return prev, nil
|
||||
}
|
||||
|
||||
/*
|
||||
* Unimplemented
|
||||
*/
|
||||
// AfsSyscall
|
||||
// Alarm
|
||||
// ArchPrctl
|
||||
// Brk
|
||||
// ClockNanosleep
|
||||
@ -2334,7 +2376,6 @@ type RemoteIovec struct {
|
||||
// GetMempolicy
|
||||
// GetRobustList
|
||||
// GetThreadArea
|
||||
// Getitimer
|
||||
// Getpmsg
|
||||
// IoCancel
|
||||
// IoDestroy
|
||||
@ -2412,5 +2453,4 @@ type RemoteIovec struct {
|
||||
// Vfork
|
||||
// Vhangup
|
||||
// Vserver
|
||||
// Waitid
|
||||
// _Sysctl
|
||||
|
12
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux_386.go
generated
vendored
12
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux_386.go
generated
vendored
@ -35,8 +35,8 @@ func setTimeval(sec, usec int64) Timeval {
|
||||
//sys Iopl(level int) (err error)
|
||||
//sys Lchown(path string, uid int, gid int) (err error) = SYS_LCHOWN32
|
||||
//sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
|
||||
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
|
||||
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
|
||||
//sys pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
|
||||
//sys pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
|
||||
//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
|
||||
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64
|
||||
//sys setfsgid(gid int) (prev int, err error) = SYS_SETFSGID32
|
||||
@ -173,14 +173,6 @@ const (
|
||||
_SENDMMSG = 20
|
||||
)
|
||||
|
||||
func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
|
||||
fd, e := socketcall(_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)
|
||||
if e != 0 {
|
||||
err = e
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
|
||||
fd, e := socketcall(_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
|
||||
if e != 0 {
|
||||
|
14
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux_alarm.go
generated
vendored
Normal file
14
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux_alarm.go
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
// Copyright 2022 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build linux && (386 || amd64 || mips || mipsle || mips64 || mipsle || ppc64 || ppc64le || ppc || s390x || sparc64)
|
||||
// +build linux
|
||||
// +build 386 amd64 mips mipsle mips64 mipsle ppc64 ppc64le ppc s390x sparc64
|
||||
|
||||
package unix
|
||||
|
||||
// SYS_ALARM is not defined on arm or riscv, but is available for other GOARCH
|
||||
// values.
|
||||
|
||||
//sys Alarm(seconds uint) (remaining uint, err error)
|
6
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux_amd64.go
generated
vendored
6
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux_amd64.go
generated
vendored
@ -28,9 +28,10 @@ func Lstat(path string, stat *Stat_t) (err error) {
|
||||
return Fstatat(AT_FDCWD, path, stat, AT_SYMLINK_NOFOLLOW)
|
||||
}
|
||||
|
||||
//sys MemfdSecret(flags int) (fd int, err error)
|
||||
//sys Pause() (err error)
|
||||
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
|
||||
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
|
||||
//sys pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
|
||||
//sys pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
|
||||
//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
|
||||
//sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
|
||||
|
||||
@ -62,7 +63,6 @@ func Stat(path string, stat *Stat_t) (err error) {
|
||||
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
|
||||
//sys Truncate(path string, length int64) (err error)
|
||||
//sys Ustat(dev int, ubuf *Ustat_t) (err error)
|
||||
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
|
||||
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
|
||||
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
|
||||
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
|
||||
|
5
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux_arm.go
generated
vendored
5
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux_arm.go
generated
vendored
@ -27,7 +27,6 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
|
||||
return newoffset, nil
|
||||
}
|
||||
|
||||
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
|
||||
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
|
||||
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
|
||||
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
|
||||
@ -97,8 +96,8 @@ func Utime(path string, buf *Utimbuf) error {
|
||||
|
||||
//sys utimes(path string, times *[2]Timeval) (err error)
|
||||
|
||||
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
|
||||
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
|
||||
//sys pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
|
||||
//sys pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
|
||||
//sys Truncate(path string, length int64) (err error) = SYS_TRUNCATE64
|
||||
//sys Ftruncate(fd int, length int64) (err error) = SYS_FTRUNCATE64
|
||||
|
||||
|
6
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go
generated
vendored
6
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go
generated
vendored
@ -22,8 +22,9 @@ import "unsafe"
|
||||
//sysnb getrlimit(resource int, rlim *Rlimit) (err error)
|
||||
//sysnb Getuid() (uid int)
|
||||
//sys Listen(s int, n int) (err error)
|
||||
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
|
||||
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
|
||||
//sys MemfdSecret(flags int) (fd int, err error)
|
||||
//sys pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
|
||||
//sys pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
|
||||
//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
|
||||
//sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
|
||||
|
||||
@ -66,7 +67,6 @@ func Ustat(dev int, ubuf *Ustat_t) (err error) {
|
||||
return ENOSYS
|
||||
}
|
||||
|
||||
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
|
||||
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
|
||||
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
|
||||
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
|
||||
|
5
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go
generated
vendored
5
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go
generated
vendored
@ -21,8 +21,8 @@ package unix
|
||||
//sys Lchown(path string, uid int, gid int) (err error)
|
||||
//sys Listen(s int, n int) (err error)
|
||||
//sys Pause() (err error)
|
||||
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
|
||||
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
|
||||
//sys pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
|
||||
//sys pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
|
||||
//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
|
||||
//sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
|
||||
|
||||
@ -48,7 +48,6 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err
|
||||
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
|
||||
//sys Truncate(path string, length int64) (err error)
|
||||
//sys Ustat(dev int, ubuf *Ustat_t) (err error)
|
||||
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
|
||||
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
|
||||
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
|
||||
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
|
||||
|
5
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go
generated
vendored
5
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go
generated
vendored
@ -25,8 +25,8 @@ func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr,
|
||||
//sysnb Getuid() (uid int)
|
||||
//sys Lchown(path string, uid int, gid int) (err error)
|
||||
//sys Listen(s int, n int) (err error)
|
||||
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
|
||||
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
|
||||
//sys pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
|
||||
//sys pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
|
||||
//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
|
||||
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT
|
||||
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64
|
||||
@ -41,7 +41,6 @@ func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr,
|
||||
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
|
||||
//sys Truncate(path string, length int64) (err error) = SYS_TRUNCATE64
|
||||
//sys Ustat(dev int, ubuf *Ustat_t) (err error)
|
||||
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
|
||||
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
|
||||
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
|
||||
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
|
||||
|
5
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux_ppc.go
generated
vendored
5
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux_ppc.go
generated
vendored
@ -27,8 +27,8 @@ import (
|
||||
//sys Listen(s int, n int) (err error)
|
||||
//sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
|
||||
//sys Pause() (err error)
|
||||
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
|
||||
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
|
||||
//sys pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
|
||||
//sys pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
|
||||
//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
|
||||
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT
|
||||
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64
|
||||
@ -43,7 +43,6 @@ import (
|
||||
//sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
|
||||
//sys Truncate(path string, length int64) (err error) = SYS_TRUNCATE64
|
||||
//sys Ustat(dev int, ubuf *Ustat_t) (err error)
|
||||
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
|
||||
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
|
||||
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
|
||||
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
|
||||
|
5
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go
generated
vendored
5
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go
generated
vendored
@ -26,8 +26,8 @@ package unix
|
||||
//sys Listen(s int, n int) (err error)
|
||||
//sys Lstat(path string, stat *Stat_t) (err error)
|
||||
//sys Pause() (err error)
|
||||
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
|
||||
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
|
||||
//sys pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
|
||||
//sys pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
|
||||
//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
|
||||
//sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
|
||||
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT
|
||||
@ -45,7 +45,6 @@ package unix
|
||||
//sys Statfs(path string, buf *Statfs_t) (err error)
|
||||
//sys Truncate(path string, length int64) (err error)
|
||||
//sys Ustat(dev int, ubuf *Ustat_t) (err error)
|
||||
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
|
||||
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
|
||||
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
|
||||
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
|
||||
|
5
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go
generated
vendored
5
src/runtime/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go
generated
vendored
@ -22,8 +22,8 @@ import "unsafe"
|
||||
//sysnb Getrlimit(resource int, rlim *Rlimit) (err error)
|
||||
//sysnb Getuid() (uid int)
|
||||
//sys Listen(s int, n int) (err error)
|
||||
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
|
||||
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
|
||||
//sys pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
|
||||
//sys pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
|
||||
//sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
|
||||
|
||||
func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) {
|
||||
@ -65,7 +65,6 @@ func Ustat(dev int, ubuf *Ustat_t) (err error) {
|
||||
return ENOSYS
|
||||
}
|
||||
|
||||
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
|
||||
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
|
||||
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
|
||||
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user