mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-10-31 18:28:13 +00:00 
			
		
		
		
	Revert "Merge pull request 101888 from kolyshkin/update-runc-rc94"
This reverts commitb1b06fe0a4, reversing changes made to382a33986b.
This commit is contained in:
		| @@ -1,4 +1,4 @@ | ||||
| = vendor/github.com/checkpoint-restore/go-criu/v5 licensed under: = | ||||
| = vendor/github.com/checkpoint-restore/go-criu/v4 licensed under: = | ||||
| 
 | ||||
|                                  Apache License | ||||
|                            Version 2.0, January 2004 | ||||
| @@ -202,4 +202,4 @@ | ||||
|    See the License for the specific language governing permissions and | ||||
|    limitations under the License. | ||||
| 
 | ||||
| = vendor/github.com/checkpoint-restore/go-criu/v5/LICENSE e3fc50a88d0a364313df4b21ef20c29e | ||||
| = vendor/github.com/checkpoint-restore/go-criu/v4/LICENSE e3fc50a88d0a364313df4b21ef20c29e | ||||
							
								
								
									
										31
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								go.mod
									
									
									
									
									
								
							| @@ -43,13 +43,13 @@ require ( | ||||
| 	github.com/fsnotify/fsnotify v1.4.9 | ||||
| 	github.com/go-bindata/go-bindata v3.1.1+incompatible | ||||
| 	github.com/go-ozzo/ozzo-validation v3.5.0+incompatible // indirect | ||||
| 	github.com/godbus/dbus/v5 v5.0.4 | ||||
| 	github.com/godbus/dbus/v5 v5.0.3 | ||||
| 	github.com/gogo/protobuf v1.3.2 | ||||
| 	github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e | ||||
| 	github.com/golang/mock v1.4.4 | ||||
| 	github.com/golang/protobuf v1.4.3 | ||||
| 	github.com/google/cadvisor v0.39.0 | ||||
| 	github.com/google/go-cmp v0.5.4 | ||||
| 	github.com/google/go-cmp v0.5.2 | ||||
| 	github.com/google/gofuzz v1.1.0 | ||||
| 	github.com/google/uuid v1.1.2 | ||||
| 	github.com/googleapis/gnostic v0.5.1 | ||||
| @@ -70,7 +70,7 @@ require ( | ||||
| 	github.com/onsi/ginkgo v1.11.0 | ||||
| 	github.com/onsi/gomega v1.7.0 | ||||
| 	github.com/opencontainers/go-digest v1.0.0 | ||||
| 	github.com/opencontainers/runc v1.0.0-rc94 | ||||
| 	github.com/opencontainers/runc v1.0.0-rc93 | ||||
| 	github.com/opencontainers/selinux v1.8.0 | ||||
| 	github.com/pkg/errors v0.9.1 | ||||
| 	github.com/pmezard/go-difflib v1.0.0 | ||||
| @@ -94,7 +94,7 @@ require ( | ||||
| 	golang.org/x/exp v0.0.0-20210220032938-85be41e4509f // indirect | ||||
| 	golang.org/x/net v0.0.0-20210224082022-3d97a244fca7 | ||||
| 	golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d | ||||
| 	golang.org/x/sys v0.0.0-20210426230700-d19ff857e887 | ||||
| 	golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 | ||||
| 	golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d | ||||
| 	golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba | ||||
| 	golang.org/x/tools v0.1.0 | ||||
| @@ -192,17 +192,17 @@ replace ( | ||||
| 	github.com/census-instrumentation/opencensus-proto => github.com/census-instrumentation/opencensus-proto v0.2.1 | ||||
| 	github.com/cespare/xxhash/v2 => github.com/cespare/xxhash/v2 v2.1.1 | ||||
| 	github.com/chai2010/gettext-go => github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 | ||||
| 	github.com/checkpoint-restore/go-criu/v5 => github.com/checkpoint-restore/go-criu/v5 v5.0.0 | ||||
| 	github.com/checkpoint-restore/go-criu/v4 => github.com/checkpoint-restore/go-criu/v4 v4.1.0 | ||||
| 	github.com/cheekybits/genny => github.com/cheekybits/genny v0.0.0-20170328200008-9127e812e1e9 | ||||
| 	github.com/chzyer/logex => github.com/chzyer/logex v1.1.10 | ||||
| 	github.com/chzyer/readline => github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e | ||||
| 	github.com/chzyer/test => github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 | ||||
| 	github.com/cilium/ebpf => github.com/cilium/ebpf v0.5.0 | ||||
| 	github.com/cilium/ebpf => github.com/cilium/ebpf v0.2.0 | ||||
| 	github.com/clusterhq/flocker-go => github.com/clusterhq/flocker-go v0.0.0-20160920122132-2b8b7259d313 | ||||
| 	github.com/cockroachdb/datadriven => github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa | ||||
| 	github.com/container-storage-interface/spec => github.com/container-storage-interface/spec v1.3.0 | ||||
| 	github.com/containerd/cgroups => github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59 | ||||
| 	github.com/containerd/console => github.com/containerd/console v1.0.2 | ||||
| 	github.com/containerd/console => github.com/containerd/console v1.0.1 | ||||
| 	github.com/containerd/containerd => github.com/containerd/containerd v1.4.4 | ||||
| 	github.com/containerd/continuity => github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc | ||||
| 	github.com/containerd/fifo => github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448 | ||||
| @@ -216,7 +216,7 @@ replace ( | ||||
| 	github.com/coreos/go-oidc => github.com/coreos/go-oidc v2.1.0+incompatible | ||||
| 	github.com/coreos/go-semver => github.com/coreos/go-semver v0.3.0 | ||||
| 	github.com/coreos/go-systemd => github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e | ||||
| 	github.com/coreos/go-systemd/v22 => github.com/coreos/go-systemd/v22 v22.3.1 | ||||
| 	github.com/coreos/go-systemd/v22 => github.com/coreos/go-systemd/v22 v22.1.0 | ||||
| 	github.com/coreos/pkg => github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f | ||||
| 	github.com/cpuguy83/go-md2man/v2 => github.com/cpuguy83/go-md2man/v2 v2.0.0 | ||||
| 	github.com/creack/pty => github.com/creack/pty v1.1.11 | ||||
| @@ -243,7 +243,6 @@ replace ( | ||||
| 	github.com/flynn/go-shlex => github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 | ||||
| 	github.com/fogleman/gg => github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90 | ||||
| 	github.com/form3tech-oss/jwt-go => github.com/form3tech-oss/jwt-go v3.2.2+incompatible | ||||
| 	github.com/frankban/quicktest => github.com/frankban/quicktest v1.11.3 | ||||
| 	github.com/fsnotify/fsnotify => github.com/fsnotify/fsnotify v1.4.9 | ||||
| 	github.com/fvbommel/sortorder => github.com/fvbommel/sortorder v1.0.1 | ||||
| 	github.com/ghodss/yaml => github.com/ghodss/yaml v1.0.0 | ||||
| @@ -267,7 +266,7 @@ replace ( | ||||
| 	github.com/go-ozzo/ozzo-validation => github.com/go-ozzo/ozzo-validation v3.5.0+incompatible | ||||
| 	github.com/go-stack/stack => github.com/go-stack/stack v1.8.0 | ||||
| 	github.com/gobuffalo/here => github.com/gobuffalo/here v0.6.0 | ||||
| 	github.com/godbus/dbus/v5 => github.com/godbus/dbus/v5 v5.0.4 | ||||
| 	github.com/godbus/dbus/v5 => github.com/godbus/dbus/v5 v5.0.3 | ||||
| 	github.com/gofrs/uuid => github.com/gofrs/uuid v4.0.0+incompatible | ||||
| 	github.com/gogo/protobuf => github.com/gogo/protobuf v1.3.2 | ||||
| 	github.com/golang/freetype => github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 | ||||
| @@ -278,7 +277,7 @@ replace ( | ||||
| 	github.com/golangplus/testing => github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e | ||||
| 	github.com/google/btree => github.com/google/btree v1.0.0 | ||||
| 	github.com/google/cadvisor => github.com/google/cadvisor v0.39.0 | ||||
| 	github.com/google/go-cmp => github.com/google/go-cmp v0.5.4 | ||||
| 	github.com/google/go-cmp => github.com/google/go-cmp v0.5.2 | ||||
| 	github.com/google/gofuzz => github.com/google/gofuzz v1.1.0 | ||||
| 	github.com/google/martian => github.com/google/martian v2.1.0+incompatible | ||||
| 	github.com/google/pprof => github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3 | ||||
| @@ -335,7 +334,7 @@ replace ( | ||||
| 	github.com/klauspost/cpuid => github.com/klauspost/cpuid v1.2.0 | ||||
| 	github.com/konsorten/go-windows-terminal-sequences => github.com/konsorten/go-windows-terminal-sequences v1.0.2 | ||||
| 	github.com/kr/logfmt => github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 | ||||
| 	github.com/kr/pretty => github.com/kr/pretty v0.2.1 | ||||
| 	github.com/kr/pretty => github.com/kr/pretty v0.2.0 | ||||
| 	github.com/kr/text => github.com/kr/text v0.2.0 | ||||
| 	github.com/kylelemons/godebug => github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348 | ||||
| 	github.com/libopenstorage/openstorage => github.com/libopenstorage/openstorage v1.0.0 | ||||
| @@ -367,7 +366,7 @@ replace ( | ||||
| 	github.com/mitchellh/mapstructure => github.com/mitchellh/mapstructure v1.1.2 | ||||
| 	github.com/moby/ipvs => github.com/moby/ipvs v1.0.1 | ||||
| 	github.com/moby/spdystream => github.com/moby/spdystream v0.2.0 | ||||
| 	github.com/moby/sys/mountinfo => github.com/moby/sys/mountinfo v0.4.1 | ||||
| 	github.com/moby/sys/mountinfo => github.com/moby/sys/mountinfo v0.4.0 | ||||
| 	github.com/moby/term => github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 | ||||
| 	github.com/modern-go/concurrent => github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd | ||||
| 	github.com/modern-go/reflect2 => github.com/modern-go/reflect2 v1.0.1 | ||||
| @@ -387,8 +386,8 @@ replace ( | ||||
| 	github.com/onsi/gomega => github.com/onsi/gomega v1.7.0 | ||||
| 	github.com/opencontainers/go-digest => github.com/opencontainers/go-digest v1.0.0 | ||||
| 	github.com/opencontainers/image-spec => github.com/opencontainers/image-spec v1.0.1 | ||||
| 	github.com/opencontainers/runc => github.com/opencontainers/runc v1.0.0-rc94 | ||||
| 	github.com/opencontainers/runtime-spec => github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 | ||||
| 	github.com/opencontainers/runc => github.com/opencontainers/runc v1.0.0-rc93 | ||||
| 	github.com/opencontainers/runtime-spec => github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d | ||||
| 	github.com/opencontainers/selinux => github.com/opencontainers/selinux v1.8.0 | ||||
| 	github.com/pascaldekloe/goe => github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c | ||||
| 	github.com/pelletier/go-toml => github.com/pelletier/go-toml v1.2.0 | ||||
| @@ -461,7 +460,7 @@ replace ( | ||||
| 	golang.org/x/net => golang.org/x/net v0.0.0-20210224082022-3d97a244fca7 | ||||
| 	golang.org/x/oauth2 => golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d | ||||
| 	golang.org/x/sync => golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 | ||||
| 	golang.org/x/sys => golang.org/x/sys v0.0.0-20210426230700-d19ff857e887 | ||||
| 	golang.org/x/sys => golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 | ||||
| 	golang.org/x/term => golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d | ||||
| 	golang.org/x/text => golang.org/x/text v0.3.4 | ||||
| 	golang.org/x/time => golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba | ||||
|   | ||||
							
								
								
									
										45
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										45
									
								
								go.sum
									
									
									
									
									
								
							| @@ -81,14 +81,14 @@ github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+ | ||||
| github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= | ||||
| github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 h1:7aWHqerlJ41y6FOsEUvknqgXnGmJyJSbjhAWq5pO4F8= | ||||
| github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw= | ||||
| github.com/checkpoint-restore/go-criu/v5 v5.0.0 h1:TW8f/UvntYoVDMN1K2HlT82qH1rb0sOjpGw3m6Ym+i4= | ||||
| github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M= | ||||
| github.com/checkpoint-restore/go-criu/v4 v4.1.0 h1:WW2B2uxx9KWF6bGlHqhm8Okiafwwx7Y2kcpn8lCpjgo= | ||||
| github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw= | ||||
| github.com/cheekybits/genny v0.0.0-20170328200008-9127e812e1e9/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= | ||||
| github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= | ||||
| github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= | ||||
| github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= | ||||
| github.com/cilium/ebpf v0.5.0 h1:E1KshmrMEtkMP2UjlWzfmUV1owWY+BnbL5FxxuatnrU= | ||||
| github.com/cilium/ebpf v0.5.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= | ||||
| github.com/cilium/ebpf v0.2.0 h1:Fv93L3KKckEcEHR3oApXVzyBTDA8WAm6VXhPE00N3f8= | ||||
| github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= | ||||
| github.com/clusterhq/flocker-go v0.0.0-20160920122132-2b8b7259d313 h1:eIHD9GNM3Hp7kcRW5mvcz7WTR3ETeoYYKwpgA04kaXE= | ||||
| github.com/clusterhq/flocker-go v0.0.0-20160920122132-2b8b7259d313/go.mod h1:P1wt9Z3DP8O6W3rvwCt0REIlshg1InHImaLW0t3ObY0= | ||||
| github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa h1:OaNxuTZr7kxeODyLWsRMC+OD03aFUH+mW6r2d+MWa5Y= | ||||
| @@ -97,8 +97,8 @@ github.com/container-storage-interface/spec v1.3.0 h1:wMH4UIoWnK/TXYw8mbcIHgZmB6 | ||||
| github.com/container-storage-interface/spec v1.3.0/go.mod h1:6URME8mwIBbpVyZV93Ce5St17xBiQJQY67NDsuohiy4= | ||||
| github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59 h1:qWj4qVYZ95vLWwqyNJCQg7rDsG5wPdze0UaPolH7DUk= | ||||
| github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59/go.mod h1:pA0z1pT8KYB3TCXK/ocprsh7MAkoW8bZVzPdih9snmM= | ||||
| github.com/containerd/console v1.0.2 h1:Pi6D+aZXM+oUw1czuKgH5IJ+y0jhYcwBJfx5/Ghn9dE= | ||||
| github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ= | ||||
| github.com/containerd/console v1.0.1 h1:u7SFAJyRqWcG6ogaMAx3KjSTy1e3hT9QxqX7Jco7dRc= | ||||
| github.com/containerd/console v1.0.1/go.mod h1:XUsP6YE/mKtz6bxc+I8UiKKTP04qjQL4qcS3XoQ5xkw= | ||||
| github.com/containerd/containerd v1.4.4 h1:rtRG4N6Ct7GNssATwgpvMGfnjnwfjnu/Zs9W3Ikzq+M= | ||||
| github.com/containerd/containerd v1.4.4/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= | ||||
| github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= | ||||
| @@ -120,8 +120,8 @@ github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmf | ||||
| github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= | ||||
| github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8= | ||||
| github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= | ||||
| github.com/coreos/go-systemd/v22 v22.3.1 h1:7OO2CXWMYNDdaAzP51t4lCCZWwpQHmvPbm9sxWjm3So= | ||||
| github.com/coreos/go-systemd/v22 v22.3.1/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= | ||||
| github.com/coreos/go-systemd/v22 v22.1.0 h1:kq/SbG2BCKLkDKkjQf5OWwKWUKj1lgs3lFI4PxnR5lg= | ||||
| github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= | ||||
| github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg= | ||||
| github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= | ||||
| github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= | ||||
| @@ -168,8 +168,6 @@ github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI | ||||
| github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= | ||||
| github.com/form3tech-oss/jwt-go v3.2.2+incompatible h1:TcekIExNqud5crz4xD2pavyTgWiPvpYe4Xau31I0PRk= | ||||
| github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= | ||||
| github.com/frankban/quicktest v1.11.3 h1:8sXhOn0uLys67V8EsXLc6eszDs8VXWxL3iRvebPhedY= | ||||
| github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= | ||||
| github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= | ||||
| github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= | ||||
| github.com/fvbommel/sortorder v1.0.1 h1:dSnXLt4mJYH25uDDGa3biZNQsozaUWDSWeKJ0qqFfzE= | ||||
| @@ -203,8 +201,8 @@ github.com/go-ozzo/ozzo-validation v3.5.0+incompatible h1:sUy/in/P6askYr16XJgTKq | ||||
| github.com/go-ozzo/ozzo-validation v3.5.0+incompatible/go.mod h1:gsEKFIVnabGBt6mXmxK0MoFy+cZoTJY6mu5Ll3LVLBU= | ||||
| github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= | ||||
| github.com/gobuffalo/here v0.6.0/go.mod h1:wAG085dHOYqUpf+Ap+WOdrPTp5IYcDAs/x7PLa8Y5fM= | ||||
| 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.3 h1:ZqHaoEF7TBzh4jzPmqVhE/5A1z9of6orkAe5uHoAeME= | ||||
| github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= | ||||
| github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw= | ||||
| github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= | ||||
| github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= | ||||
| @@ -224,8 +222,8 @@ github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= | ||||
| github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= | ||||
| github.com/google/cadvisor v0.39.0 h1:jai6dmBP9QAYluNGqU18yVUTw6uuyAW0AqtZIjvl8Qg= | ||||
| github.com/google/cadvisor v0.39.0/go.mod h1:rjQFmK4jPCpxeUdLq9bYhNFFsjgGOtpnDmDeap0+nsw= | ||||
| github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= | ||||
| github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= | ||||
| github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= | ||||
| github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= | ||||
| @@ -309,8 +307,7 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o | ||||
| github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= | ||||
| github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= | ||||
| github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= | ||||
| github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= | ||||
| github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= | ||||
| github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= | ||||
| github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= | ||||
| github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= | ||||
| github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= | ||||
| @@ -357,8 +354,8 @@ github.com/moby/ipvs v1.0.1 h1:aoZ7fhLTXgDbzVrAnvV+XbKOU8kOET7B3+xULDF/1o0= | ||||
| github.com/moby/ipvs v1.0.1/go.mod h1:2pngiyseZbIKXNv7hsKj3O9UEz30c53MT9005gt2hxQ= | ||||
| github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= | ||||
| github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= | ||||
| github.com/moby/sys/mountinfo v0.4.1 h1:1O+1cHA1aujwEwwVMa2Xm2l+gIpUHyd3+D+d7LZh1kM= | ||||
| github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= | ||||
| github.com/moby/sys/mountinfo v0.4.0 h1:1KInV3Huv18akCu58V7lzNlt+jFmqlu1EaErnEHE/VM= | ||||
| github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= | ||||
| github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 h1:rzf0wL0CHVc8CEsgyygG0Mn9CNCCPZqOPaz8RiiHYQk= | ||||
| github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc= | ||||
| github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= | ||||
| @@ -393,10 +390,10 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8 | ||||
| github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= | ||||
| github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI= | ||||
| github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= | ||||
| github.com/opencontainers/runc v1.0.0-rc94 h1:atqAFoBGp+Wkh9HKpYN3g/8NCbMzYG6SJrr+YgwamgM= | ||||
| github.com/opencontainers/runc v1.0.0-rc94/go.mod h1:z+bZxa/+Tz/FmYVWkhUajJdzFeOqjc5vrqskhVyHGUM= | ||||
| github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 h1:3snG66yBm59tKhhSPQrQ/0bCrv1LQbKt40LnUPiUxdc= | ||||
| github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= | ||||
| github.com/opencontainers/runc v1.0.0-rc93 h1:x2UMpOOVf3kQ8arv/EsDGwim8PTNqzL1/EYDr/+scOM= | ||||
| github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0= | ||||
| github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d h1:pNa8metDkwZjb9g4T8s+krQ+HRgZAkqnXml+wNir/+s= | ||||
| github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= | ||||
| github.com/opencontainers/selinux v1.8.0 h1:+77ba4ar4jsCbL1GLbFL8fFM57w6suPfSS9PDLDY7KM= | ||||
| github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo= | ||||
| github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= | ||||
| @@ -526,8 +523,8 @@ golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BG | ||||
| golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= | ||||
| golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck= | ||||
| golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887 h1:dXfMednGJh/SUUFjTLsWJz3P+TQt9qnR11GgeI3vWKs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 h1:8qxJSnu+7dRq6upnbntrmriWByIakBuct5OM/MdQC1M= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE= | ||||
| golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= | ||||
| golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc= | ||||
|   | ||||
| @@ -334,7 +334,7 @@ type subsystem interface { | ||||
| 	// Name returns the name of the subsystem. | ||||
| 	Name() string | ||||
| 	// Set the cgroup represented by cgroup. | ||||
| 	Set(path string, cgroup *libcontainerconfigs.Resources) error | ||||
| 	Set(path string, cgroup *libcontainerconfigs.Cgroup) error | ||||
| 	// GetStats returns the statistics associated with the cgroup | ||||
| 	GetStats(path string, stats *libcontainercgroups.Stats) error | ||||
| } | ||||
| @@ -370,7 +370,7 @@ func setSupportedSubsystemsV1(cgroupConfig *libcontainerconfigs.Cgroup) error { | ||||
| 			klog.V(6).InfoS("Unable to find subsystem mount for optional subsystem", "subsystemName", sys.Name()) | ||||
| 			continue | ||||
| 		} | ||||
| 		if err := sys.Set(cgroupConfig.Paths[sys.Name()], cgroupConfig.Resources); err != nil { | ||||
| 		if err := sys.Set(cgroupConfig.Paths[sys.Name()], cgroupConfig); err != nil { | ||||
| 			return fmt.Errorf("failed to set config for supported subsystems : %v", err) | ||||
| 		} | ||||
| 	} | ||||
| @@ -492,7 +492,10 @@ func setResourcesV2(cgroupConfig *libcontainerconfigs.Cgroup) error { | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("failed to create cgroup v2 manager: %v", err) | ||||
| 	} | ||||
| 	return manager.Set(cgroupConfig.Resources) | ||||
| 	config := &libcontainerconfigs.Config{ | ||||
| 		Cgroups: cgroupConfig, | ||||
| 	} | ||||
| 	return manager.Set(config) | ||||
| } | ||||
|  | ||||
| func (m *cgroupManagerImpl) toResources(resourceConfig *ResourceConfig) *libcontainerconfigs.Resources { | ||||
|   | ||||
| @@ -533,8 +533,12 @@ func (cm *containerManagerImpl) setupNode(activePods ActivePodsFunc) error { | ||||
| 			return err | ||||
| 		} | ||||
|  | ||||
| 		manager, err := createManager(cm.KubeletCgroupsName) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		cont.ensureStateFunc = func(_ cgroups.Manager) error { | ||||
| 			return ensureProcessInContainerWithOOMScore(os.Getpid(), qos.KubeletOOMScoreAdj, cont.manager) | ||||
| 			return ensureProcessInContainerWithOOMScore(os.Getpid(), qos.KubeletOOMScoreAdj, manager) | ||||
| 		} | ||||
| 		systemContainers = append(systemContainers, cont) | ||||
| 	} else { | ||||
|   | ||||
| @@ -71,10 +71,6 @@ func (obj *fakeDBusObject) SetProperty(p string, v interface{}) error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (obj *fakeDBusObject) StoreProperty(p string, v interface{}) error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (obj *fakeDBusObject) Destination() string { | ||||
| 	return "" | ||||
| } | ||||
|   | ||||
							
								
								
									
										6
									
								
								staging/src/k8s.io/api/go.sum
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										6
									
								
								staging/src/k8s.io/api/go.sum
									
									
									
										generated
									
									
									
								
							| @@ -44,8 +44,8 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw | ||||
| github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | ||||
| github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= | ||||
| github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= | ||||
| github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= | ||||
| github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| @@ -135,7 +135,7 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w | ||||
| golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= | ||||
| golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||||
| golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= | ||||
|   | ||||
| @@ -7,7 +7,7 @@ go 1.16 | ||||
| require ( | ||||
| 	github.com/emicklei/go-restful v2.9.5+incompatible | ||||
| 	github.com/gogo/protobuf v1.3.2 | ||||
| 	github.com/google/go-cmp v0.5.4 | ||||
| 	github.com/google/go-cmp v0.5.2 | ||||
| 	github.com/google/gofuzz v1.1.0 | ||||
| 	github.com/google/uuid v1.1.2 | ||||
| 	github.com/googleapis/gnostic v0.5.1 | ||||
|   | ||||
| @@ -165,8 +165,8 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw | ||||
| github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | ||||
| github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= | ||||
| github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= | ||||
| github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= | ||||
| github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| @@ -515,8 +515,8 @@ golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7w | ||||
| golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887 h1:dXfMednGJh/SUUFjTLsWJz3P+TQt9qnR11GgeI3vWKs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 h1:8qxJSnu+7dRq6upnbntrmriWByIakBuct5OM/MdQC1M= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| 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 h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE= | ||||
|   | ||||
| @@ -11,7 +11,7 @@ require ( | ||||
| 	github.com/gogo/protobuf v1.3.2 | ||||
| 	github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e | ||||
| 	github.com/golang/protobuf v1.4.3 | ||||
| 	github.com/google/go-cmp v0.5.4 | ||||
| 	github.com/google/go-cmp v0.5.2 | ||||
| 	github.com/google/gofuzz v1.1.0 | ||||
| 	github.com/google/uuid v1.1.2 | ||||
| 	github.com/googleapis/gnostic v0.5.1 | ||||
| @@ -28,7 +28,7 @@ require ( | ||||
| 	github.com/spf13/pflag v1.0.5 | ||||
| 	github.com/stretchr/testify v1.6.1 | ||||
| 	golang.org/x/net v0.0.0-20210224082022-3d97a244fca7 | ||||
| 	golang.org/x/sys v0.0.0-20210426230700-d19ff857e887 // indirect | ||||
| 	golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 // indirect | ||||
| 	golang.org/x/text v0.3.4 // indirect | ||||
| 	google.golang.org/protobuf v1.25.0 // indirect | ||||
| 	gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect | ||||
|   | ||||
							
								
								
									
										8
									
								
								staging/src/k8s.io/apimachinery/go.sum
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										8
									
								
								staging/src/k8s.io/apimachinery/go.sum
									
									
									
										generated
									
									
									
								
							| @@ -47,8 +47,8 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw | ||||
| github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | ||||
| github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= | ||||
| github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= | ||||
| github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= | ||||
| github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| @@ -147,8 +147,8 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w | ||||
| golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887 h1:dXfMednGJh/SUUFjTLsWJz3P+TQt9qnR11GgeI3vWKs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 h1:8qxJSnu+7dRq6upnbntrmriWByIakBuct5OM/MdQC1M= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= | ||||
| golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||||
| golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= | ||||
|   | ||||
| @@ -14,7 +14,7 @@ require ( | ||||
| 	github.com/emicklei/go-restful v2.9.5+incompatible | ||||
| 	github.com/evanphx/json-patch v4.9.0+incompatible | ||||
| 	github.com/gogo/protobuf v1.3.2 | ||||
| 	github.com/google/go-cmp v0.5.4 | ||||
| 	github.com/google/go-cmp v0.5.2 | ||||
| 	github.com/google/gofuzz v1.1.0 | ||||
| 	github.com/google/uuid v1.1.2 | ||||
| 	github.com/googleapis/gnostic v0.5.1 | ||||
| @@ -33,7 +33,7 @@ require ( | ||||
| 	golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 | ||||
| 	golang.org/x/net v0.0.0-20210224082022-3d97a244fca7 | ||||
| 	golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 | ||||
| 	golang.org/x/sys v0.0.0-20210426230700-d19ff857e887 | ||||
| 	golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 | ||||
| 	google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a // indirect | ||||
| 	google.golang.org/grpc v1.27.1 | ||||
| 	gopkg.in/natefinch/lumberjack.v2 v2.0.0 | ||||
|   | ||||
							
								
								
									
										8
									
								
								staging/src/k8s.io/apiserver/go.sum
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										8
									
								
								staging/src/k8s.io/apiserver/go.sum
									
									
									
										generated
									
									
									
								
							| @@ -164,8 +164,8 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw | ||||
| github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | ||||
| github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= | ||||
| github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= | ||||
| github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= | ||||
| github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| @@ -514,8 +514,8 @@ golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7w | ||||
| golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887 h1:dXfMednGJh/SUUFjTLsWJz3P+TQt9qnR11GgeI3vWKs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 h1:8qxJSnu+7dRq6upnbntrmriWByIakBuct5OM/MdQC1M= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| 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 h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE= | ||||
|   | ||||
							
								
								
									
										8
									
								
								staging/src/k8s.io/cli-runtime/go.sum
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										8
									
								
								staging/src/k8s.io/cli-runtime/go.sum
									
									
									
										generated
									
									
									
								
							| @@ -183,8 +183,8 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw | ||||
| github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | ||||
| github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= | ||||
| github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= | ||||
| github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= | ||||
| github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| @@ -503,8 +503,8 @@ golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7w | ||||
| golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887 h1:dXfMednGJh/SUUFjTLsWJz3P+TQt9qnR11GgeI3vWKs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 h1:8qxJSnu+7dRq6upnbntrmriWByIakBuct5OM/MdQC1M= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| 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 h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE= | ||||
|   | ||||
| @@ -13,7 +13,7 @@ require ( | ||||
| 	github.com/gogo/protobuf v1.3.2 | ||||
| 	github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e | ||||
| 	github.com/golang/protobuf v1.4.3 | ||||
| 	github.com/google/go-cmp v0.5.4 | ||||
| 	github.com/google/go-cmp v0.5.2 | ||||
| 	github.com/google/gofuzz v1.1.0 | ||||
| 	github.com/google/uuid v1.1.2 | ||||
| 	github.com/googleapis/gnostic v0.5.1 | ||||
|   | ||||
							
								
								
									
										8
									
								
								staging/src/k8s.io/client-go/go.sum
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										8
									
								
								staging/src/k8s.io/client-go/go.sum
									
									
									
										generated
									
									
									
								
							| @@ -106,8 +106,8 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw | ||||
| github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | ||||
| github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= | ||||
| github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= | ||||
| github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= | ||||
| github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| @@ -293,8 +293,8 @@ golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7w | ||||
| golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887 h1:dXfMednGJh/SUUFjTLsWJz3P+TQt9qnR11GgeI3vWKs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 h1:8qxJSnu+7dRq6upnbntrmriWByIakBuct5OM/MdQC1M= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| 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 h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE= | ||||
|   | ||||
| @@ -5,7 +5,7 @@ module k8s.io/cloud-provider | ||||
| go 1.16 | ||||
|  | ||||
| require ( | ||||
| 	github.com/google/go-cmp v0.5.4 | ||||
| 	github.com/google/go-cmp v0.5.2 | ||||
| 	github.com/spf13/cobra v1.1.1 | ||||
| 	github.com/spf13/pflag v1.0.5 | ||||
| 	github.com/stretchr/testify v1.6.1 | ||||
|   | ||||
							
								
								
									
										8
									
								
								staging/src/k8s.io/cloud-provider/go.sum
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										8
									
								
								staging/src/k8s.io/cloud-provider/go.sum
									
									
									
										generated
									
									
									
								
							| @@ -165,8 +165,8 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw | ||||
| github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | ||||
| github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= | ||||
| github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= | ||||
| github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= | ||||
| github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| @@ -515,8 +515,8 @@ golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7w | ||||
| golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887 h1:dXfMednGJh/SUUFjTLsWJz3P+TQt9qnR11GgeI3vWKs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 h1:8qxJSnu+7dRq6upnbntrmriWByIakBuct5OM/MdQC1M= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| 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 h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE= | ||||
|   | ||||
							
								
								
									
										6
									
								
								staging/src/k8s.io/cluster-bootstrap/go.sum
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										6
									
								
								staging/src/k8s.io/cluster-bootstrap/go.sum
									
									
									
										generated
									
									
									
								
							| @@ -43,8 +43,8 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw | ||||
| github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | ||||
| github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= | ||||
| github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= | ||||
| github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= | ||||
| github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| @@ -137,7 +137,7 @@ golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7w | ||||
| golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| 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/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||||
|   | ||||
| @@ -101,8 +101,8 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw | ||||
| github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | ||||
| github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= | ||||
| github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= | ||||
| github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= | ||||
| github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| @@ -284,8 +284,8 @@ golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7w | ||||
| golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887 h1:dXfMednGJh/SUUFjTLsWJz3P+TQt9qnR11GgeI3vWKs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 h1:8qxJSnu+7dRq6upnbntrmriWByIakBuct5OM/MdQC1M= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| 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 h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE= | ||||
|   | ||||
| @@ -8,7 +8,7 @@ require ( | ||||
| 	github.com/emicklei/go-restful v2.9.5+incompatible // indirect | ||||
| 	github.com/gogo/protobuf v1.3.2 | ||||
| 	github.com/golang/protobuf v1.4.3 // indirect | ||||
| 	github.com/google/go-cmp v0.5.4 // indirect | ||||
| 	github.com/google/go-cmp v0.5.2 // indirect | ||||
| 	github.com/googleapis/gnostic v0.5.1 | ||||
| 	github.com/json-iterator/go v1.1.10 // indirect | ||||
| 	github.com/kr/text v0.2.0 // indirect | ||||
| @@ -20,7 +20,7 @@ require ( | ||||
| 	github.com/stretchr/testify v1.6.1 // indirect | ||||
| 	golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449 // indirect | ||||
| 	golang.org/x/net v0.0.0-20210224082022-3d97a244fca7 // indirect | ||||
| 	golang.org/x/sys v0.0.0-20210426230700-d19ff857e887 // indirect | ||||
| 	golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 // indirect | ||||
| 	golang.org/x/text v0.3.4 // indirect | ||||
| 	golang.org/x/tools v0.1.0 // indirect | ||||
| 	google.golang.org/protobuf v1.25.0 // indirect | ||||
|   | ||||
							
								
								
									
										8
									
								
								staging/src/k8s.io/code-generator/go.sum
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										8
									
								
								staging/src/k8s.io/code-generator/go.sum
									
									
									
										generated
									
									
									
								
							| @@ -49,8 +49,8 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw | ||||
| github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | ||||
| github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= | ||||
| github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= | ||||
| github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= | ||||
| github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| @@ -143,8 +143,8 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7w | ||||
| golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887 h1:dXfMednGJh/SUUFjTLsWJz3P+TQt9qnR11GgeI3vWKs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 h1:8qxJSnu+7dRq6upnbntrmriWByIakBuct5OM/MdQC1M= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= | ||||
| golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||||
| golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= | ||||
|   | ||||
| @@ -7,7 +7,7 @@ go 1.16 | ||||
| require ( | ||||
| 	github.com/blang/semver v3.5.1+incompatible | ||||
| 	github.com/go-logr/logr v0.4.0 | ||||
| 	github.com/google/go-cmp v0.5.4 | ||||
| 	github.com/google/go-cmp v0.5.2 | ||||
| 	github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect | ||||
| 	github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 | ||||
| 	github.com/prometheus/client_golang v1.7.1 | ||||
| @@ -19,7 +19,7 @@ require ( | ||||
| 	github.com/stretchr/testify v1.6.1 | ||||
| 	go.uber.org/zap v1.16.0 | ||||
| 	golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449 // indirect | ||||
| 	golang.org/x/sys v0.0.0-20210426230700-d19ff857e887 | ||||
| 	golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 | ||||
| 	golang.org/x/tools v0.1.0 // indirect | ||||
| 	gotest.tools/v3 v3.0.3 // indirect | ||||
| 	k8s.io/apimachinery v0.0.0 | ||||
|   | ||||
							
								
								
									
										8
									
								
								staging/src/k8s.io/component-base/go.sum
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										8
									
								
								staging/src/k8s.io/component-base/go.sum
									
									
									
										generated
									
									
									
								
							| @@ -139,8 +139,8 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw | ||||
| github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | ||||
| github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= | ||||
| github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= | ||||
| github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= | ||||
| github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| @@ -445,8 +445,8 @@ golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7w | ||||
| golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887 h1:dXfMednGJh/SUUFjTLsWJz3P+TQt9qnR11GgeI3vWKs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 h1:8qxJSnu+7dRq6upnbntrmriWByIakBuct5OM/MdQC1M= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| 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 h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE= | ||||
|   | ||||
| @@ -5,7 +5,7 @@ module k8s.io/component-helpers | ||||
| go 1.16 | ||||
|  | ||||
| require ( | ||||
| 	github.com/google/go-cmp v0.5.4 | ||||
| 	github.com/google/go-cmp v0.5.2 | ||||
| 	k8s.io/api v0.0.0 | ||||
| 	k8s.io/apimachinery v0.0.0 | ||||
| 	k8s.io/client-go v0.0.0 | ||||
|   | ||||
							
								
								
									
										8
									
								
								staging/src/k8s.io/component-helpers/go.sum
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										8
									
								
								staging/src/k8s.io/component-helpers/go.sum
									
									
									
										generated
									
									
									
								
							| @@ -94,8 +94,8 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw | ||||
| github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | ||||
| github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= | ||||
| github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= | ||||
| github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= | ||||
| github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| @@ -274,8 +274,8 @@ golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7w | ||||
| golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887 h1:dXfMednGJh/SUUFjTLsWJz3P+TQt9qnR11GgeI3vWKs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 h1:8qxJSnu+7dRq6upnbntrmriWByIakBuct5OM/MdQC1M= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| 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 h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE= | ||||
|   | ||||
							
								
								
									
										8
									
								
								staging/src/k8s.io/controller-manager/go.sum
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										8
									
								
								staging/src/k8s.io/controller-manager/go.sum
									
									
									
										generated
									
									
									
								
							| @@ -229,8 +229,8 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw | ||||
| github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= | ||||
| github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= | ||||
| github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= | ||||
| @@ -705,8 +705,8 @@ golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7w | ||||
| golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887 h1:dXfMednGJh/SUUFjTLsWJz3P+TQt9qnR11GgeI3vWKs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 h1:8qxJSnu+7dRq6upnbntrmriWByIakBuct5OM/MdQC1M= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| 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 h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE= | ||||
|   | ||||
| @@ -8,12 +8,12 @@ require ( | ||||
| 	github.com/davecgh/go-spew v1.1.1 // indirect | ||||
| 	github.com/gogo/protobuf v1.3.2 | ||||
| 	github.com/golang/protobuf v1.4.3 // indirect | ||||
| 	github.com/google/go-cmp v0.5.4 // indirect | ||||
| 	github.com/google/go-cmp v0.5.2 // indirect | ||||
| 	github.com/kr/text v0.2.0 // indirect | ||||
| 	github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect | ||||
| 	github.com/stretchr/testify v1.6.1 | ||||
| 	golang.org/x/net v0.0.0-20210224082022-3d97a244fca7 // indirect | ||||
| 	golang.org/x/sys v0.0.0-20210426230700-d19ff857e887 // indirect | ||||
| 	golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 // indirect | ||||
| 	golang.org/x/text v0.3.4 // indirect | ||||
| 	google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a // indirect | ||||
| 	google.golang.org/grpc v1.27.1 | ||||
|   | ||||
							
								
								
									
										8
									
								
								staging/src/k8s.io/cri-api/go.sum
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										8
									
								
								staging/src/k8s.io/cri-api/go.sum
									
									
									
										generated
									
									
									
								
							| @@ -28,8 +28,8 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw | ||||
| github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | ||||
| github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= | ||||
| github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= | ||||
| github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= | ||||
| github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= | ||||
| github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= | ||||
| @@ -76,8 +76,8 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h | ||||
| golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887 h1:dXfMednGJh/SUUFjTLsWJz3P+TQt9qnR11GgeI3vWKs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 h1:8qxJSnu+7dRq6upnbntrmriWByIakBuct5OM/MdQC1M= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= | ||||
| golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||||
| golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | ||||
|   | ||||
							
								
								
									
										6
									
								
								staging/src/k8s.io/csi-translation-lib/go.sum
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										6
									
								
								staging/src/k8s.io/csi-translation-lib/go.sum
									
									
									
										generated
									
									
									
								
							| @@ -43,8 +43,8 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw | ||||
| github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | ||||
| github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= | ||||
| github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= | ||||
| github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= | ||||
| github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| @@ -135,7 +135,7 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w | ||||
| golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= | ||||
| golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||||
| golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= | ||||
|   | ||||
							
								
								
									
										8
									
								
								staging/src/k8s.io/kube-aggregator/go.sum
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										8
									
								
								staging/src/k8s.io/kube-aggregator/go.sum
									
									
									
										generated
									
									
									
								
							| @@ -165,8 +165,8 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw | ||||
| github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | ||||
| github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= | ||||
| github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= | ||||
| github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= | ||||
| github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| @@ -516,8 +516,8 @@ golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7w | ||||
| golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887 h1:dXfMednGJh/SUUFjTLsWJz3P+TQt9qnR11GgeI3vWKs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 h1:8qxJSnu+7dRq6upnbntrmriWByIakBuct5OM/MdQC1M= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| 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 h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE= | ||||
|   | ||||
| @@ -140,8 +140,8 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw | ||||
| github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | ||||
| github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= | ||||
| github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= | ||||
| github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= | ||||
| github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| @@ -451,7 +451,7 @@ golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7w | ||||
| golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| 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= | ||||
|   | ||||
							
								
								
									
										6
									
								
								staging/src/k8s.io/kube-proxy/go.sum
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										6
									
								
								staging/src/k8s.io/kube-proxy/go.sum
									
									
									
										generated
									
									
									
								
							| @@ -129,8 +129,8 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw | ||||
| github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | ||||
| github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= | ||||
| github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= | ||||
| github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= | ||||
| github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| @@ -418,7 +418,7 @@ golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7w | ||||
| golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| 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= | ||||
|   | ||||
| @@ -5,7 +5,7 @@ module k8s.io/kube-scheduler | ||||
| go 1.16 | ||||
|  | ||||
| require ( | ||||
| 	github.com/google/go-cmp v0.5.4 | ||||
| 	github.com/google/go-cmp v0.5.2 | ||||
| 	k8s.io/api v0.0.0 | ||||
| 	k8s.io/apimachinery v0.0.0 | ||||
| 	k8s.io/component-base v0.0.0 | ||||
|   | ||||
							
								
								
									
										6
									
								
								staging/src/k8s.io/kube-scheduler/go.sum
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										6
									
								
								staging/src/k8s.io/kube-scheduler/go.sum
									
									
									
										generated
									
									
									
								
							| @@ -129,8 +129,8 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw | ||||
| github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | ||||
| github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= | ||||
| github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= | ||||
| github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= | ||||
| github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| @@ -418,7 +418,7 @@ golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7w | ||||
| golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| 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= | ||||
|   | ||||
| @@ -16,7 +16,7 @@ require ( | ||||
| 	github.com/fsnotify/fsnotify v1.4.9 // indirect | ||||
| 	github.com/fvbommel/sortorder v1.0.1 | ||||
| 	github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e // indirect | ||||
| 	github.com/google/go-cmp v0.5.4 | ||||
| 	github.com/google/go-cmp v0.5.2 | ||||
| 	github.com/googleapis/gnostic v0.5.1 | ||||
| 	github.com/jonboulle/clockwork v0.1.0 | ||||
| 	github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de | ||||
| @@ -30,7 +30,7 @@ require ( | ||||
| 	github.com/spf13/cobra v1.1.1 | ||||
| 	github.com/spf13/pflag v1.0.5 | ||||
| 	github.com/stretchr/testify v1.6.1 | ||||
| 	golang.org/x/sys v0.0.0-20210426230700-d19ff857e887 | ||||
| 	golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 | ||||
| 	gopkg.in/yaml.v2 v2.4.0 | ||||
| 	k8s.io/api v0.0.0 | ||||
| 	k8s.io/apimachinery v0.0.0 | ||||
|   | ||||
							
								
								
									
										7
									
								
								staging/src/k8s.io/kubectl/go.sum
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										7
									
								
								staging/src/k8s.io/kubectl/go.sum
									
									
									
										generated
									
									
									
								
							| @@ -215,9 +215,8 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw | ||||
| github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | ||||
| github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= | ||||
| github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= | ||||
| github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= | ||||
| github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| @@ -577,8 +576,8 @@ golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7w | ||||
| golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887 h1:dXfMednGJh/SUUFjTLsWJz3P+TQt9qnR11GgeI3vWKs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 h1:8qxJSnu+7dRq6upnbntrmriWByIakBuct5OM/MdQC1M= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| 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 h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE= | ||||
|   | ||||
							
								
								
									
										8
									
								
								staging/src/k8s.io/kubelet/go.sum
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										8
									
								
								staging/src/k8s.io/kubelet/go.sum
									
									
									
										generated
									
									
									
								
							| @@ -131,8 +131,8 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw | ||||
| github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | ||||
| github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= | ||||
| github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= | ||||
| github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= | ||||
| github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| @@ -420,8 +420,8 @@ golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7w | ||||
| golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887 h1:dXfMednGJh/SUUFjTLsWJz3P+TQt9qnR11GgeI3vWKs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 h1:8qxJSnu+7dRq6upnbntrmriWByIakBuct5OM/MdQC1M= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| 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= | ||||
|   | ||||
| @@ -18,7 +18,7 @@ require ( | ||||
| 	github.com/dnaeon/go-vcr v1.0.1 // indirect | ||||
| 	github.com/gofrs/uuid v4.0.0+incompatible // indirect | ||||
| 	github.com/golang/mock v1.4.4 | ||||
| 	github.com/google/go-cmp v0.5.4 | ||||
| 	github.com/google/go-cmp v0.5.2 | ||||
| 	github.com/gophercloud/gophercloud v0.1.0 | ||||
| 	github.com/mitchellh/mapstructure v1.1.2 | ||||
| 	github.com/rubiojr/go-vhd v0.0.0-20200706105327-02e210299021 | ||||
|   | ||||
							
								
								
									
										8
									
								
								staging/src/k8s.io/legacy-cloud-providers/go.sum
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										8
									
								
								staging/src/k8s.io/legacy-cloud-providers/go.sum
									
									
									
										generated
									
									
									
								
							| @@ -174,8 +174,8 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw | ||||
| github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | ||||
| github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= | ||||
| github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= | ||||
| github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= | ||||
| github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| @@ -518,8 +518,8 @@ golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7w | ||||
| golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887 h1:dXfMednGJh/SUUFjTLsWJz3P+TQt9qnR11GgeI3vWKs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 h1:8qxJSnu+7dRq6upnbntrmriWByIakBuct5OM/MdQC1M= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| 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 h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE= | ||||
|   | ||||
							
								
								
									
										8
									
								
								staging/src/k8s.io/metrics/go.sum
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										8
									
								
								staging/src/k8s.io/metrics/go.sum
									
									
									
										generated
									
									
									
								
							| @@ -102,8 +102,8 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw | ||||
| github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | ||||
| github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= | ||||
| github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= | ||||
| github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= | ||||
| github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| @@ -287,8 +287,8 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7w | ||||
| golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887 h1:dXfMednGJh/SUUFjTLsWJz3P+TQt9qnR11GgeI3vWKs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 h1:8qxJSnu+7dRq6upnbntrmriWByIakBuct5OM/MdQC1M= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| 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 h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE= | ||||
|   | ||||
							
								
								
									
										8
									
								
								staging/src/k8s.io/sample-apiserver/go.sum
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										8
									
								
								staging/src/k8s.io/sample-apiserver/go.sum
									
									
									
										generated
									
									
									
								
							| @@ -164,8 +164,8 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw | ||||
| github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | ||||
| github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= | ||||
| github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= | ||||
| github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= | ||||
| github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| @@ -513,8 +513,8 @@ golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7w | ||||
| golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887 h1:dXfMednGJh/SUUFjTLsWJz3P+TQt9qnR11GgeI3vWKs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 h1:8qxJSnu+7dRq6upnbntrmriWByIakBuct5OM/MdQC1M= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| 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 h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE= | ||||
|   | ||||
							
								
								
									
										8
									
								
								staging/src/k8s.io/sample-cli-plugin/go.sum
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										8
									
								
								staging/src/k8s.io/sample-cli-plugin/go.sum
									
									
									
										generated
									
									
									
								
							| @@ -183,8 +183,8 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw | ||||
| github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | ||||
| github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= | ||||
| github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= | ||||
| github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= | ||||
| github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| @@ -503,8 +503,8 @@ golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7w | ||||
| golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887 h1:dXfMednGJh/SUUFjTLsWJz3P+TQt9qnR11GgeI3vWKs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 h1:8qxJSnu+7dRq6upnbntrmriWByIakBuct5OM/MdQC1M= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| 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 h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE= | ||||
|   | ||||
							
								
								
									
										8
									
								
								staging/src/k8s.io/sample-controller/go.sum
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										8
									
								
								staging/src/k8s.io/sample-controller/go.sum
									
									
									
										generated
									
									
									
								
							| @@ -103,8 +103,8 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw | ||||
| github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | ||||
| github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= | ||||
| github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= | ||||
| github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= | ||||
| github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| @@ -291,8 +291,8 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7w | ||||
| golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887 h1:dXfMednGJh/SUUFjTLsWJz3P+TQt9qnR11GgeI3vWKs= | ||||
| golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 h1:8qxJSnu+7dRq6upnbntrmriWByIakBuct5OM/MdQC1M= | ||||
| golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| 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 h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE= | ||||
|   | ||||
| @@ -124,7 +124,7 @@ var _ = SIGDescribe("Summary API [NodeConformance]", func() { | ||||
| 				"WorkingSetBytes": bounded(10*e2evolume.Kb, memoryLimit), | ||||
| 				"RSSBytes":        bounded(1*e2evolume.Kb, memoryLimit), | ||||
| 				"PageFaults":      bounded(0, 1000000), | ||||
| 				"MajorPageFaults": bounded(0, 1000), | ||||
| 				"MajorPageFaults": bounded(0, 10), | ||||
| 			}) | ||||
| 			runtimeContExpectations := sysContExpectations().(*gstruct.FieldsMatcher) | ||||
| 			if systemdutil.IsRunningSystemd() && framework.TestContext.ContainerRuntime == "docker" { | ||||
|   | ||||
| @@ -1,6 +1,5 @@ | ||||
| test/test | ||||
| test/piggie/piggie | ||||
| test/piggie | ||||
| test/phaul | ||||
| image | ||||
| rpc/rpc.proto | ||||
| stats/stats.proto | ||||
							
								
								
									
										28
									
								
								vendor/github.com/checkpoint-restore/go-criu/v4/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								vendor/github.com/checkpoint-restore/go-criu/v4/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| language: go | ||||
| dist: bionic | ||||
| os: | ||||
|   - linux | ||||
| go: | ||||
|   - "1.14.x" | ||||
|   - "1.13.x" | ||||
|   - tip | ||||
| env: | ||||
|   # Run the tests with CRIU master and criu-dev | ||||
|   - CRIU_BRANCH="master" | ||||
|   - CRIU_BRANCH="criu-dev" | ||||
| install: | ||||
|   - sudo apt-get update | ||||
|   - sudo apt-get install -y libprotobuf-dev libprotobuf-c0-dev protobuf-c-compiler protobuf-compiler python-protobuf libnl-3-dev libnet-dev libcap-dev | ||||
|   - make install.tools | ||||
|   - go get github.com/checkpoint-restore/go-criu | ||||
|   - git clone --single-branch -b ${CRIU_BRANCH} https://github.com/checkpoint-restore/criu.git | ||||
|   - cd criu; make | ||||
|   - sudo install -D -m 755 criu/criu /usr/sbin/ | ||||
|   - cd .. | ||||
| script: | ||||
|   # This builds the code without running the tests. | ||||
|   - make lint build phaul test/test test/phaul test/piggie | ||||
|   # Run actual test as root as it uses CRIU. | ||||
|   - sudo make test phaul-test | ||||
|   # This builds crit-go | ||||
|   - make -C crit-go/magic-gen lint build magicgen test | ||||
							
								
								
									
										60
									
								
								vendor/github.com/checkpoint-restore/go-criu/v4/Makefile
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								vendor/github.com/checkpoint-restore/go-criu/v4/Makefile
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,60 @@ | ||||
| GO ?= go | ||||
| CC ?= gcc | ||||
| ifeq ($(GOPATH),) | ||||
| export GOPATH := $(shell $(GO) env GOPATH) | ||||
| endif | ||||
| FIRST_GOPATH := $(firstword $(subst :, ,$(GOPATH))) | ||||
| GOBIN := $(shell $(GO) env GOBIN) | ||||
| ifeq ($(GOBIN),) | ||||
| 	GOBIN := $(FIRST_GOPATH)/bin | ||||
| endif | ||||
|  | ||||
| all: build test phaul phaul-test | ||||
|  | ||||
| lint: | ||||
| 	@golint -set_exit_status . test phaul | ||||
| build: | ||||
| 	@$(GO) build -v | ||||
|  | ||||
| test/piggie: test/piggie.c | ||||
| 	@$(CC) $^ -o $@ | ||||
|  | ||||
| test/test: test/main.go | ||||
| 	@$(GO) build -v -o test/test test/main.go | ||||
|  | ||||
| test: test/test test/piggie | ||||
| 	mkdir -p image | ||||
| 	test/piggie | ||||
| 	test/test dump `pidof piggie` image | ||||
| 	test/test restore image | ||||
| 	pkill -9 piggie || : | ||||
|  | ||||
| phaul: | ||||
| 	@cd phaul; go build -v | ||||
|  | ||||
| test/phaul: test/phaul-main.go | ||||
| 	@$(GO) build -v -o test/phaul test/phaul-main.go | ||||
|  | ||||
| phaul-test: test/phaul test/piggie | ||||
| 	rm -rf image | ||||
| 	test/piggie | ||||
| 	test/phaul `pidof piggie` | ||||
| 	pkill -9 piggie || : | ||||
|  | ||||
| clean: | ||||
| 	@rm -f test/test test/piggie test/phaul | ||||
| 	@rm -rf image | ||||
| 	@rm -f rpc/rpc.proto | ||||
|  | ||||
| install.tools: | ||||
| 	if [ ! -x "$(GOBIN)/golint" ]; then \ | ||||
| 		$(GO) get -u golang.org/x/lint/golint; \ | ||||
| 	fi | ||||
|  | ||||
| rpc/rpc.proto: | ||||
| 	curl -s https://raw.githubusercontent.com/checkpoint-restore/criu/master/images/rpc.proto -o $@ | ||||
|  | ||||
| rpc/rpc.pb.go: rpc/rpc.proto | ||||
| 	protoc --go_out=. $^ | ||||
|  | ||||
| .PHONY: build test clean lint phaul | ||||
| @@ -1,10 +1,8 @@ | ||||
| [](https://github.com/checkpoint-restore/go-criu/actions?query=workflow%3Aci) | ||||
| [](https://github.com/checkpoint-restore/go-criu/actions?query=workflow%3Averify) | ||||
| [](https://pkg.go.dev/github.com/checkpoint-restore/go-criu) | ||||
| [](https://travis-ci.org/checkpoint-restore/go-criu) | ||||
| 
 | ||||
| ## go-criu -- Go bindings for CRIU | ||||
| ## go-criu -- Go bindings for [CRIU](https://criu.org/) | ||||
| 
 | ||||
| This repository provides Go bindings for [CRIU](https://criu.org/). The code is based on the Go-based PHaul | ||||
| This repository provides Go bindings for CRIU. The code is based on the Go based PHaul | ||||
| implementation from the CRIU repository. For easier inclusion into other Go projects the | ||||
| CRIU Go bindings have been moved to this repository. | ||||
| 
 | ||||
| @@ -12,26 +10,13 @@ The Go bindings provide an easy way to use the CRIU RPC calls from Go without th | ||||
| to set up all the infrastructure to make the actual RPC connection to CRIU. | ||||
| 
 | ||||
| The following example would print the version of CRIU: | ||||
| ```go | ||||
| import ( | ||||
| 	"log" | ||||
| 
 | ||||
| 	"github.com/checkpoint/restore/go-criu/v5" | ||||
| ) | ||||
| 
 | ||||
| func main() { | ||||
| ``` | ||||
| 	c := criu.MakeCriu() | ||||
| 	version, err := c.GetCriuVersion() | ||||
| 	if err != nil { | ||||
| 		log.Fatalln(err) | ||||
| 	} | ||||
| 	log.Println(version) | ||||
| } | ||||
| 	fmt.Println(version) | ||||
| ``` | ||||
| 
 | ||||
| or to just check if at least a certain CRIU version is installed: | ||||
| 
 | ||||
| ```go | ||||
| ``` | ||||
| 	c := criu.MakeCriu() | ||||
| 	result, err := c.IsCriuAtLeast(31100) | ||||
| ``` | ||||
| @@ -46,12 +31,7 @@ As go-criu is imported in other projects and as Go modules are expected | ||||
| to follow Semantic Versioning go-criu will also follow Semantic Versioning | ||||
| starting with the 4.0.0 release. | ||||
| 
 | ||||
| The following table shows the relation between go-criu and criu versions: | ||||
| 
 | ||||
| | Major version  | Latest release | CRIU version | | ||||
| | -------------- | -------------- | ------------ | | ||||
| | v5             | 5.0.0          | 3.15         | | ||||
| | v4             | 4.1.0          | 3.14         | | ||||
| 4.0.0 is based on CRIU 3.14 | ||||
| 
 | ||||
| ## How to contribute | ||||
| 
 | ||||
							
								
								
									
										5
									
								
								vendor/github.com/checkpoint-restore/go-criu/v4/go.mod
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								vendor/github.com/checkpoint-restore/go-criu/v4/go.mod
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| module github.com/checkpoint-restore/go-criu/v4 | ||||
|  | ||||
| go 1.13 | ||||
|  | ||||
| require github.com/golang/protobuf v1.3.5 | ||||
							
								
								
									
										2
									
								
								vendor/github.com/checkpoint-restore/go-criu/v4/go.sum
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/checkpoint-restore/go-criu/v4/go.sum
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| github.com/golang/protobuf v1.3.5 h1:F768QJ1E9tib+q5Sc8MkdJi1RxLTbRcTf8LJV56aRls= | ||||
| github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= | ||||
| @@ -8,8 +8,8 @@ import ( | ||||
| 	"strconv" | ||||
| 	"syscall" | ||||
| 
 | ||||
| 	"github.com/checkpoint-restore/go-criu/v5/rpc" | ||||
| 	"google.golang.org/protobuf/proto" | ||||
| 	"github.com/checkpoint-restore/go-criu/v4/rpc" | ||||
| 	"github.com/golang/protobuf/proto" | ||||
| ) | ||||
| 
 | ||||
| // Criu struct | ||||
| @@ -45,7 +45,6 @@ func (c *Criu) Prepare() error { | ||||
| 	defer srv.Close() | ||||
| 
 | ||||
| 	args := []string{"swrk", strconv.Itoa(fds[1])} | ||||
| 	// #nosec G204 | ||||
| 	cmd := exec.Command(c.swrkPath, args...) | ||||
| 
 | ||||
| 	err = cmd.Start() | ||||
| @@ -65,7 +64,7 @@ func (c *Criu) Cleanup() { | ||||
| 	if c.swrkCmd != nil { | ||||
| 		c.swrkSk.Close() | ||||
| 		c.swrkSk = nil | ||||
| 		_ = c.swrkCmd.Wait() | ||||
| 		c.swrkCmd.Wait() | ||||
| 		c.swrkCmd = nil | ||||
| 	} | ||||
| } | ||||
| @@ -188,28 +187,28 @@ func (c *Criu) doSwrkWithResp(reqType rpc.CriuReqType, opts *rpc.CriuOpts, nfy N | ||||
| } | ||||
| 
 | ||||
| // Dump dumps a process | ||||
| func (c *Criu) Dump(opts *rpc.CriuOpts, nfy Notify) error { | ||||
| 	return c.doSwrk(rpc.CriuReqType_DUMP, opts, nfy) | ||||
| func (c *Criu) Dump(opts rpc.CriuOpts, nfy Notify) error { | ||||
| 	return c.doSwrk(rpc.CriuReqType_DUMP, &opts, nfy) | ||||
| } | ||||
| 
 | ||||
| // Restore restores a process | ||||
| func (c *Criu) Restore(opts *rpc.CriuOpts, nfy Notify) error { | ||||
| 	return c.doSwrk(rpc.CriuReqType_RESTORE, opts, nfy) | ||||
| func (c *Criu) Restore(opts rpc.CriuOpts, nfy Notify) error { | ||||
| 	return c.doSwrk(rpc.CriuReqType_RESTORE, &opts, nfy) | ||||
| } | ||||
| 
 | ||||
| // PreDump does a pre-dump | ||||
| func (c *Criu) PreDump(opts *rpc.CriuOpts, nfy Notify) error { | ||||
| 	return c.doSwrk(rpc.CriuReqType_PRE_DUMP, opts, nfy) | ||||
| func (c *Criu) PreDump(opts rpc.CriuOpts, nfy Notify) error { | ||||
| 	return c.doSwrk(rpc.CriuReqType_PRE_DUMP, &opts, nfy) | ||||
| } | ||||
| 
 | ||||
| // StartPageServer starts the page server | ||||
| func (c *Criu) StartPageServer(opts *rpc.CriuOpts) error { | ||||
| 	return c.doSwrk(rpc.CriuReqType_PAGE_SERVER, opts, nil) | ||||
| func (c *Criu) StartPageServer(opts rpc.CriuOpts) error { | ||||
| 	return c.doSwrk(rpc.CriuReqType_PAGE_SERVER, &opts, nil) | ||||
| } | ||||
| 
 | ||||
| // StartPageServerChld starts the page server and returns PID and port | ||||
| func (c *Criu) StartPageServerChld(opts *rpc.CriuOpts) (int, int, error) { | ||||
| 	resp, err := c.doSwrkWithResp(rpc.CriuReqType_PAGE_SERVER_CHLD, opts, nil) | ||||
| func (c *Criu) StartPageServerChld(opts rpc.CriuOpts) (int, int, error) { | ||||
| 	resp, err := c.doSwrkWithResp(rpc.CriuReqType_PAGE_SERVER_CHLD, &opts, nil) | ||||
| 	if err != nil { | ||||
| 		return 0, 0, err | ||||
| 	} | ||||
| @@ -1,6 +1,6 @@ | ||||
| package criu | ||||
| 
 | ||||
| // Notify interface | ||||
| //Notify interface | ||||
| type Notify interface { | ||||
| 	PreDump() error | ||||
| 	PostDump() error | ||||
| @@ -14,7 +14,8 @@ type Notify interface { | ||||
| } | ||||
| 
 | ||||
| // NoNotify struct | ||||
| type NoNotify struct{} | ||||
| type NoNotify struct { | ||||
| } | ||||
| 
 | ||||
| // PreDump NoNotify | ||||
| func (c NoNotify) PreDump() error { | ||||
							
								
								
									
										1667
									
								
								vendor/github.com/checkpoint-restore/go-criu/v4/rpc/rpc.pb.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1667
									
								
								vendor/github.com/checkpoint-restore/go-criu/v4/rpc/rpc.pb.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										12
									
								
								vendor/github.com/checkpoint-restore/go-criu/v5/.golangci.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								vendor/github.com/checkpoint-restore/go-criu/v5/.golangci.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,12 +0,0 @@ | ||||
| run: | ||||
|   skip_dirs: | ||||
|     - rpc | ||||
|     - stats | ||||
|  | ||||
| linters: | ||||
|   disable-all: false | ||||
|   presets: | ||||
|     - bugs | ||||
|     - performance | ||||
|     - unused | ||||
|     - format | ||||
							
								
								
									
										57
									
								
								vendor/github.com/checkpoint-restore/go-criu/v5/Makefile
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										57
									
								
								vendor/github.com/checkpoint-restore/go-criu/v5/Makefile
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,57 +0,0 @@ | ||||
| GO ?= go | ||||
| CC ?= gcc | ||||
|  | ||||
| all: build test phaul-test | ||||
|  | ||||
| lint: | ||||
| 	golangci-lint run ./... | ||||
|  | ||||
| build: | ||||
| 	$(GO) build -v ./... | ||||
|  | ||||
| TEST_BINARIES := test/test test/piggie/piggie test/phaul/phaul | ||||
| test-bin: $(TEST_BINARIES) | ||||
|  | ||||
| test/piggie/piggie: test/piggie/piggie.c | ||||
| 	$(CC) $^ -o $@ | ||||
|  | ||||
| test/test: test/*.go | ||||
| 	$(GO) build -v -o $@ $^ | ||||
|  | ||||
| test: $(TEST_BINARIES) | ||||
| 	mkdir -p image | ||||
| 	PID=$$(test/piggie/piggie) && { \ | ||||
| 	test/test dump $$PID image && \ | ||||
| 	test/test restore image; \ | ||||
| 	pkill -9 piggie; \ | ||||
| 	} | ||||
| 	rm -rf image | ||||
|  | ||||
| test/phaul/phaul: test/phaul/*.go | ||||
| 	$(GO) build -v -o $@ $^ | ||||
|  | ||||
| phaul-test: $(TEST_BINARIES) | ||||
| 	rm -rf image | ||||
| 	PID=$$(test/piggie/piggie) && { \ | ||||
| 	test/phaul/phaul $$PID; \ | ||||
| 	pkill -9 piggie; \ | ||||
| 	} | ||||
|  | ||||
| clean: | ||||
| 	@rm -f $(TEST_BINARIES) | ||||
| 	@rm -rf image | ||||
| 	@rm -f rpc/rpc.proto stats/stats.proto | ||||
|  | ||||
| rpc/rpc.proto: | ||||
| 	curl -sSL https://raw.githubusercontent.com/checkpoint-restore/criu/master/images/rpc.proto -o $@ | ||||
|  | ||||
| stats/stats.proto: | ||||
| 	curl -sSL https://raw.githubusercontent.com/checkpoint-restore/criu/master/images/stats.proto -o $@ | ||||
|  | ||||
| rpc/rpc.pb.go: rpc/rpc.proto | ||||
| 	protoc --go_out=. $^ | ||||
|  | ||||
| stats/stats.pb.go: stats/stats.proto | ||||
| 	protoc --go_out=. $^ | ||||
|  | ||||
| .PHONY: build test phaul-test test-bin clean lint | ||||
							
								
								
									
										9
									
								
								vendor/github.com/checkpoint-restore/go-criu/v5/go.mod
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								vendor/github.com/checkpoint-restore/go-criu/v5/go.mod
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,9 +0,0 @@ | ||||
| module github.com/checkpoint-restore/go-criu/v5 | ||||
|  | ||||
| go 1.13 | ||||
|  | ||||
| require ( | ||||
| 	github.com/golang/protobuf v1.4.3 | ||||
| 	golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c | ||||
| 	google.golang.org/protobuf v1.23.0 | ||||
| ) | ||||
							
								
								
									
										22
									
								
								vendor/github.com/checkpoint-restore/go-criu/v5/go.sum
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										22
									
								
								vendor/github.com/checkpoint-restore/go-criu/v5/go.sum
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,22 +0,0 @@ | ||||
| github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= | ||||
| github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= | ||||
| github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= | ||||
| github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= | ||||
| github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= | ||||
| github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= | ||||
| github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= | ||||
| github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | ||||
| github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | ||||
| github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= | ||||
| github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| 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/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= | ||||
| golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||||
| google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= | ||||
| google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= | ||||
| google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= | ||||
| google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= | ||||
| google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= | ||||
| google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= | ||||
| google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= | ||||
							
								
								
									
										2208
									
								
								vendor/github.com/checkpoint-restore/go-criu/v5/rpc/rpc.pb.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2208
									
								
								vendor/github.com/checkpoint-restore/go-criu/v5/rpc/rpc.pb.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										29
									
								
								vendor/github.com/cilium/ebpf/.golangci.yaml
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										29
									
								
								vendor/github.com/cilium/ebpf/.golangci.yaml
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,29 +0,0 @@ | ||||
| --- | ||||
| issues: | ||||
|   exclude-rules: | ||||
|     # syscall param structs will have unused fields in Go code. | ||||
|     - path: syscall.*.go | ||||
|       linters: | ||||
|         - structcheck | ||||
|  | ||||
| linters: | ||||
|   disable-all: true | ||||
|   enable: | ||||
|     - deadcode | ||||
|     - errcheck | ||||
|     - goimports | ||||
|     - gosimple | ||||
|     - govet | ||||
|     - ineffassign | ||||
|     - misspell | ||||
|     - staticcheck | ||||
|     - structcheck | ||||
|     - typecheck | ||||
|     - unused | ||||
|     - varcheck | ||||
|  | ||||
|     # Could be enabled later: | ||||
|     # - gocyclo | ||||
|     # - prealloc | ||||
|     # - maligned | ||||
|     # - gosec | ||||
							
								
								
									
										80
									
								
								vendor/github.com/cilium/ebpf/ARCHITECTURE.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										80
									
								
								vendor/github.com/cilium/ebpf/ARCHITECTURE.md
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,80 +0,0 @@ | ||||
| Architecture of the library | ||||
| === | ||||
|  | ||||
|     ELF -> Specifications -> Objects -> Links | ||||
|  | ||||
| ELF | ||||
| --- | ||||
|  | ||||
| BPF is usually produced by using Clang to compile a subset of C. Clang outputs | ||||
| an ELF file which contains program byte code (aka BPF), but also metadata for | ||||
| maps used by the program. The metadata follows the conventions set by libbpf | ||||
| shipped with the kernel. Certain ELF sections have special meaning | ||||
| and contain structures defined by libbpf. Newer versions of clang emit | ||||
| additional metadata in BPF Type Format (aka BTF). | ||||
|  | ||||
| The library aims to be compatible with libbpf so that moving from a C toolchain | ||||
| to a Go one creates little friction. To that end, the [ELF reader](elf_reader.go) | ||||
| is tested against the Linux selftests and avoids introducing custom behaviour | ||||
| if possible. | ||||
|  | ||||
| The output of the ELF reader is a `CollectionSpec` which encodes | ||||
| all of the information contained in the ELF in a form that is easy to work with | ||||
| in Go. | ||||
|  | ||||
| ### BTF | ||||
|  | ||||
| The BPF Type Format describes more than just the types used by a BPF program. It | ||||
| includes debug aids like which source line corresponds to which instructions and | ||||
| what global variables are used. | ||||
|  | ||||
| [BTF parsing](internal/btf/) lives in a separate internal package since exposing | ||||
| it would mean an additional maintenance burden, and because the API still | ||||
| has sharp corners. The most important concept is the `btf.Type` interface, which | ||||
| also describes things that aren't really types like `.rodata` or `.bss` sections. | ||||
| `btf.Type`s can form cyclical graphs, which can easily lead to infinite loops if | ||||
| one is not careful. Hopefully a safe pattern to work with `btf.Type` emerges as | ||||
| we write more code that deals with it. | ||||
|  | ||||
| Specifications | ||||
| --- | ||||
|  | ||||
| `CollectionSpec`, `ProgramSpec` and `MapSpec` are blueprints for in-kernel | ||||
| objects and contain everything necessary to execute the relevant `bpf(2)` | ||||
| syscalls. Since the ELF reader outputs a `CollectionSpec` it's possible to | ||||
| modify clang-compiled BPF code, for example to rewrite constants. At the same | ||||
| time the [asm](asm/) package provides an assembler that can be used to generate | ||||
| `ProgramSpec` on the fly. | ||||
|  | ||||
| Creating a spec should never require any privileges or be restricted in any way, | ||||
| for example by only allowing programs in native endianness. This ensures that | ||||
| the library stays flexible. | ||||
|  | ||||
| Objects | ||||
| --- | ||||
|  | ||||
| `Program` and `Map` are the result of loading specs into the kernel. Sometimes | ||||
| 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 | ||||
|   automatically detects support for names, and omits them during load if | ||||
|   necessary. This works since name is primarily a debug aid. | ||||
|  | ||||
| * Sentinel error: sometimes it's possible to detect that a feature isn't available. | ||||
|   In that case the library will return an error wrapping `ErrNotSupported`. | ||||
|   This is also useful to skip tests that can't run on the current kernel. | ||||
|  | ||||
| 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. | ||||
|  | ||||
| Links | ||||
| --- | ||||
|  | ||||
| BPF can be attached to many different points in the kernel and newer BPF hooks | ||||
| tend to use bpf_link to do so. Older hooks unfortunately use a combination of | ||||
| syscalls, netlink messages, etc. Adding support for a new link type should not | ||||
| pull in large dependencies like netlink, so XDP programs or tracepoints are | ||||
| out of scope. | ||||
							
								
								
									
										23
									
								
								vendor/github.com/cilium/ebpf/CONTRIBUTING.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										23
									
								
								vendor/github.com/cilium/ebpf/CONTRIBUTING.md
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,23 +0,0 @@ | ||||
| # How to contribute | ||||
|  | ||||
| Development is on [GitHub](https://github.com/cilium/ebpf) and contributions in | ||||
| the form of pull requests and issues reporting bugs or suggesting new features | ||||
| 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 | ||||
| discuss the design first. | ||||
|  | ||||
| When submitting pull requests, consider writing details about what problem you | ||||
| are solving and why the proposed approach solves that problem in commit messages | ||||
| and/or pull request description to help future library users and maintainers to | ||||
| reason about the proposed changes. | ||||
|  | ||||
| ## Running the tests | ||||
|  | ||||
| Many of the tests require privileges to set resource limits and load eBPF code. | ||||
| The easiest way to obtain these is to run the tests with `sudo`: | ||||
|  | ||||
|     sudo go test ./... | ||||
							
								
								
									
										67
									
								
								vendor/github.com/cilium/ebpf/Makefile
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										67
									
								
								vendor/github.com/cilium/ebpf/Makefile
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,67 +0,0 @@ | ||||
| # The development version of clang is distributed as the 'clang' binary, | ||||
| # while stable/released versions have a version number attached. | ||||
| # Pin the default clang to a stable version. | ||||
| CLANG ?= clang-11 | ||||
| CFLAGS := -target bpf -O2 -g -Wall -Werror $(CFLAGS) | ||||
|  | ||||
| # Obtain an absolute path to the directory of the Makefile. | ||||
| # Assume the Makefile is in the root of the repository. | ||||
| REPODIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST)))) | ||||
| UIDGID := $(shell stat -c '%u:%g' ${REPODIR}) | ||||
|  | ||||
| IMAGE := $(shell cat ${REPODIR}/testdata/docker/IMAGE) | ||||
| VERSION := $(shell cat ${REPODIR}/testdata/docker/VERSION) | ||||
|  | ||||
| # clang <8 doesn't tag relocs properly (STT_NOTYPE) | ||||
| # clang 9 is the first version emitting BTF | ||||
| TARGETS := \ | ||||
| 	testdata/loader-clang-7 \ | ||||
| 	testdata/loader-clang-9 \ | ||||
| 	testdata/loader-clang-11 \ | ||||
| 	testdata/invalid_map \ | ||||
| 	testdata/raw_tracepoint \ | ||||
| 	testdata/invalid_map_static \ | ||||
| 	testdata/initialized_btf_map \ | ||||
| 	testdata/strings \ | ||||
| 	internal/btf/testdata/relocs | ||||
|  | ||||
| .PHONY: all clean docker-all docker-shell | ||||
|  | ||||
| .DEFAULT_TARGET = docker-all | ||||
|  | ||||
| # Build all ELF binaries using a Dockerized LLVM toolchain. | ||||
| docker-all: | ||||
| 	docker run --rm --user "${UIDGID}" \ | ||||
| 		-v "${REPODIR}":/ebpf -w /ebpf --env MAKEFLAGS \ | ||||
| 		"${IMAGE}:${VERSION}" \ | ||||
| 		make all | ||||
|  | ||||
| # (debug) Drop the user into a shell inside the Docker container as root. | ||||
| docker-shell: | ||||
| 	docker run --rm -ti \ | ||||
| 		-v "${REPODIR}":/ebpf -w /ebpf \ | ||||
| 		"${IMAGE}:${VERSION}" | ||||
|  | ||||
| clean: | ||||
| 	-$(RM) testdata/*.elf | ||||
| 	-$(RM) internal/btf/testdata/*.elf | ||||
|  | ||||
| all: $(addsuffix -el.elf,$(TARGETS)) $(addsuffix -eb.elf,$(TARGETS)) | ||||
|  | ||||
| testdata/loader-%-el.elf: testdata/loader.c | ||||
| 	$* $(CFLAGS) -mlittle-endian -c $< -o $@ | ||||
|  | ||||
| testdata/loader-%-eb.elf: testdata/loader.c | ||||
| 	$* $(CFLAGS) -mbig-endian -c $< -o $@ | ||||
|  | ||||
| %-el.elf: %.c | ||||
| 	$(CLANG) $(CFLAGS) -mlittle-endian -c $< -o $@ | ||||
|  | ||||
| %-eb.elf : %.c | ||||
| 	$(CLANG) $(CFLAGS) -mbig-endian -c $< -o $@ | ||||
|  | ||||
| # Usage: make VMLINUX=/path/to/vmlinux vmlinux-btf | ||||
| .PHONY: vmlinux-btf | ||||
| vmlinux-btf: internal/btf/testdata/vmlinux-btf.gz | ||||
| internal/btf/testdata/vmlinux-btf.gz: $(VMLINUX) | ||||
| 	objcopy --dump-section .BTF=/dev/stdout "$<" /dev/null | gzip > "$@" | ||||
							
								
								
									
										62
									
								
								vendor/github.com/cilium/ebpf/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										62
									
								
								vendor/github.com/cilium/ebpf/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,62 +0,0 @@ | ||||
| # eBPF | ||||
|  | ||||
| [](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. | ||||
|  | ||||
| ## 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. | ||||
|  | ||||
| ## Getting Started | ||||
|  | ||||
| A small collection of Go and eBPF programs that serve as examples for building | ||||
| 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. | ||||
|  | ||||
| ## 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) | ||||
|  | ||||
| ## Regenerating Testdata | ||||
|  | ||||
| Run `make` in the root of this repository to rebuild testdata in all | ||||
| subpackages. This requires Docker, as it relies on a standardized build | ||||
| environment to keep the build output stable. | ||||
|  | ||||
| The toolchain image build files are kept in [testdata/docker/](testdata/docker/). | ||||
|  | ||||
| ## License | ||||
|  | ||||
| MIT | ||||
							
								
								
									
										200
									
								
								vendor/github.com/cilium/ebpf/abi.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										200
									
								
								vendor/github.com/cilium/ebpf/abi.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,200 @@ | ||||
| package ebpf | ||||
|  | ||||
| import ( | ||||
| 	"bufio" | ||||
| 	"bytes" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"os" | ||||
| 	"syscall" | ||||
|  | ||||
| 	"github.com/cilium/ebpf/internal" | ||||
| ) | ||||
|  | ||||
| // MapABI are the attributes of a Map which are available across all supported kernels. | ||||
| type MapABI struct { | ||||
| 	Type       MapType | ||||
| 	KeySize    uint32 | ||||
| 	ValueSize  uint32 | ||||
| 	MaxEntries uint32 | ||||
| 	Flags      uint32 | ||||
| } | ||||
|  | ||||
| func newMapABIFromSpec(spec *MapSpec) *MapABI { | ||||
| 	return &MapABI{ | ||||
| 		spec.Type, | ||||
| 		spec.KeySize, | ||||
| 		spec.ValueSize, | ||||
| 		spec.MaxEntries, | ||||
| 		spec.Flags, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func newMapABIFromFd(fd *internal.FD) (string, *MapABI, error) { | ||||
| 	info, err := bpfGetMapInfoByFD(fd) | ||||
| 	if err != nil { | ||||
| 		if errors.Is(err, syscall.EINVAL) { | ||||
| 			abi, err := newMapABIFromProc(fd) | ||||
| 			return "", abi, err | ||||
| 		} | ||||
| 		return "", nil, err | ||||
| 	} | ||||
|  | ||||
| 	return "", &MapABI{ | ||||
| 		MapType(info.mapType), | ||||
| 		info.keySize, | ||||
| 		info.valueSize, | ||||
| 		info.maxEntries, | ||||
| 		info.flags, | ||||
| 	}, nil | ||||
| } | ||||
|  | ||||
| func newMapABIFromProc(fd *internal.FD) (*MapABI, error) { | ||||
| 	var abi MapABI | ||||
| 	err := scanFdInfo(fd, map[string]interface{}{ | ||||
| 		"map_type":    &abi.Type, | ||||
| 		"key_size":    &abi.KeySize, | ||||
| 		"value_size":  &abi.ValueSize, | ||||
| 		"max_entries": &abi.MaxEntries, | ||||
| 		"map_flags":   &abi.Flags, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return &abi, nil | ||||
| } | ||||
|  | ||||
| // Equal returns true if two ABIs have the same values. | ||||
| func (abi *MapABI) Equal(other *MapABI) bool { | ||||
| 	switch { | ||||
| 	case abi.Type != other.Type: | ||||
| 		return false | ||||
| 	case abi.KeySize != other.KeySize: | ||||
| 		return false | ||||
| 	case abi.ValueSize != other.ValueSize: | ||||
| 		return false | ||||
| 	case abi.MaxEntries != other.MaxEntries: | ||||
| 		return false | ||||
| 	case abi.Flags != other.Flags: | ||||
| 		return false | ||||
| 	default: | ||||
| 		return true | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // ProgramABI are the attributes of a Program which are available across all supported kernels. | ||||
| type ProgramABI struct { | ||||
| 	Type ProgramType | ||||
| } | ||||
|  | ||||
| func newProgramABIFromFd(fd *internal.FD) (string, *ProgramABI, error) { | ||||
| 	info, err := bpfGetProgInfoByFD(fd) | ||||
| 	if err != nil { | ||||
| 		if errors.Is(err, syscall.EINVAL) { | ||||
| 			return newProgramABIFromProc(fd) | ||||
| 		} | ||||
|  | ||||
| 		return "", nil, err | ||||
| 	} | ||||
|  | ||||
| 	var name string | ||||
| 	if bpfName := internal.CString(info.name[:]); bpfName != "" { | ||||
| 		name = bpfName | ||||
| 	} else { | ||||
| 		name = internal.CString(info.tag[:]) | ||||
| 	} | ||||
|  | ||||
| 	return name, &ProgramABI{ | ||||
| 		Type: ProgramType(info.progType), | ||||
| 	}, nil | ||||
| } | ||||
|  | ||||
| func newProgramABIFromProc(fd *internal.FD) (string, *ProgramABI, error) { | ||||
| 	var ( | ||||
| 		abi  ProgramABI | ||||
| 		name string | ||||
| 	) | ||||
|  | ||||
| 	err := scanFdInfo(fd, map[string]interface{}{ | ||||
| 		"prog_type": &abi.Type, | ||||
| 		"prog_tag":  &name, | ||||
| 	}) | ||||
| 	if errors.Is(err, errMissingFields) { | ||||
| 		return "", nil, &internal.UnsupportedFeatureError{ | ||||
| 			Name:           "reading ABI from /proc/self/fdinfo", | ||||
| 			MinimumVersion: internal.Version{4, 11, 0}, | ||||
| 		} | ||||
| 	} | ||||
| 	if err != nil { | ||||
| 		return "", nil, err | ||||
| 	} | ||||
|  | ||||
| 	return name, &abi, nil | ||||
| } | ||||
|  | ||||
| func scanFdInfo(fd *internal.FD, fields map[string]interface{}) error { | ||||
| 	raw, err := fd.Value() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	fh, err := os.Open(fmt.Sprintf("/proc/self/fdinfo/%d", raw)) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	defer fh.Close() | ||||
|  | ||||
| 	if err := scanFdInfoReader(fh, fields); err != nil { | ||||
| 		return fmt.Errorf("%s: %w", fh.Name(), err) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| var errMissingFields = errors.New("missing fields") | ||||
|  | ||||
| func scanFdInfoReader(r io.Reader, fields map[string]interface{}) error { | ||||
| 	var ( | ||||
| 		scanner = bufio.NewScanner(r) | ||||
| 		scanned int | ||||
| 	) | ||||
|  | ||||
| 	for scanner.Scan() { | ||||
| 		parts := bytes.SplitN(scanner.Bytes(), []byte("\t"), 2) | ||||
| 		if len(parts) != 2 { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		name := bytes.TrimSuffix(parts[0], []byte(":")) | ||||
| 		field, ok := fields[string(name)] | ||||
| 		if !ok { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		if n, err := fmt.Fscanln(bytes.NewReader(parts[1]), field); err != nil || n != 1 { | ||||
| 			return fmt.Errorf("can't parse field %s: %v", name, err) | ||||
| 		} | ||||
|  | ||||
| 		scanned++ | ||||
| 	} | ||||
|  | ||||
| 	if err := scanner.Err(); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	if scanned != len(fields) { | ||||
| 		return errMissingFields | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Equal returns true if two ABIs have the same values. | ||||
| func (abi *ProgramABI) Equal(other *ProgramABI) bool { | ||||
| 	switch { | ||||
| 	case abi.Type != other.Type: | ||||
| 		return false | ||||
| 	default: | ||||
| 		return true | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										2
									
								
								vendor/github.com/cilium/ebpf/asm/func.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/cilium/ebpf/asm/func.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -7,7 +7,7 @@ type BuiltinFunc int32 | ||||
|  | ||||
| // eBPF built-in functions | ||||
| // | ||||
| // You can regenerate this list using the following gawk script: | ||||
| // You can renegerate this list using the following gawk script: | ||||
| // | ||||
| //    /FN\(.+\),/ { | ||||
| //      match($1, /\((.+)\)/, r) | ||||
|   | ||||
							
								
								
									
										31
									
								
								vendor/github.com/cilium/ebpf/asm/instruction.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										31
									
								
								vendor/github.com/cilium/ebpf/asm/instruction.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,16 +1,12 @@ | ||||
| package asm | ||||
|  | ||||
| import ( | ||||
| 	"crypto/sha1" | ||||
| 	"encoding/binary" | ||||
| 	"encoding/hex" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"math" | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/cilium/ebpf/internal/unix" | ||||
| ) | ||||
|  | ||||
| // InstructionSize is the size of a BPF instruction in bytes | ||||
| @@ -163,9 +159,6 @@ func (ins *Instruction) mapOffset() uint32 { | ||||
| 	return uint32(uint64(ins.Constant) >> 32) | ||||
| } | ||||
|  | ||||
| // isLoadFromMap returns true if the instruction loads from a map. | ||||
| // | ||||
| // This covers both loading the map pointer and direct map value loads. | ||||
| func (ins *Instruction) isLoadFromMap() bool { | ||||
| 	return ins.OpCode == LoadImmOp(DWord) && (ins.Src == PseudoMapFD || ins.Src == PseudoMapValue) | ||||
| } | ||||
| @@ -337,7 +330,7 @@ func (insns Instructions) ReferenceOffsets() map[string][]int { | ||||
| // You can control indentation of symbols by | ||||
| // specifying a width. Setting a precision controls the indentation of | ||||
| // instructions. | ||||
| // The default character is a tab, which can be overridden by specifying | ||||
| // The default character is a tab, which can be overriden by specifying | ||||
| // the ' ' space flag. | ||||
| func (insns Instructions) Format(f fmt.State, c rune) { | ||||
| 	if c != 's' && c != 'v' { | ||||
| @@ -382,6 +375,8 @@ func (insns Instructions) Format(f fmt.State, c rune) { | ||||
| 		} | ||||
| 		fmt.Fprintf(f, "%s%*d: %v\n", indent, offsetWidth, iter.Offset, iter.Ins) | ||||
| 	} | ||||
|  | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // Marshal encodes a BPF program into the kernel format. | ||||
| @@ -395,25 +390,6 @@ func (insns Instructions) Marshal(w io.Writer, bo binary.ByteOrder) error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Tag calculates the kernel tag for a series of instructions. | ||||
| // | ||||
| // It mirrors bpf_prog_calc_tag in the kernel and so can be compared | ||||
| // to ProgramInfo.Tag to figure out whether a loaded program matches | ||||
| // certain instructions. | ||||
| func (insns Instructions) Tag(bo binary.ByteOrder) (string, error) { | ||||
| 	h := sha1.New() | ||||
| 	for i, ins := range insns { | ||||
| 		if ins.isLoadFromMap() { | ||||
| 			ins.Constant = 0 | ||||
| 		} | ||||
| 		_, err := ins.Marshal(h, bo) | ||||
| 		if err != nil { | ||||
| 			return "", fmt.Errorf("instruction %d: %w", i, err) | ||||
| 		} | ||||
| 	} | ||||
| 	return hex.EncodeToString(h.Sum(nil)[:unix.BPF_TAG_SIZE]), nil | ||||
| } | ||||
|  | ||||
| // Iterate allows iterating a BPF program while keeping track of | ||||
| // various offsets. | ||||
| // | ||||
| @@ -441,7 +417,6 @@ func (iter *InstructionIterator) Next() bool { | ||||
| 	} | ||||
|  | ||||
| 	if iter.Ins != nil { | ||||
| 		iter.Index++ | ||||
| 		iter.Offset += RawInstructionOffset(iter.Ins.OpCode.rawInstructions()) | ||||
| 	} | ||||
| 	iter.Ins = &iter.insns[0] | ||||
|   | ||||
							
								
								
									
										309
									
								
								vendor/github.com/cilium/ebpf/collection.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										309
									
								
								vendor/github.com/cilium/ebpf/collection.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -131,11 +131,10 @@ func (cs *CollectionSpec) RewriteConstants(consts map[string]interface{}) error | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Assign the contents of a CollectionSpec to a struct. | ||||
| // Assign the contents of a collection spec 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. | ||||
| // of maps and programs in a collection spec. | ||||
| // | ||||
| // 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 | ||||
| @@ -174,61 +173,21 @@ func (cs *CollectionSpec) Assign(to interface{}) error { | ||||
| 	return assignValues(to, valueOf) | ||||
| } | ||||
|  | ||||
| // LoadAndAssign maps and programs into the kernel and assign them to a struct. | ||||
| // LoadAndAssign creates a collection from a spec, and assigns it 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. | ||||
| // | ||||
| // 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. | ||||
| // | ||||
| //    struct { | ||||
| //        Foo     *ebpf.Program `ebpf:"xdp_foo"` | ||||
| //        Bar     *ebpf.Map     `ebpf:"bar_map"` | ||||
| //        Ignored int | ||||
| //    } | ||||
| // | ||||
| // 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. | ||||
| // See Collection.Assign for details. | ||||
| func (cs *CollectionSpec) LoadAndAssign(to interface{}, opts *CollectionOptions) error { | ||||
| 	if opts == nil { | ||||
| 		opts = &CollectionOptions{} | ||||
| 	} | ||||
|  | ||||
| 	loadMap, loadProgram, done, cleanup := lazyLoadCollection(cs, opts) | ||||
| 	defer cleanup() | ||||
|  | ||||
| 	valueOf := func(typ reflect.Type, name string) (reflect.Value, error) { | ||||
| 		switch typ { | ||||
| 		case reflect.TypeOf((*Program)(nil)): | ||||
| 			p, err := loadProgram(name) | ||||
| 			if err != nil { | ||||
| 				return reflect.Value{}, err | ||||
| 			} | ||||
| 			return reflect.ValueOf(p), nil | ||||
| 		case reflect.TypeOf((*Map)(nil)): | ||||
| 			m, err := loadMap(name) | ||||
| 			if err != nil { | ||||
| 				return reflect.Value{}, err | ||||
| 			} | ||||
| 			return reflect.ValueOf(m), nil | ||||
| 		default: | ||||
| 			return reflect.Value{}, fmt.Errorf("unsupported type %s", typ) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if err := assignValues(to, valueOf); err != nil { | ||||
| 	coll, err := NewCollectionWithOptions(cs, *opts) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	defer coll.Close() | ||||
|  | ||||
| 	done() | ||||
| 	return nil | ||||
| 	return coll.Assign(to) | ||||
| } | ||||
|  | ||||
| // Collection is a collection of Programs and Maps associated | ||||
| @@ -239,75 +198,28 @@ type Collection struct { | ||||
| } | ||||
|  | ||||
| // NewCollection creates a Collection from a specification. | ||||
| // | ||||
| // Only maps referenced by at least one of the programs are initialized. | ||||
| func NewCollection(spec *CollectionSpec) (*Collection, error) { | ||||
| 	return NewCollectionWithOptions(spec, CollectionOptions{}) | ||||
| } | ||||
|  | ||||
| // NewCollectionWithOptions creates a Collection from a specification. | ||||
| func NewCollectionWithOptions(spec *CollectionSpec, opts CollectionOptions) (*Collection, error) { | ||||
| 	loadMap, loadProgram, done, cleanup := lazyLoadCollection(spec, &opts) | ||||
| 	defer cleanup() | ||||
|  | ||||
| 	for mapName := range spec.Maps { | ||||
| 		_, err := loadMap(mapName) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	for progName := range spec.Programs { | ||||
| 		_, err := loadProgram(progName) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	maps, progs := done() | ||||
| 	return &Collection{ | ||||
| 		progs, | ||||
| 		maps, | ||||
| 	}, nil | ||||
| } | ||||
|  | ||||
| type btfHandleCache map[*btf.Spec]*btf.Handle | ||||
|  | ||||
| func (btfs btfHandleCache) load(spec *btf.Spec) (*btf.Handle, error) { | ||||
| 	if btfs[spec] != nil { | ||||
| 		return btfs[spec], nil | ||||
| 	} | ||||
|  | ||||
| 	handle, err := btf.NewHandle(spec) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	btfs[spec] = handle | ||||
| 	return handle, nil | ||||
| } | ||||
|  | ||||
| func (btfs btfHandleCache) close() { | ||||
| 	for _, handle := range btfs { | ||||
| 		handle.Close() | ||||
| 	} | ||||
| } | ||||
|  | ||||
| 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(), | ||||
| ) { | ||||
| // | ||||
| // Only maps referenced by at least one of the programs are initialized. | ||||
| func NewCollectionWithOptions(spec *CollectionSpec, opts CollectionOptions) (coll *Collection, err error) { | ||||
| 	var ( | ||||
| 		maps             = make(map[string]*Map) | ||||
| 		progs            = make(map[string]*Program) | ||||
| 		btfs             = make(btfHandleCache) | ||||
| 		skipMapsAndProgs = false | ||||
| 		maps  = make(map[string]*Map) | ||||
| 		progs = make(map[string]*Program) | ||||
| 		btfs  = make(map[*btf.Spec]*btf.Handle) | ||||
| 	) | ||||
|  | ||||
| 	cleanup = func() { | ||||
| 		btfs.close() | ||||
| 	defer func() { | ||||
| 		for _, btf := range btfs { | ||||
| 			btf.Close() | ||||
| 		} | ||||
|  | ||||
| 		if skipMapsAndProgs { | ||||
| 		if err == nil { | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| @@ -318,43 +230,40 @@ func lazyLoadCollection(coll *CollectionSpec, opts *CollectionOptions) ( | ||||
| 		for _, p := range progs { | ||||
| 			p.Close() | ||||
| 		} | ||||
| 	} | ||||
| 	}() | ||||
|  | ||||
| 	done = func() (map[string]*Map, map[string]*Program) { | ||||
| 		skipMapsAndProgs = true | ||||
| 		return maps, progs | ||||
| 	} | ||||
|  | ||||
| 	loadMap = func(mapName string) (*Map, error) { | ||||
| 		if m := maps[mapName]; m != nil { | ||||
| 			return m, nil | ||||
| 	loadBTF := func(spec *btf.Spec) (*btf.Handle, error) { | ||||
| 		if btfs[spec] != nil { | ||||
| 			return btfs[spec], nil | ||||
| 		} | ||||
|  | ||||
| 		mapSpec := coll.Maps[mapName] | ||||
| 		if mapSpec == nil { | ||||
| 			return nil, fmt.Errorf("missing map %s", mapName) | ||||
| 		handle, err := btf.NewHandle(spec) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
|  | ||||
| 		m, err := newMapWithOptions(mapSpec, opts.Maps, btfs) | ||||
| 		btfs[spec] = handle | ||||
| 		return handle, nil | ||||
| 	} | ||||
|  | ||||
| 	for mapName, mapSpec := range spec.Maps { | ||||
| 		var handle *btf.Handle | ||||
| 		if mapSpec.BTF != nil { | ||||
| 			handle, err = loadBTF(btf.MapSpec(mapSpec.BTF)) | ||||
| 			if err != nil && !errors.Is(err, btf.ErrNotSupported) { | ||||
| 				return nil, err | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		m, err := newMapWithBTF(mapSpec, handle, opts.Maps) | ||||
| 		if err != nil { | ||||
| 			return nil, fmt.Errorf("map %s: %w", mapName, err) | ||||
| 		} | ||||
|  | ||||
| 		maps[mapName] = m | ||||
| 		return m, nil | ||||
| 	} | ||||
|  | ||||
| 	loadProgram = func(progName string) (*Program, error) { | ||||
| 		if prog := progs[progName]; prog != nil { | ||||
| 			return prog, nil | ||||
| 		} | ||||
|  | ||||
| 		progSpec := coll.Programs[progName] | ||||
| 		if progSpec == nil { | ||||
| 			return nil, fmt.Errorf("unknown program %s", progName) | ||||
| 		} | ||||
|  | ||||
| 		progSpec = progSpec.Copy() | ||||
| 	for progName, origProgSpec := range spec.Programs { | ||||
| 		progSpec := origProgSpec.Copy() | ||||
|  | ||||
| 		// Rewrite any reference to a valid map. | ||||
| 		for i := range progSpec.Instructions { | ||||
| @@ -370,9 +279,9 @@ func lazyLoadCollection(coll *CollectionSpec, opts *CollectionOptions) ( | ||||
| 				continue | ||||
| 			} | ||||
|  | ||||
| 			m, err := loadMap(ins.Reference) | ||||
| 			if err != nil { | ||||
| 				return nil, fmt.Errorf("program %s: %s", progName, err) | ||||
| 			m := maps[ins.Reference] | ||||
| 			if m == nil { | ||||
| 				return nil, fmt.Errorf("program %s: missing map %s", progName, ins.Reference) | ||||
| 			} | ||||
|  | ||||
| 			fd := m.FD() | ||||
| @@ -384,16 +293,25 @@ func lazyLoadCollection(coll *CollectionSpec, opts *CollectionOptions) ( | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		prog, err := newProgramWithOptions(progSpec, opts.Programs, btfs) | ||||
| 		var handle *btf.Handle | ||||
| 		if progSpec.BTF != nil { | ||||
| 			handle, err = loadBTF(btf.ProgramSpec(progSpec.BTF)) | ||||
| 			if err != nil && !errors.Is(err, btf.ErrNotSupported) { | ||||
| 				return nil, err | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		prog, err := newProgramWithBTF(progSpec, handle, opts.Programs) | ||||
| 		if err != nil { | ||||
| 			return nil, fmt.Errorf("program %s: %w", progName, err) | ||||
| 		} | ||||
|  | ||||
| 		progs[progName] = prog | ||||
| 		return prog, nil | ||||
| 	} | ||||
|  | ||||
| 	return | ||||
| 	return &Collection{ | ||||
| 		progs, | ||||
| 		maps, | ||||
| 	}, nil | ||||
| } | ||||
|  | ||||
| // LoadCollection parses an object file and converts it to a collection. | ||||
| @@ -441,8 +359,18 @@ func (coll *Collection) DetachProgram(name string) *Program { | ||||
|  | ||||
| // 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. | ||||
| // `to` must be a pointer to a struct like the following: | ||||
| // | ||||
| //    struct { | ||||
| //        Foo     *ebpf.Program `ebpf:"xdp_foo"` | ||||
| //        Bar     *ebpf.Map     `ebpf:"bar_map"` | ||||
| //        Ignored int | ||||
| //    } | ||||
| // | ||||
| // See CollectionSpec.Assign for the semantics of this function. | ||||
| // | ||||
| // DetachMap and DetachProgram is invoked for all assigned elements | ||||
| // if the function is successful. | ||||
| func (coll *Collection) Assign(to interface{}) error { | ||||
| 	assignedMaps := make(map[string]struct{}) | ||||
| 	assignedPrograms := make(map[string]struct{}) | ||||
| @@ -483,86 +411,28 @@ func (coll *Collection) Assign(to interface{}) error { | ||||
| } | ||||
|  | ||||
| func assignValues(to interface{}, valueOf func(reflect.Type, string) (reflect.Value, error)) error { | ||||
| 	type structField struct { | ||||
| 		reflect.StructField | ||||
| 		value reflect.Value | ||||
| 	} | ||||
|  | ||||
| 	var ( | ||||
| 		fields        []structField | ||||
| 		visitedTypes  = make(map[reflect.Type]bool) | ||||
| 		flattenStruct func(reflect.Value) error | ||||
| 	) | ||||
|  | ||||
| 	flattenStruct = func(structVal reflect.Value) error { | ||||
| 		structType := structVal.Type() | ||||
| 		if structType.Kind() != reflect.Struct { | ||||
| 			return fmt.Errorf("%s is not a struct", structType) | ||||
| 		} | ||||
|  | ||||
| 		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) | ||||
| 				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 err != nil { | ||||
| 				return fmt.Errorf("field %s: %s", field.Name, err) | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	toValue := reflect.ValueOf(to) | ||||
| 	if toValue.Type().Kind() != reflect.Ptr { | ||||
| 		return fmt.Errorf("%T is not a pointer to struct", to) | ||||
| 	} | ||||
|  | ||||
| 	if toValue.IsNil() { | ||||
| 		return fmt.Errorf("nil pointer to %T", to) | ||||
| 	} | ||||
|  | ||||
| 	if err := flattenStruct(toValue.Elem()); err != nil { | ||||
| 		return err | ||||
| 	v := reflect.ValueOf(to) | ||||
| 	if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct { | ||||
| 		return fmt.Errorf("%T is not a pointer to a struct", to) | ||||
| 	} | ||||
|  | ||||
| 	type elem struct { | ||||
| 		// Either *Map or *Program | ||||
| 		typ  reflect.Type | ||||
| 		name string | ||||
| 	} | ||||
|  | ||||
| 	assignedTo := make(map[elem]string) | ||||
| 	for _, field := range fields { | ||||
| 	var ( | ||||
| 		s          = v.Elem() | ||||
| 		sT         = s.Type() | ||||
| 		assignedTo = make(map[elem]string) | ||||
| 	) | ||||
| 	for i := 0; i < sT.NumField(); i++ { | ||||
| 		field := sT.Field(i) | ||||
|  | ||||
| 		name := field.Tag.Get("ebpf") | ||||
| 		if name == "" { | ||||
| 			continue | ||||
| 		} | ||||
| 		if strings.Contains(name, ",") { | ||||
| 			return fmt.Errorf("field %s: ebpf tag contains a comma", field.Name) | ||||
| 		} | ||||
| @@ -577,11 +447,12 @@ func assignValues(to interface{}, valueOf func(reflect.Type, string) (reflect.Va | ||||
| 			return fmt.Errorf("field %s: %w", field.Name, err) | ||||
| 		} | ||||
|  | ||||
| 		if !field.value.CanSet() { | ||||
| 			return fmt.Errorf("field %s: can't set value", field.Name) | ||||
| 		fieldValue := s.Field(i) | ||||
| 		if !fieldValue.CanSet() { | ||||
| 			return fmt.Errorf("can't set value of field %s", field.Name) | ||||
| 		} | ||||
|  | ||||
| 		field.value.Set(value) | ||||
| 		fieldValue.Set(value) | ||||
| 		assignedTo[e] = field.Name | ||||
| 	} | ||||
|  | ||||
|   | ||||
							
								
								
									
										725
									
								
								vendor/github.com/cilium/ebpf/elf_reader.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										725
									
								
								vendor/github.com/cilium/ebpf/elf_reader.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -18,14 +18,12 @@ import ( | ||||
| 	"github.com/cilium/ebpf/internal/unix" | ||||
| ) | ||||
|  | ||||
| // 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. | ||||
| type elfCode struct { | ||||
| 	*internal.SafeELFFile | ||||
| 	sections map[elf.SectionIndex]*elfSection | ||||
| 	license  string | ||||
| 	version  uint32 | ||||
| 	btf      *btf.Spec | ||||
| 	*elf.File | ||||
| 	symbols           []elf.Symbol | ||||
| 	symbolsPerSection map[elf.SectionIndex]map[uint64]elf.Symbol | ||||
| 	license           string | ||||
| 	version           uint32 | ||||
| } | ||||
|  | ||||
| // LoadCollectionSpec parses an ELF file into a CollectionSpec. | ||||
| @@ -45,52 +43,63 @@ func LoadCollectionSpec(file string) (*CollectionSpec, error) { | ||||
|  | ||||
| // LoadCollectionSpecFromReader parses an ELF file into a CollectionSpec. | ||||
| func LoadCollectionSpecFromReader(rd io.ReaderAt) (*CollectionSpec, error) { | ||||
| 	f, err := internal.NewSafeELFFile(rd) | ||||
| 	f, err := elf.NewFile(rd) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	defer f.Close() | ||||
|  | ||||
| 	symbols, err := f.Symbols() | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("load symbols: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	ec := &elfCode{f, symbols, symbolsPerSection(symbols), "", 0} | ||||
|  | ||||
| 	var ( | ||||
| 		licenseSection *elf.Section | ||||
| 		versionSection *elf.Section | ||||
| 		sections       = make(map[elf.SectionIndex]*elfSection) | ||||
| 		btfMaps        = make(map[elf.SectionIndex]*elf.Section) | ||||
| 		progSections   = make(map[elf.SectionIndex]*elf.Section) | ||||
| 		relSections    = make(map[elf.SectionIndex]*elf.Section) | ||||
| 		mapSections    = make(map[elf.SectionIndex]*elf.Section) | ||||
| 		dataSections   = make(map[elf.SectionIndex]*elf.Section) | ||||
| 	) | ||||
|  | ||||
| 	// This is the target of relocations generated by inline assembly. | ||||
| 	sections[elf.SHN_UNDEF] = newElfSection(new(elf.Section), undefSection) | ||||
|  | ||||
| 	// Collect all the sections we're interested in. This includes relocations | ||||
| 	// which we parse later. | ||||
| 	for i, sec := range f.Sections { | ||||
| 		idx := elf.SectionIndex(i) | ||||
|  | ||||
| 	for i, sec := range ec.Sections { | ||||
| 		switch { | ||||
| 		case strings.HasPrefix(sec.Name, "license"): | ||||
| 			licenseSection = sec | ||||
| 		case strings.HasPrefix(sec.Name, "version"): | ||||
| 			versionSection = sec | ||||
| 		case strings.HasPrefix(sec.Name, "maps"): | ||||
| 			sections[idx] = newElfSection(sec, mapSection) | ||||
| 			mapSections[elf.SectionIndex(i)] = sec | ||||
| 		case sec.Name == ".maps": | ||||
| 			sections[idx] = newElfSection(sec, btfMapSection) | ||||
| 		case sec.Name == ".bss" || sec.Name == ".data" || strings.HasPrefix(sec.Name, ".rodata"): | ||||
| 			sections[idx] = newElfSection(sec, dataSection) | ||||
| 			btfMaps[elf.SectionIndex(i)] = sec | ||||
| 		case sec.Name == ".bss" || sec.Name == ".rodata" || sec.Name == ".data": | ||||
| 			dataSections[elf.SectionIndex(i)] = sec | ||||
| 		case sec.Type == elf.SHT_REL: | ||||
| 			if int(sec.Info) >= len(ec.Sections) { | ||||
| 				return nil, fmt.Errorf("found relocation section %v for missing section %v", i, sec.Info) | ||||
| 			} | ||||
|  | ||||
| 			// Store relocations under the section index of the target | ||||
| 			relSections[elf.SectionIndex(sec.Info)] = sec | ||||
| 			idx := elf.SectionIndex(sec.Info) | ||||
| 			if relSections[idx] != nil { | ||||
| 				return nil, fmt.Errorf("section %d has multiple relocation sections", sec.Info) | ||||
| 			} | ||||
| 			relSections[idx] = sec | ||||
| 		case sec.Type == elf.SHT_PROGBITS && (sec.Flags&elf.SHF_EXECINSTR) != 0 && sec.Size > 0: | ||||
| 			sections[idx] = newElfSection(sec, programSection) | ||||
| 			progSections[elf.SectionIndex(i)] = sec | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	license, err := loadLicense(licenseSection) | ||||
| 	ec.license, err = loadLicense(licenseSection) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("load license: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	version, err := loadVersion(versionSection, f.ByteOrder) | ||||
| 	ec.version, err = loadVersion(versionSection, ec.ByteOrder) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("load version: %w", err) | ||||
| 	} | ||||
| @@ -100,90 +109,37 @@ func LoadCollectionSpecFromReader(rd io.ReaderAt) (*CollectionSpec, error) { | ||||
| 		return nil, fmt.Errorf("load BTF: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	// Assign symbols to all the sections we're interested in. | ||||
| 	symbols, err := f.Symbols() | ||||
| 	relocations, referencedSections, err := ec.loadRelocations(relSections) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("load symbols: %v", err) | ||||
| 		return nil, fmt.Errorf("load relocations: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	for _, symbol := range symbols { | ||||
| 		idx := symbol.Section | ||||
| 		symType := elf.ST_TYPE(symbol.Info) | ||||
|  | ||||
| 		section := sections[idx] | ||||
| 		if section == nil { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		// Older versions of LLVM don't tag symbols correctly, so keep | ||||
| 		// all NOTYPE ones. | ||||
| 		keep := symType == elf.STT_NOTYPE | ||||
| 		switch section.kind { | ||||
| 		case mapSection, btfMapSection, dataSection: | ||||
| 			keep = keep || symType == elf.STT_OBJECT | ||||
| 		case programSection: | ||||
| 			keep = keep || symType == elf.STT_FUNC | ||||
| 		} | ||||
| 		if !keep || symbol.Name == "" { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		section.symbols[symbol.Value] = symbol | ||||
| 	} | ||||
|  | ||||
| 	ec := &elfCode{ | ||||
| 		SafeELFFile: f, | ||||
| 		sections:    sections, | ||||
| 		license:     license, | ||||
| 		version:     version, | ||||
| 		btf:         btfSpec, | ||||
| 	} | ||||
|  | ||||
| 	// Go through relocation sections, and parse the ones for sections we're | ||||
| 	// interested in. Make sure that relocations point at valid sections. | ||||
| 	for idx, relSection := range relSections { | ||||
| 		section := sections[idx] | ||||
| 		if section == nil { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		rels, err := ec.loadRelocations(relSection, symbols) | ||||
| 		if err != nil { | ||||
| 			return nil, fmt.Errorf("relocation for section %q: %w", section.Name, err) | ||||
| 		} | ||||
|  | ||||
| 		for _, rel := range rels { | ||||
| 			target := sections[rel.Section] | ||||
| 			if target == nil { | ||||
| 				return nil, fmt.Errorf("section %q: reference to %q in section %s: %w", section.Name, rel.Name, rel.Section, ErrNotSupported) | ||||
| 			} | ||||
|  | ||||
| 			if target.Flags&elf.SHF_STRINGS > 0 { | ||||
| 				return nil, fmt.Errorf("section %q: string %q is not stack allocated: %w", section.Name, rel.Name, ErrNotSupported) | ||||
| 			} | ||||
|  | ||||
| 			target.references++ | ||||
| 		} | ||||
|  | ||||
| 		section.relocations = rels | ||||
| 	} | ||||
|  | ||||
| 	// Collect all the various ways to define maps. | ||||
| 	maps := make(map[string]*MapSpec) | ||||
| 	if err := ec.loadMaps(maps); err != nil { | ||||
| 	if err := ec.loadMaps(maps, mapSections); err != nil { | ||||
| 		return nil, fmt.Errorf("load maps: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	if err := ec.loadBTFMaps(maps); err != nil { | ||||
| 		return nil, fmt.Errorf("load BTF maps: %w", err) | ||||
| 	if len(btfMaps) > 0 { | ||||
| 		if err := ec.loadBTFMaps(maps, btfMaps, btfSpec); err != nil { | ||||
| 			return nil, fmt.Errorf("load BTF maps: %w", err) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if err := ec.loadDataSections(maps); err != nil { | ||||
| 		return nil, fmt.Errorf("load data sections: %w", err) | ||||
| 	if len(dataSections) > 0 { | ||||
| 		for idx := range dataSections { | ||||
| 			if !referencedSections[idx] { | ||||
| 				// Prune data sections which are not referenced by any | ||||
| 				// instructions. | ||||
| 				delete(dataSections, idx) | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if err := ec.loadDataSections(maps, dataSections, btfSpec); err != nil { | ||||
| 			return nil, fmt.Errorf("load data sections: %w", err) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// Finally, collect programs and link them. | ||||
| 	progs, err := ec.loadPrograms() | ||||
| 	progs, err := ec.loadPrograms(progSections, relocations, btfSpec) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("load programs: %w", err) | ||||
| 	} | ||||
| @@ -215,69 +171,33 @@ func loadVersion(sec *elf.Section, bo binary.ByteOrder) (uint32, error) { | ||||
| 	return version, nil | ||||
| } | ||||
|  | ||||
| type elfSectionKind int | ||||
|  | ||||
| const ( | ||||
| 	undefSection elfSectionKind = iota | ||||
| 	mapSection | ||||
| 	btfMapSection | ||||
| 	programSection | ||||
| 	dataSection | ||||
| ) | ||||
|  | ||||
| type elfSection struct { | ||||
| 	*elf.Section | ||||
| 	kind elfSectionKind | ||||
| 	// Offset from the start of the section to a symbol | ||||
| 	symbols map[uint64]elf.Symbol | ||||
| 	// Offset from the start of the section to a relocation, which points at | ||||
| 	// a symbol in another section. | ||||
| 	relocations map[uint64]elf.Symbol | ||||
| 	// The number of relocations pointing at this section. | ||||
| 	references int | ||||
| } | ||||
|  | ||||
| func newElfSection(section *elf.Section, kind elfSectionKind) *elfSection { | ||||
| 	return &elfSection{ | ||||
| 		section, | ||||
| 		kind, | ||||
| 		make(map[uint64]elf.Symbol), | ||||
| 		make(map[uint64]elf.Symbol), | ||||
| 		0, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (ec *elfCode) loadPrograms() (map[string]*ProgramSpec, error) { | ||||
| func (ec *elfCode) loadPrograms(progSections map[elf.SectionIndex]*elf.Section, relocations map[elf.SectionIndex]map[uint64]elf.Symbol, btfSpec *btf.Spec) (map[string]*ProgramSpec, error) { | ||||
| 	var ( | ||||
| 		progs []*ProgramSpec | ||||
| 		libs  []*ProgramSpec | ||||
| 	) | ||||
|  | ||||
| 	for _, sec := range ec.sections { | ||||
| 		if sec.kind != programSection { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		if len(sec.symbols) == 0 { | ||||
| 	for idx, sec := range progSections { | ||||
| 		syms := ec.symbolsPerSection[idx] | ||||
| 		if len(syms) == 0 { | ||||
| 			return nil, fmt.Errorf("section %v: missing symbols", sec.Name) | ||||
| 		} | ||||
|  | ||||
| 		funcSym, ok := sec.symbols[0] | ||||
| 		funcSym, ok := syms[0] | ||||
| 		if !ok { | ||||
| 			return nil, fmt.Errorf("section %v: no label at start", sec.Name) | ||||
| 		} | ||||
|  | ||||
| 		insns, length, err := ec.loadInstructions(sec) | ||||
| 		insns, length, err := ec.loadInstructions(sec, syms, relocations[idx]) | ||||
| 		if err != nil { | ||||
| 			return nil, fmt.Errorf("program %s: %w", funcSym.Name, err) | ||||
| 			return nil, fmt.Errorf("program %s: can't unmarshal instructions: %w", funcSym.Name, err) | ||||
| 		} | ||||
|  | ||||
| 		progType, attachType, progFlags, attachTo := getProgType(sec.Name) | ||||
| 		progType, attachType, attachTo := getProgType(sec.Name) | ||||
|  | ||||
| 		spec := &ProgramSpec{ | ||||
| 			Name:          funcSym.Name, | ||||
| 			Type:          progType, | ||||
| 			Flags:         progFlags, | ||||
| 			AttachType:    attachType, | ||||
| 			AttachTo:      attachTo, | ||||
| 			License:       ec.license, | ||||
| @@ -286,8 +206,8 @@ func (ec *elfCode) loadPrograms() (map[string]*ProgramSpec, error) { | ||||
| 			ByteOrder:     ec.ByteOrder, | ||||
| 		} | ||||
|  | ||||
| 		if ec.btf != nil { | ||||
| 			spec.BTF, err = ec.btf.Program(sec.Name, length) | ||||
| 		if btfSpec != nil { | ||||
| 			spec.BTF, err = btfSpec.Program(sec.Name, length) | ||||
| 			if err != nil && !errors.Is(err, btf.ErrNoExtendedInfo) { | ||||
| 				return nil, fmt.Errorf("program %s: %w", funcSym.Name, err) | ||||
| 			} | ||||
| @@ -315,7 +235,7 @@ func (ec *elfCode) loadPrograms() (map[string]*ProgramSpec, error) { | ||||
| 	return res, nil | ||||
| } | ||||
|  | ||||
| func (ec *elfCode) loadInstructions(section *elfSection) (asm.Instructions, uint64, error) { | ||||
| func (ec *elfCode) loadInstructions(section *elf.Section, symbols, relocations map[uint64]elf.Symbol) (asm.Instructions, uint64, error) { | ||||
| 	var ( | ||||
| 		r      = bufio.NewReader(section.Open()) | ||||
| 		insns  asm.Instructions | ||||
| @@ -331,11 +251,11 @@ func (ec *elfCode) loadInstructions(section *elfSection) (asm.Instructions, uint | ||||
| 			return nil, 0, fmt.Errorf("offset %d: %w", offset, err) | ||||
| 		} | ||||
|  | ||||
| 		ins.Symbol = section.symbols[offset].Name | ||||
| 		ins.Symbol = symbols[offset].Name | ||||
|  | ||||
| 		if rel, ok := section.relocations[offset]; ok { | ||||
| 		if rel, ok := relocations[offset]; ok { | ||||
| 			if err = ec.relocateInstruction(&ins, rel); err != nil { | ||||
| 				return nil, 0, fmt.Errorf("offset %d: relocate instruction: %w", offset, err) | ||||
| 				return nil, 0, fmt.Errorf("offset %d: can't relocate instruction: %w", offset, err) | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| @@ -351,66 +271,69 @@ func (ec *elfCode) relocateInstruction(ins *asm.Instruction, rel elf.Symbol) err | ||||
| 		name = rel.Name | ||||
| 	) | ||||
|  | ||||
| 	target := ec.sections[rel.Section] | ||||
|  | ||||
| 	switch target.kind { | ||||
| 	case mapSection, btfMapSection: | ||||
| 		if bind != elf.STB_GLOBAL { | ||||
| 			return fmt.Errorf("possible erroneous static qualifier on map definition: found reference to %q", name) | ||||
| 	if typ == elf.STT_SECTION { | ||||
| 		// Symbols with section type do not have a name set. Get it | ||||
| 		// from the section itself. | ||||
| 		idx := int(rel.Section) | ||||
| 		if idx > len(ec.Sections) { | ||||
| 			return errors.New("out-of-bounds section index") | ||||
| 		} | ||||
|  | ||||
| 		if typ != elf.STT_OBJECT && typ != elf.STT_NOTYPE { | ||||
| 			// STT_NOTYPE is generated on clang < 8 which doesn't tag | ||||
| 			// relocations appropriately. | ||||
| 			return fmt.Errorf("map load: incorrect relocation type %v", typ) | ||||
| 		} | ||||
| 		name = ec.Sections[idx].Name | ||||
| 	} | ||||
|  | ||||
| 		ins.Src = asm.PseudoMapFD | ||||
|  | ||||
| 		// Mark the instruction as needing an update when creating the | ||||
| 		// collection. | ||||
| 		if err := ins.RewriteMapPtr(-1); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
|  | ||||
| 	case dataSection: | ||||
| outer: | ||||
| 	switch { | ||||
| 	case ins.OpCode == asm.LoadImmOp(asm.DWord): | ||||
| 		// There are two distinct types of a load from a map: | ||||
| 		// a direct one, where the value is extracted without | ||||
| 		// a call to map_lookup_elem in eBPF, and an indirect one | ||||
| 		// that goes via the helper. They are distinguished by | ||||
| 		// different relocations. | ||||
| 		switch typ { | ||||
| 		case elf.STT_SECTION: | ||||
| 			// This is a direct load since the referenced symbol is a | ||||
| 			// section. Weirdly, the offset of the real symbol in the | ||||
| 			// section is encoded in the instruction stream. | ||||
| 			if bind != elf.STB_LOCAL { | ||||
| 				return fmt.Errorf("direct load: %s: unsupported relocation %s", name, bind) | ||||
| 			} | ||||
|  | ||||
| 		case elf.STT_OBJECT: | ||||
| 			if bind != elf.STB_GLOBAL { | ||||
| 				return fmt.Errorf("direct load: %s: unsupported relocation %s", name, bind) | ||||
| 			// For some reason, clang encodes the offset of the symbol its | ||||
| 			// section in the first basic BPF instruction, while the kernel | ||||
| 			// expects it in the second one. | ||||
| 			ins.Constant <<= 32 | ||||
| 			ins.Src = asm.PseudoMapValue | ||||
|  | ||||
| 		case elf.STT_NOTYPE: | ||||
| 			if bind == elf.STB_GLOBAL && rel.Section == elf.SHN_UNDEF { | ||||
| 				// This is a relocation generated by inline assembly. | ||||
| 				// We can't do more than assigning ins.Reference. | ||||
| 				break outer | ||||
| 			} | ||||
|  | ||||
| 			// This is an ELF generated on clang < 8, which doesn't tag | ||||
| 			// relocations appropriately. | ||||
| 			fallthrough | ||||
|  | ||||
| 		case elf.STT_OBJECT: | ||||
| 			if bind != elf.STB_GLOBAL { | ||||
| 				return fmt.Errorf("load: %s: unsupported binding: %s", name, bind) | ||||
| 			} | ||||
|  | ||||
| 			ins.Src = asm.PseudoMapFD | ||||
|  | ||||
| 		default: | ||||
| 			return fmt.Errorf("incorrect relocation type %v for direct map load", typ) | ||||
| 			return fmt.Errorf("load: %s: unsupported relocation: %s", name, typ) | ||||
| 		} | ||||
|  | ||||
| 		// We rely on using the name of the data section as the reference. It | ||||
| 		// would be nicer to keep the real name in case of an STT_OBJECT, but | ||||
| 		// it's not clear how to encode that into Instruction. | ||||
| 		name = target.Name | ||||
|  | ||||
| 		// For some reason, clang encodes the offset of the symbol its | ||||
| 		// section in the first basic BPF instruction, while the kernel | ||||
| 		// expects it in the second one. | ||||
| 		ins.Constant <<= 32 | ||||
| 		ins.Src = asm.PseudoMapValue | ||||
|  | ||||
| 		// Mark the instruction as needing an update when creating the | ||||
| 		// collection. | ||||
| 		if err := ins.RewriteMapPtr(-1); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
|  | ||||
| 	case programSection: | ||||
| 		if ins.OpCode.JumpOp() != asm.Call { | ||||
| 			return fmt.Errorf("not a call instruction: %s", ins) | ||||
| 		} | ||||
|  | ||||
| 	case ins.OpCode.JumpOp() == asm.Call: | ||||
| 		if ins.Src != asm.PseudoCall { | ||||
| 			return fmt.Errorf("call: %s: incorrect source register", name) | ||||
| 		} | ||||
| @@ -435,7 +358,7 @@ func (ec *elfCode) relocateInstruction(ins *asm.Instruction, rel elf.Symbol) err | ||||
| 				return fmt.Errorf("call: %s: invalid offset %d", name, offset) | ||||
| 			} | ||||
|  | ||||
| 			sym, ok := target.symbols[uint64(offset)] | ||||
| 			sym, ok := ec.symbolsPerSection[rel.Section][uint64(offset)] | ||||
| 			if !ok { | ||||
| 				return fmt.Errorf("call: %s: no symbol at offset %d", name, offset) | ||||
| 			} | ||||
| @@ -447,46 +370,31 @@ func (ec *elfCode) relocateInstruction(ins *asm.Instruction, rel elf.Symbol) err | ||||
| 			return fmt.Errorf("call: %s: invalid symbol type %s", name, typ) | ||||
| 		} | ||||
|  | ||||
| 	case undefSection: | ||||
| 		if bind != elf.STB_GLOBAL { | ||||
| 			return fmt.Errorf("asm relocation: %s: unsupported binding: %s", name, bind) | ||||
| 		} | ||||
|  | ||||
| 		if typ != elf.STT_NOTYPE { | ||||
| 			return fmt.Errorf("asm relocation: %s: unsupported type %s", name, typ) | ||||
| 		} | ||||
|  | ||||
| 		// There is nothing to do here but set ins.Reference. | ||||
|  | ||||
| 	default: | ||||
| 		return fmt.Errorf("relocation to %q: %w", target.Name, ErrNotSupported) | ||||
| 		return fmt.Errorf("relocation for unsupported instruction: %s", ins.OpCode) | ||||
| 	} | ||||
|  | ||||
| 	ins.Reference = name | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (ec *elfCode) loadMaps(maps map[string]*MapSpec) error { | ||||
| 	for _, sec := range ec.sections { | ||||
| 		if sec.kind != mapSection { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		nSym := len(sec.symbols) | ||||
| 		if nSym == 0 { | ||||
| func (ec *elfCode) loadMaps(maps map[string]*MapSpec, mapSections map[elf.SectionIndex]*elf.Section) error { | ||||
| 	for idx, sec := range mapSections { | ||||
| 		syms := ec.symbolsPerSection[idx] | ||||
| 		if len(syms) == 0 { | ||||
| 			return fmt.Errorf("section %v: no symbols", sec.Name) | ||||
| 		} | ||||
|  | ||||
| 		if sec.Size%uint64(nSym) != 0 { | ||||
| 		if sec.Size%uint64(len(syms)) != 0 { | ||||
| 			return fmt.Errorf("section %v: map descriptors are not of equal size", sec.Name) | ||||
| 		} | ||||
|  | ||||
| 		var ( | ||||
| 			r    = bufio.NewReader(sec.Open()) | ||||
| 			size = sec.Size / uint64(nSym) | ||||
| 			size = sec.Size / uint64(len(syms)) | ||||
| 		) | ||||
| 		for i, offset := 0, uint64(0); i < nSym; i, offset = i+1, offset+size { | ||||
| 			mapSym, ok := sec.symbols[offset] | ||||
| 		for i, offset := 0, uint64(0); i < len(syms); i, offset = i+1, offset+size { | ||||
| 			mapSym, ok := syms[offset] | ||||
| 			if !ok { | ||||
| 				return fmt.Errorf("section %s: missing symbol for map at offset %d", sec.Name, offset) | ||||
| 			} | ||||
| @@ -524,43 +432,24 @@ func (ec *elfCode) loadMaps(maps map[string]*MapSpec) error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (ec *elfCode) loadBTFMaps(maps map[string]*MapSpec) error { | ||||
| 	for _, sec := range ec.sections { | ||||
| 		if sec.kind != btfMapSection { | ||||
| 			continue | ||||
| func (ec *elfCode) loadBTFMaps(maps map[string]*MapSpec, mapSections map[elf.SectionIndex]*elf.Section, spec *btf.Spec) error { | ||||
| 	if spec == nil { | ||||
| 		return fmt.Errorf("missing BTF") | ||||
| 	} | ||||
|  | ||||
| 	for idx, sec := range mapSections { | ||||
| 		syms := ec.symbolsPerSection[idx] | ||||
| 		if len(syms) == 0 { | ||||
| 			return fmt.Errorf("section %v: no symbols", sec.Name) | ||||
| 		} | ||||
|  | ||||
| 		if ec.btf == nil { | ||||
| 			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 | ||||
| 		if err := ec.btf.FindType(sec.Name, &ds); err != nil { | ||||
| 			return fmt.Errorf("cannot find section '%s' in BTF: %w", sec.Name, err) | ||||
| 		} | ||||
|  | ||||
| 		for _, vs := range ds.Vars { | ||||
| 			v, ok := vs.Type.(*btf.Var) | ||||
| 			if !ok { | ||||
| 				return fmt.Errorf("section %v: unexpected type %s", sec.Name, vs.Type) | ||||
| 			} | ||||
| 			name := string(v.Name) | ||||
|  | ||||
| 		for _, sym := range syms { | ||||
| 			name := sym.Name | ||||
| 			if maps[name] != nil { | ||||
| 				return fmt.Errorf("section %v: map %s already exists", sec.Name, name) | ||||
| 				return fmt.Errorf("section %v: map %v already exists", sec.Name, sym) | ||||
| 			} | ||||
|  | ||||
| 			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(spec, name) | ||||
| 			if err != nil { | ||||
| 				return fmt.Errorf("map %v: %w", name, err) | ||||
| 			} | ||||
| @@ -572,21 +461,31 @@ func (ec *elfCode) loadBTFMaps(maps map[string]*MapSpec) error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // 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(spec *btf.Spec, name string) (*MapSpec, error) { | ||||
| 	btfMap, btfMapMembers, err := spec.Map(name) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("can't get BTF: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	keyType := btf.MapKey(btfMap) | ||||
| 	size, err := btf.Sizeof(keyType) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("can't get size of BTF key: %w", err) | ||||
| 	} | ||||
| 	keySize := uint32(size) | ||||
|  | ||||
| 	valueType := btf.MapValue(btfMap) | ||||
| 	size, err = btf.Sizeof(valueType) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("can't get size of BTF value: %w", err) | ||||
| 	} | ||||
| 	valueSize := uint32(size) | ||||
|  | ||||
| 	var ( | ||||
| 		key, value                 btf.Type | ||||
| 		keySize, valueSize         uint32 | ||||
| 		mapType, flags, maxEntries uint32 | ||||
| 		pinType                    PinType | ||||
| 		innerMapSpec               *MapSpec | ||||
| 		err                        error | ||||
| 	) | ||||
|  | ||||
| 	for i, member := range def.Members { | ||||
| 	for _, member := range btfMapMembers { | ||||
| 		switch member.Name { | ||||
| 		case "type": | ||||
| 			mapType, err = uintFromBTF(member.Type) | ||||
| @@ -606,48 +505,8 @@ func mapSpecFromBTF(name string, def *btf.Struct, inner bool, spec *btf.Spec) (* | ||||
| 				return nil, fmt.Errorf("can't get BTF map max entries: %w", err) | ||||
| 			} | ||||
|  | ||||
| 		case "key": | ||||
| 			if keySize != 0 { | ||||
| 				return nil, errors.New("both key and key_size given") | ||||
| 			} | ||||
|  | ||||
| 			pk, ok := member.Type.(*btf.Pointer) | ||||
| 			if !ok { | ||||
| 				return nil, fmt.Errorf("key type is not a pointer: %T", member.Type) | ||||
| 			} | ||||
|  | ||||
| 			key = pk.Target | ||||
|  | ||||
| 			size, err := btf.Sizeof(pk.Target) | ||||
| 			if err != nil { | ||||
| 				return nil, fmt.Errorf("can't get size of BTF key: %w", err) | ||||
| 			} | ||||
|  | ||||
| 			keySize = uint32(size) | ||||
|  | ||||
| 		case "value": | ||||
| 			if valueSize != 0 { | ||||
| 				return nil, errors.New("both value and value_size given") | ||||
| 			} | ||||
|  | ||||
| 			vk, ok := member.Type.(*btf.Pointer) | ||||
| 			if !ok { | ||||
| 				return nil, fmt.Errorf("value type is not a pointer: %T", member.Type) | ||||
| 			} | ||||
|  | ||||
| 			value = vk.Target | ||||
|  | ||||
| 			size, err := btf.Sizeof(vk.Target) | ||||
| 			if err != nil { | ||||
| 				return nil, fmt.Errorf("can't get size of BTF value: %w", err) | ||||
| 			} | ||||
|  | ||||
| 			valueSize = uint32(size) | ||||
|  | ||||
| 		case "key_size": | ||||
| 			// Key needs to be nil and keySize needs to be 0 for key_size to be | ||||
| 			// considered a valid member. | ||||
| 			if key != nil || keySize != 0 { | ||||
| 			if _, isVoid := keyType.(*btf.Void); !isVoid { | ||||
| 				return nil, errors.New("both key and key_size given") | ||||
| 			} | ||||
|  | ||||
| @@ -657,9 +516,7 @@ func mapSpecFromBTF(name string, def *btf.Struct, inner bool, spec *btf.Spec) (* | ||||
| 			} | ||||
|  | ||||
| 		case "value_size": | ||||
| 			// Value needs to be nil and valueSize needs to be 0 for value_size to be | ||||
| 			// considered a valid member. | ||||
| 			if value != nil || valueSize != 0 { | ||||
| 			if _, isVoid := valueType.(*btf.Void); !isVoid { | ||||
| 				return nil, errors.New("both value and value_size given") | ||||
| 			} | ||||
|  | ||||
| @@ -669,10 +526,6 @@ func mapSpecFromBTF(name string, def *btf.Struct, inner bool, spec *btf.Spec) (* | ||||
| 			} | ||||
|  | ||||
| 		case "pinning": | ||||
| 			if inner { | ||||
| 				return nil, errors.New("inner maps can't be pinned") | ||||
| 			} | ||||
|  | ||||
| 			pinning, err := uintFromBTF(member.Type) | ||||
| 			if err != nil { | ||||
| 				return nil, fmt.Errorf("can't get pinning: %w", err) | ||||
| @@ -680,58 +533,12 @@ func mapSpecFromBTF(name string, def *btf.Struct, inner bool, spec *btf.Spec) (* | ||||
|  | ||||
| 			pinType = PinType(pinning) | ||||
|  | ||||
| 		case "values": | ||||
| 			// The 'values' field in BTF map definitions is used for declaring map | ||||
| 			// value types that are references to other BPF objects, like other maps | ||||
| 			// or programs. It is always expected to be an array of pointers. | ||||
| 			if i != len(def.Members)-1 { | ||||
| 				return nil, errors.New("'values' must be the last member in a BTF map definition") | ||||
| 			} | ||||
|  | ||||
| 			if valueSize != 0 && valueSize != 4 { | ||||
| 				return nil, errors.New("value_size must be 0 or 4") | ||||
| 			} | ||||
| 			valueSize = 4 | ||||
|  | ||||
| 			valueType, err := resolveBTFArrayMacro(member.Type) | ||||
| 			if err != nil { | ||||
| 				return nil, fmt.Errorf("can't resolve type of member 'values': %w", err) | ||||
| 			} | ||||
|  | ||||
| 			switch t := valueType.(type) { | ||||
| 			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 { | ||||
| 					return nil, errors.New("outer map needs to be an array or a hash of maps") | ||||
| 				} | ||||
| 				if inner { | ||||
| 					return nil, fmt.Errorf("nested inner maps are not supported") | ||||
| 				} | ||||
|  | ||||
| 				// This inner map spec is used as a map template, but it needs to be | ||||
| 				// created as a traditional map before it can be used to do so. | ||||
| 				// libbpf names the inner map template '<outer_name>.inner', but we | ||||
| 				// opted for _inner to simplify validation logic. (dots only supported | ||||
| 				// 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) | ||||
| 				if err != nil { | ||||
| 					return nil, fmt.Errorf("can't parse BTF map definition of inner map: %w", err) | ||||
| 				} | ||||
|  | ||||
| 			default: | ||||
| 				return nil, fmt.Errorf("unsupported value type %q in 'values' field", t) | ||||
| 			} | ||||
|  | ||||
| 		case "key", "value": | ||||
| 		default: | ||||
| 			return nil, fmt.Errorf("unrecognized field %s in BTF map definition", member.Name) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	bm := btf.NewMap(spec, key, value) | ||||
|  | ||||
| 	return &MapSpec{ | ||||
| 		Name:       SanitizeName(name, -1), | ||||
| 		Type:       MapType(mapType), | ||||
| @@ -739,9 +546,8 @@ func mapSpecFromBTF(name string, def *btf.Struct, inner bool, spec *btf.Spec) (* | ||||
| 		ValueSize:  valueSize, | ||||
| 		MaxEntries: maxEntries, | ||||
| 		Flags:      flags, | ||||
| 		BTF:        &bm, | ||||
| 		BTF:        btfMap, | ||||
| 		Pinning:    pinType, | ||||
| 		InnerMap:   innerMapSpec, | ||||
| 	}, nil | ||||
| } | ||||
|  | ||||
| @@ -761,40 +567,13 @@ func uintFromBTF(typ btf.Type) (uint32, error) { | ||||
| 	return arr.Nelems, nil | ||||
| } | ||||
|  | ||||
| // resolveBTFArrayMacro resolves the __array macro, which declares an array | ||||
| // of pointers to a given type. This function returns the target Type of | ||||
| // the pointers in the array. | ||||
| func resolveBTFArrayMacro(typ btf.Type) (btf.Type, error) { | ||||
| 	arr, ok := typ.(*btf.Array) | ||||
| 	if !ok { | ||||
| 		return nil, fmt.Errorf("not an array: %v", typ) | ||||
| func (ec *elfCode) loadDataSections(maps map[string]*MapSpec, dataSections map[elf.SectionIndex]*elf.Section, spec *btf.Spec) error { | ||||
| 	if spec == nil { | ||||
| 		return errors.New("data sections require BTF, make sure all consts are marked as static") | ||||
| 	} | ||||
|  | ||||
| 	ptr, ok := arr.Type.(*btf.Pointer) | ||||
| 	if !ok { | ||||
| 		return nil, fmt.Errorf("not an array of pointers: %v", typ) | ||||
| 	} | ||||
|  | ||||
| 	return ptr.Target, nil | ||||
| } | ||||
|  | ||||
| func (ec *elfCode) loadDataSections(maps map[string]*MapSpec) error { | ||||
| 	for _, sec := range ec.sections { | ||||
| 		if sec.kind != dataSection { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		if sec.references == 0 { | ||||
| 			// Prune data sections which are not referenced by any | ||||
| 			// instructions. | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		if ec.btf == nil { | ||||
| 			return errors.New("data sections require BTF, make sure all consts are marked as static") | ||||
| 		} | ||||
|  | ||||
| 		btfMap, err := ec.btf.Datasec(sec.Name) | ||||
| 	for _, sec := range dataSections { | ||||
| 		btfMap, err := spec.Datasec(sec.Name) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| @@ -832,61 +611,56 @@ func (ec *elfCode) loadDataSections(maps map[string]*MapSpec) error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func getProgType(sectionName string) (ProgramType, AttachType, uint32, string) { | ||||
| func getProgType(sectionName string) (ProgramType, AttachType, string) { | ||||
| 	types := map[string]struct { | ||||
| 		progType   ProgramType | ||||
| 		attachType AttachType | ||||
| 		progFlags  uint32 | ||||
| 	}{ | ||||
| 		// From https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tools/lib/bpf/libbpf.c | ||||
| 		"socket":                {SocketFilter, AttachNone, 0}, | ||||
| 		"seccomp":               {SocketFilter, AttachNone, 0}, | ||||
| 		"kprobe/":               {Kprobe, AttachNone, 0}, | ||||
| 		"uprobe/":               {Kprobe, AttachNone, 0}, | ||||
| 		"kretprobe/":            {Kprobe, AttachNone, 0}, | ||||
| 		"uretprobe/":            {Kprobe, AttachNone, 0}, | ||||
| 		"tracepoint/":           {TracePoint, AttachNone, 0}, | ||||
| 		"raw_tracepoint/":       {RawTracepoint, AttachNone, 0}, | ||||
| 		"xdp":                   {XDP, AttachNone, 0}, | ||||
| 		"perf_event":            {PerfEvent, AttachNone, 0}, | ||||
| 		"lwt_in":                {LWTIn, AttachNone, 0}, | ||||
| 		"lwt_out":               {LWTOut, AttachNone, 0}, | ||||
| 		"lwt_xmit":              {LWTXmit, AttachNone, 0}, | ||||
| 		"lwt_seg6local":         {LWTSeg6Local, AttachNone, 0}, | ||||
| 		"sockops":               {SockOps, AttachCGroupSockOps, 0}, | ||||
| 		"sk_skb/stream_parser":  {SkSKB, AttachSkSKBStreamParser, 0}, | ||||
| 		"sk_skb/stream_verdict": {SkSKB, AttachSkSKBStreamParser, 0}, | ||||
| 		"sk_msg":                {SkMsg, AttachSkSKBStreamVerdict, 0}, | ||||
| 		"lirc_mode2":            {LircMode2, AttachLircMode2, 0}, | ||||
| 		"flow_dissector":        {FlowDissector, AttachFlowDissector, 0}, | ||||
| 		"iter/":                 {Tracing, AttachTraceIter, 0}, | ||||
| 		"fentry.s/":             {Tracing, AttachTraceFEntry, unix.BPF_F_SLEEPABLE}, | ||||
| 		"fmod_ret.s/":           {Tracing, AttachModifyReturn, unix.BPF_F_SLEEPABLE}, | ||||
| 		"fexit.s/":              {Tracing, AttachTraceFExit, unix.BPF_F_SLEEPABLE}, | ||||
| 		"sk_lookup/":            {SkLookup, AttachSkLookup, 0}, | ||||
| 		"lsm/":                  {LSM, AttachLSMMac, 0}, | ||||
| 		"lsm.s/":                {LSM, AttachLSMMac, unix.BPF_F_SLEEPABLE}, | ||||
| 		"socket":                {SocketFilter, AttachNone}, | ||||
| 		"seccomp":               {SocketFilter, AttachNone}, | ||||
| 		"kprobe/":               {Kprobe, AttachNone}, | ||||
| 		"uprobe/":               {Kprobe, AttachNone}, | ||||
| 		"kretprobe/":            {Kprobe, AttachNone}, | ||||
| 		"uretprobe/":            {Kprobe, AttachNone}, | ||||
| 		"tracepoint/":           {TracePoint, AttachNone}, | ||||
| 		"raw_tracepoint/":       {RawTracepoint, AttachNone}, | ||||
| 		"xdp":                   {XDP, AttachNone}, | ||||
| 		"perf_event":            {PerfEvent, AttachNone}, | ||||
| 		"lwt_in":                {LWTIn, AttachNone}, | ||||
| 		"lwt_out":               {LWTOut, AttachNone}, | ||||
| 		"lwt_xmit":              {LWTXmit, AttachNone}, | ||||
| 		"lwt_seg6local":         {LWTSeg6Local, AttachNone}, | ||||
| 		"sockops":               {SockOps, AttachCGroupSockOps}, | ||||
| 		"sk_skb/stream_parser":  {SkSKB, AttachSkSKBStreamParser}, | ||||
| 		"sk_skb/stream_verdict": {SkSKB, AttachSkSKBStreamParser}, | ||||
| 		"sk_msg":                {SkMsg, AttachSkSKBStreamVerdict}, | ||||
| 		"lirc_mode2":            {LircMode2, AttachLircMode2}, | ||||
| 		"flow_dissector":        {FlowDissector, AttachFlowDissector}, | ||||
| 		"iter/":                 {Tracing, AttachTraceIter}, | ||||
| 		"sk_lookup/":            {SkLookup, AttachSkLookup}, | ||||
| 		"lsm/":                  {LSM, AttachLSMMac}, | ||||
|  | ||||
| 		"cgroup_skb/ingress": {CGroupSKB, AttachCGroupInetIngress, 0}, | ||||
| 		"cgroup_skb/egress":  {CGroupSKB, AttachCGroupInetEgress, 0}, | ||||
| 		"cgroup/dev":         {CGroupDevice, AttachCGroupDevice, 0}, | ||||
| 		"cgroup/skb":         {CGroupSKB, AttachNone, 0}, | ||||
| 		"cgroup/sock":        {CGroupSock, AttachCGroupInetSockCreate, 0}, | ||||
| 		"cgroup/post_bind4":  {CGroupSock, AttachCGroupInet4PostBind, 0}, | ||||
| 		"cgroup/post_bind6":  {CGroupSock, AttachCGroupInet6PostBind, 0}, | ||||
| 		"cgroup/bind4":       {CGroupSockAddr, AttachCGroupInet4Bind, 0}, | ||||
| 		"cgroup/bind6":       {CGroupSockAddr, AttachCGroupInet6Bind, 0}, | ||||
| 		"cgroup/connect4":    {CGroupSockAddr, AttachCGroupInet4Connect, 0}, | ||||
| 		"cgroup/connect6":    {CGroupSockAddr, AttachCGroupInet6Connect, 0}, | ||||
| 		"cgroup/sendmsg4":    {CGroupSockAddr, AttachCGroupUDP4Sendmsg, 0}, | ||||
| 		"cgroup/sendmsg6":    {CGroupSockAddr, AttachCGroupUDP6Sendmsg, 0}, | ||||
| 		"cgroup/recvmsg4":    {CGroupSockAddr, AttachCGroupUDP4Recvmsg, 0}, | ||||
| 		"cgroup/recvmsg6":    {CGroupSockAddr, AttachCGroupUDP6Recvmsg, 0}, | ||||
| 		"cgroup/sysctl":      {CGroupSysctl, AttachCGroupSysctl, 0}, | ||||
| 		"cgroup/getsockopt":  {CGroupSockopt, AttachCGroupGetsockopt, 0}, | ||||
| 		"cgroup/setsockopt":  {CGroupSockopt, AttachCGroupSetsockopt, 0}, | ||||
| 		"classifier":         {SchedCLS, AttachNone, 0}, | ||||
| 		"action":             {SchedACT, AttachNone, 0}, | ||||
| 		"cgroup_skb/ingress": {CGroupSKB, AttachCGroupInetIngress}, | ||||
| 		"cgroup_skb/egress":  {CGroupSKB, AttachCGroupInetEgress}, | ||||
| 		"cgroup/dev":         {CGroupDevice, AttachCGroupDevice}, | ||||
| 		"cgroup/skb":         {CGroupSKB, AttachNone}, | ||||
| 		"cgroup/sock":        {CGroupSock, AttachCGroupInetSockCreate}, | ||||
| 		"cgroup/post_bind4":  {CGroupSock, AttachCGroupInet4PostBind}, | ||||
| 		"cgroup/post_bind6":  {CGroupSock, AttachCGroupInet6PostBind}, | ||||
| 		"cgroup/bind4":       {CGroupSockAddr, AttachCGroupInet4Bind}, | ||||
| 		"cgroup/bind6":       {CGroupSockAddr, AttachCGroupInet6Bind}, | ||||
| 		"cgroup/connect4":    {CGroupSockAddr, AttachCGroupInet4Connect}, | ||||
| 		"cgroup/connect6":    {CGroupSockAddr, AttachCGroupInet6Connect}, | ||||
| 		"cgroup/sendmsg4":    {CGroupSockAddr, AttachCGroupUDP4Sendmsg}, | ||||
| 		"cgroup/sendmsg6":    {CGroupSockAddr, AttachCGroupUDP6Sendmsg}, | ||||
| 		"cgroup/recvmsg4":    {CGroupSockAddr, AttachCGroupUDP4Recvmsg}, | ||||
| 		"cgroup/recvmsg6":    {CGroupSockAddr, AttachCGroupUDP6Recvmsg}, | ||||
| 		"cgroup/sysctl":      {CGroupSysctl, AttachCGroupSysctl}, | ||||
| 		"cgroup/getsockopt":  {CGroupSockopt, AttachCGroupGetsockopt}, | ||||
| 		"cgroup/setsockopt":  {CGroupSockopt, AttachCGroupSetsockopt}, | ||||
| 		"classifier":         {SchedCLS, AttachNone}, | ||||
| 		"action":             {SchedACT, AttachNone}, | ||||
| 	} | ||||
|  | ||||
| 	for prefix, t := range types { | ||||
| @@ -895,39 +669,78 @@ func getProgType(sectionName string) (ProgramType, AttachType, uint32, string) { | ||||
| 		} | ||||
|  | ||||
| 		if !strings.HasSuffix(prefix, "/") { | ||||
| 			return t.progType, t.attachType, t.progFlags, "" | ||||
| 			return t.progType, t.attachType, "" | ||||
| 		} | ||||
|  | ||||
| 		return t.progType, t.attachType, t.progFlags, sectionName[len(prefix):] | ||||
| 		return t.progType, t.attachType, sectionName[len(prefix):] | ||||
| 	} | ||||
|  | ||||
| 	return UnspecifiedProgram, AttachNone, 0, "" | ||||
| 	return UnspecifiedProgram, AttachNone, "" | ||||
| } | ||||
|  | ||||
| func (ec *elfCode) loadRelocations(sec *elf.Section, symbols []elf.Symbol) (map[uint64]elf.Symbol, error) { | ||||
| 	rels := make(map[uint64]elf.Symbol) | ||||
| func (ec *elfCode) loadRelocations(sections map[elf.SectionIndex]*elf.Section) (map[elf.SectionIndex]map[uint64]elf.Symbol, map[elf.SectionIndex]bool, error) { | ||||
| 	result := make(map[elf.SectionIndex]map[uint64]elf.Symbol) | ||||
| 	targets := make(map[elf.SectionIndex]bool) | ||||
| 	for idx, sec := range sections { | ||||
| 		rels := make(map[uint64]elf.Symbol) | ||||
|  | ||||
| 	if sec.Entsize < 16 { | ||||
| 		return nil, fmt.Errorf("section %s: relocations are less than 16 bytes", sec.Name) | ||||
| 	} | ||||
|  | ||||
| 	r := bufio.NewReader(sec.Open()) | ||||
| 	for off := uint64(0); off < sec.Size; off += sec.Entsize { | ||||
| 		ent := io.LimitReader(r, int64(sec.Entsize)) | ||||
|  | ||||
| 		var rel elf.Rel64 | ||||
| 		if binary.Read(ent, ec.ByteOrder, &rel) != nil { | ||||
| 			return nil, fmt.Errorf("can't parse relocation at offset %v", off) | ||||
| 		if sec.Entsize < 16 { | ||||
| 			return nil, nil, fmt.Errorf("section %s: relocations are less than 16 bytes", sec.Name) | ||||
| 		} | ||||
|  | ||||
| 		symNo := int(elf.R_SYM64(rel.Info) - 1) | ||||
| 		if symNo >= len(symbols) { | ||||
| 			return nil, fmt.Errorf("offset %d: symbol %d doesn't exist", off, symNo) | ||||
| 		r := bufio.NewReader(sec.Open()) | ||||
| 		for off := uint64(0); off < sec.Size; off += sec.Entsize { | ||||
| 			ent := io.LimitReader(r, int64(sec.Entsize)) | ||||
|  | ||||
| 			var rel elf.Rel64 | ||||
| 			if binary.Read(ent, ec.ByteOrder, &rel) != nil { | ||||
| 				return nil, nil, fmt.Errorf("can't parse relocation at offset %v", off) | ||||
| 			} | ||||
|  | ||||
| 			symNo := int(elf.R_SYM64(rel.Info) - 1) | ||||
| 			if symNo >= len(ec.symbols) { | ||||
| 				return nil, nil, fmt.Errorf("relocation at offset %d: symbol %v doesnt exist", off, symNo) | ||||
| 			} | ||||
|  | ||||
| 			symbol := ec.symbols[symNo] | ||||
| 			targets[symbol.Section] = true | ||||
| 			rels[rel.Off] = ec.symbols[symNo] | ||||
| 		} | ||||
|  | ||||
| 		symbol := symbols[symNo] | ||||
| 		rels[rel.Off] = symbol | ||||
| 		result[idx] = rels | ||||
| 	} | ||||
|  | ||||
| 	return rels, nil | ||||
| 	return result, targets, nil | ||||
| } | ||||
|  | ||||
| func symbolsPerSection(symbols []elf.Symbol) map[elf.SectionIndex]map[uint64]elf.Symbol { | ||||
| 	result := make(map[elf.SectionIndex]map[uint64]elf.Symbol) | ||||
| 	for _, sym := range symbols { | ||||
| 		switch elf.ST_TYPE(sym.Info) { | ||||
| 		case elf.STT_NOTYPE: | ||||
| 			// Older versions of LLVM doesn't tag | ||||
| 			// symbols correctly. | ||||
| 			break | ||||
| 		case elf.STT_OBJECT: | ||||
| 			break | ||||
| 		case elf.STT_FUNC: | ||||
| 			break | ||||
| 		default: | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		if sym.Section == elf.SHN_UNDEF || sym.Section >= elf.SHN_LORESERVE { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		if sym.Name == "" { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		idx := sym.Section | ||||
| 		if _, ok := result[idx]; !ok { | ||||
| 			result[idx] = make(map[uint64]elf.Symbol) | ||||
| 		} | ||||
| 		result[idx][sym.Value] = sym | ||||
| 	} | ||||
| 	return result | ||||
| } | ||||
|   | ||||
							
								
								
									
										21
									
								
								vendor/github.com/cilium/ebpf/elf_reader_fuzz.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										21
									
								
								vendor/github.com/cilium/ebpf/elf_reader_fuzz.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,21 +0,0 @@ | ||||
| // +build gofuzz | ||||
|  | ||||
| // Use with https://github.com/dvyukov/go-fuzz | ||||
|  | ||||
| package ebpf | ||||
|  | ||||
| import "bytes" | ||||
|  | ||||
| func FuzzLoadCollectionSpec(data []byte) int { | ||||
| 	spec, err := LoadCollectionSpecFromReader(bytes.NewReader(data)) | ||||
| 	if err != nil { | ||||
| 		if spec != nil { | ||||
| 			panic("spec is not nil") | ||||
| 		} | ||||
| 		return 0 | ||||
| 	} | ||||
| 	if spec == nil { | ||||
| 		panic("spec is nil") | ||||
| 	} | ||||
| 	return 1 | ||||
| } | ||||
							
								
								
									
										7
									
								
								vendor/github.com/cilium/ebpf/go.mod
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								vendor/github.com/cilium/ebpf/go.mod
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,9 +1,8 @@ | ||||
| module github.com/cilium/ebpf | ||||
|  | ||||
| go 1.15 | ||||
| go 1.14 | ||||
|  | ||||
| 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 | ||||
| 	github.com/google/go-cmp v0.5.2 | ||||
| 	golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9 | ||||
| ) | ||||
|   | ||||
							
								
								
									
										15
									
								
								vendor/github.com/cilium/ebpf/go.sum
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										15
									
								
								vendor/github.com/cilium/ebpf/go.sum
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,13 +1,6 @@ | ||||
| github.com/frankban/quicktest v1.11.3 h1:8sXhOn0uLys67V8EsXLc6eszDs8VXWxL3iRvebPhedY= | ||||
| github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= | ||||
| github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= | ||||
| github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= | ||||
| github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= | ||||
| 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= | ||||
| github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= | ||||
| github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9 h1:1/DFK4b7JH8DmkqhUk48onnSfrPzImPoVxuomtbT2nk= | ||||
| golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| 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= | ||||
|   | ||||
							
								
								
									
										239
									
								
								vendor/github.com/cilium/ebpf/info.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										239
									
								
								vendor/github.com/cilium/ebpf/info.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,239 +0,0 @@ | ||||
| package ebpf | ||||
|  | ||||
| import ( | ||||
| 	"bufio" | ||||
| 	"encoding/hex" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"os" | ||||
| 	"strings" | ||||
| 	"syscall" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/cilium/ebpf/internal" | ||||
| ) | ||||
|  | ||||
| // MapInfo describes a map. | ||||
| type MapInfo struct { | ||||
| 	Type       MapType | ||||
| 	id         MapID | ||||
| 	KeySize    uint32 | ||||
| 	ValueSize  uint32 | ||||
| 	MaxEntries uint32 | ||||
| 	Flags      uint32 | ||||
| 	// Name as supplied by user space at load time. | ||||
| 	Name string | ||||
| } | ||||
|  | ||||
| func newMapInfoFromFd(fd *internal.FD) (*MapInfo, error) { | ||||
| 	info, err := bpfGetMapInfoByFD(fd) | ||||
| 	if errors.Is(err, syscall.EINVAL) { | ||||
| 		return newMapInfoFromProc(fd) | ||||
| 	} | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return &MapInfo{ | ||||
| 		MapType(info.map_type), | ||||
| 		MapID(info.id), | ||||
| 		info.key_size, | ||||
| 		info.value_size, | ||||
| 		info.max_entries, | ||||
| 		info.map_flags, | ||||
| 		// name is available from 4.15. | ||||
| 		internal.CString(info.name[:]), | ||||
| 	}, nil | ||||
| } | ||||
|  | ||||
| func newMapInfoFromProc(fd *internal.FD) (*MapInfo, error) { | ||||
| 	var mi MapInfo | ||||
| 	err := scanFdInfo(fd, map[string]interface{}{ | ||||
| 		"map_type":    &mi.Type, | ||||
| 		"key_size":    &mi.KeySize, | ||||
| 		"value_size":  &mi.ValueSize, | ||||
| 		"max_entries": &mi.MaxEntries, | ||||
| 		"map_flags":   &mi.Flags, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return &mi, nil | ||||
| } | ||||
|  | ||||
| // ID returns the map ID. | ||||
| // | ||||
| // Available from 4.13. | ||||
| // | ||||
| // The bool return value indicates whether this optional field is available. | ||||
| func (mi *MapInfo) ID() (MapID, bool) { | ||||
| 	return mi.id, mi.id > 0 | ||||
| } | ||||
|  | ||||
| // programStats holds statistics of a program. | ||||
| type programStats struct { | ||||
| 	// Total accumulated runtime of the program ins ns. | ||||
| 	runtime time.Duration | ||||
| 	// Total number of times the program was called. | ||||
| 	runCount uint64 | ||||
| } | ||||
|  | ||||
| // ProgramInfo describes a program. | ||||
| type ProgramInfo struct { | ||||
| 	Type ProgramType | ||||
| 	id   ProgramID | ||||
| 	// Truncated hash of the BPF bytecode. | ||||
| 	Tag string | ||||
| 	// Name as supplied by user space at load time. | ||||
| 	Name string | ||||
|  | ||||
| 	stats *programStats | ||||
| } | ||||
|  | ||||
| func newProgramInfoFromFd(fd *internal.FD) (*ProgramInfo, error) { | ||||
| 	info, err := bpfGetProgInfoByFD(fd) | ||||
| 	if errors.Is(err, syscall.EINVAL) { | ||||
| 		return newProgramInfoFromProc(fd) | ||||
| 	} | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return &ProgramInfo{ | ||||
| 		Type: ProgramType(info.prog_type), | ||||
| 		id:   ProgramID(info.id), | ||||
| 		// tag is available if the kernel supports BPF_PROG_GET_INFO_BY_FD. | ||||
| 		Tag: hex.EncodeToString(info.tag[:]), | ||||
| 		// name is available from 4.15. | ||||
| 		Name: internal.CString(info.name[:]), | ||||
| 		stats: &programStats{ | ||||
| 			runtime:  time.Duration(info.run_time_ns), | ||||
| 			runCount: info.run_cnt, | ||||
| 		}, | ||||
| 	}, nil | ||||
| } | ||||
|  | ||||
| func newProgramInfoFromProc(fd *internal.FD) (*ProgramInfo, error) { | ||||
| 	var info ProgramInfo | ||||
| 	err := scanFdInfo(fd, map[string]interface{}{ | ||||
| 		"prog_type": &info.Type, | ||||
| 		"prog_tag":  &info.Tag, | ||||
| 	}) | ||||
| 	if errors.Is(err, errMissingFields) { | ||||
| 		return nil, &internal.UnsupportedFeatureError{ | ||||
| 			Name:           "reading program info from /proc/self/fdinfo", | ||||
| 			MinimumVersion: internal.Version{4, 10, 0}, | ||||
| 		} | ||||
| 	} | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return &info, nil | ||||
| } | ||||
|  | ||||
| // ID returns the program ID. | ||||
| // | ||||
| // Available from 4.13. | ||||
| // | ||||
| // The bool return value indicates whether this optional field is available. | ||||
| func (pi *ProgramInfo) ID() (ProgramID, bool) { | ||||
| 	return pi.id, pi.id > 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(). | ||||
| // The bool return value indicates whether this optional field is available. | ||||
| func (pi *ProgramInfo) RunCount() (uint64, bool) { | ||||
| 	if pi.stats != nil { | ||||
| 		return pi.stats.runCount, true | ||||
| 	} | ||||
| 	return 0, false | ||||
| } | ||||
|  | ||||
| // Runtime returns the total accumulated runtime of the program. | ||||
| // | ||||
| // Can return 0 if the collection of statistics is not enabled. See EnableStats(). | ||||
| // The bool return value indicates whether this optional field is available. | ||||
| func (pi *ProgramInfo) Runtime() (time.Duration, bool) { | ||||
| 	if pi.stats != nil { | ||||
| 		return pi.stats.runtime, true | ||||
| 	} | ||||
| 	return time.Duration(0), false | ||||
| } | ||||
|  | ||||
| func scanFdInfo(fd *internal.FD, fields map[string]interface{}) error { | ||||
| 	raw, err := fd.Value() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	fh, err := os.Open(fmt.Sprintf("/proc/self/fdinfo/%d", raw)) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	defer fh.Close() | ||||
|  | ||||
| 	if err := scanFdInfoReader(fh, fields); err != nil { | ||||
| 		return fmt.Errorf("%s: %w", fh.Name(), err) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| var errMissingFields = errors.New("missing fields") | ||||
|  | ||||
| func scanFdInfoReader(r io.Reader, fields map[string]interface{}) error { | ||||
| 	var ( | ||||
| 		scanner = bufio.NewScanner(r) | ||||
| 		scanned int | ||||
| 	) | ||||
|  | ||||
| 	for scanner.Scan() { | ||||
| 		parts := strings.SplitN(scanner.Text(), "\t", 2) | ||||
| 		if len(parts) != 2 { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		name := strings.TrimSuffix(parts[0], ":") | ||||
| 		field, ok := fields[string(name)] | ||||
| 		if !ok { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		if n, err := fmt.Sscanln(parts[1], field); err != nil || n != 1 { | ||||
| 			return fmt.Errorf("can't parse field %s: %v", name, err) | ||||
| 		} | ||||
|  | ||||
| 		scanned++ | ||||
| 	} | ||||
|  | ||||
| 	if err := scanner.Err(); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	if scanned != len(fields) { | ||||
| 		return errMissingFields | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // EnableStats starts the measuring of the runtime | ||||
| // and run counts of eBPF programs. | ||||
| // | ||||
| // Collecting statistics can have an impact on the performance. | ||||
| // | ||||
| // Requires at least 5.8. | ||||
| func EnableStats(which uint32) (io.Closer, error) { | ||||
| 	attr := internal.BPFEnableStatsAttr{ | ||||
| 		StatsType: which, | ||||
| 	} | ||||
|  | ||||
| 	fd, err := internal.BPFEnableStats(&attr) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return fd, nil | ||||
| } | ||||
							
								
								
									
										170
									
								
								vendor/github.com/cilium/ebpf/internal/btf/btf.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										170
									
								
								vendor/github.com/cilium/ebpf/internal/btf/btf.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -29,14 +29,12 @@ var ( | ||||
|  | ||||
| // Spec represents decoded BTF. | ||||
| type Spec struct { | ||||
| 	rawTypes   []rawType | ||||
| 	strings    stringTable | ||||
| 	types      []Type | ||||
| 	namedTypes map[string][]namedType | ||||
| 	funcInfos  map[string]extInfo | ||||
| 	lineInfos  map[string]extInfo | ||||
| 	coreRelos  map[string]bpfCoreRelos | ||||
| 	byteOrder  binary.ByteOrder | ||||
| 	rawTypes  []rawType | ||||
| 	strings   stringTable | ||||
| 	types     map[string][]namedType | ||||
| 	funcInfos map[string]extInfo | ||||
| 	lineInfos map[string]extInfo | ||||
| 	byteOrder binary.ByteOrder | ||||
| } | ||||
|  | ||||
| type btfHeader struct { | ||||
| @@ -55,7 +53,7 @@ type btfHeader struct { | ||||
| // | ||||
| // Returns a nil Spec and no error if no BTF was present. | ||||
| func LoadSpecFromReader(rd io.ReaderAt) (*Spec, error) { | ||||
| 	file, err := internal.NewSafeELFFile(rd) | ||||
| 	file, err := elf.NewFile(rd) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| @@ -82,10 +80,6 @@ func LoadSpecFromReader(rd io.ReaderAt) (*Spec, error) { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		if int(symbol.Section) >= len(file.Sections) { | ||||
| 			return nil, fmt.Errorf("symbol %s: invalid section %d", symbol.Name, symbol.Section) | ||||
| 		} | ||||
|  | ||||
| 		secName := file.Sections[symbol.Section].Name | ||||
| 		if _, ok := sectionSizes[secName]; !ok { | ||||
| 			continue | ||||
| @@ -107,7 +101,7 @@ func LoadSpecFromReader(rd io.ReaderAt) (*Spec, error) { | ||||
| 		return spec, nil | ||||
| 	} | ||||
|  | ||||
| 	spec.funcInfos, spec.lineInfos, spec.coreRelos, err = parseExtInfos(btfExtSection.Open(), file.ByteOrder, spec.strings) | ||||
| 	spec.funcInfos, spec.lineInfos, err = parseExtInfos(btfExtSection.Open(), file.ByteOrder, spec.strings) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("can't read ext info: %w", err) | ||||
| 	} | ||||
| @@ -115,7 +109,7 @@ func LoadSpecFromReader(rd io.ReaderAt) (*Spec, error) { | ||||
| 	return spec, nil | ||||
| } | ||||
|  | ||||
| func findBtfSections(file *internal.SafeELFFile) (*elf.Section, *elf.Section, map[string]uint32, error) { | ||||
| func findBtfSections(file *elf.File) (*elf.Section, *elf.Section, map[string]uint32, error) { | ||||
| 	var ( | ||||
| 		btfSection    *elf.Section | ||||
| 		btfExtSection *elf.Section | ||||
| @@ -144,7 +138,7 @@ func findBtfSections(file *internal.SafeELFFile) (*elf.Section, *elf.Section, ma | ||||
| } | ||||
|  | ||||
| func loadSpecFromVmlinux(rd io.ReaderAt) (*Spec, error) { | ||||
| 	file, err := internal.NewSafeELFFile(rd) | ||||
| 	file, err := elf.NewFile(rd) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| @@ -171,17 +165,16 @@ func loadNakedSpec(btf io.ReadSeeker, bo binary.ByteOrder, sectionSizes map[stri | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	types, typesByName, err := inflateRawTypes(rawTypes, rawStrings) | ||||
| 	types, err := inflateRawTypes(rawTypes, rawStrings) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return &Spec{ | ||||
| 		rawTypes:   rawTypes, | ||||
| 		namedTypes: typesByName, | ||||
| 		types:      types, | ||||
| 		strings:    rawStrings, | ||||
| 		byteOrder:  bo, | ||||
| 		rawTypes:  rawTypes, | ||||
| 		types:     types, | ||||
| 		strings:   rawStrings, | ||||
| 		byteOrder: bo, | ||||
| 	}, nil | ||||
| } | ||||
|  | ||||
| @@ -318,14 +311,10 @@ func fixupDatasec(rawTypes []rawType, rawStrings stringTable, sectionSizes map[s | ||||
| 			return err | ||||
| 		} | ||||
|  | ||||
| 		if name == ".kconfig" || name == ".ksyms" { | ||||
| 		if name == ".kconfig" || name == ".ksym" { | ||||
| 			return fmt.Errorf("reference to %s: %w", name, ErrNotSupported) | ||||
| 		} | ||||
|  | ||||
| 		if rawTypes[i].SizeType != 0 { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		size, ok := sectionSizes[name] | ||||
| 		if !ok { | ||||
| 			return fmt.Errorf("data section %s: missing size", name) | ||||
| @@ -432,19 +421,64 @@ func (s *Spec) Program(name string, length uint64) (*Program, error) { | ||||
| 		return nil, errors.New("length musn't be zero") | ||||
| 	} | ||||
|  | ||||
| 	if s.funcInfos == nil && s.lineInfos == nil && s.coreRelos == nil { | ||||
| 	if s.funcInfos == nil && s.lineInfos == nil { | ||||
| 		return nil, fmt.Errorf("BTF for section %s: %w", name, ErrNoExtendedInfo) | ||||
| 	} | ||||
|  | ||||
| 	funcInfos, funcOK := s.funcInfos[name] | ||||
| 	lineInfos, lineOK := s.lineInfos[name] | ||||
| 	coreRelos, coreOK := s.coreRelos[name] | ||||
|  | ||||
| 	if !funcOK && !lineOK && !coreOK { | ||||
| 	if !funcOK && !lineOK { | ||||
| 		return nil, fmt.Errorf("no extended BTF info for section %s", name) | ||||
| 	} | ||||
|  | ||||
| 	return &Program{s, length, funcInfos, lineInfos, coreRelos}, nil | ||||
| 	return &Program{s, length, funcInfos, lineInfos}, nil | ||||
| } | ||||
|  | ||||
| // Map finds the BTF for a map. | ||||
| // | ||||
| // Returns an error if there is no BTF for the given name. | ||||
| func (s *Spec) Map(name string) (*Map, []Member, error) { | ||||
| 	var mapVar Var | ||||
| 	if err := s.FindType(name, &mapVar); err != nil { | ||||
| 		return nil, nil, err | ||||
| 	} | ||||
|  | ||||
| 	mapStruct, ok := mapVar.Type.(*Struct) | ||||
| 	if !ok { | ||||
| 		return nil, nil, fmt.Errorf("expected struct, have %s", mapVar.Type) | ||||
| 	} | ||||
|  | ||||
| 	var key, value Type | ||||
| 	for _, member := range mapStruct.Members { | ||||
| 		switch member.Name { | ||||
| 		case "key": | ||||
| 			key = member.Type | ||||
| 			if pk, isPtr := key.(*Pointer); !isPtr { | ||||
| 				return nil, nil, fmt.Errorf("key type is not a pointer: %T", key) | ||||
| 			} else { | ||||
| 				key = pk.Target | ||||
| 			} | ||||
|  | ||||
| 		case "value": | ||||
| 			value = member.Type | ||||
| 			if vk, isPtr := value.(*Pointer); !isPtr { | ||||
| 				return nil, nil, fmt.Errorf("value type is not a pointer: %T", value) | ||||
| 			} else { | ||||
| 				value = vk.Target | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if key == nil { | ||||
| 		key = (*Void)(nil) | ||||
| 	} | ||||
|  | ||||
| 	if value == nil { | ||||
| 		value = (*Void)(nil) | ||||
| 	} | ||||
|  | ||||
| 	return &Map{s, key, value}, mapStruct.Members, nil | ||||
| } | ||||
|  | ||||
| // Datasec returns the BTF required to create maps which represent data sections. | ||||
| @@ -454,8 +488,7 @@ func (s *Spec) Datasec(name string) (*Map, error) { | ||||
| 		return nil, fmt.Errorf("data section %s: can't get BTF: %w", name, err) | ||||
| 	} | ||||
|  | ||||
| 	m := NewMap(s, &Void{}, &datasec) | ||||
| 	return &m, nil | ||||
| 	return &Map{s, &Void{}, &datasec}, nil | ||||
| } | ||||
|  | ||||
| // FindType searches for a type with a specific name. | ||||
| @@ -470,7 +503,7 @@ func (s *Spec) FindType(name string, typ Type) error { | ||||
| 		candidate Type | ||||
| 	) | ||||
|  | ||||
| 	for _, typ := range s.namedTypes[essentialName(name)] { | ||||
| 	for _, typ := range s.types[essentialName(name)] { | ||||
| 		if reflect.TypeOf(typ) != wanted { | ||||
| 			continue | ||||
| 		} | ||||
| @@ -566,23 +599,6 @@ type Map struct { | ||||
| 	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 { | ||||
| @@ -606,7 +622,6 @@ type Program struct { | ||||
| 	spec                 *Spec | ||||
| 	length               uint64 | ||||
| 	funcInfos, lineInfos extInfo | ||||
| 	coreRelos            bpfCoreRelos | ||||
| } | ||||
|  | ||||
| // ProgramSpec returns the Spec needed for loading function and line infos into the kernel. | ||||
| @@ -632,10 +647,9 @@ func ProgramAppend(s, other *Program) error { | ||||
| 		return fmt.Errorf("line infos: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	s.length += other.length | ||||
| 	s.funcInfos = funcInfos | ||||
| 	s.lineInfos = lineInfos | ||||
| 	s.coreRelos = s.coreRelos.append(other.coreRelos, s.length) | ||||
| 	s.length += other.length | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| @@ -665,19 +679,6 @@ func ProgramLineInfos(s *Program) (recordSize uint32, bytes []byte, err error) { | ||||
| 	return s.lineInfos.recordSize, bytes, nil | ||||
| } | ||||
|  | ||||
| // ProgramRelocations returns the CO-RE relocations 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 ProgramRelocations(s *Program, target *Spec) (map[uint64]Relocation, error) { | ||||
| 	if len(s.coreRelos) == 0 { | ||||
| 		return nil, nil | ||||
| 	} | ||||
|  | ||||
| 	return coreRelocate(s.spec, target, s.coreRelos) | ||||
| } | ||||
|  | ||||
| type bpfLoadBTFAttr struct { | ||||
| 	btf         internal.Pointer | ||||
| 	logBuf      internal.Pointer | ||||
| @@ -717,7 +718,7 @@ func marshalBTF(types interface{}, strings []byte, bo binary.ByteOrder) []byte { | ||||
| 	return buf.Bytes() | ||||
| } | ||||
|  | ||||
| var haveBTF = internal.FeatureTest("BTF", "5.1", func() error { | ||||
| var haveBTF = internal.FeatureTest("BTF", "5.1", func() (bool, error) { | ||||
| 	var ( | ||||
| 		types struct { | ||||
| 			Integer btfType | ||||
| @@ -741,24 +742,15 @@ var haveBTF = internal.FeatureTest("BTF", "5.1", func() error { | ||||
| 		btf:     internal.NewSlicePointer(btf), | ||||
| 		btfSize: uint32(len(btf)), | ||||
| 	}) | ||||
| 	if errors.Is(err, unix.EINVAL) || errors.Is(err, unix.EPERM) { | ||||
| 		// Treat both EINVAL and EPERM as not supported: loading the program | ||||
| 		// might still succeed without BTF. | ||||
| 		return internal.ErrNotSupported | ||||
| 	if err == nil { | ||||
| 		fd.Close() | ||||
| 	} | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	fd.Close() | ||||
| 	return nil | ||||
| 	// Check for EINVAL specifically, rather than err != nil since we | ||||
| 	// otherwise misdetect due to insufficient permissions. | ||||
| 	return !errors.Is(err, unix.EINVAL), nil | ||||
| }) | ||||
|  | ||||
| var haveFuncLinkage = internal.FeatureTest("BTF func linkage", "5.6", func() error { | ||||
| 	if err := haveBTF(); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| var haveFuncLinkage = internal.FeatureTest("BTF func linkage", "5.6", func() (bool, error) { | ||||
| 	var ( | ||||
| 		types struct { | ||||
| 			FuncProto btfType | ||||
| @@ -779,13 +771,11 @@ var haveFuncLinkage = internal.FeatureTest("BTF func linkage", "5.6", func() err | ||||
| 		btf:     internal.NewSlicePointer(btf), | ||||
| 		btfSize: uint32(len(btf)), | ||||
| 	}) | ||||
| 	if errors.Is(err, unix.EINVAL) { | ||||
| 		return internal.ErrNotSupported | ||||
| 	} | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	if err == nil { | ||||
| 		fd.Close() | ||||
| 	} | ||||
|  | ||||
| 	fd.Close() | ||||
| 	return nil | ||||
| 	// Check for EINVAL specifically, rather than err != nil since we | ||||
| 	// otherwise misdetect due to insufficient permissions. | ||||
| 	return !errors.Is(err, unix.EINVAL), nil | ||||
| }) | ||||
|   | ||||
							
								
								
									
										4
									
								
								vendor/github.com/cilium/ebpf/internal/btf/btf_types.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/cilium/ebpf/internal/btf/btf_types.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -31,14 +31,12 @@ const ( | ||||
| 	kindDatasec | ||||
| ) | ||||
|  | ||||
| // btfFuncLinkage describes BTF function linkage metadata. | ||||
| type btfFuncLinkage uint8 | ||||
|  | ||||
| // Equivalent of enum btf_func_linkage. | ||||
| const ( | ||||
| 	linkageStatic btfFuncLinkage = iota | ||||
| 	linkageGlobal | ||||
| 	// linkageExtern // Currently unused in libbpf. | ||||
| 	linkageExtern | ||||
| ) | ||||
|  | ||||
| const ( | ||||
|   | ||||
							
								
								
									
										388
									
								
								vendor/github.com/cilium/ebpf/internal/btf/core.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										388
									
								
								vendor/github.com/cilium/ebpf/internal/btf/core.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,388 +0,0 @@ | ||||
| package btf | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"reflect" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| // Code in this file is derived from libbpf, which is available under a BSD | ||||
| // 2-Clause license. | ||||
|  | ||||
| // Relocation describes a CO-RE relocation. | ||||
| type Relocation struct { | ||||
| 	Current uint32 | ||||
| 	New     uint32 | ||||
| } | ||||
|  | ||||
| func (r Relocation) equal(other Relocation) bool { | ||||
| 	return r.Current == other.Current && r.New == other.New | ||||
| } | ||||
|  | ||||
| // coreReloKind is the type of CO-RE relocation | ||||
| type coreReloKind uint32 | ||||
|  | ||||
| const ( | ||||
| 	reloFieldByteOffset coreReloKind = iota /* field byte offset */ | ||||
| 	reloFieldByteSize                       /* field size in bytes */ | ||||
| 	reloFieldExists                         /* field existence in target kernel */ | ||||
| 	reloFieldSigned                         /* field signedness (0 - unsigned, 1 - signed) */ | ||||
| 	reloFieldLShiftU64                      /* bitfield-specific left bitshift */ | ||||
| 	reloFieldRShiftU64                      /* bitfield-specific right bitshift */ | ||||
| 	reloTypeIDLocal                         /* type ID in local BPF object */ | ||||
| 	reloTypeIDTarget                        /* type ID in target kernel */ | ||||
| 	reloTypeExists                          /* type existence in target kernel */ | ||||
| 	reloTypeSize                            /* type size in bytes */ | ||||
| 	reloEnumvalExists                       /* enum value existence in target kernel */ | ||||
| 	reloEnumvalValue                        /* enum value integer value */ | ||||
| ) | ||||
|  | ||||
| func (k coreReloKind) String() string { | ||||
| 	switch k { | ||||
| 	case reloFieldByteOffset: | ||||
| 		return "byte_off" | ||||
| 	case reloFieldByteSize: | ||||
| 		return "byte_sz" | ||||
| 	case reloFieldExists: | ||||
| 		return "field_exists" | ||||
| 	case reloFieldSigned: | ||||
| 		return "signed" | ||||
| 	case reloFieldLShiftU64: | ||||
| 		return "lshift_u64" | ||||
| 	case reloFieldRShiftU64: | ||||
| 		return "rshift_u64" | ||||
| 	case reloTypeIDLocal: | ||||
| 		return "local_type_id" | ||||
| 	case reloTypeIDTarget: | ||||
| 		return "target_type_id" | ||||
| 	case reloTypeExists: | ||||
| 		return "type_exists" | ||||
| 	case reloTypeSize: | ||||
| 		return "type_size" | ||||
| 	case reloEnumvalExists: | ||||
| 		return "enumval_exists" | ||||
| 	case reloEnumvalValue: | ||||
| 		return "enumval_value" | ||||
| 	default: | ||||
| 		return "unknown" | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func coreRelocate(local, target *Spec, coreRelos bpfCoreRelos) (map[uint64]Relocation, error) { | ||||
| 	if target == nil { | ||||
| 		var err error | ||||
| 		target, err = loadKernelSpec() | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if local.byteOrder != target.byteOrder { | ||||
| 		return nil, fmt.Errorf("can't relocate %s against %s", local.byteOrder, target.byteOrder) | ||||
| 	} | ||||
|  | ||||
| 	relocations := make(map[uint64]Relocation, len(coreRelos)) | ||||
| 	for _, relo := range coreRelos { | ||||
| 		accessorStr, err := local.strings.Lookup(relo.AccessStrOff) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
|  | ||||
| 		accessor, err := parseCoreAccessor(accessorStr) | ||||
| 		if err != nil { | ||||
| 			return nil, fmt.Errorf("accessor %q: %s", accessorStr, err) | ||||
| 		} | ||||
|  | ||||
| 		if int(relo.TypeID) >= len(local.types) { | ||||
| 			return nil, fmt.Errorf("invalid type id %d", relo.TypeID) | ||||
| 		} | ||||
|  | ||||
| 		typ := local.types[relo.TypeID] | ||||
|  | ||||
| 		if relo.ReloKind == reloTypeIDLocal { | ||||
| 			relocations[uint64(relo.InsnOff)] = Relocation{ | ||||
| 				uint32(typ.ID()), | ||||
| 				uint32(typ.ID()), | ||||
| 			} | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		named, ok := typ.(namedType) | ||||
| 		if !ok || named.name() == "" { | ||||
| 			return nil, fmt.Errorf("relocate anonymous type %s: %w", typ.String(), ErrNotSupported) | ||||
| 		} | ||||
|  | ||||
| 		name := essentialName(named.name()) | ||||
| 		res, err := coreCalculateRelocation(typ, target.namedTypes[name], relo.ReloKind, accessor) | ||||
| 		if err != nil { | ||||
| 			return nil, fmt.Errorf("relocate %s: %w", name, err) | ||||
| 		} | ||||
|  | ||||
| 		relocations[uint64(relo.InsnOff)] = res | ||||
| 	} | ||||
|  | ||||
| 	return relocations, nil | ||||
| } | ||||
|  | ||||
| var errAmbiguousRelocation = errors.New("ambiguous relocation") | ||||
|  | ||||
| func coreCalculateRelocation(local Type, targets []namedType, kind coreReloKind, localAccessor coreAccessor) (Relocation, error) { | ||||
| 	var relos []Relocation | ||||
| 	var matches []Type | ||||
| 	for _, target := range targets { | ||||
| 		switch kind { | ||||
| 		case reloTypeIDTarget: | ||||
| 			if localAccessor[0] != 0 { | ||||
| 				return Relocation{}, fmt.Errorf("%s: unexpected non-zero accessor", kind) | ||||
| 			} | ||||
|  | ||||
| 			if compat, err := coreAreTypesCompatible(local, target); err != nil { | ||||
| 				return Relocation{}, fmt.Errorf("%s: %s", kind, err) | ||||
| 			} else if !compat { | ||||
| 				continue | ||||
| 			} | ||||
|  | ||||
| 			relos = append(relos, Relocation{uint32(target.ID()), uint32(target.ID())}) | ||||
|  | ||||
| 		default: | ||||
| 			return Relocation{}, fmt.Errorf("relocation %s: %w", kind, ErrNotSupported) | ||||
| 		} | ||||
| 		matches = append(matches, target) | ||||
| 	} | ||||
|  | ||||
| 	if len(relos) == 0 { | ||||
| 		// TODO: Add switch for existence checks like reloEnumvalExists here. | ||||
|  | ||||
| 		// TODO: This might have to be poisoned. | ||||
| 		return Relocation{}, fmt.Errorf("no relocation found, tried %v", targets) | ||||
| 	} | ||||
|  | ||||
| 	relo := relos[0] | ||||
| 	for _, altRelo := range relos[1:] { | ||||
| 		if !altRelo.equal(relo) { | ||||
| 			return Relocation{}, fmt.Errorf("multiple types %v match: %w", matches, errAmbiguousRelocation) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return relo, nil | ||||
| } | ||||
|  | ||||
| /* coreAccessor contains a path through a struct. It contains at least one index. | ||||
|  * | ||||
|  * The interpretation depends on the kind of the relocation. The following is | ||||
|  * taken from struct bpf_core_relo in libbpf_internal.h: | ||||
|  * | ||||
|  * - for field-based relocations, string encodes an accessed field using | ||||
|  *   a sequence of field and array indices, separated by colon (:). It's | ||||
|  *   conceptually very close to LLVM's getelementptr ([0]) instruction's | ||||
|  *   arguments for identifying offset to a field. | ||||
|  * - for type-based relocations, strings is expected to be just "0"; | ||||
|  * - for enum value-based relocations, string contains an index of enum | ||||
|  *   value within its enum type; | ||||
|  * | ||||
|  * Example to provide a better feel. | ||||
|  * | ||||
|  *   struct sample { | ||||
|  *       int a; | ||||
|  *       struct { | ||||
|  *           int b[10]; | ||||
|  *       }; | ||||
|  *   }; | ||||
|  * | ||||
|  *   struct sample s = ...; | ||||
|  *   int x = &s->a;     // encoded as "0:0" (a is field #0) | ||||
|  *   int y = &s->b[5];  // encoded as "0:1:0:5" (anon struct is field #1, | ||||
|  *                      // b is field #0 inside anon struct, accessing elem #5) | ||||
|  *   int z = &s[10]->b; // encoded as "10:1" (ptr is used as an array) | ||||
|  */ | ||||
| type coreAccessor []int | ||||
|  | ||||
| func parseCoreAccessor(accessor string) (coreAccessor, error) { | ||||
| 	if accessor == "" { | ||||
| 		return nil, fmt.Errorf("empty accessor") | ||||
| 	} | ||||
|  | ||||
| 	var result coreAccessor | ||||
| 	parts := strings.Split(accessor, ":") | ||||
| 	for _, part := range parts { | ||||
| 		// 31 bits to avoid overflowing int on 32 bit platforms. | ||||
| 		index, err := strconv.ParseUint(part, 10, 31) | ||||
| 		if err != nil { | ||||
| 			return nil, fmt.Errorf("accessor index %q: %s", part, err) | ||||
| 		} | ||||
|  | ||||
| 		result = append(result, int(index)) | ||||
| 	} | ||||
|  | ||||
| 	return result, nil | ||||
| } | ||||
|  | ||||
| /* The comment below is from bpf_core_types_are_compat in libbpf.c: | ||||
|  * | ||||
|  * Check local and target types for compatibility. This check is used for | ||||
|  * type-based CO-RE relocations and follow slightly different rules than | ||||
|  * field-based relocations. This function assumes that root types were already | ||||
|  * checked for name match. Beyond that initial root-level name check, names | ||||
|  * are completely ignored. Compatibility rules are as follows: | ||||
|  *   - any two STRUCTs/UNIONs/FWDs/ENUMs/INTs are considered compatible, but | ||||
|  *     kind should match for local and target types (i.e., STRUCT is not | ||||
|  *     compatible with UNION); | ||||
|  *   - for ENUMs, the size is ignored; | ||||
|  *   - for INT, size and signedness are ignored; | ||||
|  *   - for ARRAY, dimensionality is ignored, element types are checked for | ||||
|  *     compatibility recursively; | ||||
|  *   - CONST/VOLATILE/RESTRICT modifiers are ignored; | ||||
|  *   - TYPEDEFs/PTRs are compatible if types they pointing to are compatible; | ||||
|  *   - FUNC_PROTOs are compatible if they have compatible signature: same | ||||
|  *     number of input args and compatible return and argument types. | ||||
|  * These rules are not set in stone and probably will be adjusted as we get | ||||
|  * more experience with using BPF CO-RE relocations. | ||||
|  */ | ||||
| func coreAreTypesCompatible(localType Type, targetType Type) (bool, error) { | ||||
| 	var ( | ||||
| 		localTs, targetTs typeDeque | ||||
| 		l, t              = &localType, &targetType | ||||
| 		depth             = 0 | ||||
| 	) | ||||
|  | ||||
| 	for ; l != nil && t != nil; l, t = localTs.shift(), targetTs.shift() { | ||||
| 		if depth >= maxTypeDepth { | ||||
| 			return false, errors.New("types are nested too deep") | ||||
| 		} | ||||
|  | ||||
| 		localType = skipQualifierAndTypedef(*l) | ||||
| 		targetType = skipQualifierAndTypedef(*t) | ||||
|  | ||||
| 		if reflect.TypeOf(localType) != reflect.TypeOf(targetType) { | ||||
| 			return false, nil | ||||
| 		} | ||||
|  | ||||
| 		switch lv := (localType).(type) { | ||||
| 		case *Void, *Struct, *Union, *Enum, *Fwd: | ||||
| 			// Nothing to do here | ||||
|  | ||||
| 		case *Int: | ||||
| 			tv := targetType.(*Int) | ||||
| 			if lv.isBitfield() || tv.isBitfield() { | ||||
| 				return false, nil | ||||
| 			} | ||||
|  | ||||
| 		case *Pointer, *Array: | ||||
| 			depth++ | ||||
| 			localType.walk(&localTs) | ||||
| 			targetType.walk(&targetTs) | ||||
|  | ||||
| 		case *FuncProto: | ||||
| 			tv := targetType.(*FuncProto) | ||||
| 			if len(lv.Params) != len(tv.Params) { | ||||
| 				return false, nil | ||||
| 			} | ||||
|  | ||||
| 			depth++ | ||||
| 			localType.walk(&localTs) | ||||
| 			targetType.walk(&targetTs) | ||||
|  | ||||
| 		default: | ||||
| 			return false, fmt.Errorf("unsupported type %T", localType) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if l != nil { | ||||
| 		return false, fmt.Errorf("dangling local type %T", *l) | ||||
| 	} | ||||
|  | ||||
| 	if t != nil { | ||||
| 		return false, fmt.Errorf("dangling target type %T", *t) | ||||
| 	} | ||||
|  | ||||
| 	return true, nil | ||||
| } | ||||
|  | ||||
| /* The comment below is from bpf_core_fields_are_compat in libbpf.c: | ||||
|  * | ||||
|  * Check two types for compatibility for the purpose of field access | ||||
|  * relocation. const/volatile/restrict and typedefs are skipped to ensure we | ||||
|  * are relocating semantically compatible entities: | ||||
|  *   - any two STRUCTs/UNIONs are compatible and can be mixed; | ||||
|  *   - any two FWDs are compatible, if their names match (modulo flavor suffix); | ||||
|  *   - any two PTRs are always compatible; | ||||
|  *   - for ENUMs, names should be the same (ignoring flavor suffix) or at | ||||
|  *     least one of enums should be anonymous; | ||||
|  *   - for ENUMs, check sizes, names are ignored; | ||||
|  *   - for INT, size and signedness are ignored; | ||||
|  *   - for ARRAY, dimensionality is ignored, element types are checked for | ||||
|  *     compatibility recursively; | ||||
|  *   - everything else shouldn't be ever a target of relocation. | ||||
|  * These rules are not set in stone and probably will be adjusted as we get | ||||
|  * more experience with using BPF CO-RE relocations. | ||||
|  */ | ||||
| func coreAreMembersCompatible(localType Type, targetType Type) (bool, error) { | ||||
| 	doNamesMatch := func(a, b string) bool { | ||||
| 		if a == "" || b == "" { | ||||
| 			// allow anonymous and named type to match | ||||
| 			return true | ||||
| 		} | ||||
|  | ||||
| 		return essentialName(a) == essentialName(b) | ||||
| 	} | ||||
|  | ||||
| 	for depth := 0; depth <= maxTypeDepth; depth++ { | ||||
| 		localType = skipQualifierAndTypedef(localType) | ||||
| 		targetType = skipQualifierAndTypedef(targetType) | ||||
|  | ||||
| 		_, lok := localType.(composite) | ||||
| 		_, tok := targetType.(composite) | ||||
| 		if lok && tok { | ||||
| 			return true, nil | ||||
| 		} | ||||
|  | ||||
| 		if reflect.TypeOf(localType) != reflect.TypeOf(targetType) { | ||||
| 			return false, nil | ||||
| 		} | ||||
|  | ||||
| 		switch lv := localType.(type) { | ||||
| 		case *Pointer: | ||||
| 			return true, nil | ||||
|  | ||||
| 		case *Enum: | ||||
| 			tv := targetType.(*Enum) | ||||
| 			return doNamesMatch(lv.name(), tv.name()), nil | ||||
|  | ||||
| 		case *Fwd: | ||||
| 			tv := targetType.(*Fwd) | ||||
| 			return doNamesMatch(lv.name(), tv.name()), nil | ||||
|  | ||||
| 		case *Int: | ||||
| 			tv := targetType.(*Int) | ||||
| 			return !lv.isBitfield() && !tv.isBitfield(), nil | ||||
|  | ||||
| 		case *Array: | ||||
| 			tv := targetType.(*Array) | ||||
|  | ||||
| 			localType = lv.Type | ||||
| 			targetType = tv.Type | ||||
|  | ||||
| 		default: | ||||
| 			return false, fmt.Errorf("unsupported type %T", localType) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return false, errors.New("types are nested too deep") | ||||
| } | ||||
|  | ||||
| func skipQualifierAndTypedef(typ Type) Type { | ||||
| 	result := typ | ||||
| 	for depth := 0; depth <= maxTypeDepth; depth++ { | ||||
| 		switch v := (result).(type) { | ||||
| 		case qualifier: | ||||
| 			result = v.qualify() | ||||
| 		case *Typedef: | ||||
| 			result = v.Type | ||||
| 		default: | ||||
| 			return result | ||||
| 		} | ||||
| 	} | ||||
| 	return typ | ||||
| } | ||||
							
								
								
									
										141
									
								
								vendor/github.com/cilium/ebpf/internal/btf/ext_info.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										141
									
								
								vendor/github.com/cilium/ebpf/internal/btf/ext_info.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -25,82 +25,57 @@ type btfExtHeader struct { | ||||
| 	LineInfoLen uint32 | ||||
| } | ||||
|  | ||||
| type btfExtCoreHeader struct { | ||||
| 	CoreReloOff uint32 | ||||
| 	CoreReloLen uint32 | ||||
| } | ||||
|  | ||||
| func parseExtInfos(r io.ReadSeeker, bo binary.ByteOrder, strings stringTable) (funcInfo, lineInfo map[string]extInfo, coreRelos map[string]bpfCoreRelos, err error) { | ||||
| func parseExtInfos(r io.ReadSeeker, bo binary.ByteOrder, strings stringTable) (funcInfo, lineInfo map[string]extInfo, err error) { | ||||
| 	var header btfExtHeader | ||||
| 	var coreHeader btfExtCoreHeader | ||||
| 	if err := binary.Read(r, bo, &header); err != nil { | ||||
| 		return nil, nil, nil, fmt.Errorf("can't read header: %v", err) | ||||
| 		return nil, nil, fmt.Errorf("can't read header: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	if header.Magic != btfMagic { | ||||
| 		return nil, nil, nil, fmt.Errorf("incorrect magic value %v", header.Magic) | ||||
| 		return nil, nil, fmt.Errorf("incorrect magic value %v", header.Magic) | ||||
| 	} | ||||
|  | ||||
| 	if header.Version != 1 { | ||||
| 		return nil, nil, nil, fmt.Errorf("unexpected version %v", header.Version) | ||||
| 		return nil, nil, fmt.Errorf("unexpected version %v", header.Version) | ||||
| 	} | ||||
|  | ||||
| 	if header.Flags != 0 { | ||||
| 		return nil, nil, nil, fmt.Errorf("unsupported flags %v", header.Flags) | ||||
| 		return nil, nil, fmt.Errorf("unsupported flags %v", header.Flags) | ||||
| 	} | ||||
|  | ||||
| 	remainder := int64(header.HdrLen) - int64(binary.Size(&header)) | ||||
| 	if remainder < 0 { | ||||
| 		return nil, nil, nil, errors.New("header is too short") | ||||
| 	} | ||||
|  | ||||
| 	coreHdrSize := int64(binary.Size(&coreHeader)) | ||||
| 	if remainder >= coreHdrSize { | ||||
| 		if err := binary.Read(r, bo, &coreHeader); err != nil { | ||||
| 			return nil, nil, nil, fmt.Errorf("can't read CO-RE relocation header: %v", err) | ||||
| 		} | ||||
| 		remainder -= coreHdrSize | ||||
| 		return nil, nil, errors.New("header is too short") | ||||
| 	} | ||||
|  | ||||
| 	// 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) | ||||
| 	if err != nil { | ||||
| 		return nil, nil, nil, fmt.Errorf("header padding: %v", err) | ||||
| 		return nil, nil, fmt.Errorf("header padding: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	if _, err := r.Seek(int64(header.HdrLen+header.FuncInfoOff), io.SeekStart); err != nil { | ||||
| 		return nil, nil, nil, fmt.Errorf("can't seek to function info section: %v", err) | ||||
| 		return nil, nil, fmt.Errorf("can't seek to function info section: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	buf := bufio.NewReader(io.LimitReader(r, int64(header.FuncInfoLen))) | ||||
| 	funcInfo, err = parseExtInfo(buf, bo, strings) | ||||
| 	if err != nil { | ||||
| 		return nil, nil, nil, fmt.Errorf("function info: %w", err) | ||||
| 		return nil, nil, fmt.Errorf("function info: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	if _, err := r.Seek(int64(header.HdrLen+header.LineInfoOff), io.SeekStart); err != nil { | ||||
| 		return nil, nil, nil, fmt.Errorf("can't seek to line info section: %v", err) | ||||
| 		return nil, nil, fmt.Errorf("can't seek to line info section: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	buf = bufio.NewReader(io.LimitReader(r, int64(header.LineInfoLen))) | ||||
| 	lineInfo, err = parseExtInfo(buf, bo, strings) | ||||
| 	if err != nil { | ||||
| 		return nil, nil, nil, fmt.Errorf("line info: %w", err) | ||||
| 		return nil, nil, fmt.Errorf("line info: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	if coreHeader.CoreReloOff > 0 && coreHeader.CoreReloLen > 0 { | ||||
| 		if _, err := r.Seek(int64(header.HdrLen+coreHeader.CoreReloOff), io.SeekStart); err != nil { | ||||
| 			return nil, nil, nil, fmt.Errorf("can't seek to CO-RE relocation section: %v", err) | ||||
| 		} | ||||
|  | ||||
| 		coreRelos, err = parseExtInfoRelos(io.LimitReader(r, int64(coreHeader.CoreReloLen)), bo, strings) | ||||
| 		if err != nil { | ||||
| 			return nil, nil, nil, fmt.Errorf("CO-RE relocation info: %w", err) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return funcInfo, lineInfo, coreRelos, nil | ||||
| 	return funcInfo, lineInfo, nil | ||||
| } | ||||
|  | ||||
| type btfExtInfoSec struct { | ||||
| @@ -172,9 +147,20 @@ func parseExtInfo(r io.Reader, bo binary.ByteOrder, strings stringTable) (map[st | ||||
|  | ||||
| 	result := make(map[string]extInfo) | ||||
| 	for { | ||||
| 		secName, infoHeader, err := parseExtInfoHeader(r, bo, strings) | ||||
| 		if errors.Is(err, io.EOF) { | ||||
| 		var infoHeader btfExtInfoSec | ||||
| 		if err := binary.Read(r, bo, &infoHeader); err == io.EOF { | ||||
| 			return result, nil | ||||
| 		} else if err != nil { | ||||
| 			return nil, fmt.Errorf("can't read ext info header: %v", err) | ||||
| 		} | ||||
|  | ||||
| 		secName, err := strings.Lookup(infoHeader.SecNameOff) | ||||
| 		if err != nil { | ||||
| 			return nil, fmt.Errorf("can't get section name: %w", err) | ||||
| 		} | ||||
|  | ||||
| 		if infoHeader.NumInfo == 0 { | ||||
| 			return nil, fmt.Errorf("section %s has invalid number of records", secName) | ||||
| 		} | ||||
|  | ||||
| 		var records []extInfoRecord | ||||
| @@ -202,80 +188,3 @@ func parseExtInfo(r io.Reader, bo binary.ByteOrder, strings stringTable) (map[st | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // bpfCoreRelo matches `struct bpf_core_relo` from the kernel | ||||
| type bpfCoreRelo struct { | ||||
| 	InsnOff      uint32 | ||||
| 	TypeID       TypeID | ||||
| 	AccessStrOff uint32 | ||||
| 	ReloKind     coreReloKind | ||||
| } | ||||
|  | ||||
| type bpfCoreRelos []bpfCoreRelo | ||||
|  | ||||
| // append two slices of extInfoRelo to each other. The InsnOff of b are adjusted | ||||
| // by offset. | ||||
| func (r bpfCoreRelos) append(other bpfCoreRelos, offset uint64) bpfCoreRelos { | ||||
| 	result := make([]bpfCoreRelo, 0, len(r)+len(other)) | ||||
| 	result = append(result, r...) | ||||
| 	for _, relo := range other { | ||||
| 		relo.InsnOff += uint32(offset) | ||||
| 		result = append(result, relo) | ||||
| 	} | ||||
| 	return result | ||||
| } | ||||
|  | ||||
| var extInfoReloSize = binary.Size(bpfCoreRelo{}) | ||||
|  | ||||
| func parseExtInfoRelos(r io.Reader, bo binary.ByteOrder, strings stringTable) (map[string]bpfCoreRelos, error) { | ||||
| 	var recordSize uint32 | ||||
| 	if err := binary.Read(r, bo, &recordSize); err != nil { | ||||
| 		return nil, fmt.Errorf("read record size: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	if recordSize != uint32(extInfoReloSize) { | ||||
| 		return nil, fmt.Errorf("expected record size %d, got %d", extInfoReloSize, recordSize) | ||||
| 	} | ||||
|  | ||||
| 	result := make(map[string]bpfCoreRelos) | ||||
| 	for { | ||||
| 		secName, infoHeader, err := parseExtInfoHeader(r, bo, strings) | ||||
| 		if errors.Is(err, io.EOF) { | ||||
| 			return result, nil | ||||
| 		} | ||||
|  | ||||
| 		var relos []bpfCoreRelo | ||||
| 		for i := uint32(0); i < infoHeader.NumInfo; i++ { | ||||
| 			var relo bpfCoreRelo | ||||
| 			if err := binary.Read(r, bo, &relo); err != nil { | ||||
| 				return nil, fmt.Errorf("section %v: read record: %v", secName, err) | ||||
| 			} | ||||
|  | ||||
| 			if relo.InsnOff%asm.InstructionSize != 0 { | ||||
| 				return nil, fmt.Errorf("section %v: offset %v is not aligned with instruction size", secName, relo.InsnOff) | ||||
| 			} | ||||
|  | ||||
| 			relos = append(relos, relo) | ||||
| 		} | ||||
|  | ||||
| 		result[secName] = relos | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func parseExtInfoHeader(r io.Reader, bo binary.ByteOrder, strings stringTable) (string, *btfExtInfoSec, error) { | ||||
| 	var infoHeader btfExtInfoSec | ||||
| 	if err := binary.Read(r, bo, &infoHeader); err != nil { | ||||
| 		return "", nil, fmt.Errorf("read ext info header: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	secName, err := strings.Lookup(infoHeader.SecNameOff) | ||||
| 	if err != nil { | ||||
| 		return "", nil, fmt.Errorf("get section name: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	if infoHeader.NumInfo == 0 { | ||||
| 		return "", nil, fmt.Errorf("section %s has zero records", secName) | ||||
| 	} | ||||
|  | ||||
| 	return secName, &infoHeader, nil | ||||
| } | ||||
|   | ||||
							
								
								
									
										275
									
								
								vendor/github.com/cilium/ebpf/internal/btf/types.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										275
									
								
								vendor/github.com/cilium/ebpf/internal/btf/types.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -21,14 +21,12 @@ func (tid TypeID) ID() TypeID { | ||||
| type Type interface { | ||||
| 	ID() TypeID | ||||
|  | ||||
| 	String() string | ||||
|  | ||||
| 	// Make a copy of the type, without copying Type members. | ||||
| 	copy() Type | ||||
|  | ||||
| 	// Enumerate all nested Types. Repeated calls must visit nested | ||||
| 	// types in the same order. | ||||
| 	walk(*typeDeque) | ||||
| 	walk(*copyStack) | ||||
| } | ||||
|  | ||||
| // namedType is a type with a name. | ||||
| @@ -52,10 +50,9 @@ func (n Name) name() string { | ||||
| type Void struct{} | ||||
|  | ||||
| func (v *Void) ID() TypeID      { return 0 } | ||||
| func (v *Void) String() string  { return "void#0" } | ||||
| func (v *Void) size() uint32    { return 0 } | ||||
| func (v *Void) copy() Type      { return (*Void)(nil) } | ||||
| func (v *Void) walk(*typeDeque) {} | ||||
| func (v *Void) walk(*copyStack) {} | ||||
|  | ||||
| type IntEncoding byte | ||||
|  | ||||
| @@ -81,54 +78,21 @@ type Int struct { | ||||
|  | ||||
| var _ namedType = (*Int)(nil) | ||||
|  | ||||
| func (i *Int) String() string { | ||||
| 	var s strings.Builder | ||||
|  | ||||
| 	switch { | ||||
| 	case i.Encoding&Char != 0: | ||||
| 		s.WriteString("char") | ||||
| 	case i.Encoding&Bool != 0: | ||||
| 		s.WriteString("bool") | ||||
| 	default: | ||||
| 		if i.Encoding&Signed == 0 { | ||||
| 			s.WriteRune('u') | ||||
| 		} | ||||
| 		s.WriteString("int") | ||||
| 		fmt.Fprintf(&s, "%d", i.Size*8) | ||||
| 	} | ||||
|  | ||||
| 	fmt.Fprintf(&s, "#%d", i.TypeID) | ||||
|  | ||||
| 	if i.Bits > 0 { | ||||
| 		fmt.Fprintf(&s, "[bits=%d]", i.Bits) | ||||
| 	} | ||||
|  | ||||
| 	return s.String() | ||||
| } | ||||
|  | ||||
| func (i *Int) size() uint32    { return i.Size } | ||||
| func (i *Int) walk(*typeDeque) {} | ||||
| func (i *Int) walk(*copyStack) {} | ||||
| func (i *Int) copy() Type { | ||||
| 	cpy := *i | ||||
| 	return &cpy | ||||
| } | ||||
|  | ||||
| func (i *Int) isBitfield() bool { | ||||
| 	return i.Offset > 0 | ||||
| } | ||||
|  | ||||
| // Pointer is a pointer to another type. | ||||
| type Pointer struct { | ||||
| 	TypeID | ||||
| 	Target Type | ||||
| } | ||||
|  | ||||
| func (p *Pointer) String() string { | ||||
| 	return fmt.Sprintf("pointer#%d[target=#%d]", p.TypeID, p.Target.ID()) | ||||
| } | ||||
|  | ||||
| func (p *Pointer) size() uint32        { return 8 } | ||||
| func (p *Pointer) walk(tdq *typeDeque) { tdq.push(&p.Target) } | ||||
| func (p *Pointer) size() uint32       { return 8 } | ||||
| func (p *Pointer) walk(cs *copyStack) { cs.push(&p.Target) } | ||||
| func (p *Pointer) copy() Type { | ||||
| 	cpy := *p | ||||
| 	return &cpy | ||||
| @@ -141,11 +105,7 @@ type Array struct { | ||||
| 	Nelems uint32 | ||||
| } | ||||
|  | ||||
| func (arr *Array) String() string { | ||||
| 	return fmt.Sprintf("array#%d[type=#%d n=%d]", arr.TypeID, arr.Type.ID(), arr.Nelems) | ||||
| } | ||||
|  | ||||
| func (arr *Array) walk(tdq *typeDeque) { tdq.push(&arr.Type) } | ||||
| func (arr *Array) walk(cs *copyStack) { cs.push(&arr.Type) } | ||||
| func (arr *Array) copy() Type { | ||||
| 	cpy := *arr | ||||
| 	return &cpy | ||||
| @@ -160,15 +120,11 @@ type Struct struct { | ||||
| 	Members []Member | ||||
| } | ||||
|  | ||||
| func (s *Struct) String() string { | ||||
| 	return fmt.Sprintf("struct#%d[%q]", s.TypeID, s.Name) | ||||
| } | ||||
|  | ||||
| func (s *Struct) size() uint32 { return s.Size } | ||||
|  | ||||
| func (s *Struct) walk(tdq *typeDeque) { | ||||
| func (s *Struct) walk(cs *copyStack) { | ||||
| 	for i := range s.Members { | ||||
| 		tdq.push(&s.Members[i].Type) | ||||
| 		cs.push(&s.Members[i].Type) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -192,15 +148,11 @@ type Union struct { | ||||
| 	Members []Member | ||||
| } | ||||
|  | ||||
| func (u *Union) String() string { | ||||
| 	return fmt.Sprintf("union#%d[%q]", u.TypeID, u.Name) | ||||
| } | ||||
|  | ||||
| func (u *Union) size() uint32 { return u.Size } | ||||
|  | ||||
| func (u *Union) walk(tdq *typeDeque) { | ||||
| func (u *Union) walk(cs *copyStack) { | ||||
| 	for i := range u.Members { | ||||
| 		tdq.push(&u.Members[i].Type) | ||||
| 		cs.push(&u.Members[i].Type) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -242,10 +194,6 @@ type Enum struct { | ||||
| 	Values []EnumValue | ||||
| } | ||||
|  | ||||
| func (e *Enum) String() string { | ||||
| 	return fmt.Sprintf("enum#%d[%q]", e.TypeID, e.Name) | ||||
| } | ||||
|  | ||||
| // EnumValue is part of an Enum | ||||
| // | ||||
| // Is is not a valid Type | ||||
| @@ -255,7 +203,7 @@ type EnumValue struct { | ||||
| } | ||||
|  | ||||
| func (e *Enum) size() uint32    { return 4 } | ||||
| func (e *Enum) walk(*typeDeque) {} | ||||
| func (e *Enum) walk(*copyStack) {} | ||||
| func (e *Enum) copy() Type { | ||||
| 	cpy := *e | ||||
| 	cpy.Values = make([]EnumValue, len(e.Values)) | ||||
| @@ -263,38 +211,13 @@ func (e *Enum) copy() Type { | ||||
| 	return &cpy | ||||
| } | ||||
|  | ||||
| // FwdKind is the type of forward declaration. | ||||
| type FwdKind int | ||||
|  | ||||
| // Valid types of forward declaration. | ||||
| const ( | ||||
| 	FwdStruct FwdKind = iota | ||||
| 	FwdUnion | ||||
| ) | ||||
|  | ||||
| func (fk FwdKind) String() string { | ||||
| 	switch fk { | ||||
| 	case FwdStruct: | ||||
| 		return "struct" | ||||
| 	case FwdUnion: | ||||
| 		return "union" | ||||
| 	default: | ||||
| 		return fmt.Sprintf("%T(%d)", fk, int(fk)) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Fwd is a forward declaration of a Type. | ||||
| type Fwd struct { | ||||
| 	TypeID | ||||
| 	Name | ||||
| 	Kind FwdKind | ||||
| } | ||||
|  | ||||
| func (f *Fwd) String() string { | ||||
| 	return fmt.Sprintf("fwd#%d[%s %q]", f.TypeID, f.Kind, f.Name) | ||||
| } | ||||
|  | ||||
| func (f *Fwd) walk(*typeDeque) {} | ||||
| func (f *Fwd) walk(*copyStack) {} | ||||
| func (f *Fwd) copy() Type { | ||||
| 	cpy := *f | ||||
| 	return &cpy | ||||
| @@ -307,11 +230,7 @@ type Typedef struct { | ||||
| 	Type Type | ||||
| } | ||||
|  | ||||
| func (td *Typedef) String() string { | ||||
| 	return fmt.Sprintf("typedef#%d[%q #%d]", td.TypeID, td.Name, td.Type.ID()) | ||||
| } | ||||
|  | ||||
| func (td *Typedef) walk(tdq *typeDeque) { tdq.push(&td.Type) } | ||||
| func (td *Typedef) walk(cs *copyStack) { cs.push(&td.Type) } | ||||
| func (td *Typedef) copy() Type { | ||||
| 	cpy := *td | ||||
| 	return &cpy | ||||
| @@ -323,12 +242,8 @@ type Volatile struct { | ||||
| 	Type Type | ||||
| } | ||||
|  | ||||
| func (v *Volatile) String() string { | ||||
| 	return fmt.Sprintf("volatile#%d[#%d]", v.TypeID, v.Type.ID()) | ||||
| } | ||||
|  | ||||
| func (v *Volatile) qualify() Type       { return v.Type } | ||||
| func (v *Volatile) walk(tdq *typeDeque) { tdq.push(&v.Type) } | ||||
| func (v *Volatile) qualify() Type      { return v.Type } | ||||
| func (v *Volatile) walk(cs *copyStack) { cs.push(&v.Type) } | ||||
| func (v *Volatile) copy() Type { | ||||
| 	cpy := *v | ||||
| 	return &cpy | ||||
| @@ -340,12 +255,8 @@ type Const struct { | ||||
| 	Type Type | ||||
| } | ||||
|  | ||||
| func (c *Const) String() string { | ||||
| 	return fmt.Sprintf("const#%d[#%d]", c.TypeID, c.Type.ID()) | ||||
| } | ||||
|  | ||||
| func (c *Const) qualify() Type       { return c.Type } | ||||
| func (c *Const) walk(tdq *typeDeque) { tdq.push(&c.Type) } | ||||
| func (c *Const) qualify() Type      { return c.Type } | ||||
| func (c *Const) walk(cs *copyStack) { cs.push(&c.Type) } | ||||
| func (c *Const) copy() Type { | ||||
| 	cpy := *c | ||||
| 	return &cpy | ||||
| @@ -357,12 +268,8 @@ type Restrict struct { | ||||
| 	Type Type | ||||
| } | ||||
|  | ||||
| func (r *Restrict) String() string { | ||||
| 	return fmt.Sprintf("restrict#%d[#%d]", r.TypeID, r.Type.ID()) | ||||
| } | ||||
|  | ||||
| func (r *Restrict) qualify() Type       { return r.Type } | ||||
| func (r *Restrict) walk(tdq *typeDeque) { tdq.push(&r.Type) } | ||||
| func (r *Restrict) qualify() Type      { return r.Type } | ||||
| func (r *Restrict) walk(cs *copyStack) { cs.push(&r.Type) } | ||||
| func (r *Restrict) copy() Type { | ||||
| 	cpy := *r | ||||
| 	return &cpy | ||||
| @@ -375,11 +282,7 @@ type Func struct { | ||||
| 	Type Type | ||||
| } | ||||
|  | ||||
| func (f *Func) String() string { | ||||
| 	return fmt.Sprintf("func#%d[%q proto=#%d]", f.TypeID, f.Name, f.Type.ID()) | ||||
| } | ||||
|  | ||||
| func (f *Func) walk(tdq *typeDeque) { tdq.push(&f.Type) } | ||||
| func (f *Func) walk(cs *copyStack) { cs.push(&f.Type) } | ||||
| func (f *Func) copy() Type { | ||||
| 	cpy := *f | ||||
| 	return &cpy | ||||
| @@ -392,20 +295,10 @@ type FuncProto struct { | ||||
| 	Params []FuncParam | ||||
| } | ||||
|  | ||||
| func (fp *FuncProto) String() string { | ||||
| 	var s strings.Builder | ||||
| 	fmt.Fprintf(&s, "proto#%d[", fp.TypeID) | ||||
| 	for _, param := range fp.Params { | ||||
| 		fmt.Fprintf(&s, "%q=#%d, ", param.Name, param.Type.ID()) | ||||
| 	} | ||||
| 	fmt.Fprintf(&s, "return=#%d]", fp.Return.ID()) | ||||
| 	return s.String() | ||||
| } | ||||
|  | ||||
| func (fp *FuncProto) walk(tdq *typeDeque) { | ||||
| 	tdq.push(&fp.Return) | ||||
| func (fp *FuncProto) walk(cs *copyStack) { | ||||
| 	cs.push(&fp.Return) | ||||
| 	for i := range fp.Params { | ||||
| 		tdq.push(&fp.Params[i].Type) | ||||
| 		cs.push(&fp.Params[i].Type) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -428,12 +321,7 @@ type Var struct { | ||||
| 	Type Type | ||||
| } | ||||
|  | ||||
| func (v *Var) String() string { | ||||
| 	// TODO: Linkage | ||||
| 	return fmt.Sprintf("var#%d[%q]", v.TypeID, v.Name) | ||||
| } | ||||
|  | ||||
| func (v *Var) walk(tdq *typeDeque) { tdq.push(&v.Type) } | ||||
| func (v *Var) walk(cs *copyStack) { cs.push(&v.Type) } | ||||
| func (v *Var) copy() Type { | ||||
| 	cpy := *v | ||||
| 	return &cpy | ||||
| @@ -447,15 +335,11 @@ type Datasec struct { | ||||
| 	Vars []VarSecinfo | ||||
| } | ||||
|  | ||||
| func (ds *Datasec) String() string { | ||||
| 	return fmt.Sprintf("section#%d[%q]", ds.TypeID, ds.Name) | ||||
| } | ||||
|  | ||||
| func (ds *Datasec) size() uint32 { return ds.Size } | ||||
|  | ||||
| func (ds *Datasec) walk(tdq *typeDeque) { | ||||
| func (ds *Datasec) walk(cs *copyStack) { | ||||
| 	for i := range ds.Vars { | ||||
| 		tdq.push(&ds.Vars[i].Type) | ||||
| 		cs.push(&ds.Vars[i].Type) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -467,8 +351,6 @@ func (ds *Datasec) copy() Type { | ||||
| } | ||||
|  | ||||
| // VarSecinfo describes variable in a Datasec | ||||
| // | ||||
| // It is not a valid Type. | ||||
| type VarSecinfo struct { | ||||
| 	Type   Type | ||||
| 	Offset uint32 | ||||
| @@ -556,7 +438,7 @@ func Sizeof(typ Type) (int, error) { | ||||
| func copyType(typ Type) Type { | ||||
| 	var ( | ||||
| 		copies = make(map[Type]Type) | ||||
| 		work   typeDeque | ||||
| 		work   copyStack | ||||
| 	) | ||||
|  | ||||
| 	for t := &typ; t != nil; t = work.pop() { | ||||
| @@ -577,83 +459,34 @@ func copyType(typ Type) Type { | ||||
| 	return typ | ||||
| } | ||||
|  | ||||
| // typeDeque keeps track of pointers to types which still | ||||
| // copyStack keeps track of pointers to types which still | ||||
| // need to be visited. | ||||
| type typeDeque struct { | ||||
| 	types       []*Type | ||||
| 	read, write uint64 | ||||
| 	mask        uint64 | ||||
| } | ||||
| type copyStack []*Type | ||||
|  | ||||
| // push adds a type to the stack. | ||||
| func (dq *typeDeque) push(t *Type) { | ||||
| 	if dq.write-dq.read < uint64(len(dq.types)) { | ||||
| 		dq.types[dq.write&dq.mask] = t | ||||
| 		dq.write++ | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	new := len(dq.types) * 2 | ||||
| 	if new == 0 { | ||||
| 		new = 8 | ||||
| 	} | ||||
|  | ||||
| 	types := make([]*Type, new) | ||||
| 	pivot := dq.read & dq.mask | ||||
| 	n := copy(types, dq.types[pivot:]) | ||||
| 	n += copy(types[n:], dq.types[:pivot]) | ||||
| 	types[n] = t | ||||
|  | ||||
| 	dq.types = types | ||||
| 	dq.mask = uint64(new) - 1 | ||||
| 	dq.read, dq.write = 0, uint64(n+1) | ||||
| func (cs *copyStack) push(t *Type) { | ||||
| 	*cs = append(*cs, t) | ||||
| } | ||||
|  | ||||
| // shift returns the first element or null. | ||||
| func (dq *typeDeque) shift() *Type { | ||||
| 	if dq.read == dq.write { | ||||
| // pop returns the topmost Type, or nil. | ||||
| func (cs *copyStack) pop() *Type { | ||||
| 	n := len(*cs) | ||||
| 	if n == 0 { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	index := dq.read & dq.mask | ||||
| 	t := dq.types[index] | ||||
| 	dq.types[index] = nil | ||||
| 	dq.read++ | ||||
| 	t := (*cs)[n-1] | ||||
| 	*cs = (*cs)[:n-1] | ||||
| 	return t | ||||
| } | ||||
|  | ||||
| // pop returns the last element or null. | ||||
| func (dq *typeDeque) pop() *Type { | ||||
| 	if dq.read == dq.write { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	dq.write-- | ||||
| 	index := dq.write & dq.mask | ||||
| 	t := dq.types[index] | ||||
| 	dq.types[index] = nil | ||||
| 	return t | ||||
| } | ||||
|  | ||||
| // all returns all elements. | ||||
| // | ||||
| // The deque is empty after calling this method. | ||||
| func (dq *typeDeque) all() []*Type { | ||||
| 	length := dq.write - dq.read | ||||
| 	types := make([]*Type, 0, length) | ||||
| 	for t := dq.shift(); t != nil; t = dq.shift() { | ||||
| 		types = append(types, t) | ||||
| 	} | ||||
| 	return types | ||||
| } | ||||
|  | ||||
| // inflateRawTypes takes a list of raw btf types linked via type IDs, and turns | ||||
| // it into a graph of Types connected via pointers. | ||||
| // | ||||
| // 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) { | ||||
| // Returns a map of named types (so, where NameOff is non-zero). 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) (namedTypes map[string][]namedType, err error) { | ||||
| 	type fixupDef struct { | ||||
| 		id           TypeID | ||||
| 		expectedKind btfKind | ||||
| @@ -690,7 +523,7 @@ func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (types []Type, | ||||
| 		return members, nil | ||||
| 	} | ||||
|  | ||||
| 	types = make([]Type, 0, len(rawTypes)) | ||||
| 	types := make([]Type, 0, len(rawTypes)) | ||||
| 	types = append(types, (*Void)(nil)) | ||||
| 	namedTypes = make(map[string][]namedType) | ||||
|  | ||||
| @@ -704,7 +537,7 @@ func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (types []Type, | ||||
|  | ||||
| 		name, err := rawStrings.LookupName(raw.NameOff) | ||||
| 		if err != nil { | ||||
| 			return nil, nil, fmt.Errorf("get name for type id %d: %w", id, err) | ||||
| 			return nil, fmt.Errorf("can't get name for type id %d: %w", id, err) | ||||
| 		} | ||||
|  | ||||
| 		switch raw.Kind() { | ||||
| @@ -729,14 +562,14 @@ func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (types []Type, | ||||
| 		case kindStruct: | ||||
| 			members, err := convertMembers(raw.data.([]btfMember), raw.KindFlag()) | ||||
| 			if err != nil { | ||||
| 				return nil, nil, fmt.Errorf("struct %s (id %d): %w", name, id, err) | ||||
| 				return nil, fmt.Errorf("struct %s (id %d): %w", name, id, err) | ||||
| 			} | ||||
| 			typ = &Struct{id, name, raw.Size(), members} | ||||
|  | ||||
| 		case kindUnion: | ||||
| 			members, err := convertMembers(raw.data.([]btfMember), raw.KindFlag()) | ||||
| 			if err != nil { | ||||
| 				return nil, nil, fmt.Errorf("union %s (id %d): %w", name, id, err) | ||||
| 				return nil, fmt.Errorf("union %s (id %d): %w", name, id, err) | ||||
| 			} | ||||
| 			typ = &Union{id, name, raw.Size(), members} | ||||
|  | ||||
| @@ -746,7 +579,7 @@ func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (types []Type, | ||||
| 			for i, btfVal := range rawvals { | ||||
| 				name, err := rawStrings.LookupName(btfVal.NameOff) | ||||
| 				if err != nil { | ||||
| 					return nil, nil, fmt.Errorf("get name for enum value %d: %s", i, err) | ||||
| 					return nil, fmt.Errorf("can't get name for enum value %d: %s", i, err) | ||||
| 				} | ||||
| 				vals = append(vals, EnumValue{ | ||||
| 					Name:  name, | ||||
| @@ -756,11 +589,7 @@ func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (types []Type, | ||||
| 			typ = &Enum{id, name, vals} | ||||
|  | ||||
| 		case kindForward: | ||||
| 			if raw.KindFlag() { | ||||
| 				typ = &Fwd{id, name, FwdUnion} | ||||
| 			} else { | ||||
| 				typ = &Fwd{id, name, FwdStruct} | ||||
| 			} | ||||
| 			typ = &Fwd{id, name} | ||||
|  | ||||
| 		case kindTypedef: | ||||
| 			typedef := &Typedef{id, name, nil} | ||||
| @@ -793,7 +622,7 @@ func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (types []Type, | ||||
| 			for i, param := range rawparams { | ||||
| 				name, err := rawStrings.LookupName(param.NameOff) | ||||
| 				if err != nil { | ||||
| 					return nil, nil, fmt.Errorf("get name for func proto parameter %d: %s", i, err) | ||||
| 					return nil, fmt.Errorf("can't get name for func proto parameter %d: %s", i, err) | ||||
| 				} | ||||
| 				params = append(params, FuncParam{ | ||||
| 					Name: name, | ||||
| @@ -827,7 +656,7 @@ func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (types []Type, | ||||
| 			typ = &Datasec{id, name, raw.SizeType, vars} | ||||
|  | ||||
| 		default: | ||||
| 			return nil, nil, fmt.Errorf("type id %d: unknown kind: %v", id, raw.Kind()) | ||||
| 			return nil, fmt.Errorf("type id %d: unknown kind: %v", id, raw.Kind()) | ||||
| 		} | ||||
|  | ||||
| 		types = append(types, typ) | ||||
| @@ -842,7 +671,7 @@ func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (types []Type, | ||||
| 	for _, fixup := range fixups { | ||||
| 		i := int(fixup.id) | ||||
| 		if i >= len(types) { | ||||
| 			return nil, nil, fmt.Errorf("reference to invalid type id: %d", fixup.id) | ||||
| 			return nil, fmt.Errorf("reference to invalid type id: %d", fixup.id) | ||||
| 		} | ||||
|  | ||||
| 		// Default void (id 0) to unknown | ||||
| @@ -852,13 +681,13 @@ func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (types []Type, | ||||
| 		} | ||||
|  | ||||
| 		if expected := fixup.expectedKind; expected != kindUnknown && rawKind != expected { | ||||
| 			return nil, nil, fmt.Errorf("expected type id %d to have kind %s, found %s", fixup.id, expected, rawKind) | ||||
| 			return nil, fmt.Errorf("expected type id %d to have kind %s, found %s", fixup.id, expected, rawKind) | ||||
| 		} | ||||
|  | ||||
| 		*fixup.typ = types[i] | ||||
| 	} | ||||
|  | ||||
| 	return types, namedTypes, nil | ||||
| 	return namedTypes, nil | ||||
| } | ||||
|  | ||||
| // essentialName returns name without a ___ suffix. | ||||
|   | ||||
							
								
								
									
										52
									
								
								vendor/github.com/cilium/ebpf/internal/elf.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										52
									
								
								vendor/github.com/cilium/ebpf/internal/elf.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,52 +0,0 @@ | ||||
| package internal | ||||
|  | ||||
| import ( | ||||
| 	"debug/elf" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| ) | ||||
|  | ||||
| type SafeELFFile struct { | ||||
| 	*elf.File | ||||
| } | ||||
|  | ||||
| // NewSafeELFFile reads an ELF safely. | ||||
| // | ||||
| // Any panic during parsing is turned into an error. This is necessary since | ||||
| // there are a bunch of unfixed bugs in debug/elf. | ||||
| // | ||||
| // https://github.com/golang/go/issues?q=is%3Aissue+is%3Aopen+debug%2Felf+in%3Atitle | ||||
| func NewSafeELFFile(r io.ReaderAt) (safe *SafeELFFile, err error) { | ||||
| 	defer func() { | ||||
| 		r := recover() | ||||
| 		if r == nil { | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		safe = nil | ||||
| 		err = fmt.Errorf("reading ELF file panicked: %s", r) | ||||
| 	}() | ||||
|  | ||||
| 	file, err := elf.NewFile(r) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return &SafeELFFile{file}, nil | ||||
| } | ||||
|  | ||||
| // Symbols is the safe version of elf.File.Symbols. | ||||
| func (se *SafeELFFile) Symbols() (syms []elf.Symbol, err error) { | ||||
| 	defer func() { | ||||
| 		r := recover() | ||||
| 		if r == nil { | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		syms = nil | ||||
| 		err = fmt.Errorf("reading ELF symbols panicked: %s", r) | ||||
| 	}() | ||||
|  | ||||
| 	syms, err = se.File.Symbols() | ||||
| 	return | ||||
| } | ||||
							
								
								
									
										86
									
								
								vendor/github.com/cilium/ebpf/internal/feature.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										86
									
								
								vendor/github.com/cilium/ebpf/internal/feature.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -32,7 +32,7 @@ func (ufe *UnsupportedFeatureError) Is(target error) bool { | ||||
| } | ||||
|  | ||||
| type featureTest struct { | ||||
| 	sync.RWMutex | ||||
| 	sync.Mutex | ||||
| 	successful bool | ||||
| 	result     error | ||||
| } | ||||
| @@ -42,10 +42,10 @@ type featureTest struct { | ||||
| // | ||||
| // The return values have the following semantics: | ||||
| // | ||||
| //   err == ErrNotSupported: the feature is not available | ||||
| //   err == nil: the feature is available | ||||
| //   err != nil: the test couldn't be executed | ||||
| type FeatureTestFn func() error | ||||
| //   err == nil && available: the feature is available | ||||
| //   err == nil && !available: the feature isn't available | ||||
| type FeatureTestFn func() (available bool, err error) | ||||
|  | ||||
| // FeatureTest wraps a function so that it is run at most once. | ||||
| // | ||||
| @@ -61,40 +61,70 @@ func FeatureTest(name, version string, fn FeatureTestFn) func() error { | ||||
|  | ||||
| 	ft := new(featureTest) | ||||
| 	return func() error { | ||||
| 		ft.RLock() | ||||
| 		if ft.successful { | ||||
| 			defer ft.RUnlock() | ||||
| 			return ft.result | ||||
| 		} | ||||
| 		ft.RUnlock() | ||||
| 		ft.Lock() | ||||
| 		defer ft.Unlock() | ||||
| 		// check one more time on the off | ||||
| 		// chance that two go routines | ||||
| 		// were able to call into the write | ||||
| 		// lock | ||||
|  | ||||
| 		if ft.successful { | ||||
| 			return ft.result | ||||
| 		} | ||||
| 		err := fn() | ||||
| 		switch { | ||||
| 		case errors.Is(err, ErrNotSupported): | ||||
|  | ||||
| 		available, err := fn() | ||||
| 		if errors.Is(err, ErrNotSupported) { | ||||
| 			// The feature test aborted because a dependent feature | ||||
| 			// is missing, which we should cache. | ||||
| 			available = false | ||||
| 		} else if err != nil { | ||||
| 			// We couldn't execute the feature test to a point | ||||
| 			// where it could make a determination. | ||||
| 			// Don't cache the result, just return it. | ||||
| 			return fmt.Errorf("can't detect support for %s: %w", name, err) | ||||
| 		} | ||||
|  | ||||
| 		ft.successful = true | ||||
| 		if !available { | ||||
| 			ft.result = &UnsupportedFeatureError{ | ||||
| 				MinimumVersion: v, | ||||
| 				Name:           name, | ||||
| 			} | ||||
| 			fallthrough | ||||
|  | ||||
| 		case err == nil: | ||||
| 			ft.successful = true | ||||
|  | ||||
| 		default: | ||||
| 			// We couldn't execute the feature test to a point | ||||
| 			// where it could make a determination. | ||||
| 			// Don't cache the result, just return it. | ||||
| 			return fmt.Errorf("detect support for %s: %w", name, err) | ||||
| 		} | ||||
|  | ||||
| 		return ft.result | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // A Version in the form Major.Minor.Patch. | ||||
| type Version [3]uint16 | ||||
|  | ||||
| // NewVersion creates a version from a string like "Major.Minor.Patch". | ||||
| // | ||||
| // Patch is optional. | ||||
| func NewVersion(ver string) (Version, error) { | ||||
| 	var major, minor, patch uint16 | ||||
| 	n, _ := fmt.Sscanf(ver, "%d.%d.%d", &major, &minor, &patch) | ||||
| 	if n < 2 { | ||||
| 		return Version{}, fmt.Errorf("invalid version: %s", ver) | ||||
| 	} | ||||
| 	return Version{major, minor, patch}, nil | ||||
| } | ||||
|  | ||||
| func (v Version) String() string { | ||||
| 	if v[2] == 0 { | ||||
| 		return fmt.Sprintf("v%d.%d", v[0], v[1]) | ||||
| 	} | ||||
| 	return fmt.Sprintf("v%d.%d.%d", v[0], v[1], v[2]) | ||||
| } | ||||
|  | ||||
| // Less returns true if the version is less than another version. | ||||
| func (v Version) Less(other Version) bool { | ||||
| 	for i, a := range v { | ||||
| 		if a == other[i] { | ||||
| 			continue | ||||
| 		} | ||||
| 		return a < other[i] | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| // Unspecified returns true if the version is all zero. | ||||
| func (v Version) Unspecified() bool { | ||||
| 	return v[0] == 0 && v[1] == 0 && v[2] == 0 | ||||
| } | ||||
|   | ||||
							
								
								
									
										44
									
								
								vendor/github.com/cilium/ebpf/internal/pinning.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										44
									
								
								vendor/github.com/cilium/ebpf/internal/pinning.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,44 +0,0 @@ | ||||
| package internal | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"os" | ||||
|  | ||||
| 	"github.com/cilium/ebpf/internal/unix" | ||||
| ) | ||||
|  | ||||
| func Pin(currentPath, newPath string, fd *FD) error { | ||||
| 	if newPath == "" { | ||||
| 		return errors.New("given pinning path cannot be empty") | ||||
| 	} | ||||
| 	if currentPath == newPath { | ||||
| 		return nil | ||||
| 	} | ||||
| 	if currentPath == "" { | ||||
| 		return BPFObjPin(newPath, fd) | ||||
| 	} | ||||
| 	var err error | ||||
| 	// Renameat2 is used instead of os.Rename to disallow the new path replacing | ||||
| 	// an existing path. | ||||
| 	if err = unix.Renameat2(unix.AT_FDCWD, currentPath, unix.AT_FDCWD, newPath, unix.RENAME_NOREPLACE); err == nil { | ||||
| 		// Object is now moved to the new pinning path. | ||||
| 		return nil | ||||
| 	} | ||||
| 	if !os.IsNotExist(err) { | ||||
| 		return fmt.Errorf("unable to move pinned object to new path %v: %w", newPath, err) | ||||
| 	} | ||||
| 	// Internal state not in sync with the file system so let's fix it. | ||||
| 	return BPFObjPin(newPath, fd) | ||||
| } | ||||
|  | ||||
| func Unpin(pinnedPath string) error { | ||||
| 	if pinnedPath == "" { | ||||
| 		return nil | ||||
| 	} | ||||
| 	err := os.Remove(pinnedPath) | ||||
| 	if err == nil || os.IsNotExist(err) { | ||||
| 		return nil | ||||
| 	} | ||||
| 	return err | ||||
| } | ||||
							
								
								
									
										15
									
								
								vendor/github.com/cilium/ebpf/internal/ptr.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										15
									
								
								vendor/github.com/cilium/ebpf/internal/ptr.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,10 +1,6 @@ | ||||
| package internal | ||||
|  | ||||
| import ( | ||||
| 	"unsafe" | ||||
|  | ||||
| 	"github.com/cilium/ebpf/internal/unix" | ||||
| ) | ||||
| import "unsafe" | ||||
|  | ||||
| // NewPointer creates a 64-bit pointer from an unsafe Pointer. | ||||
| func NewPointer(ptr unsafe.Pointer) Pointer { | ||||
| @@ -26,10 +22,9 @@ func NewStringPointer(str string) Pointer { | ||||
| 		return Pointer{} | ||||
| 	} | ||||
|  | ||||
| 	p, err := unix.BytePtrFromString(str) | ||||
| 	if err != nil { | ||||
| 		return Pointer{} | ||||
| 	} | ||||
| 	// The kernel expects strings to be zero terminated | ||||
| 	buf := make([]byte, len(str)+1) | ||||
| 	copy(buf, str) | ||||
|  | ||||
| 	return Pointer{ptr: unsafe.Pointer(p)} | ||||
| 	return Pointer{ptr: unsafe.Pointer(&buf[0])} | ||||
| } | ||||
|   | ||||
							
								
								
									
										18
									
								
								vendor/github.com/cilium/ebpf/internal/syscall.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										18
									
								
								vendor/github.com/cilium/ebpf/internal/syscall.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -91,19 +91,6 @@ func BPFProgDetach(attr *BPFProgDetachAttr) error { | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| type BPFEnableStatsAttr struct { | ||||
| 	StatsType uint32 | ||||
| } | ||||
|  | ||||
| func BPFEnableStats(attr *BPFEnableStatsAttr) (*FD, error) { | ||||
| 	ptr, err := BPF(BPF_ENABLE_STATS, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("enable stats: %w", err) | ||||
| 	} | ||||
| 	return NewFD(uint32(ptr)), nil | ||||
|  | ||||
| } | ||||
|  | ||||
| type bpfObjAttr struct { | ||||
| 	fileName  Pointer | ||||
| 	fd        uint32 | ||||
| @@ -140,10 +127,9 @@ func BPFObjPin(fileName string, fd *FD) error { | ||||
| } | ||||
|  | ||||
| // BPFObjGet wraps BPF_OBJ_GET. | ||||
| func BPFObjGet(fileName string, flags uint32) (*FD, error) { | ||||
| func BPFObjGet(fileName string) (*FD, error) { | ||||
| 	attr := bpfObjAttr{ | ||||
| 		fileName:  NewStringPointer(fileName), | ||||
| 		fileFlags: flags, | ||||
| 		fileName: NewStringPointer(fileName), | ||||
| 	} | ||||
| 	ptr, err := BPF(BPF_OBJ_GET, unsafe.Pointer(&attr), unsafe.Sizeof(attr)) | ||||
| 	if err != nil { | ||||
|   | ||||
							
								
								
									
										57
									
								
								vendor/github.com/cilium/ebpf/internal/unix/types_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										57
									
								
								vendor/github.com/cilium/ebpf/internal/unix/types_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -10,27 +10,19 @@ import ( | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	ENOENT  = linux.ENOENT | ||||
| 	EEXIST  = linux.EEXIST | ||||
| 	EAGAIN  = linux.EAGAIN | ||||
| 	ENOSPC  = linux.ENOSPC | ||||
| 	EINVAL  = linux.EINVAL | ||||
| 	EPOLLIN = linux.EPOLLIN | ||||
| 	EINTR   = linux.EINTR | ||||
| 	EPERM   = linux.EPERM | ||||
| 	ESRCH   = linux.ESRCH | ||||
| 	ENODEV  = linux.ENODEV | ||||
| 	// 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 | ||||
| 	ENOENT                   = linux.ENOENT | ||||
| 	EEXIST                   = linux.EEXIST | ||||
| 	EAGAIN                   = linux.EAGAIN | ||||
| 	ENOSPC                   = linux.ENOSPC | ||||
| 	EINVAL                   = linux.EINVAL | ||||
| 	EPOLLIN                  = linux.EPOLLIN | ||||
| 	EINTR                    = linux.EINTR | ||||
| 	EPERM                    = linux.EPERM | ||||
| 	ESRCH                    = linux.ESRCH | ||||
| 	ENODEV                   = linux.ENODEV | ||||
| 	BPF_F_NUMA_NODE          = linux.BPF_F_NUMA_NODE | ||||
| 	BPF_F_RDONLY             = linux.BPF_F_RDONLY | ||||
| 	BPF_F_WRONLY             = linux.BPF_F_WRONLY | ||||
| 	BPF_F_RDONLY_PROG        = linux.BPF_F_RDONLY_PROG | ||||
| 	BPF_F_WRONLY_PROG        = linux.BPF_F_WRONLY_PROG | ||||
| 	BPF_F_SLEEPABLE          = linux.BPF_F_SLEEPABLE | ||||
| 	BPF_OBJ_NAME_LEN         = linux.BPF_OBJ_NAME_LEN | ||||
| 	BPF_TAG_SIZE             = linux.BPF_TAG_SIZE | ||||
| 	SYS_BPF                  = linux.SYS_BPF | ||||
| @@ -43,21 +35,12 @@ const ( | ||||
| 	PROT_WRITE               = linux.PROT_WRITE | ||||
| 	MAP_SHARED               = linux.MAP_SHARED | ||||
| 	PERF_TYPE_SOFTWARE       = linux.PERF_TYPE_SOFTWARE | ||||
| 	PERF_TYPE_TRACEPOINT     = linux.PERF_TYPE_TRACEPOINT | ||||
| 	PERF_COUNT_SW_BPF_OUTPUT = linux.PERF_COUNT_SW_BPF_OUTPUT | ||||
| 	PERF_EVENT_IOC_DISABLE   = linux.PERF_EVENT_IOC_DISABLE | ||||
| 	PERF_EVENT_IOC_ENABLE    = linux.PERF_EVENT_IOC_ENABLE | ||||
| 	PERF_EVENT_IOC_SET_BPF   = linux.PERF_EVENT_IOC_SET_BPF | ||||
| 	PerfBitWatermark         = linux.PerfBitWatermark | ||||
| 	PERF_SAMPLE_RAW          = linux.PERF_SAMPLE_RAW | ||||
| 	PERF_FLAG_FD_CLOEXEC     = linux.PERF_FLAG_FD_CLOEXEC | ||||
| 	RLIM_INFINITY            = linux.RLIM_INFINITY | ||||
| 	RLIMIT_MEMLOCK           = linux.RLIMIT_MEMLOCK | ||||
| 	BPF_STATS_RUN_TIME       = linux.BPF_STATS_RUN_TIME | ||||
| 	PERF_RECORD_LOST         = linux.PERF_RECORD_LOST | ||||
| 	PERF_RECORD_SAMPLE       = linux.PERF_RECORD_SAMPLE | ||||
| 	AT_FDCWD                 = linux.AT_FDCWD | ||||
| 	RENAME_NOREPLACE         = linux.RENAME_NOREPLACE | ||||
| ) | ||||
|  | ||||
| // Statfs_t is a wrapper | ||||
| @@ -81,11 +64,6 @@ func FcntlInt(fd uintptr, cmd, arg int) (int, error) { | ||||
| 	return linux.FcntlInt(fd, cmd, arg) | ||||
| } | ||||
|  | ||||
| // IoctlSetInt is a wrapper | ||||
| func IoctlSetInt(fd int, req uint, value int) error { | ||||
| 	return linux.IoctlSetInt(fd, req, value) | ||||
| } | ||||
|  | ||||
| // Statfs is a wrapper | ||||
| func Statfs(path string, buf *Statfs_t) (err error) { | ||||
| 	return linux.Statfs(path, buf) | ||||
| @@ -173,21 +151,6 @@ func Tgkill(tgid int, tid int, sig syscall.Signal) (err error) { | ||||
| 	return linux.Tgkill(tgid, tid, sig) | ||||
| } | ||||
|  | ||||
| // BytePtrFromString is a wrapper | ||||
| func BytePtrFromString(s string) (*byte, error) { | ||||
| 	return linux.BytePtrFromString(s) | ||||
| } | ||||
|  | ||||
| // ByteSliceToString is a wrapper | ||||
| func ByteSliceToString(s []byte) string { | ||||
| 	return linux.ByteSliceToString(s) | ||||
| } | ||||
|  | ||||
| // Renameat2 is a wrapper | ||||
| func Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) error { | ||||
| 	return linux.Renameat2(olddirfd, oldpath, newdirfd, newpath, flags) | ||||
| } | ||||
|  | ||||
| func KernelRelease() (string, error) { | ||||
| 	var uname Utsname | ||||
| 	err := Uname(&uname) | ||||
|   | ||||
							
								
								
									
										56
									
								
								vendor/github.com/cilium/ebpf/internal/unix/types_other.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										56
									
								
								vendor/github.com/cilium/ebpf/internal/unix/types_other.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -11,26 +11,18 @@ import ( | ||||
| var errNonLinux = fmt.Errorf("unsupported platform %s/%s", runtime.GOOS, runtime.GOARCH) | ||||
|  | ||||
| const ( | ||||
| 	ENOENT = syscall.ENOENT | ||||
| 	EEXIST = syscall.EEXIST | ||||
| 	EAGAIN = syscall.EAGAIN | ||||
| 	ENOSPC = syscall.ENOSPC | ||||
| 	EINVAL = syscall.EINVAL | ||||
| 	EINTR  = syscall.EINTR | ||||
| 	EPERM  = syscall.EPERM | ||||
| 	ESRCH  = syscall.ESRCH | ||||
| 	ENODEV = syscall.ENODEV | ||||
| 	EBADF  = syscall.Errno(0) | ||||
| 	// ENOTSUPP is not the same as ENOTSUP or EOPNOTSUP | ||||
| 	ENOTSUPP = syscall.Errno(0x20c) | ||||
|  | ||||
| 	BPF_F_NO_PREALLOC        = 0 | ||||
| 	ENOENT                   = syscall.ENOENT | ||||
| 	EEXIST                   = syscall.EEXIST | ||||
| 	EAGAIN                   = syscall.EAGAIN | ||||
| 	ENOSPC                   = syscall.ENOSPC | ||||
| 	EINVAL                   = syscall.EINVAL | ||||
| 	EINTR                    = syscall.EINTR | ||||
| 	EPERM                    = syscall.EPERM | ||||
| 	ESRCH                    = syscall.ESRCH | ||||
| 	ENODEV                   = syscall.ENODEV | ||||
| 	BPF_F_NUMA_NODE          = 0 | ||||
| 	BPF_F_RDONLY             = 0 | ||||
| 	BPF_F_WRONLY             = 0 | ||||
| 	BPF_F_RDONLY_PROG        = 0 | ||||
| 	BPF_F_WRONLY_PROG        = 0 | ||||
| 	BPF_F_SLEEPABLE          = 0 | ||||
| 	BPF_OBJ_NAME_LEN         = 0x10 | ||||
| 	BPF_TAG_SIZE             = 0x8 | ||||
| 	SYS_BPF                  = 321 | ||||
| @@ -44,21 +36,12 @@ const ( | ||||
| 	PROT_WRITE               = 0x2 | ||||
| 	MAP_SHARED               = 0x1 | ||||
| 	PERF_TYPE_SOFTWARE       = 0x1 | ||||
| 	PERF_TYPE_TRACEPOINT     = 0 | ||||
| 	PERF_COUNT_SW_BPF_OUTPUT = 0xa | ||||
| 	PERF_EVENT_IOC_DISABLE   = 0 | ||||
| 	PERF_EVENT_IOC_ENABLE    = 0 | ||||
| 	PERF_EVENT_IOC_SET_BPF   = 0 | ||||
| 	PerfBitWatermark         = 0x4000 | ||||
| 	PERF_SAMPLE_RAW          = 0x400 | ||||
| 	PERF_FLAG_FD_CLOEXEC     = 0x8 | ||||
| 	RLIM_INFINITY            = 0x7fffffffffffffff | ||||
| 	RLIMIT_MEMLOCK           = 8 | ||||
| 	BPF_STATS_RUN_TIME       = 0 | ||||
| 	PERF_RECORD_LOST         = 2 | ||||
| 	PERF_RECORD_SAMPLE       = 9 | ||||
| 	AT_FDCWD                 = -0x2 | ||||
| 	RENAME_NOREPLACE         = 0x1 | ||||
| ) | ||||
|  | ||||
| // Statfs_t is a wrapper | ||||
| @@ -98,11 +81,6 @@ func FcntlInt(fd uintptr, cmd, arg int) (int, error) { | ||||
| 	return -1, errNonLinux | ||||
| } | ||||
|  | ||||
| // IoctlSetInt is a wrapper | ||||
| func IoctlSetInt(fd int, req uint, value int) error { | ||||
| 	return errNonLinux | ||||
| } | ||||
|  | ||||
| // Statfs is a wrapper | ||||
| func Statfs(path string, buf *Statfs_t) error { | ||||
| 	return errNonLinux | ||||
| @@ -217,7 +195,6 @@ func PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int | ||||
| // Utsname is a wrapper | ||||
| type Utsname struct { | ||||
| 	Release [65]byte | ||||
| 	Version [65]byte | ||||
| } | ||||
|  | ||||
| // Uname is a wrapper | ||||
| @@ -240,21 +217,6 @@ func Tgkill(tgid int, tid int, sig syscall.Signal) (err error) { | ||||
| 	return errNonLinux | ||||
| } | ||||
|  | ||||
| // BytePtrFromString is a wrapper | ||||
| func BytePtrFromString(s string) (*byte, error) { | ||||
| 	return nil, errNonLinux | ||||
| } | ||||
|  | ||||
| // ByteSliceToString is a wrapper | ||||
| func ByteSliceToString(s []byte) string { | ||||
| 	return "" | ||||
| } | ||||
|  | ||||
| // Renameat2 is a wrapper | ||||
| func Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) error { | ||||
| 	return errNonLinux | ||||
| } | ||||
|  | ||||
| func KernelRelease() (string, error) { | ||||
| 	return "", errNonLinux | ||||
| } | ||||
|   | ||||
							
								
								
									
										163
									
								
								vendor/github.com/cilium/ebpf/internal/version.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										163
									
								
								vendor/github.com/cilium/ebpf/internal/version.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,163 +0,0 @@ | ||||
| package internal | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"io/ioutil" | ||||
| 	"regexp" | ||||
| 	"sync" | ||||
|  | ||||
| 	"github.com/cilium/ebpf/internal/unix" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	// Version constant used in ELF binaries indicating that the loader needs to | ||||
| 	// substitute the eBPF program's version with the value of the kernel's | ||||
| 	// KERNEL_VERSION compile-time macro. Used for compatibility with BCC, gobpf | ||||
| 	// and RedSift. | ||||
| 	MagicKernelVersion = 0xFFFFFFFE | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	// Match between one and three decimals separated by dots, with the last | ||||
| 	// segment (patch level) being optional on some kernels. | ||||
| 	// The x.y.z string must appear at the start of a string or right after | ||||
| 	// whitespace to prevent sequences like 'x.y.z-a.b.c' from matching 'a.b.c'. | ||||
| 	rgxKernelVersion = regexp.MustCompile(`(?:\A|\s)\d{1,3}\.\d{1,3}(?:\.\d{1,3})?`) | ||||
|  | ||||
| 	kernelVersion = struct { | ||||
| 		once    sync.Once | ||||
| 		version Version | ||||
| 		err     error | ||||
| 	}{} | ||||
| ) | ||||
|  | ||||
| // A Version in the form Major.Minor.Patch. | ||||
| type Version [3]uint16 | ||||
|  | ||||
| // NewVersion creates a version from a string like "Major.Minor.Patch". | ||||
| // | ||||
| // Patch is optional. | ||||
| func NewVersion(ver string) (Version, error) { | ||||
| 	var major, minor, patch uint16 | ||||
| 	n, _ := fmt.Sscanf(ver, "%d.%d.%d", &major, &minor, &patch) | ||||
| 	if n < 2 { | ||||
| 		return Version{}, fmt.Errorf("invalid version: %s", ver) | ||||
| 	} | ||||
| 	return Version{major, minor, patch}, nil | ||||
| } | ||||
|  | ||||
| func (v Version) String() string { | ||||
| 	if v[2] == 0 { | ||||
| 		return fmt.Sprintf("v%d.%d", v[0], v[1]) | ||||
| 	} | ||||
| 	return fmt.Sprintf("v%d.%d.%d", v[0], v[1], v[2]) | ||||
| } | ||||
|  | ||||
| // Less returns true if the version is less than another version. | ||||
| func (v Version) Less(other Version) bool { | ||||
| 	for i, a := range v { | ||||
| 		if a == other[i] { | ||||
| 			continue | ||||
| 		} | ||||
| 		return a < other[i] | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| // Unspecified returns true if the version is all zero. | ||||
| func (v Version) Unspecified() bool { | ||||
| 	return v[0] == 0 && v[1] == 0 && v[2] == 0 | ||||
| } | ||||
|  | ||||
| // Kernel implements the kernel's KERNEL_VERSION macro from linux/version.h. | ||||
| // It represents the kernel version and patch level as a single value. | ||||
| func (v Version) Kernel() uint32 { | ||||
|  | ||||
| 	// Kernels 4.4 and 4.9 have their SUBLEVEL clamped to 255 to avoid | ||||
| 	// overflowing into PATCHLEVEL. | ||||
| 	// See kernel commit 9b82f13e7ef3 ("kbuild: clamp SUBLEVEL to 255"). | ||||
| 	s := v[2] | ||||
| 	if s > 255 { | ||||
| 		s = 255 | ||||
| 	} | ||||
|  | ||||
| 	// Truncate members to uint8 to prevent them from spilling over into | ||||
| 	// each other when overflowing 8 bits. | ||||
| 	return uint32(uint8(v[0]))<<16 | uint32(uint8(v[1]))<<8 | uint32(uint8(s)) | ||||
| } | ||||
|  | ||||
| // KernelVersion returns the version of the currently running kernel. | ||||
| func KernelVersion() (Version, error) { | ||||
| 	kernelVersion.once.Do(func() { | ||||
| 		kernelVersion.version, kernelVersion.err = detectKernelVersion() | ||||
| 	}) | ||||
|  | ||||
| 	if kernelVersion.err != nil { | ||||
| 		return Version{}, kernelVersion.err | ||||
| 	} | ||||
| 	return kernelVersion.version, nil | ||||
| } | ||||
|  | ||||
| // detectKernelVersion returns the version of the running kernel. It scans the | ||||
| // following sources in order: /proc/version_signature, uname -v, uname -r. | ||||
| // In each of those locations, the last-appearing x.y(.z) value is selected | ||||
| // for parsing. The first location that yields a usable version number is | ||||
| // returned. | ||||
| func detectKernelVersion() (Version, error) { | ||||
|  | ||||
| 	// Try reading /proc/version_signature for Ubuntu compatibility. | ||||
| 	// 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 /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. | ||||
| 		v, err := findKernelVersion(string(pvs)) | ||||
| 		if err != nil { | ||||
| 			return Version{}, err | ||||
| 		} | ||||
| 		return v, nil | ||||
| 	} | ||||
|  | ||||
| 	var uname unix.Utsname | ||||
| 	if err := unix.Uname(&uname); err != nil { | ||||
| 		return Version{}, fmt.Errorf("calling uname: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	// Debian puts the version including the patch level in uname.Version. | ||||
| 	// It is not an error if there's no version number in uname.Version, | ||||
| 	// as most distributions don't use it. Parsing can continue on uname.Release. | ||||
| 	// Example format: #1 SMP Debian 4.19.37-5+deb10u2 (2019-08-08) | ||||
| 	if v, err := findKernelVersion(unix.ByteSliceToString(uname.Version[:])); err == nil { | ||||
| 		return v, nil | ||||
| 	} | ||||
|  | ||||
| 	// Most other distributions have the full kernel version including patch | ||||
| 	// level in uname.Release. | ||||
| 	// Example format: 4.19.0-5-amd64, 5.5.10-arch1-1 | ||||
| 	v, err := findKernelVersion(unix.ByteSliceToString(uname.Release[:])) | ||||
| 	if err != nil { | ||||
| 		return Version{}, err | ||||
| 	} | ||||
|  | ||||
| 	return v, nil | ||||
| } | ||||
|  | ||||
| // findKernelVersion matches s against rgxKernelVersion and parses the result | ||||
| // into a Version. If s contains multiple matches, the last entry is selected. | ||||
| func findKernelVersion(s string) (Version, error) { | ||||
| 	m := rgxKernelVersion.FindAllString(s, -1) | ||||
| 	if m == nil { | ||||
| 		return Version{}, fmt.Errorf("no kernel version in string: %s", s) | ||||
| 	} | ||||
| 	// Pick the last match of the string in case there are multiple. | ||||
| 	s = m[len(m)-1] | ||||
|  | ||||
| 	v, err := NewVersion(s) | ||||
| 	if err != nil { | ||||
| 		return Version{}, fmt.Errorf("parsing version string %s: %w", s, err) | ||||
| 	} | ||||
|  | ||||
| 	return v, nil | ||||
| } | ||||
							
								
								
									
										171
									
								
								vendor/github.com/cilium/ebpf/link/cgroup.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										171
									
								
								vendor/github.com/cilium/ebpf/link/cgroup.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,171 +0,0 @@ | ||||
| package link | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"os" | ||||
|  | ||||
| 	"github.com/cilium/ebpf" | ||||
| ) | ||||
|  | ||||
| type cgroupAttachFlags uint32 | ||||
|  | ||||
| // cgroup attach flags | ||||
| const ( | ||||
| 	flagAllowOverride cgroupAttachFlags = 1 << iota | ||||
| 	flagAllowMulti | ||||
| 	flagReplace | ||||
| ) | ||||
|  | ||||
| type CgroupOptions struct { | ||||
| 	// Path to a cgroupv2 folder. | ||||
| 	Path string | ||||
| 	// One of the AttachCgroup* constants | ||||
| 	Attach ebpf.AttachType | ||||
| 	// Program must be of type CGroup*, and the attach type must match Attach. | ||||
| 	Program *ebpf.Program | ||||
| } | ||||
|  | ||||
| // AttachCgroup links a BPF program to a cgroup. | ||||
| func AttachCgroup(opts CgroupOptions) (Link, error) { | ||||
| 	cgroup, err := os.Open(opts.Path) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("can't open cgroup: %s", err) | ||||
| 	} | ||||
|  | ||||
| 	clone, err := opts.Program.Clone() | ||||
| 	if err != nil { | ||||
| 		cgroup.Close() | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	var cg Link | ||||
| 	cg, err = newLinkCgroup(cgroup, opts.Attach, clone) | ||||
| 	if errors.Is(err, ErrNotSupported) { | ||||
| 		cg, err = newProgAttachCgroup(cgroup, opts.Attach, clone, flagAllowMulti) | ||||
| 	} | ||||
| 	if errors.Is(err, ErrNotSupported) { | ||||
| 		cg, err = newProgAttachCgroup(cgroup, opts.Attach, clone, flagAllowOverride) | ||||
| 	} | ||||
| 	if err != nil { | ||||
| 		cgroup.Close() | ||||
| 		clone.Close() | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return cg, nil | ||||
| } | ||||
|  | ||||
| // LoadPinnedCgroup loads a pinned cgroup from a bpffs. | ||||
| func LoadPinnedCgroup(fileName string, opts *ebpf.LoadPinOptions) (Link, error) { | ||||
| 	link, err := LoadPinnedRawLink(fileName, CgroupType, opts) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return &linkCgroup{*link}, nil | ||||
| } | ||||
|  | ||||
| type progAttachCgroup struct { | ||||
| 	cgroup     *os.File | ||||
| 	current    *ebpf.Program | ||||
| 	attachType ebpf.AttachType | ||||
| 	flags      cgroupAttachFlags | ||||
| } | ||||
|  | ||||
| var _ Link = (*progAttachCgroup)(nil) | ||||
|  | ||||
| func (cg *progAttachCgroup) isLink() {} | ||||
|  | ||||
| func newProgAttachCgroup(cgroup *os.File, attach ebpf.AttachType, prog *ebpf.Program, flags cgroupAttachFlags) (*progAttachCgroup, error) { | ||||
| 	if flags&flagAllowMulti > 0 { | ||||
| 		if err := haveProgAttachReplace(); err != nil { | ||||
| 			return nil, fmt.Errorf("can't support multiple programs: %w", err) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	err := RawAttachProgram(RawAttachProgramOptions{ | ||||
| 		Target:  int(cgroup.Fd()), | ||||
| 		Program: prog, | ||||
| 		Flags:   uint32(flags), | ||||
| 		Attach:  attach, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("cgroup: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	return &progAttachCgroup{cgroup, prog, attach, flags}, nil | ||||
| } | ||||
|  | ||||
| func (cg *progAttachCgroup) Close() error { | ||||
| 	defer cg.cgroup.Close() | ||||
| 	defer cg.current.Close() | ||||
|  | ||||
| 	err := RawDetachProgram(RawDetachProgramOptions{ | ||||
| 		Target:  int(cg.cgroup.Fd()), | ||||
| 		Program: cg.current, | ||||
| 		Attach:  cg.attachType, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("close cgroup: %s", err) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (cg *progAttachCgroup) Update(prog *ebpf.Program) error { | ||||
| 	new, err := prog.Clone() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	args := RawAttachProgramOptions{ | ||||
| 		Target:  int(cg.cgroup.Fd()), | ||||
| 		Program: prog, | ||||
| 		Attach:  cg.attachType, | ||||
| 		Flags:   uint32(cg.flags), | ||||
| 	} | ||||
|  | ||||
| 	if cg.flags&flagAllowMulti > 0 { | ||||
| 		// Atomically replacing multiple programs requires at least | ||||
| 		// 5.5 (commit 7dd68b3279f17921 "bpf: Support replacing cgroup-bpf | ||||
| 		// program in MULTI mode") | ||||
| 		args.Flags |= uint32(flagReplace) | ||||
| 		args.Replace = cg.current | ||||
| 	} | ||||
|  | ||||
| 	if err := RawAttachProgram(args); err != nil { | ||||
| 		new.Close() | ||||
| 		return fmt.Errorf("can't update cgroup: %s", err) | ||||
| 	} | ||||
|  | ||||
| 	cg.current.Close() | ||||
| 	cg.current = new | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (cg *progAttachCgroup) Pin(string) error { | ||||
| 	return fmt.Errorf("can't pin cgroup: %w", ErrNotSupported) | ||||
| } | ||||
|  | ||||
| func (cg *progAttachCgroup) Unpin() error { | ||||
| 	return fmt.Errorf("can't pin cgroup: %w", ErrNotSupported) | ||||
| } | ||||
|  | ||||
| type linkCgroup struct { | ||||
| 	RawLink | ||||
| } | ||||
|  | ||||
| var _ Link = (*linkCgroup)(nil) | ||||
|  | ||||
| func newLinkCgroup(cgroup *os.File, attach ebpf.AttachType, prog *ebpf.Program) (*linkCgroup, error) { | ||||
| 	link, err := AttachRawLink(RawLinkOptions{ | ||||
| 		Target:  int(cgroup.Fd()), | ||||
| 		Program: prog, | ||||
| 		Attach:  attach, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return &linkCgroup{*link}, err | ||||
| } | ||||
							
								
								
									
										2
									
								
								vendor/github.com/cilium/ebpf/link/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/cilium/ebpf/link/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,2 +0,0 @@ | ||||
| // Package link allows attaching eBPF programs to various kernel hooks. | ||||
| package link | ||||
							
								
								
									
										67
									
								
								vendor/github.com/cilium/ebpf/link/iter.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										67
									
								
								vendor/github.com/cilium/ebpf/link/iter.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,67 +0,0 @@ | ||||
| package link | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"io" | ||||
|  | ||||
| 	"github.com/cilium/ebpf" | ||||
| ) | ||||
|  | ||||
| type IterOptions struct { | ||||
| 	// Program must be of type Tracing with attach type | ||||
| 	// AttachTraceIter. The kind of iterator to attach to is | ||||
| 	// determined at load time via the AttachTo field. | ||||
| 	// | ||||
| 	// AttachTo requires the kernel to include BTF of itself, | ||||
| 	// and it to be compiled with a recent pahole (>= 1.16). | ||||
| 	Program *ebpf.Program | ||||
| } | ||||
|  | ||||
| // AttachIter attaches a BPF seq_file iterator. | ||||
| func AttachIter(opts IterOptions) (*Iter, error) { | ||||
| 	link, err := AttachRawLink(RawLinkOptions{ | ||||
| 		Program: opts.Program, | ||||
| 		Attach:  ebpf.AttachTraceIter, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("can't link iterator: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	return &Iter{*link}, err | ||||
| } | ||||
|  | ||||
| // LoadPinnedIter loads a pinned iterator from a bpffs. | ||||
| func LoadPinnedIter(fileName string, opts *ebpf.LoadPinOptions) (*Iter, error) { | ||||
| 	link, err := LoadPinnedRawLink(fileName, IterType, opts) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return &Iter{*link}, err | ||||
| } | ||||
|  | ||||
| // Iter represents an attached bpf_iter. | ||||
| type Iter struct { | ||||
| 	RawLink | ||||
| } | ||||
|  | ||||
| // Open creates a new instance of the iterator. | ||||
| // | ||||
| // Reading from the returned reader triggers the BPF program. | ||||
| func (it *Iter) Open() (io.ReadCloser, error) { | ||||
| 	linkFd, err := it.fd.Value() | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	attr := &bpfIterCreateAttr{ | ||||
| 		linkFd: linkFd, | ||||
| 	} | ||||
|  | ||||
| 	fd, err := bpfIterCreate(attr) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("can't create iterator: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	return fd.File("bpf_iter"), nil | ||||
| } | ||||
							
								
								
									
										296
									
								
								vendor/github.com/cilium/ebpf/link/kprobe.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										296
									
								
								vendor/github.com/cilium/ebpf/link/kprobe.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,296 +0,0 @@ | ||||
| package link | ||||
|  | ||||
| import ( | ||||
| 	"crypto/rand" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"runtime" | ||||
|  | ||||
| 	"github.com/cilium/ebpf" | ||||
| 	"github.com/cilium/ebpf/internal" | ||||
| 	"github.com/cilium/ebpf/internal/unix" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	kprobeEventsPath = filepath.Join(tracefsPath, "kprobe_events") | ||||
| ) | ||||
|  | ||||
| // Kprobe attaches the given eBPF program to a perf event that fires when the | ||||
| // given kernel symbol starts executing. See /proc/kallsyms for available | ||||
| // symbols. For example, printk(): | ||||
| // | ||||
| //	Kprobe("printk") | ||||
| // | ||||
| // The resulting 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 { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	err = k.attach(prog) | ||||
| 	if err != nil { | ||||
| 		k.Close() | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return k, nil | ||||
| } | ||||
|  | ||||
| // Kretprobe attaches the given eBPF program to a perf event that fires right | ||||
| // before the given kernel symbol exits, with the function stack left intact. | ||||
| // See /proc/kallsyms for available symbols. For example, printk(): | ||||
| // | ||||
| //	Kretprobe("printk") | ||||
| // | ||||
| // The resulting 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 { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	err = k.attach(prog) | ||||
| 	if err != nil { | ||||
| 		k.Close() | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return k, nil | ||||
| } | ||||
|  | ||||
| // kprobe opens a perf event on the given symbol and attaches prog to it. | ||||
| // If ret is true, create a kretprobe. | ||||
| func kprobe(symbol string, prog *ebpf.Program, ret bool) (*perfEvent, error) { | ||||
| 	if symbol == "" { | ||||
| 		return nil, fmt.Errorf("symbol name cannot be empty: %w", errInvalidInput) | ||||
| 	} | ||||
| 	if prog == nil { | ||||
| 		return nil, fmt.Errorf("prog cannot be nil: %w", errInvalidInput) | ||||
| 	} | ||||
| 	if !rgxTraceEvent.MatchString(symbol) { | ||||
| 		return nil, fmt.Errorf("symbol '%s' must be alphanumeric or underscore: %w", symbol, errInvalidInput) | ||||
| 	} | ||||
| 	if prog.Type() != ebpf.Kprobe { | ||||
| 		return nil, fmt.Errorf("eBPF program type %s is not a Kprobe: %w", prog.Type(), errInvalidInput) | ||||
| 	} | ||||
|  | ||||
| 	// Use kprobe PMU if the kernel has it available. | ||||
| 	tp, err := pmuKprobe(symbol, ret) | ||||
| 	if err == nil { | ||||
| 		return tp, nil | ||||
| 	} | ||||
| 	if err != nil && !errors.Is(err, ErrNotSupported) { | ||||
| 		return nil, fmt.Errorf("creating perf_kprobe PMU: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	// Use tracefs if kprobe PMU is missing. | ||||
| 	tp, err = tracefsKprobe(symbol, ret) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("creating trace event '%s' in tracefs: %w", symbol, err) | ||||
| 	} | ||||
|  | ||||
| 	return tp, nil | ||||
| } | ||||
|  | ||||
| // pmuKprobe opens a perf event based on a Performance Monitoring Unit. | ||||
| // Requires at least 4.17 (e12f03d7031a "perf/core: Implement the | ||||
| // 'perf_kprobe' PMU"). | ||||
| // Returns ErrNotSupported if the kernel doesn't support perf_kprobe PMU, | ||||
| // or os.ErrNotExist if the given symbol does not exist in the kernel. | ||||
| func pmuKprobe(symbol string, ret bool) (*perfEvent, error) { | ||||
|  | ||||
| 	// Getting the PMU type will fail if the kernel doesn't support | ||||
| 	// the perf_kprobe PMU. | ||||
| 	et, err := getPMUEventType("kprobe") | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	// Create a pointer to a NUL-terminated string for the kernel. | ||||
| 	sp, err := unsafeStringPtr(symbol) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	// TODO: Parse the position of the bit from /sys/bus/event_source/devices/%s/format/retprobe. | ||||
| 	config := 0 | ||||
| 	if ret { | ||||
| 		config = 1 | ||||
| 	} | ||||
|  | ||||
| 	attr := unix.PerfEventAttr{ | ||||
| 		Type:   uint32(et),          // PMU event type read from sysfs | ||||
| 		Ext1:   uint64(uintptr(sp)), // Kernel symbol to trace | ||||
| 		Config: uint64(config),      // perf_kprobe PMU treats config as flags | ||||
| 	} | ||||
|  | ||||
| 	fd, err := unix.PerfEventOpen(&attr, perfAllThreads, 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 | ||||
| 	// is returned to the caller. | ||||
| 	if errors.Is(err, os.ErrNotExist) || errors.Is(err, unix.EINVAL) { | ||||
| 		return nil, fmt.Errorf("symbol '%s' not found: %w", symbol, os.ErrNotExist) | ||||
| 	} | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("opening perf event: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	// Ensure the string pointer is not collected before PerfEventOpen returns. | ||||
| 	runtime.KeepAlive(sp) | ||||
|  | ||||
| 	// Kernel has perf_kprobe PMU available, initialize perf event. | ||||
| 	return &perfEvent{ | ||||
| 		fd:       internal.NewFD(uint32(fd)), | ||||
| 		pmuID:    et, | ||||
| 		name:     symbol, | ||||
| 		ret:      ret, | ||||
| 		progType: ebpf.Kprobe, | ||||
| 	}, nil | ||||
| } | ||||
|  | ||||
| // tracefsKprobe creates a trace event by writing an entry to <tracefs>/kprobe_events. | ||||
| // A new trace event group name is generated on every call to support creating | ||||
| // multiple trace events for the same kernel symbol. A perf event is then opened | ||||
| // on the newly-created trace event and returned to the caller. | ||||
| func tracefsKprobe(symbol string, 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. | ||||
| 	group, err := randomGroup("ebpf") | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("randomizing group name: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	// Before attempting to create a trace event through tracefs, | ||||
| 	// check if an event with the same group and name already exists. | ||||
| 	// Kernels 4.x and earlier don't return os.ErrExist on writing a duplicate | ||||
| 	// entry, so we need to rely on reads for detecting uniqueness. | ||||
| 	_, err = getTraceEventID(group, symbol) | ||||
| 	if err == nil { | ||||
| 		return nil, fmt.Errorf("trace event already exists: %s/%s", group, symbol) | ||||
| 	} | ||||
| 	// The read is expected to fail with ErrNotSupported due to a non-existing event. | ||||
| 	if err != nil && !errors.Is(err, ErrNotSupported) { | ||||
| 		return nil, fmt.Errorf("checking trace event %s/%s: %w", group, symbol, err) | ||||
| 	} | ||||
|  | ||||
| 	// Create the kprobe trace event using tracefs. | ||||
| 	if err := createTraceFSKprobeEvent(group, symbol, ret); err != nil { | ||||
| 		return nil, fmt.Errorf("creating kprobe event on tracefs: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	// Get the newly-created trace event's id. | ||||
| 	tid, err := getTraceEventID(group, symbol) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("getting trace event id: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	// Kprobes are ephemeral tracepoints and share the same perf event type. | ||||
| 	fd, err := openTracepointPerfEvent(tid) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return &perfEvent{ | ||||
| 		fd:        fd, | ||||
| 		group:     group, | ||||
| 		name:      symbol, | ||||
| 		ret:       ret, | ||||
| 		tracefsID: tid, | ||||
| 		progType:  ebpf.Kprobe, // kernel only allows attaching kprobe programs to kprobe events | ||||
| 	}, nil | ||||
| } | ||||
|  | ||||
| // createTraceFSKprobeEvent creates a new ephemeral trace event by writing to | ||||
| // <tracefs>/kprobe_events. Returns ErrNotSupported if symbol is not a valid | ||||
| // kernel symbol, or if it is not traceable with kprobes. | ||||
| func createTraceFSKprobeEvent(group, symbol string, ret bool) error { | ||||
| 	// Open the kprobe_events file in tracefs. | ||||
| 	f, err := os.OpenFile(kprobeEventsPath, os.O_APPEND|os.O_WRONLY, 0666) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("error opening kprobe_events: %w", err) | ||||
| 	} | ||||
| 	defer f.Close() | ||||
|  | ||||
| 	// The kprobe_events syntax is as follows (see Documentation/trace/kprobetrace.txt): | ||||
| 	// p[:[GRP/]EVENT] [MOD:]SYM[+offs]|MEMADDR [FETCHARGS] : Set a probe | ||||
| 	// r[MAXACTIVE][:[GRP/]EVENT] [MOD:]SYM[+0] [FETCHARGS] : Set a return probe | ||||
| 	// -:[GRP/]EVENT                                        : Clear a probe | ||||
| 	// | ||||
| 	// Some examples: | ||||
| 	// r:ebpf_1234/r_my_kretprobe nf_conntrack_destroy | ||||
| 	// p:ebpf_5678/p_my_kprobe __x64_sys_execve | ||||
| 	// | ||||
| 	// Leaving the kretprobe's MAXACTIVE set to 0 (or absent) will make the | ||||
| 	// kernel default to NR_CPUS. This is desired in most eBPF cases since | ||||
| 	// subsampling or rate limiting logic can be more accurately implemented in | ||||
| 	// the eBPF program itself. See Documentation/kprobes.txt for more details. | ||||
| 	pe := fmt.Sprintf("%s:%s/%s %s", kprobePrefix(ret), group, symbol, symbol) | ||||
| 	_, err = f.WriteString(pe) | ||||
| 	// Since commit 97c753e62e6c, ENOENT is correctly returned instead of EINVAL | ||||
| 	// when trying to create a kretprobe for a missing symbol. Make sure ENOENT | ||||
| 	// is returned to the caller. | ||||
| 	if errors.Is(err, os.ErrNotExist) || errors.Is(err, unix.EINVAL) { | ||||
| 		return fmt.Errorf("kernel symbol %s not found: %w", symbol, os.ErrNotExist) | ||||
| 	} | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("writing '%s' to kprobe_events: %w", pe, err) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // closeTraceFSKprobeEvent removes the kprobe with the given group, symbol and kind | ||||
| // from <tracefs>/kprobe_events. | ||||
| func closeTraceFSKprobeEvent(group, symbol string) error { | ||||
| 	f, err := os.OpenFile(kprobeEventsPath, os.O_APPEND|os.O_WRONLY, 0666) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("error opening kprobe_events: %w", err) | ||||
| 	} | ||||
| 	defer f.Close() | ||||
|  | ||||
| 	// See kprobe_events syntax above. Kprobe type does not need to be specified | ||||
| 	// for removals. | ||||
| 	pe := fmt.Sprintf("-:%s/%s", group, symbol) | ||||
| 	if _, err = f.WriteString(pe); err != nil { | ||||
| 		return fmt.Errorf("writing '%s' to kprobe_events: %w", pe, err) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // randomGroup generates a pseudorandom string for use as a tracefs group name. | ||||
| // Returns an error when the output string would exceed 63 characters (kernel | ||||
| // limitation), when rand.Read() fails or when prefix contains characters not | ||||
| // allowed by rgxTraceEvent. | ||||
| func randomGroup(prefix string) (string, error) { | ||||
| 	if !rgxTraceEvent.MatchString(prefix) { | ||||
| 		return "", fmt.Errorf("prefix '%s' must be alphanumeric or underscore: %w", prefix, errInvalidInput) | ||||
| 	} | ||||
|  | ||||
| 	b := make([]byte, 8) | ||||
| 	if _, err := rand.Read(b); err != nil { | ||||
| 		return "", fmt.Errorf("reading random bytes: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	group := fmt.Sprintf("%s_%x", prefix, b) | ||||
| 	if len(group) > 63 { | ||||
| 		return "", fmt.Errorf("group name '%s' cannot be longer than 63 characters: %w", group, errInvalidInput) | ||||
| 	} | ||||
|  | ||||
| 	return group, nil | ||||
| } | ||||
|  | ||||
| func kprobePrefix(ret bool) string { | ||||
| 	if ret { | ||||
| 		return "r" | ||||
| 	} | ||||
| 	return "p" | ||||
| } | ||||
							
								
								
									
										229
									
								
								vendor/github.com/cilium/ebpf/link/link.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										229
									
								
								vendor/github.com/cilium/ebpf/link/link.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,229 +0,0 @@ | ||||
| package link | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"unsafe" | ||||
|  | ||||
| 	"github.com/cilium/ebpf" | ||||
| 	"github.com/cilium/ebpf/internal" | ||||
| ) | ||||
|  | ||||
| var ErrNotSupported = internal.ErrNotSupported | ||||
|  | ||||
| // Link represents a Program attached to a BPF hook. | ||||
| type Link interface { | ||||
| 	// Replace the current program with a new program. | ||||
| 	// | ||||
| 	// Passing a nil program is an error. May return an error wrapping ErrNotSupported. | ||||
| 	Update(*ebpf.Program) error | ||||
|  | ||||
| 	// Persist a link by pinning it into a bpffs. | ||||
| 	// | ||||
| 	// May return an error wrapping ErrNotSupported. | ||||
| 	Pin(string) error | ||||
|  | ||||
| 	// Undo a previous call to Pin. | ||||
| 	// | ||||
| 	// May return an error wrapping ErrNotSupported. | ||||
| 	Unpin() error | ||||
|  | ||||
| 	// 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 | ||||
| 	// not called. | ||||
| 	Close() error | ||||
|  | ||||
| 	// Prevent external users from implementing this interface. | ||||
| 	isLink() | ||||
| } | ||||
|  | ||||
| // ID uniquely identifies a BPF link. | ||||
| type ID uint32 | ||||
|  | ||||
| // RawLinkOptions control the creation of a raw link. | ||||
| type RawLinkOptions struct { | ||||
| 	// File descriptor to attach to. This differs for each attach type. | ||||
| 	Target int | ||||
| 	// Program to attach. | ||||
| 	Program *ebpf.Program | ||||
| 	// Attach must match the attach type of Program. | ||||
| 	Attach ebpf.AttachType | ||||
| } | ||||
|  | ||||
| // RawLinkInfo contains metadata on a link. | ||||
| type RawLinkInfo struct { | ||||
| 	Type    Type | ||||
| 	ID      ID | ||||
| 	Program ebpf.ProgramID | ||||
| } | ||||
|  | ||||
| // RawLink is the low-level API to bpf_link. | ||||
| // | ||||
| // You should consider using the higher level interfaces in this | ||||
| // package instead. | ||||
| type RawLink struct { | ||||
| 	fd         *internal.FD | ||||
| 	pinnedPath string | ||||
| } | ||||
|  | ||||
| // AttachRawLink creates a raw link. | ||||
| func AttachRawLink(opts RawLinkOptions) (*RawLink, error) { | ||||
| 	if err := haveBPFLink(); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	if opts.Target < 0 { | ||||
| 		return nil, fmt.Errorf("invalid target: %s", internal.ErrClosedFd) | ||||
| 	} | ||||
|  | ||||
| 	progFd := opts.Program.FD() | ||||
| 	if progFd < 0 { | ||||
| 		return nil, fmt.Errorf("invalid program: %s", internal.ErrClosedFd) | ||||
| 	} | ||||
|  | ||||
| 	attr := bpfLinkCreateAttr{ | ||||
| 		targetFd:   uint32(opts.Target), | ||||
| 		progFd:     uint32(progFd), | ||||
| 		attachType: opts.Attach, | ||||
| 	} | ||||
| 	fd, err := bpfLinkCreate(&attr) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("can't create link: %s", err) | ||||
| 	} | ||||
|  | ||||
| 	return &RawLink{fd, ""}, nil | ||||
| } | ||||
|  | ||||
| // LoadPinnedRawLink loads a persisted link from a bpffs. | ||||
| // | ||||
| // Returns an error if the pinned link type doesn't match linkType. Pass | ||||
| // UnspecifiedType to disable this behaviour. | ||||
| func LoadPinnedRawLink(fileName string, linkType Type, opts *ebpf.LoadPinOptions) (*RawLink, error) { | ||||
| 	fd, err := internal.BPFObjGet(fileName, opts.Marshal()) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("load pinned link: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	link := &RawLink{fd, fileName} | ||||
| 	if linkType == UnspecifiedType { | ||||
| 		return link, nil | ||||
| 	} | ||||
|  | ||||
| 	info, err := link.Info() | ||||
| 	if err != nil { | ||||
| 		link.Close() | ||||
| 		return nil, fmt.Errorf("get pinned link info: %s", err) | ||||
| 	} | ||||
|  | ||||
| 	if info.Type != linkType { | ||||
| 		link.Close() | ||||
| 		return nil, fmt.Errorf("link type %v doesn't match %v", info.Type, linkType) | ||||
| 	} | ||||
|  | ||||
| 	return link, nil | ||||
| } | ||||
|  | ||||
| func (l *RawLink) isLink() {} | ||||
|  | ||||
| // FD returns the raw file descriptor. | ||||
| func (l *RawLink) FD() int { | ||||
| 	fd, err := l.fd.Value() | ||||
| 	if err != nil { | ||||
| 		return -1 | ||||
| 	} | ||||
| 	return int(fd) | ||||
| } | ||||
|  | ||||
| // Close breaks the link. | ||||
| // | ||||
| // Use Pin if you want to make the link persistent. | ||||
| func (l *RawLink) Close() error { | ||||
| 	return l.fd.Close() | ||||
| } | ||||
|  | ||||
| // Pin persists a link past the lifetime of the process. | ||||
| // | ||||
| // Calling Close on a pinned Link will not break the link | ||||
| // until the pin is removed. | ||||
| func (l *RawLink) Pin(fileName string) error { | ||||
| 	if err := internal.Pin(l.pinnedPath, fileName, l.fd); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	l.pinnedPath = fileName | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Unpin implements the Link interface. | ||||
| func (l *RawLink) Unpin() error { | ||||
| 	if err := internal.Unpin(l.pinnedPath); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	l.pinnedPath = "" | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Update implements the Link interface. | ||||
| func (l *RawLink) Update(new *ebpf.Program) error { | ||||
| 	return l.UpdateArgs(RawLinkUpdateOptions{ | ||||
| 		New: new, | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // RawLinkUpdateOptions control the behaviour of RawLink.UpdateArgs. | ||||
| type RawLinkUpdateOptions struct { | ||||
| 	New   *ebpf.Program | ||||
| 	Old   *ebpf.Program | ||||
| 	Flags uint32 | ||||
| } | ||||
|  | ||||
| // UpdateArgs updates a link based on args. | ||||
| func (l *RawLink) UpdateArgs(opts RawLinkUpdateOptions) error { | ||||
| 	newFd := opts.New.FD() | ||||
| 	if newFd < 0 { | ||||
| 		return fmt.Errorf("invalid program: %s", internal.ErrClosedFd) | ||||
| 	} | ||||
|  | ||||
| 	var oldFd int | ||||
| 	if opts.Old != nil { | ||||
| 		oldFd = opts.Old.FD() | ||||
| 		if oldFd < 0 { | ||||
| 			return fmt.Errorf("invalid replacement program: %s", internal.ErrClosedFd) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	linkFd, err := l.fd.Value() | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("can't update link: %s", err) | ||||
| 	} | ||||
|  | ||||
| 	attr := bpfLinkUpdateAttr{ | ||||
| 		linkFd:    linkFd, | ||||
| 		newProgFd: uint32(newFd), | ||||
| 		oldProgFd: uint32(oldFd), | ||||
| 		flags:     opts.Flags, | ||||
| 	} | ||||
| 	return bpfLinkUpdate(&attr) | ||||
| } | ||||
|  | ||||
| // struct bpf_link_info | ||||
| type bpfLinkInfo struct { | ||||
| 	typ     uint32 | ||||
| 	id      uint32 | ||||
| 	prog_id uint32 | ||||
| } | ||||
|  | ||||
| // Info returns metadata about the link. | ||||
| func (l *RawLink) Info() (*RawLinkInfo, error) { | ||||
| 	var info bpfLinkInfo | ||||
| 	err := internal.BPFObjGetInfoByFD(l.fd, unsafe.Pointer(&info), unsafe.Sizeof(info)) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("link info: %s", err) | ||||
| 	} | ||||
|  | ||||
| 	return &RawLinkInfo{ | ||||
| 		Type(info.typ), | ||||
| 		ID(info.id), | ||||
| 		ebpf.ProgramID(info.prog_id), | ||||
| 	}, nil | ||||
| } | ||||
							
								
								
									
										60
									
								
								vendor/github.com/cilium/ebpf/link/netns.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										60
									
								
								vendor/github.com/cilium/ebpf/link/netns.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,60 +0,0 @@ | ||||
| package link | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
|  | ||||
| 	"github.com/cilium/ebpf" | ||||
| ) | ||||
|  | ||||
| // NetNsInfo contains metadata about a network namespace link. | ||||
| type NetNsInfo struct { | ||||
| 	RawLinkInfo | ||||
| } | ||||
|  | ||||
| // NetNsLink is a program attached to a network namespace. | ||||
| type NetNsLink struct { | ||||
| 	*RawLink | ||||
| } | ||||
|  | ||||
| // AttachNetNs attaches a program to a network namespace. | ||||
| func AttachNetNs(ns int, prog *ebpf.Program) (*NetNsLink, error) { | ||||
| 	var attach ebpf.AttachType | ||||
| 	switch t := prog.Type(); t { | ||||
| 	case ebpf.FlowDissector: | ||||
| 		attach = ebpf.AttachFlowDissector | ||||
| 	case ebpf.SkLookup: | ||||
| 		attach = ebpf.AttachSkLookup | ||||
| 	default: | ||||
| 		return nil, fmt.Errorf("can't attach %v to network namespace", t) | ||||
| 	} | ||||
|  | ||||
| 	link, err := AttachRawLink(RawLinkOptions{ | ||||
| 		Target:  ns, | ||||
| 		Program: prog, | ||||
| 		Attach:  attach, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return &NetNsLink{link}, nil | ||||
| } | ||||
|  | ||||
| // LoadPinnedNetNs loads a network namespace link from bpffs. | ||||
| func LoadPinnedNetNs(fileName string, opts *ebpf.LoadPinOptions) (*NetNsLink, error) { | ||||
| 	link, err := LoadPinnedRawLink(fileName, NetNsType, opts) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return &NetNsLink{link}, nil | ||||
| } | ||||
|  | ||||
| // Info returns information about the link. | ||||
| func (nns *NetNsLink) Info() (*NetNsInfo, error) { | ||||
| 	info, err := nns.RawLink.Info() | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return &NetNsInfo{*info}, nil | ||||
| } | ||||
							
								
								
									
										253
									
								
								vendor/github.com/cilium/ebpf/link/perf_event.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										253
									
								
								vendor/github.com/cilium/ebpf/link/perf_event.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,253 +0,0 @@ | ||||
| package link | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"io/ioutil" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"regexp" | ||||
| 	"runtime" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| 	"unsafe" | ||||
|  | ||||
| 	"github.com/cilium/ebpf" | ||||
| 	"github.com/cilium/ebpf/internal" | ||||
| 	"github.com/cilium/ebpf/internal/unix" | ||||
| ) | ||||
|  | ||||
| // Getting the terminology right is usually the hardest part. For posterity and | ||||
| // for staying sane during implementation: | ||||
| // | ||||
| // - trace event: Representation of a kernel runtime hook. Filesystem entries | ||||
| //   under <tracefs>/events. Can be tracepoints (static), kprobes or uprobes. | ||||
| //   Can be instantiated into perf events (see below). | ||||
| // - tracepoint: A predetermined hook point in the kernel. Exposed as trace | ||||
| //   events in (sub)directories under <tracefs>/events. Cannot be closed or | ||||
| //   removed, they are static. | ||||
| // - k(ret)probe: Ephemeral trace events based on entry or exit points of | ||||
| //   exported kernel symbols. kprobe-based (tracefs) trace events can be | ||||
| //   created system-wide by writing to the <tracefs>/kprobe_events file, or | ||||
| //   they can be scoped to the current process by creating PMU perf events. | ||||
| // - perf event: An object instantiated based on an existing trace event or | ||||
| //   kernel symbol. Referred to by fd in userspace. | ||||
| //   Exactly one eBPF program can be attached to a perf event. Multiple perf | ||||
| //   events can be created from a single trace event. Closing a perf event | ||||
| //   stops any further invocations of the attached eBPF program. | ||||
|  | ||||
| var ( | ||||
| 	tracefsPath = "/sys/kernel/debug/tracing" | ||||
|  | ||||
| 	// Trace event groups, names and kernel symbols must adhere to this set | ||||
| 	// of characters. Non-empty, first character must not be a number, all | ||||
| 	// characters must be alphanumeric or underscore. | ||||
| 	rgxTraceEvent = regexp.MustCompile("^[a-zA-Z_][0-9a-zA-Z_]*$") | ||||
|  | ||||
| 	errInvalidInput = errors.New("invalid input") | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	perfAllThreads = -1 | ||||
| ) | ||||
|  | ||||
| // A perfEvent represents a perf event kernel object. Exactly one eBPF program | ||||
| // can be attached to it. It is created based on a tracefs trace event or a | ||||
| // Performance Monitoring Unit (PMU). | ||||
| type perfEvent struct { | ||||
|  | ||||
| 	// Group and name of the tracepoint/kprobe/uprobe. | ||||
| 	group string | ||||
| 	name  string | ||||
|  | ||||
| 	// PMU event ID read from sysfs. Valid IDs are non-zero. | ||||
| 	pmuID uint64 | ||||
| 	// ID of the trace event read from tracefs. Valid IDs are non-zero. | ||||
| 	tracefsID uint64 | ||||
|  | ||||
| 	// True for kretprobes/uretprobes. | ||||
| 	ret bool | ||||
|  | ||||
| 	fd       *internal.FD | ||||
| 	progType ebpf.ProgramType | ||||
| } | ||||
|  | ||||
| func (pe *perfEvent) isLink() {} | ||||
|  | ||||
| func (pe *perfEvent) Pin(string) error { | ||||
| 	return fmt.Errorf("pin perf event: %w", ErrNotSupported) | ||||
| } | ||||
|  | ||||
| func (pe *perfEvent) Unpin() error { | ||||
| 	return fmt.Errorf("unpin perf event: %w", ErrNotSupported) | ||||
| } | ||||
|  | ||||
| // Since 4.15 (e87c6bc3852b "bpf: permit multiple bpf attachments for a single perf event"), | ||||
| // calling PERF_EVENT_IOC_SET_BPF appends the given program to a prog_array | ||||
| // owned by the perf event, which means multiple programs can be attached | ||||
| // simultaneously. | ||||
| // | ||||
| // Before 4.15, calling PERF_EVENT_IOC_SET_BPF more than once on a perf event | ||||
| // returns EEXIST. | ||||
| // | ||||
| // Detaching a program from a perf event is currently not possible, so a | ||||
| // program replacement mechanism cannot be implemented for perf events. | ||||
| func (pe *perfEvent) Update(prog *ebpf.Program) error { | ||||
| 	return fmt.Errorf("can't replace eBPF program in perf event: %w", ErrNotSupported) | ||||
| } | ||||
|  | ||||
| func (pe *perfEvent) Close() error { | ||||
| 	if pe.fd == nil { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	pfd, err := pe.fd.Value() | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("getting perf event fd: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	err = unix.IoctlSetInt(int(pfd), unix.PERF_EVENT_IOC_DISABLE, 0) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("disabling perf event: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	err = pe.fd.Close() | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("closing perf event fd: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	switch t := pe.progType; t { | ||||
| 	case ebpf.Kprobe: | ||||
| 		// For kprobes created using tracefs, clean up the <tracefs>/kprobe_events entry. | ||||
| 		if pe.tracefsID != 0 { | ||||
| 			return closeTraceFSKprobeEvent(pe.group, pe.name) | ||||
| 		} | ||||
| 	case ebpf.TracePoint: | ||||
| 		// Tracepoint trace events don't hold any extra resources. | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // attach the given eBPF prog to the perf event stored in pe. | ||||
| // pe must contain a valid perf event fd. | ||||
| // prog's type must match the program type stored in pe. | ||||
| func (pe *perfEvent) attach(prog *ebpf.Program) error { | ||||
| 	if prog == nil { | ||||
| 		return errors.New("cannot attach a nil program") | ||||
| 	} | ||||
| 	if pe.fd == nil { | ||||
| 		return errors.New("cannot attach to nil perf event") | ||||
| 	} | ||||
| 	if t := prog.Type(); t != pe.progType { | ||||
| 		return fmt.Errorf("invalid program type (expected %s): %s", pe.progType, t) | ||||
| 	} | ||||
| 	if prog.FD() < 0 { | ||||
| 		return fmt.Errorf("invalid program: %w", internal.ErrClosedFd) | ||||
| 	} | ||||
|  | ||||
| 	// The ioctl below will fail when the fd is invalid. | ||||
| 	kfd, _ := pe.fd.Value() | ||||
|  | ||||
| 	// Assign the eBPF program to the perf event. | ||||
| 	err := unix.IoctlSetInt(int(kfd), unix.PERF_EVENT_IOC_SET_BPF, prog.FD()) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("setting perf event bpf program: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	// PERF_EVENT_IOC_ENABLE and _DISABLE ignore their given values. | ||||
| 	if err := unix.IoctlSetInt(int(kfd), unix.PERF_EVENT_IOC_ENABLE, 0); err != nil { | ||||
| 		return fmt.Errorf("enable perf event: %s", err) | ||||
| 	} | ||||
|  | ||||
| 	// Close the perf event when its reference is lost to avoid leaking system resources. | ||||
| 	runtime.SetFinalizer(pe, (*perfEvent).Close) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // unsafeStringPtr returns an unsafe.Pointer to a NUL-terminated copy of str. | ||||
| func unsafeStringPtr(str string) (unsafe.Pointer, error) { | ||||
| 	p, err := unix.BytePtrFromString(str) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return unsafe.Pointer(p), nil | ||||
| } | ||||
|  | ||||
| // getTraceEventID reads a trace event's ID from tracefs given its group and name. | ||||
| // group and name must be alphanumeric or underscore, as required by the kernel. | ||||
| func getTraceEventID(group, name string) (uint64, error) { | ||||
| 	tid, err := uint64FromFile(tracefsPath, "events", group, name, "id") | ||||
| 	if errors.Is(err, ErrNotSupported) { | ||||
| 		return 0, fmt.Errorf("trace event %s/%s: %w", group, name, ErrNotSupported) | ||||
| 	} | ||||
| 	if err != nil { | ||||
| 		return 0, fmt.Errorf("reading trace event ID of %s/%s: %w", group, name, err) | ||||
| 	} | ||||
|  | ||||
| 	return tid, nil | ||||
| } | ||||
|  | ||||
| // getPMUEventType reads a Performance Monitoring Unit's type (numeric identifier) | ||||
| // from /sys/bus/event_source/devices/<pmu>/type. | ||||
| func getPMUEventType(pmu string) (uint64, error) { | ||||
| 	et, err := uint64FromFile("/sys/bus/event_source/devices", pmu, "type") | ||||
| 	if errors.Is(err, ErrNotSupported) { | ||||
| 		return 0, fmt.Errorf("pmu type %s: %w", pmu, ErrNotSupported) | ||||
| 	} | ||||
| 	if err != nil { | ||||
| 		return 0, fmt.Errorf("reading pmu type %s: %w", pmu, err) | ||||
| 	} | ||||
|  | ||||
| 	return et, nil | ||||
| } | ||||
|  | ||||
| // openTracepointPerfEvent opens a tracepoint-type perf event. System-wide | ||||
| // kprobes created by writing to <tracefs>/kprobe_events are tracepoints | ||||
| // behind the scenes, and can be attached to using these perf events. | ||||
| func openTracepointPerfEvent(tid uint64) (*internal.FD, error) { | ||||
| 	attr := unix.PerfEventAttr{ | ||||
| 		Type:        unix.PERF_TYPE_TRACEPOINT, | ||||
| 		Config:      tid, | ||||
| 		Sample_type: unix.PERF_SAMPLE_RAW, | ||||
| 		Sample:      1, | ||||
| 		Wakeup:      1, | ||||
| 	} | ||||
|  | ||||
| 	fd, err := unix.PerfEventOpen(&attr, perfAllThreads, 0, -1, unix.PERF_FLAG_FD_CLOEXEC) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("opening tracepoint perf event: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	return internal.NewFD(uint32(fd)), nil | ||||
| } | ||||
|  | ||||
| // uint64FromFile reads a uint64 from a file. All elements of path are sanitized | ||||
| // and joined onto base. Returns error if base no longer prefixes the path after | ||||
| // joining all components. | ||||
| func uint64FromFile(base string, path ...string) (uint64, error) { | ||||
|  | ||||
| 	// Resolve leaf path separately for error feedback. Makes the join onto | ||||
| 	// base more readable (can't mix with variadic args). | ||||
| 	l := filepath.Join(path...) | ||||
|  | ||||
| 	p := filepath.Join(base, l) | ||||
| 	if !strings.HasPrefix(p, base) { | ||||
| 		return 0, fmt.Errorf("path '%s' attempts to escape base path '%s': %w", l, base, errInvalidInput) | ||||
| 	} | ||||
|  | ||||
| 	data, err := ioutil.ReadFile(p) | ||||
| 	if os.IsNotExist(err) { | ||||
| 		// Only echo leaf path, the base path can be prepended at the call site | ||||
| 		// if more verbosity is required. | ||||
| 		return 0, fmt.Errorf("symbol %s: %w", l, ErrNotSupported) | ||||
| 	} | ||||
| 	if err != nil { | ||||
| 		return 0, fmt.Errorf("reading file %s: %w", p, err) | ||||
| 	} | ||||
|  | ||||
| 	et := bytes.TrimSpace(data) | ||||
| 	return strconv.ParseUint(string(et), 10, 64) | ||||
| } | ||||
							
								
								
									
										76
									
								
								vendor/github.com/cilium/ebpf/link/program.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										76
									
								
								vendor/github.com/cilium/ebpf/link/program.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,76 +0,0 @@ | ||||
| package link | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
|  | ||||
| 	"github.com/cilium/ebpf" | ||||
| 	"github.com/cilium/ebpf/internal" | ||||
| ) | ||||
|  | ||||
| type RawAttachProgramOptions struct { | ||||
| 	// File descriptor to attach to. This differs for each attach type. | ||||
| 	Target int | ||||
| 	// Program to attach. | ||||
| 	Program *ebpf.Program | ||||
| 	// Program to replace (cgroups). | ||||
| 	Replace *ebpf.Program | ||||
| 	// Attach must match the attach type of Program (and Replace). | ||||
| 	Attach ebpf.AttachType | ||||
| 	// Flags control the attach behaviour. This differs for each attach type. | ||||
| 	Flags uint32 | ||||
| } | ||||
|  | ||||
| // RawAttachProgram is a low level wrapper around BPF_PROG_ATTACH. | ||||
| // | ||||
| // You should use one of the higher level abstractions available in this | ||||
| // package if possible. | ||||
| func RawAttachProgram(opts RawAttachProgramOptions) error { | ||||
| 	if err := haveProgAttach(); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	var replaceFd uint32 | ||||
| 	if opts.Replace != nil { | ||||
| 		replaceFd = uint32(opts.Replace.FD()) | ||||
| 	} | ||||
|  | ||||
| 	attr := internal.BPFProgAttachAttr{ | ||||
| 		TargetFd:     uint32(opts.Target), | ||||
| 		AttachBpfFd:  uint32(opts.Program.FD()), | ||||
| 		ReplaceBpfFd: replaceFd, | ||||
| 		AttachType:   uint32(opts.Attach), | ||||
| 		AttachFlags:  uint32(opts.Flags), | ||||
| 	} | ||||
|  | ||||
| 	if err := internal.BPFProgAttach(&attr); err != nil { | ||||
| 		return fmt.Errorf("can't attach program: %s", err) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| type RawDetachProgramOptions struct { | ||||
| 	Target  int | ||||
| 	Program *ebpf.Program | ||||
| 	Attach  ebpf.AttachType | ||||
| } | ||||
|  | ||||
| // RawDetachProgram is a low level wrapper around BPF_PROG_DETACH. | ||||
| // | ||||
| // You should use one of the higher level abstractions available in this | ||||
| // package if possible. | ||||
| func RawDetachProgram(opts RawDetachProgramOptions) error { | ||||
| 	if err := haveProgAttach(); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	attr := internal.BPFProgDetachAttr{ | ||||
| 		TargetFd:    uint32(opts.Target), | ||||
| 		AttachBpfFd: uint32(opts.Program.FD()), | ||||
| 		AttachType:  uint32(opts.Attach), | ||||
| 	} | ||||
| 	if err := internal.BPFProgDetach(&attr); err != nil { | ||||
| 		return fmt.Errorf("can't detach program: %s", err) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										61
									
								
								vendor/github.com/cilium/ebpf/link/raw_tracepoint.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										61
									
								
								vendor/github.com/cilium/ebpf/link/raw_tracepoint.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,61 +0,0 @@ | ||||
| package link | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
|  | ||||
| 	"github.com/cilium/ebpf" | ||||
| 	"github.com/cilium/ebpf/internal" | ||||
| ) | ||||
|  | ||||
| type RawTracepointOptions struct { | ||||
| 	// Tracepoint name. | ||||
| 	Name string | ||||
| 	// Program must be of type RawTracepoint* | ||||
| 	Program *ebpf.Program | ||||
| } | ||||
|  | ||||
| // AttachRawTracepoint links a BPF program to a raw_tracepoint. | ||||
| // | ||||
| // Requires at least Linux 4.17. | ||||
| func AttachRawTracepoint(opts RawTracepointOptions) (Link, error) { | ||||
| 	if t := opts.Program.Type(); t != ebpf.RawTracepoint && t != ebpf.RawTracepointWritable { | ||||
| 		return nil, fmt.Errorf("invalid program type %s, expected RawTracepoint(Writable)", t) | ||||
| 	} | ||||
| 	if opts.Program.FD() < 0 { | ||||
| 		return nil, fmt.Errorf("invalid program: %w", internal.ErrClosedFd) | ||||
| 	} | ||||
|  | ||||
| 	fd, err := bpfRawTracepointOpen(&bpfRawTracepointOpenAttr{ | ||||
| 		name: internal.NewStringPointer(opts.Name), | ||||
| 		fd:   uint32(opts.Program.FD()), | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return &progAttachRawTracepoint{fd: fd}, nil | ||||
| } | ||||
|  | ||||
| type progAttachRawTracepoint struct { | ||||
| 	fd *internal.FD | ||||
| } | ||||
|  | ||||
| var _ Link = (*progAttachRawTracepoint)(nil) | ||||
|  | ||||
| func (rt *progAttachRawTracepoint) isLink() {} | ||||
|  | ||||
| func (rt *progAttachRawTracepoint) Close() error { | ||||
| 	return rt.fd.Close() | ||||
| } | ||||
|  | ||||
| func (rt *progAttachRawTracepoint) Update(_ *ebpf.Program) error { | ||||
| 	return fmt.Errorf("can't update raw_tracepoint: %w", ErrNotSupported) | ||||
| } | ||||
|  | ||||
| func (rt *progAttachRawTracepoint) Pin(_ string) error { | ||||
| 	return fmt.Errorf("can't pin raw_tracepoint: %w", ErrNotSupported) | ||||
| } | ||||
|  | ||||
| func (rt *progAttachRawTracepoint) Unpin() error { | ||||
| 	return fmt.Errorf("unpin raw_tracepoint: %w", ErrNotSupported) | ||||
| } | ||||
							
								
								
									
										173
									
								
								vendor/github.com/cilium/ebpf/link/syscalls.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										173
									
								
								vendor/github.com/cilium/ebpf/link/syscalls.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,173 +0,0 @@ | ||||
| package link | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"unsafe" | ||||
|  | ||||
| 	"github.com/cilium/ebpf" | ||||
| 	"github.com/cilium/ebpf/asm" | ||||
| 	"github.com/cilium/ebpf/internal" | ||||
| 	"github.com/cilium/ebpf/internal/unix" | ||||
| ) | ||||
|  | ||||
| // Type is the kind of link. | ||||
| type Type uint32 | ||||
|  | ||||
| // Valid link types. | ||||
| // | ||||
| // Equivalent to enum bpf_link_type. | ||||
| const ( | ||||
| 	UnspecifiedType Type = iota | ||||
| 	RawTracepointType | ||||
| 	TracingType | ||||
| 	CgroupType | ||||
| 	IterType | ||||
| 	NetNsType | ||||
| 	XDPType | ||||
| ) | ||||
|  | ||||
| var haveProgAttach = internal.FeatureTest("BPF_PROG_ATTACH", "4.10", func() error { | ||||
| 	prog, err := ebpf.NewProgram(&ebpf.ProgramSpec{ | ||||
| 		Type:       ebpf.CGroupSKB, | ||||
| 		AttachType: ebpf.AttachCGroupInetIngress, | ||||
| 		License:    "MIT", | ||||
| 		Instructions: asm.Instructions{ | ||||
| 			asm.Mov.Imm(asm.R0, 0), | ||||
| 			asm.Return(), | ||||
| 		}, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		return internal.ErrNotSupported | ||||
| 	} | ||||
|  | ||||
| 	// BPF_PROG_ATTACH was introduced at the same time as CGgroupSKB, | ||||
| 	// so being able to load the program is enough to infer that we | ||||
| 	// have the syscall. | ||||
| 	prog.Close() | ||||
| 	return nil | ||||
| }) | ||||
|  | ||||
| var haveProgAttachReplace = internal.FeatureTest("BPF_PROG_ATTACH atomic replacement", "5.5", func() error { | ||||
| 	if err := haveProgAttach(); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	prog, err := ebpf.NewProgram(&ebpf.ProgramSpec{ | ||||
| 		Type:       ebpf.CGroupSKB, | ||||
| 		AttachType: ebpf.AttachCGroupInetIngress, | ||||
| 		License:    "MIT", | ||||
| 		Instructions: asm.Instructions{ | ||||
| 			asm.Mov.Imm(asm.R0, 0), | ||||
| 			asm.Return(), | ||||
| 		}, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		return internal.ErrNotSupported | ||||
| 	} | ||||
| 	defer prog.Close() | ||||
|  | ||||
| 	// We know that we have BPF_PROG_ATTACH since we can load CGroupSKB programs. | ||||
| 	// If passing BPF_F_REPLACE gives us EINVAL we know that the feature isn't | ||||
| 	// present. | ||||
| 	attr := internal.BPFProgAttachAttr{ | ||||
| 		// We rely on this being checked after attachFlags. | ||||
| 		TargetFd:    ^uint32(0), | ||||
| 		AttachBpfFd: uint32(prog.FD()), | ||||
| 		AttachType:  uint32(ebpf.AttachCGroupInetIngress), | ||||
| 		AttachFlags: uint32(flagReplace), | ||||
| 	} | ||||
|  | ||||
| 	err = internal.BPFProgAttach(&attr) | ||||
| 	if errors.Is(err, unix.EINVAL) { | ||||
| 		return internal.ErrNotSupported | ||||
| 	} | ||||
| 	if errors.Is(err, unix.EBADF) { | ||||
| 		return nil | ||||
| 	} | ||||
| 	return err | ||||
| }) | ||||
|  | ||||
| type bpfLinkCreateAttr struct { | ||||
| 	progFd     uint32 | ||||
| 	targetFd   uint32 | ||||
| 	attachType ebpf.AttachType | ||||
| 	flags      uint32 | ||||
| } | ||||
|  | ||||
| func bpfLinkCreate(attr *bpfLinkCreateAttr) (*internal.FD, error) { | ||||
| 	ptr, err := internal.BPF(internal.BPF_LINK_CREATE, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return internal.NewFD(uint32(ptr)), nil | ||||
| } | ||||
|  | ||||
| type bpfLinkUpdateAttr struct { | ||||
| 	linkFd    uint32 | ||||
| 	newProgFd uint32 | ||||
| 	flags     uint32 | ||||
| 	oldProgFd uint32 | ||||
| } | ||||
|  | ||||
| func bpfLinkUpdate(attr *bpfLinkUpdateAttr) error { | ||||
| 	_, err := internal.BPF(internal.BPF_LINK_UPDATE, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| var haveBPFLink = internal.FeatureTest("bpf_link", "5.7", func() error { | ||||
| 	prog, err := ebpf.NewProgram(&ebpf.ProgramSpec{ | ||||
| 		Type:       ebpf.CGroupSKB, | ||||
| 		AttachType: ebpf.AttachCGroupInetIngress, | ||||
| 		License:    "MIT", | ||||
| 		Instructions: asm.Instructions{ | ||||
| 			asm.Mov.Imm(asm.R0, 0), | ||||
| 			asm.Return(), | ||||
| 		}, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		return internal.ErrNotSupported | ||||
| 	} | ||||
| 	defer prog.Close() | ||||
|  | ||||
| 	attr := bpfLinkCreateAttr{ | ||||
| 		// This is a hopefully invalid file descriptor, which triggers EBADF. | ||||
| 		targetFd:   ^uint32(0), | ||||
| 		progFd:     uint32(prog.FD()), | ||||
| 		attachType: ebpf.AttachCGroupInetIngress, | ||||
| 	} | ||||
| 	_, err = bpfLinkCreate(&attr) | ||||
| 	if errors.Is(err, unix.EINVAL) { | ||||
| 		return internal.ErrNotSupported | ||||
| 	} | ||||
| 	if errors.Is(err, unix.EBADF) { | ||||
| 		return nil | ||||
| 	} | ||||
| 	return err | ||||
| }) | ||||
|  | ||||
| type bpfIterCreateAttr struct { | ||||
| 	linkFd uint32 | ||||
| 	flags  uint32 | ||||
| } | ||||
|  | ||||
| func bpfIterCreate(attr *bpfIterCreateAttr) (*internal.FD, error) { | ||||
| 	ptr, err := internal.BPF(internal.BPF_ITER_CREATE, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) | ||||
| 	if err == nil { | ||||
| 		return internal.NewFD(uint32(ptr)), nil | ||||
| 	} | ||||
| 	return nil, err | ||||
| } | ||||
|  | ||||
| type bpfRawTracepointOpenAttr struct { | ||||
| 	name internal.Pointer | ||||
| 	fd   uint32 | ||||
| 	_    uint32 | ||||
| } | ||||
|  | ||||
| func bpfRawTracepointOpen(attr *bpfRawTracepointOpenAttr) (*internal.FD, error) { | ||||
| 	ptr, err := internal.BPF(internal.BPF_RAW_TRACEPOINT_OPEN, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) | ||||
| 	if err == nil { | ||||
| 		return internal.NewFD(uint32(ptr)), nil | ||||
| 	} | ||||
| 	return nil, err | ||||
| } | ||||
							
								
								
									
										56
									
								
								vendor/github.com/cilium/ebpf/link/tracepoint.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										56
									
								
								vendor/github.com/cilium/ebpf/link/tracepoint.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,56 +0,0 @@ | ||||
| package link | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
|  | ||||
| 	"github.com/cilium/ebpf" | ||||
| ) | ||||
|  | ||||
| // Tracepoint attaches the given eBPF program to the tracepoint with the given | ||||
| // group and name. See /sys/kernel/debug/tracing/events to find available | ||||
| // tracepoints. The top-level directory is the group, the event's subdirectory | ||||
| // is the name. Example: | ||||
| // | ||||
| //	Tracepoint("syscalls", "sys_enter_fork") | ||||
| // | ||||
| // Note that attaching eBPF programs to syscalls (sys_enter_*/sys_exit_*) is | ||||
| // only possible as of kernel 4.14 (commit cf5f5ce). | ||||
| func Tracepoint(group, name string, prog *ebpf.Program) (Link, error) { | ||||
| 	if group == "" || name == "" { | ||||
| 		return nil, fmt.Errorf("group and name cannot be empty: %w", errInvalidInput) | ||||
| 	} | ||||
| 	if prog == nil { | ||||
| 		return nil, fmt.Errorf("prog cannot be nil: %w", errInvalidInput) | ||||
| 	} | ||||
| 	if !rgxTraceEvent.MatchString(group) || !rgxTraceEvent.MatchString(name) { | ||||
| 		return nil, fmt.Errorf("group and name '%s/%s' must be alphanumeric or underscore: %w", group, name, errInvalidInput) | ||||
| 	} | ||||
| 	if prog.Type() != ebpf.TracePoint { | ||||
| 		return nil, fmt.Errorf("eBPF program type %s is not a Tracepoint: %w", prog.Type(), errInvalidInput) | ||||
| 	} | ||||
|  | ||||
| 	tid, err := getTraceEventID(group, name) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	fd, err := openTracepointPerfEvent(tid) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	pe := &perfEvent{ | ||||
| 		fd:        fd, | ||||
| 		tracefsID: tid, | ||||
| 		group:     group, | ||||
| 		name:      name, | ||||
| 		progType:  ebpf.TracePoint, | ||||
| 	} | ||||
|  | ||||
| 	if err := pe.attach(prog); err != nil { | ||||
| 		pe.Close() | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return pe, nil | ||||
| } | ||||
							
								
								
									
										4
									
								
								vendor/github.com/cilium/ebpf/linker.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/cilium/ebpf/linker.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -113,7 +113,7 @@ func fixupJumpsAndCalls(insns asm.Instructions) error { | ||||
| 			// Rewrite bpf to bpf call | ||||
| 			callOffset, ok := symbolOffsets[ins.Reference] | ||||
| 			if !ok { | ||||
| 				return fmt.Errorf("instruction %d: reference to missing symbol %q", i, ins.Reference) | ||||
| 				return fmt.Errorf("instruction %d: reference to missing symbol %s", i, ins.Reference) | ||||
| 			} | ||||
|  | ||||
| 			ins.Constant = int64(callOffset - offset - 1) | ||||
| @@ -122,7 +122,7 @@ func fixupJumpsAndCalls(insns asm.Instructions) error { | ||||
| 			// Rewrite jump to label | ||||
| 			jumpOffset, ok := symbolOffsets[ins.Reference] | ||||
| 			if !ok { | ||||
| 				return fmt.Errorf("instruction %d: reference to missing symbol %q", i, ins.Reference) | ||||
| 				return fmt.Errorf("instruction %d: reference to missing symbol %s", i, ins.Reference) | ||||
| 			} | ||||
|  | ||||
| 			ins.Offset = int16(jumpOffset - offset - 1) | ||||
|   | ||||
							
								
								
									
										640
									
								
								vendor/github.com/cilium/ebpf/map.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										640
									
								
								vendor/github.com/cilium/ebpf/map.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -5,7 +5,6 @@ import ( | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"path/filepath" | ||||
| 	"reflect" | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/cilium/ebpf/internal" | ||||
| @@ -25,8 +24,7 @@ type MapOptions struct { | ||||
| 	// The base path to pin maps in if requested via PinByName. | ||||
| 	// Existing maps will be re-used if they are compatible, otherwise an | ||||
| 	// error is returned. | ||||
| 	PinPath        string | ||||
| 	LoadPinOptions LoadPinOptions | ||||
| 	PinPath string | ||||
| } | ||||
|  | ||||
| // MapID represents the unique ID of an eBPF map | ||||
| @@ -41,10 +39,7 @@ type MapSpec struct { | ||||
| 	KeySize    uint32 | ||||
| 	ValueSize  uint32 | ||||
| 	MaxEntries uint32 | ||||
|  | ||||
| 	// Flags is passed to the kernel and specifies additional map | ||||
| 	// creation attributes. | ||||
| 	Flags uint32 | ||||
| 	Flags      uint32 | ||||
|  | ||||
| 	// Automatically pin and load a map from MapOptions.PinPath. | ||||
| 	// Generates an error if an existing pinned map is incompatible with the MapSpec. | ||||
| @@ -95,20 +90,20 @@ type MapKV struct { | ||||
|  | ||||
| func (ms *MapSpec) checkCompatibility(m *Map) error { | ||||
| 	switch { | ||||
| 	case m.typ != ms.Type: | ||||
| 		return fmt.Errorf("expected type %v, got %v", ms.Type, m.typ) | ||||
| 	case m.abi.Type != ms.Type: | ||||
| 		return fmt.Errorf("expected type %v, got %v", ms.Type, m.abi.Type) | ||||
|  | ||||
| 	case m.keySize != ms.KeySize: | ||||
| 		return fmt.Errorf("expected key size %v, got %v", ms.KeySize, m.keySize) | ||||
| 	case m.abi.KeySize != ms.KeySize: | ||||
| 		return fmt.Errorf("expected key size %v, got %v", ms.KeySize, m.abi.KeySize) | ||||
|  | ||||
| 	case m.valueSize != ms.ValueSize: | ||||
| 		return fmt.Errorf("expected value size %v, got %v", ms.ValueSize, m.valueSize) | ||||
| 	case m.abi.ValueSize != ms.ValueSize: | ||||
| 		return fmt.Errorf("expected value size %v, got %v", ms.ValueSize, m.abi.ValueSize) | ||||
|  | ||||
| 	case m.maxEntries != ms.MaxEntries: | ||||
| 		return fmt.Errorf("expected max entries %v, got %v", ms.MaxEntries, m.maxEntries) | ||||
| 	case m.abi.MaxEntries != ms.MaxEntries: | ||||
| 		return fmt.Errorf("expected max entries %v, got %v", ms.MaxEntries, m.abi.MaxEntries) | ||||
|  | ||||
| 	case m.flags != ms.Flags: | ||||
| 		return fmt.Errorf("expected flags %v, got %v", ms.Flags, m.flags) | ||||
| 	case m.abi.Flags != ms.Flags: | ||||
| 		return fmt.Errorf("expected flags %v, got %v", ms.Flags, m.abi.Flags) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| @@ -123,14 +118,9 @@ func (ms *MapSpec) checkCompatibility(m *Map) error { | ||||
| // Implement encoding.BinaryMarshaler or encoding.BinaryUnmarshaler | ||||
| // if you require custom encoding. | ||||
| type Map struct { | ||||
| 	name       string | ||||
| 	fd         *internal.FD | ||||
| 	typ        MapType | ||||
| 	keySize    uint32 | ||||
| 	valueSize  uint32 | ||||
| 	maxEntries uint32 | ||||
| 	flags      uint32 | ||||
| 	pinnedPath string | ||||
| 	name string | ||||
| 	fd   *internal.FD | ||||
| 	abi  MapABI | ||||
| 	// Per CPU maps return values larger than the size in the spec | ||||
| 	fullValueSize int | ||||
| } | ||||
| @@ -142,18 +132,14 @@ func NewMapFromFD(fd int) (*Map, error) { | ||||
| 	if fd < 0 { | ||||
| 		return nil, errors.New("invalid fd") | ||||
| 	} | ||||
| 	bpfFd := internal.NewFD(uint32(fd)) | ||||
|  | ||||
| 	return newMapFromFD(internal.NewFD(uint32(fd))) | ||||
| } | ||||
|  | ||||
| func newMapFromFD(fd *internal.FD) (*Map, error) { | ||||
| 	info, err := newMapInfoFromFd(fd) | ||||
| 	name, abi, err := newMapABIFromFd(bpfFd) | ||||
| 	if err != nil { | ||||
| 		fd.Close() | ||||
| 		return nil, fmt.Errorf("get map info: %s", err) | ||||
| 		bpfFd.Forget() | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return newMap(fd, info.Name, info.Type, info.KeySize, info.ValueSize, info.MaxEntries, info.Flags) | ||||
| 	return newMap(bpfFd, name, abi) | ||||
| } | ||||
|  | ||||
| // NewMap creates a new Map. | ||||
| @@ -172,36 +158,35 @@ func NewMap(spec *MapSpec) (*Map, error) { | ||||
| // sufficiently high for locking memory during map creation. This can be done | ||||
| // by calling unix.Setrlimit with unix.RLIMIT_MEMLOCK prior to calling NewMapWithOptions. | ||||
| func NewMapWithOptions(spec *MapSpec, opts MapOptions) (*Map, error) { | ||||
| 	btfs := make(btfHandleCache) | ||||
| 	defer btfs.close() | ||||
|  | ||||
| 	return newMapWithOptions(spec, opts, btfs) | ||||
| } | ||||
|  | ||||
| func newMapWithOptions(spec *MapSpec, opts MapOptions, btfs btfHandleCache) (_ *Map, err error) { | ||||
| 	closeOnError := func(c io.Closer) { | ||||
| 		if err != nil { | ||||
| 			c.Close() | ||||
| 		} | ||||
| 	if spec.BTF == nil { | ||||
| 		return newMapWithBTF(spec, nil, opts) | ||||
| 	} | ||||
|  | ||||
| 	handle, err := btf.NewHandle(btf.MapSpec(spec.BTF)) | ||||
| 	if err != nil && !errors.Is(err, btf.ErrNotSupported) { | ||||
| 		return nil, fmt.Errorf("can't load BTF: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	return newMapWithBTF(spec, handle, opts) | ||||
| } | ||||
|  | ||||
| func newMapWithBTF(spec *MapSpec, handle *btf.Handle, opts MapOptions) (*Map, error) { | ||||
| 	switch spec.Pinning { | ||||
| 	case PinByName: | ||||
| 		if spec.Name == "" || opts.PinPath == "" { | ||||
| 			return nil, fmt.Errorf("pin by name: missing Name or PinPath") | ||||
| 		} | ||||
|  | ||||
| 		path := filepath.Join(opts.PinPath, spec.Name) | ||||
| 		m, err := LoadPinnedMap(path, &opts.LoadPinOptions) | ||||
| 		m, err := LoadPinnedMap(filepath.Join(opts.PinPath, spec.Name)) | ||||
| 		if errors.Is(err, unix.ENOENT) { | ||||
| 			break | ||||
| 		} | ||||
| 		if err != nil { | ||||
| 			return nil, fmt.Errorf("load pinned map: %w", err) | ||||
| 			return nil, fmt.Errorf("load pinned map: %s", err) | ||||
| 		} | ||||
| 		defer closeOnError(m) | ||||
|  | ||||
| 		if err := spec.checkCompatibility(m); err != nil { | ||||
| 			m.Close() | ||||
| 			return nil, fmt.Errorf("use pinned map %s: %s", spec.Name, err) | ||||
| 		} | ||||
|  | ||||
| @@ -220,11 +205,7 @@ func newMapWithOptions(spec *MapSpec, opts MapOptions, btfs btfHandleCache) (_ * | ||||
| 			return nil, fmt.Errorf("%s requires InnerMap", spec.Type) | ||||
| 		} | ||||
|  | ||||
| 		if spec.InnerMap.Pinning != PinNone { | ||||
| 			return nil, errors.New("inner maps cannot be pinned") | ||||
| 		} | ||||
|  | ||||
| 		template, err := createMap(spec.InnerMap, nil, opts, btfs) | ||||
| 		template, err := createMap(spec.InnerMap, nil, handle, opts) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| @@ -233,15 +214,14 @@ func newMapWithOptions(spec *MapSpec, opts MapOptions, btfs btfHandleCache) (_ * | ||||
| 		innerFd = template.fd | ||||
| 	} | ||||
|  | ||||
| 	m, err := createMap(spec, innerFd, opts, btfs) | ||||
| 	m, err := createMap(spec, innerFd, handle, opts) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	defer closeOnError(m) | ||||
|  | ||||
| 	if spec.Pinning == PinByName { | ||||
| 		path := filepath.Join(opts.PinPath, spec.Name) | ||||
| 		if err := m.Pin(path); err != nil { | ||||
| 		if err := m.Pin(filepath.Join(opts.PinPath, spec.Name)); err != nil { | ||||
| 			m.Close() | ||||
| 			return nil, fmt.Errorf("pin map: %s", err) | ||||
| 		} | ||||
| 	} | ||||
| @@ -249,14 +229,14 @@ func newMapWithOptions(spec *MapSpec, opts MapOptions, btfs btfHandleCache) (_ * | ||||
| 	return m, nil | ||||
| } | ||||
|  | ||||
| func createMap(spec *MapSpec, inner *internal.FD, opts MapOptions, btfs btfHandleCache) (_ *Map, err error) { | ||||
| func createMap(spec *MapSpec, inner *internal.FD, handle *btf.Handle, opts MapOptions) (_ *Map, err error) { | ||||
| 	closeOnError := func(closer io.Closer) { | ||||
| 		if err != nil { | ||||
| 			closer.Close() | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	spec = spec.Copy() | ||||
| 	abi := newMapABIFromSpec(spec) | ||||
|  | ||||
| 	switch spec.Type { | ||||
| 	case ArrayOfMaps: | ||||
| @@ -266,43 +246,43 @@ func createMap(spec *MapSpec, inner *internal.FD, opts MapOptions, btfs btfHandl | ||||
| 			return nil, err | ||||
| 		} | ||||
|  | ||||
| 		if spec.ValueSize != 0 && spec.ValueSize != 4 { | ||||
| 		if abi.ValueSize != 0 && abi.ValueSize != 4 { | ||||
| 			return nil, errors.New("ValueSize must be zero or four for map of map") | ||||
| 		} | ||||
| 		spec.ValueSize = 4 | ||||
| 		abi.ValueSize = 4 | ||||
|  | ||||
| 	case PerfEventArray: | ||||
| 		if spec.KeySize != 0 && spec.KeySize != 4 { | ||||
| 		if abi.KeySize != 0 && abi.KeySize != 4 { | ||||
| 			return nil, errors.New("KeySize must be zero or four for perf event array") | ||||
| 		} | ||||
| 		spec.KeySize = 4 | ||||
| 		abi.KeySize = 4 | ||||
|  | ||||
| 		if spec.ValueSize != 0 && spec.ValueSize != 4 { | ||||
| 		if abi.ValueSize != 0 && abi.ValueSize != 4 { | ||||
| 			return nil, errors.New("ValueSize must be zero or four for perf event array") | ||||
| 		} | ||||
| 		spec.ValueSize = 4 | ||||
| 		abi.ValueSize = 4 | ||||
|  | ||||
| 		if spec.MaxEntries == 0 { | ||||
| 		if abi.MaxEntries == 0 { | ||||
| 			n, err := internal.PossibleCPUs() | ||||
| 			if err != nil { | ||||
| 				return nil, fmt.Errorf("perf event array: %w", err) | ||||
| 			} | ||||
| 			spec.MaxEntries = uint32(n) | ||||
| 			abi.MaxEntries = uint32(n) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if spec.Flags&(unix.BPF_F_RDONLY_PROG|unix.BPF_F_WRONLY_PROG) > 0 || spec.Freeze { | ||||
| 	if abi.Flags&(unix.BPF_F_RDONLY_PROG|unix.BPF_F_WRONLY_PROG) > 0 || spec.Freeze { | ||||
| 		if err := haveMapMutabilityModifiers(); err != nil { | ||||
| 			return nil, fmt.Errorf("map create: %w", err) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	attr := bpfMapCreateAttr{ | ||||
| 		mapType:    spec.Type, | ||||
| 		keySize:    spec.KeySize, | ||||
| 		valueSize:  spec.ValueSize, | ||||
| 		maxEntries: spec.MaxEntries, | ||||
| 		flags:      spec.Flags, | ||||
| 		mapType:    abi.Type, | ||||
| 		keySize:    abi.KeySize, | ||||
| 		valueSize:  abi.ValueSize, | ||||
| 		maxEntries: abi.MaxEntries, | ||||
| 		flags:      abi.Flags, | ||||
| 		numaNode:   spec.NumaNode, | ||||
| 	} | ||||
|  | ||||
| @@ -314,40 +294,25 @@ func createMap(spec *MapSpec, inner *internal.FD, opts MapOptions, btfs btfHandl | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if handle != nil && spec.BTF != nil { | ||||
| 		attr.btfFd = uint32(handle.FD()) | ||||
| 		attr.btfKeyTypeID = btf.MapKey(spec.BTF).ID() | ||||
| 		attr.btfValueTypeID = btf.MapValue(spec.BTF).ID() | ||||
| 	} | ||||
|  | ||||
| 	if haveObjName() == nil { | ||||
| 		attr.mapName = newBPFObjName(spec.Name) | ||||
| 	} | ||||
|  | ||||
| 	var btfDisabled bool | ||||
| 	if spec.BTF != nil { | ||||
| 		handle, err := btfs.load(btf.MapSpec(spec.BTF)) | ||||
| 		btfDisabled = errors.Is(err, btf.ErrNotSupported) | ||||
| 		if err != nil && !btfDisabled { | ||||
| 			return nil, fmt.Errorf("load BTF: %w", err) | ||||
| 		} | ||||
|  | ||||
| 		if handle != nil { | ||||
| 			attr.btfFd = uint32(handle.FD()) | ||||
| 			attr.btfKeyTypeID = btf.MapKey(spec.BTF).ID() | ||||
| 			attr.btfValueTypeID = btf.MapValue(spec.BTF).ID() | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	fd, err := 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) | ||||
| 		} | ||||
| 		if btfDisabled { | ||||
| 			return nil, fmt.Errorf("map create without BTF: %w", err) | ||||
| 		} | ||||
| 		return nil, fmt.Errorf("map create: %w", err) | ||||
| 	} | ||||
| 	defer closeOnError(fd) | ||||
|  | ||||
| 	m, err := newMap(fd, spec.Name, spec.Type, spec.KeySize, spec.ValueSize, spec.MaxEntries, spec.Flags) | ||||
| 	m, err := newMap(fd, spec.Name, abi) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("map create: %w", err) | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	if err := m.populate(spec.Contents); err != nil { | ||||
| @@ -363,20 +328,15 @@ func createMap(spec *MapSpec, inner *internal.FD, opts MapOptions, btfs btfHandl | ||||
| 	return m, nil | ||||
| } | ||||
|  | ||||
| func newMap(fd *internal.FD, name string, typ MapType, keySize, valueSize, maxEntries, flags uint32) (*Map, error) { | ||||
| func newMap(fd *internal.FD, name string, abi *MapABI) (*Map, error) { | ||||
| 	m := &Map{ | ||||
| 		name, | ||||
| 		fd, | ||||
| 		typ, | ||||
| 		keySize, | ||||
| 		valueSize, | ||||
| 		maxEntries, | ||||
| 		flags, | ||||
| 		"", | ||||
| 		int(valueSize), | ||||
| 		*abi, | ||||
| 		int(abi.ValueSize), | ||||
| 	} | ||||
|  | ||||
| 	if !typ.hasPerCPUValue() { | ||||
| 	if !abi.Type.hasPerCPUValue() { | ||||
| 		return m, nil | ||||
| 	} | ||||
|  | ||||
| @@ -385,45 +345,47 @@ func newMap(fd *internal.FD, name string, typ MapType, keySize, valueSize, maxEn | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	m.fullValueSize = align(int(valueSize), 8) * possibleCPUs | ||||
| 	m.fullValueSize = align(int(abi.ValueSize), 8) * possibleCPUs | ||||
| 	return m, nil | ||||
| } | ||||
|  | ||||
| func (m *Map) String() string { | ||||
| 	if m.name != "" { | ||||
| 		return fmt.Sprintf("%s(%s)#%v", m.typ, m.name, m.fd) | ||||
| 		return fmt.Sprintf("%s(%s)#%v", m.abi.Type, m.name, m.fd) | ||||
| 	} | ||||
| 	return fmt.Sprintf("%s#%v", m.typ, m.fd) | ||||
| 	return fmt.Sprintf("%s#%v", m.abi.Type, m.fd) | ||||
| } | ||||
|  | ||||
| // Type returns the underlying type of the map. | ||||
| func (m *Map) Type() MapType { | ||||
| 	return m.typ | ||||
| 	return m.abi.Type | ||||
| } | ||||
|  | ||||
| // KeySize returns the size of the map key in bytes. | ||||
| func (m *Map) KeySize() uint32 { | ||||
| 	return m.keySize | ||||
| 	return m.abi.KeySize | ||||
| } | ||||
|  | ||||
| // ValueSize returns the size of the map value in bytes. | ||||
| func (m *Map) ValueSize() uint32 { | ||||
| 	return m.valueSize | ||||
| 	return m.abi.ValueSize | ||||
| } | ||||
|  | ||||
| // MaxEntries returns the maximum number of elements the map can hold. | ||||
| func (m *Map) MaxEntries() uint32 { | ||||
| 	return m.maxEntries | ||||
| 	return m.abi.MaxEntries | ||||
| } | ||||
|  | ||||
| // Flags returns the flags of the map. | ||||
| func (m *Map) Flags() uint32 { | ||||
| 	return m.flags | ||||
| 	return m.abi.Flags | ||||
| } | ||||
|  | ||||
| // Info returns metadata about the map. | ||||
| func (m *Map) Info() (*MapInfo, error) { | ||||
| 	return newMapInfoFromFd(m.fd) | ||||
| // ABI gets the ABI of the Map. | ||||
| // | ||||
| // Deprecated: use Type, KeySize, ValueSize, MaxEntries and Flags instead. | ||||
| func (m *Map) ABI() MapABI { | ||||
| 	return m.abi | ||||
| } | ||||
|  | ||||
| // Lookup retrieves a value from a Map. | ||||
| @@ -431,14 +393,54 @@ func (m *Map) Info() (*MapInfo, error) { | ||||
| // Calls Close() on valueOut if it is of type **Map or **Program, | ||||
| // and *valueOut is not nil. | ||||
| // | ||||
| // Returns an error if the key doesn't exist, see ErrKeyNotExist. | ||||
| // Returns an error if the key doesn't exist, see IsNotExist. | ||||
| func (m *Map) Lookup(key, valueOut interface{}) error { | ||||
| 	valuePtr, valueBytes := makeBuffer(valueOut, m.fullValueSize) | ||||
|  | ||||
| 	if err := m.lookup(key, valuePtr); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	return m.unmarshalValue(valueOut, valueBytes) | ||||
| 	if valueBytes == nil { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	if m.abi.Type.hasPerCPUValue() { | ||||
| 		return unmarshalPerCPUValue(valueOut, int(m.abi.ValueSize), valueBytes) | ||||
| 	} | ||||
|  | ||||
| 	switch value := valueOut.(type) { | ||||
| 	case **Map: | ||||
| 		m, err := unmarshalMap(valueBytes) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
|  | ||||
| 		(*value).Close() | ||||
| 		*value = m | ||||
| 		return nil | ||||
| 	case *Map: | ||||
| 		return fmt.Errorf("can't unmarshal into %T, need %T", value, (**Map)(nil)) | ||||
| 	case Map: | ||||
| 		return fmt.Errorf("can't unmarshal into %T, need %T", value, (**Map)(nil)) | ||||
|  | ||||
| 	case **Program: | ||||
| 		p, err := unmarshalProgram(valueBytes) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
|  | ||||
| 		(*value).Close() | ||||
| 		*value = p | ||||
| 		return nil | ||||
| 	case *Program: | ||||
| 		return fmt.Errorf("can't unmarshal into %T, need %T", value, (**Program)(nil)) | ||||
| 	case Program: | ||||
| 		return fmt.Errorf("can't unmarshal into %T, need %T", value, (**Program)(nil)) | ||||
|  | ||||
| 	default: | ||||
| 		return unmarshalBytes(valueOut, valueBytes) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // LookupAndDelete retrieves and deletes a value from a Map. | ||||
| @@ -447,7 +449,7 @@ func (m *Map) Lookup(key, valueOut interface{}) error { | ||||
| func (m *Map) LookupAndDelete(key, valueOut interface{}) error { | ||||
| 	valuePtr, valueBytes := makeBuffer(valueOut, m.fullValueSize) | ||||
|  | ||||
| 	keyPtr, err := m.marshalKey(key) | ||||
| 	keyPtr, err := marshalPtr(key, int(m.abi.KeySize)) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("can't marshal key: %w", err) | ||||
| 	} | ||||
| @@ -456,7 +458,7 @@ func (m *Map) LookupAndDelete(key, valueOut interface{}) error { | ||||
| 		return fmt.Errorf("lookup and delete failed: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	return m.unmarshalValue(valueOut, valueBytes) | ||||
| 	return unmarshalBytes(valueOut, valueBytes) | ||||
| } | ||||
|  | ||||
| // LookupBytes gets a value from Map. | ||||
| @@ -475,7 +477,7 @@ func (m *Map) LookupBytes(key interface{}) ([]byte, error) { | ||||
| } | ||||
|  | ||||
| func (m *Map) lookup(key interface{}, valueOut internal.Pointer) error { | ||||
| 	keyPtr, err := m.marshalKey(key) | ||||
| 	keyPtr, err := marshalPtr(key, int(m.abi.KeySize)) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("can't marshal key: %w", err) | ||||
| 	} | ||||
| @@ -509,12 +511,17 @@ func (m *Map) Put(key, value interface{}) error { | ||||
|  | ||||
| // Update changes the value of a key. | ||||
| func (m *Map) Update(key, value interface{}, flags MapUpdateFlags) error { | ||||
| 	keyPtr, err := m.marshalKey(key) | ||||
| 	keyPtr, err := marshalPtr(key, int(m.abi.KeySize)) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("can't marshal key: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	valuePtr, err := m.marshalValue(value) | ||||
| 	var valuePtr internal.Pointer | ||||
| 	if m.abi.Type.hasPerCPUValue() { | ||||
| 		valuePtr, err = marshalPerCPUValue(value, int(m.abi.ValueSize)) | ||||
| 	} else { | ||||
| 		valuePtr, err = marshalPtr(value, int(m.abi.ValueSize)) | ||||
| 	} | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("can't marshal value: %w", err) | ||||
| 	} | ||||
| @@ -530,7 +537,7 @@ func (m *Map) Update(key, value interface{}, flags MapUpdateFlags) error { | ||||
| // | ||||
| // Returns ErrKeyNotExist if the key does not exist. | ||||
| func (m *Map) Delete(key interface{}) error { | ||||
| 	keyPtr, err := m.marshalKey(key) | ||||
| 	keyPtr, err := marshalPtr(key, int(m.abi.KeySize)) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("can't marshal key: %w", err) | ||||
| 	} | ||||
| @@ -547,13 +554,17 @@ func (m *Map) Delete(key interface{}) error { | ||||
| // | ||||
| // Returns ErrKeyNotExist if there is no next key. | ||||
| func (m *Map) NextKey(key, nextKeyOut interface{}) error { | ||||
| 	nextKeyPtr, nextKeyBytes := makeBuffer(nextKeyOut, int(m.keySize)) | ||||
| 	nextKeyPtr, nextKeyBytes := makeBuffer(nextKeyOut, int(m.abi.KeySize)) | ||||
|  | ||||
| 	if err := m.nextKey(key, nextKeyPtr); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	if err := m.unmarshalKey(nextKeyOut, nextKeyBytes); err != nil { | ||||
| 	if nextKeyBytes == nil { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	if err := unmarshalBytes(nextKeyOut, nextKeyBytes); err != nil { | ||||
| 		return fmt.Errorf("can't unmarshal next key: %w", err) | ||||
| 	} | ||||
| 	return nil | ||||
| @@ -567,7 +578,7 @@ func (m *Map) NextKey(key, nextKeyOut interface{}) error { | ||||
| // | ||||
| // Returns nil if there are no more keys. | ||||
| func (m *Map) NextKeyBytes(key interface{}) ([]byte, error) { | ||||
| 	nextKey := make([]byte, m.keySize) | ||||
| 	nextKey := make([]byte, m.abi.KeySize) | ||||
| 	nextKeyPtr := internal.NewSlicePointer(nextKey) | ||||
|  | ||||
| 	err := m.nextKey(key, nextKeyPtr) | ||||
| @@ -585,7 +596,7 @@ func (m *Map) nextKey(key interface{}, nextKeyOut internal.Pointer) error { | ||||
| 	) | ||||
|  | ||||
| 	if key != nil { | ||||
| 		keyPtr, err = m.marshalKey(key) | ||||
| 		keyPtr, err = marshalPtr(key, int(m.abi.KeySize)) | ||||
| 		if err != nil { | ||||
| 			return fmt.Errorf("can't marshal key: %w", err) | ||||
| 		} | ||||
| @@ -597,158 +608,6 @@ func (m *Map) nextKey(key interface{}, nextKeyOut internal.Pointer) error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // BatchLookup looks up many elements in a map at once. | ||||
| // | ||||
| // "keysOut" and "valuesOut" must be of type slice, a pointer | ||||
| // to a slice or buffer will not work. | ||||
| // "prevKey" is the key to start the batch lookup from, it will | ||||
| // *not* be included in the results. Use nil to start at the first key. | ||||
| // | ||||
| // ErrKeyNotExist is returned when the batch lookup has reached | ||||
| // the end of all possible results, even when partial results | ||||
| // are returned. It should be used to evaluate when lookup is "done". | ||||
| func (m *Map) BatchLookup(prevKey, nextKeyOut, keysOut, valuesOut interface{}, opts *BatchOptions) (int, error) { | ||||
| 	return m.batchLookup(internal.BPF_MAP_LOOKUP_BATCH, prevKey, nextKeyOut, keysOut, valuesOut, opts) | ||||
| } | ||||
|  | ||||
| // BatchLookupAndDelete looks up many elements in a map at once, | ||||
| // | ||||
| // It then deletes all those elements. | ||||
| // "keysOut" and "valuesOut" must be of type slice, a pointer | ||||
| // to a slice or buffer will not work. | ||||
| // "prevKey" is the key to start the batch lookup from, it will | ||||
| // *not* be included in the results. Use nil to start at the first key. | ||||
| // | ||||
| // ErrKeyNotExist is returned when the batch lookup has reached | ||||
| // the end of all possible results, even when partial results | ||||
| // are returned. It should be used to evaluate when lookup is "done". | ||||
| func (m *Map) BatchLookupAndDelete(prevKey, nextKeyOut, keysOut, valuesOut interface{}, opts *BatchOptions) (int, error) { | ||||
| 	return m.batchLookup(internal.BPF_MAP_LOOKUP_AND_DELETE_BATCH, prevKey, nextKeyOut, keysOut, valuesOut, opts) | ||||
| } | ||||
|  | ||||
| func (m *Map) batchLookup(cmd internal.BPFCmd, startKey, nextKeyOut, keysOut, valuesOut interface{}, opts *BatchOptions) (int, error) { | ||||
| 	if err := haveBatchAPI(); err != nil { | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	if m.typ.hasPerCPUValue() { | ||||
| 		return 0, ErrNotSupported | ||||
| 	} | ||||
| 	keysValue := reflect.ValueOf(keysOut) | ||||
| 	if keysValue.Kind() != reflect.Slice { | ||||
| 		return 0, fmt.Errorf("keys must be a slice") | ||||
| 	} | ||||
| 	valuesValue := reflect.ValueOf(valuesOut) | ||||
| 	if valuesValue.Kind() != reflect.Slice { | ||||
| 		return 0, fmt.Errorf("valuesOut must be a slice") | ||||
| 	} | ||||
| 	count := keysValue.Len() | ||||
| 	if count != valuesValue.Len() { | ||||
| 		return 0, fmt.Errorf("keysOut and valuesOut must be the same length") | ||||
| 	} | ||||
| 	keyBuf := make([]byte, count*int(m.keySize)) | ||||
| 	keyPtr := internal.NewSlicePointer(keyBuf) | ||||
| 	valueBuf := make([]byte, count*int(m.fullValueSize)) | ||||
| 	valuePtr := internal.NewSlicePointer(valueBuf) | ||||
|  | ||||
| 	var ( | ||||
| 		startPtr internal.Pointer | ||||
| 		err      error | ||||
| 		retErr   error | ||||
| 	) | ||||
| 	if startKey != nil { | ||||
| 		startPtr, err = marshalPtr(startKey, int(m.keySize)) | ||||
| 		if err != nil { | ||||
| 			return 0, err | ||||
| 		} | ||||
| 	} | ||||
| 	nextPtr, nextBuf := makeBuffer(nextKeyOut, int(m.keySize)) | ||||
|  | ||||
| 	ct, err := bpfMapBatch(cmd, m.fd, startPtr, nextPtr, keyPtr, valuePtr, uint32(count), opts) | ||||
| 	if err != nil { | ||||
| 		if !errors.Is(err, ErrKeyNotExist) { | ||||
| 			return 0, err | ||||
| 		} | ||||
| 		retErr = ErrKeyNotExist | ||||
| 	} | ||||
|  | ||||
| 	err = m.unmarshalKey(nextKeyOut, nextBuf) | ||||
| 	if err != nil { | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	err = unmarshalBytes(keysOut, keyBuf) | ||||
| 	if err != nil { | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	err = unmarshalBytes(valuesOut, valueBuf) | ||||
| 	if err != nil { | ||||
| 		retErr = err | ||||
| 	} | ||||
| 	return int(ct), retErr | ||||
| } | ||||
|  | ||||
| // BatchUpdate updates the map with multiple keys and values | ||||
| // simultaneously. | ||||
| // "keys" and "values" must be of type slice, a pointer | ||||
| // to a slice or buffer will not work. | ||||
| func (m *Map) BatchUpdate(keys, values interface{}, opts *BatchOptions) (int, error) { | ||||
| 	if err := haveBatchAPI(); err != nil { | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	if m.typ.hasPerCPUValue() { | ||||
| 		return 0, ErrNotSupported | ||||
| 	} | ||||
| 	keysValue := reflect.ValueOf(keys) | ||||
| 	if keysValue.Kind() != reflect.Slice { | ||||
| 		return 0, fmt.Errorf("keys must be a slice") | ||||
| 	} | ||||
| 	valuesValue := reflect.ValueOf(values) | ||||
| 	if valuesValue.Kind() != reflect.Slice { | ||||
| 		return 0, fmt.Errorf("values must be a slice") | ||||
| 	} | ||||
| 	var ( | ||||
| 		count    = keysValue.Len() | ||||
| 		valuePtr internal.Pointer | ||||
| 		err      error | ||||
| 	) | ||||
| 	if count != valuesValue.Len() { | ||||
| 		return 0, fmt.Errorf("keys and values must be the same length") | ||||
| 	} | ||||
| 	keyPtr, err := marshalPtr(keys, count*int(m.keySize)) | ||||
| 	if err != nil { | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	valuePtr, err = marshalPtr(values, count*int(m.valueSize)) | ||||
| 	if err != nil { | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	var nilPtr internal.Pointer | ||||
| 	ct, err := bpfMapBatch(internal.BPF_MAP_UPDATE_BATCH, m.fd, nilPtr, nilPtr, keyPtr, valuePtr, uint32(count), opts) | ||||
| 	return int(ct), err | ||||
| } | ||||
|  | ||||
| // BatchDelete batch deletes entries in the map by keys. | ||||
| // "keys" must be of type slice, a pointer to a slice or buffer will not work. | ||||
| func (m *Map) BatchDelete(keys interface{}, opts *BatchOptions) (int, error) { | ||||
| 	if err := haveBatchAPI(); err != nil { | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	if m.typ.hasPerCPUValue() { | ||||
| 		return 0, ErrNotSupported | ||||
| 	} | ||||
| 	keysValue := reflect.ValueOf(keys) | ||||
| 	if keysValue.Kind() != reflect.Slice { | ||||
| 		return 0, fmt.Errorf("keys must be a slice") | ||||
| 	} | ||||
| 	count := keysValue.Len() | ||||
| 	keyPtr, err := marshalPtr(keys, count*int(m.keySize)) | ||||
| 	if err != nil { | ||||
| 		return 0, fmt.Errorf("cannot marshal keys: %v", err) | ||||
| 	} | ||||
| 	var nilPtr internal.Pointer | ||||
| 	ct, err := bpfMapBatch(internal.BPF_MAP_DELETE_BATCH, m.fd, nilPtr, nilPtr, keyPtr, nilPtr, uint32(count), opts) | ||||
| 	return int(ct), err | ||||
| } | ||||
|  | ||||
| // Iterate traverses a map. | ||||
| // | ||||
| // It's safe to create multiple iterators at the same time. | ||||
| @@ -788,7 +647,6 @@ func (m *Map) FD() int { | ||||
| // | ||||
| // Closing the duplicate does not affect the original, and vice versa. | ||||
| // Changes made to the map are reflected by both instances however. | ||||
| // If the original map was pinned, the cloned map will not be pinned by default. | ||||
| // | ||||
| // Cloning a nil Map returns nil. | ||||
| func (m *Map) Clone() (*Map, error) { | ||||
| @@ -801,51 +659,14 @@ func (m *Map) Clone() (*Map, error) { | ||||
| 		return nil, fmt.Errorf("can't clone map: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	return &Map{ | ||||
| 		m.name, | ||||
| 		dup, | ||||
| 		m.typ, | ||||
| 		m.keySize, | ||||
| 		m.valueSize, | ||||
| 		m.maxEntries, | ||||
| 		m.flags, | ||||
| 		"", | ||||
| 		m.fullValueSize, | ||||
| 	}, nil | ||||
| 	return newMap(dup, m.name, &m.abi) | ||||
| } | ||||
|  | ||||
| // Pin persists the map on the BPF virtual file system past the lifetime of | ||||
| // the process that created it . | ||||
| // | ||||
| // Calling Pin on a previously pinned map will overwrite the path, except when | ||||
| // the new path already exists. Re-pinning across filesystems is not supported. | ||||
| // You can Clone a map to pin it to a different path. | ||||
| // Pin persists the map past the lifetime of the process that created it. | ||||
| // | ||||
| // This requires bpffs to be mounted above fileName. See https://docs.cilium.io/en/k8s-doc/admin/#admin-mount-bpffs | ||||
| func (m *Map) Pin(fileName string) error { | ||||
| 	if err := internal.Pin(m.pinnedPath, fileName, m.fd); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	m.pinnedPath = fileName | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Unpin removes the persisted state for the map from the BPF virtual filesystem. | ||||
| // | ||||
| // Failed calls to Unpin will not alter the state returned by IsPinned. | ||||
| // | ||||
| // Unpinning an unpinned Map returns nil. | ||||
| func (m *Map) Unpin() error { | ||||
| 	if err := internal.Unpin(m.pinnedPath); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	m.pinnedPath = "" | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // IsPinned returns true if the map has a non-empty pinned path. | ||||
| func (m *Map) IsPinned() bool { | ||||
| 	return m.pinnedPath != "" | ||||
| 	return internal.BPFObjPin(fileName, m.fd) | ||||
| } | ||||
|  | ||||
| // Freeze prevents a map to be modified from user space. | ||||
| @@ -871,151 +692,45 @@ func (m *Map) populate(contents []MapKV) error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (m *Map) marshalKey(data interface{}) (internal.Pointer, error) { | ||||
| 	if data == nil { | ||||
| 		if m.keySize == 0 { | ||||
| 			// Queues have a key length of zero, so passing nil here is valid. | ||||
| 			return internal.NewPointer(nil), nil | ||||
| 		} | ||||
| 		return internal.Pointer{}, errors.New("can't use nil as key of map") | ||||
| 	} | ||||
|  | ||||
| 	return marshalPtr(data, int(m.keySize)) | ||||
| } | ||||
|  | ||||
| func (m *Map) unmarshalKey(data interface{}, buf []byte) error { | ||||
| 	if buf == nil { | ||||
| 		// This is from a makeBuffer call, nothing do do here. | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	return unmarshalBytes(data, buf) | ||||
| } | ||||
|  | ||||
| func (m *Map) marshalValue(data interface{}) (internal.Pointer, error) { | ||||
| 	if m.typ.hasPerCPUValue() { | ||||
| 		return marshalPerCPUValue(data, int(m.valueSize)) | ||||
| 	} | ||||
|  | ||||
| 	var ( | ||||
| 		buf []byte | ||||
| 		err error | ||||
| 	) | ||||
|  | ||||
| 	switch value := data.(type) { | ||||
| 	case *Map: | ||||
| 		if !m.typ.canStoreMap() { | ||||
| 			return internal.Pointer{}, fmt.Errorf("can't store map in %s", m.typ) | ||||
| 		} | ||||
| 		buf, err = marshalMap(value, int(m.valueSize)) | ||||
|  | ||||
| 	case *Program: | ||||
| 		if !m.typ.canStoreProgram() { | ||||
| 			return internal.Pointer{}, fmt.Errorf("can't store program in %s", m.typ) | ||||
| 		} | ||||
| 		buf, err = marshalProgram(value, int(m.valueSize)) | ||||
|  | ||||
| 	default: | ||||
| 		return marshalPtr(data, int(m.valueSize)) | ||||
| 	} | ||||
|  | ||||
| 	if err != nil { | ||||
| 		return internal.Pointer{}, err | ||||
| 	} | ||||
|  | ||||
| 	return internal.NewSlicePointer(buf), nil | ||||
| } | ||||
|  | ||||
| func (m *Map) unmarshalValue(value interface{}, buf []byte) error { | ||||
| 	if buf == nil { | ||||
| 		// This is from a makeBuffer call, nothing do do here. | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	if m.typ.hasPerCPUValue() { | ||||
| 		return unmarshalPerCPUValue(value, int(m.valueSize), buf) | ||||
| 	} | ||||
|  | ||||
| 	switch value := value.(type) { | ||||
| 	case **Map: | ||||
| 		if !m.typ.canStoreMap() { | ||||
| 			return fmt.Errorf("can't read a map from %s", m.typ) | ||||
| 		} | ||||
|  | ||||
| 		other, err := unmarshalMap(buf) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
|  | ||||
| 		// The caller might close the map externally, so ignore errors. | ||||
| 		_ = (*value).Close() | ||||
|  | ||||
| 		*value = other | ||||
| 		return nil | ||||
|  | ||||
| 	case *Map: | ||||
| 		if !m.typ.canStoreMap() { | ||||
| 			return fmt.Errorf("can't read a map from %s", m.typ) | ||||
| 		} | ||||
| 		return errors.New("require pointer to *Map") | ||||
|  | ||||
| 	case **Program: | ||||
| 		if !m.typ.canStoreProgram() { | ||||
| 			return fmt.Errorf("can't read a program from %s", m.typ) | ||||
| 		} | ||||
|  | ||||
| 		other, err := unmarshalProgram(buf) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
|  | ||||
| 		// The caller might close the program externally, so ignore errors. | ||||
| 		_ = (*value).Close() | ||||
|  | ||||
| 		*value = other | ||||
| 		return nil | ||||
|  | ||||
| 	case *Program: | ||||
| 		if !m.typ.canStoreProgram() { | ||||
| 			return fmt.Errorf("can't read a program from %s", m.typ) | ||||
| 		} | ||||
| 		return errors.New("require pointer to *Program") | ||||
| 	} | ||||
|  | ||||
| 	return unmarshalBytes(value, buf) | ||||
| } | ||||
|  | ||||
| // LoadPinnedMap loads a Map from a BPF file. | ||||
| func LoadPinnedMap(fileName string, opts *LoadPinOptions) (*Map, error) { | ||||
| 	fd, err := internal.BPFObjGet(fileName, opts.Marshal()) | ||||
| // LoadPinnedMap load a Map from a BPF file. | ||||
| // | ||||
| // The function is not compatible with nested maps. | ||||
| // Use LoadPinnedMapExplicit in these situations. | ||||
| func LoadPinnedMap(fileName string) (*Map, error) { | ||||
| 	fd, err := internal.BPFObjGet(fileName) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	m, err := newMapFromFD(fd) | ||||
| 	if err == nil { | ||||
| 		m.pinnedPath = fileName | ||||
| 	name, abi, err := newMapABIFromFd(fd) | ||||
| 	if err != nil { | ||||
| 		_ = fd.Close() | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return m, err | ||||
| 	return newMap(fd, name, abi) | ||||
| } | ||||
|  | ||||
| // LoadPinnedMapExplicit loads a map with explicit parameters. | ||||
| func LoadPinnedMapExplicit(fileName string, abi *MapABI) (*Map, error) { | ||||
| 	fd, err := internal.BPFObjGet(fileName) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return newMap(fd, "", abi) | ||||
| } | ||||
|  | ||||
| // unmarshalMap creates a map from a map ID encoded in host endianness. | ||||
| func unmarshalMap(buf []byte) (*Map, error) { | ||||
| 	if len(buf) != 4 { | ||||
| 		return nil, errors.New("map id requires 4 byte value") | ||||
| 	} | ||||
|  | ||||
| 	// Looking up an entry in a nested map or prog array returns an id, | ||||
| 	// not an fd. | ||||
| 	id := internal.NativeEndian.Uint32(buf) | ||||
| 	return NewMapFromID(MapID(id)) | ||||
| } | ||||
|  | ||||
| // marshalMap marshals the fd of a map into a buffer in host endianness. | ||||
| func marshalMap(m *Map, length int) ([]byte, error) { | ||||
| 	if length != 4 { | ||||
| 		return nil, fmt.Errorf("can't marshal map to %d bytes", length) | ||||
| 	} | ||||
|  | ||||
| // MarshalBinary implements BinaryMarshaler. | ||||
| func (m *Map) MarshalBinary() ([]byte, error) { | ||||
| 	fd, err := m.fd.Value() | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| @@ -1095,8 +810,8 @@ type MapIterator struct { | ||||
| func newMapIterator(target *Map) *MapIterator { | ||||
| 	return &MapIterator{ | ||||
| 		target:     target, | ||||
| 		maxEntries: target.maxEntries, | ||||
| 		prevBytes:  make([]byte, target.keySize), | ||||
| 		maxEntries: target.abi.MaxEntries, | ||||
| 		prevBytes:  make([]byte, int(target.abi.KeySize)), | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -1115,9 +830,7 @@ func (mi *MapIterator) Next(keyOut, valueOut interface{}) bool { | ||||
| 		return false | ||||
| 	} | ||||
|  | ||||
| 	// For array-like maps NextKeyBytes returns nil only on after maxEntries | ||||
| 	// iterations. | ||||
| 	for mi.count <= mi.maxEntries { | ||||
| 	for ; mi.count < mi.maxEntries; mi.count++ { | ||||
| 		var nextBytes []byte | ||||
| 		nextBytes, mi.err = mi.target.NextKeyBytes(mi.prevKey) | ||||
| 		if mi.err != nil { | ||||
| @@ -1136,7 +849,6 @@ func (mi *MapIterator) Next(keyOut, valueOut interface{}) bool { | ||||
| 		copy(mi.prevBytes, nextBytes) | ||||
| 		mi.prevKey = mi.prevBytes | ||||
|  | ||||
| 		mi.count++ | ||||
| 		mi.err = mi.target.Lookup(nextBytes, valueOut) | ||||
| 		if errors.Is(mi.err, ErrKeyNotExist) { | ||||
| 			// Even though the key should be valid, we couldn't look up | ||||
| @@ -1153,7 +865,7 @@ func (mi *MapIterator) Next(keyOut, valueOut interface{}) bool { | ||||
| 			return false | ||||
| 		} | ||||
|  | ||||
| 		mi.err = mi.target.unmarshalKey(keyOut, nextBytes) | ||||
| 		mi.err = unmarshalBytes(keyOut, nextBytes) | ||||
| 		return mi.err == nil | ||||
| 	} | ||||
|  | ||||
| @@ -1187,12 +899,18 @@ func NewMapFromID(id MapID) (*Map, error) { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return newMapFromFD(fd) | ||||
| 	name, abi, err := newMapABIFromFd(fd) | ||||
| 	if err != nil { | ||||
| 		_ = fd.Close() | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return newMap(fd, name, abi) | ||||
| } | ||||
|  | ||||
| // ID returns the systemwide unique ID of the map. | ||||
| // | ||||
| // Deprecated: use MapInfo.ID() instead. | ||||
| // Requires at least Linux 4.13. | ||||
| func (m *Map) ID() (MapID, error) { | ||||
| 	info, err := bpfGetMapInfoByFD(m.fd) | ||||
| 	if err != nil { | ||||
|   | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user
	 Jordan Liggitt
					Jordan Liggitt