Merge pull request #5393 from dmcgowan/update-containerd-org-deps-1.5
Update containerd vendors to tags
This commit is contained in:
commit
b1eb024d91
14
go.mod
14
go.mod
@ -5,19 +5,19 @@ go 1.16
|
|||||||
require (
|
require (
|
||||||
github.com/Microsoft/go-winio v0.4.17
|
github.com/Microsoft/go-winio v0.4.17
|
||||||
github.com/Microsoft/hcsshim v0.8.16
|
github.com/Microsoft/hcsshim v0.8.16
|
||||||
github.com/containerd/aufs v0.0.0-20210416161429-fb0192dcb2c0
|
github.com/containerd/aufs v1.0.0
|
||||||
github.com/containerd/btrfs v0.0.0-20210316141732-918d888fb676
|
github.com/containerd/btrfs v1.0.0
|
||||||
github.com/containerd/cgroups v0.0.0-20210114181951-8a68de567b68
|
github.com/containerd/cgroups v1.0.0
|
||||||
github.com/containerd/console v1.0.2
|
github.com/containerd/console v1.0.2
|
||||||
github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e
|
github.com/containerd/continuity v0.1.0
|
||||||
github.com/containerd/fifo v1.0.0
|
github.com/containerd/fifo v1.0.0
|
||||||
github.com/containerd/go-cni v1.0.2
|
github.com/containerd/go-cni v1.0.2
|
||||||
github.com/containerd/go-runc v0.0.0-20201020171139-16b287bc67d0
|
github.com/containerd/go-runc v1.0.0
|
||||||
github.com/containerd/imgcrypt v1.1.1
|
github.com/containerd/imgcrypt v1.1.1
|
||||||
github.com/containerd/nri v0.0.0-20210316161719-dbaa18c31c14
|
github.com/containerd/nri v0.1.0
|
||||||
github.com/containerd/ttrpc v1.0.2
|
github.com/containerd/ttrpc v1.0.2
|
||||||
github.com/containerd/typeurl v1.0.2
|
github.com/containerd/typeurl v1.0.2
|
||||||
github.com/containerd/zfs v0.0.0-20210416085227-4140c9077d87
|
github.com/containerd/zfs v1.0.0
|
||||||
github.com/containernetworking/plugins v0.9.1
|
github.com/containernetworking/plugins v0.9.1
|
||||||
github.com/coreos/go-systemd/v22 v22.1.0
|
github.com/coreos/go-systemd/v22 v22.1.0
|
||||||
github.com/davecgh/go-spew v1.1.1
|
github.com/davecgh/go-spew v1.1.1
|
||||||
|
61
go.sum
61
go.sum
@ -55,6 +55,7 @@ github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+V
|
|||||||
github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU=
|
github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU=
|
||||||
github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY=
|
github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY=
|
||||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
||||||
|
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||||
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ=
|
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ=
|
||||||
@ -63,6 +64,7 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy
|
|||||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0=
|
github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0=
|
||||||
|
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||||
github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0=
|
github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0=
|
||||||
github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||||
@ -81,6 +83,8 @@ github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8n
|
|||||||
github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50=
|
github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50=
|
||||||
github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE=
|
github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE=
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
|
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
||||||
|
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||||
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
|
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
|
||||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw=
|
github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw=
|
||||||
@ -89,24 +93,27 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P
|
|||||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||||
github.com/cilium/ebpf v0.0.0-20200110133405-4032b1d8aae3/go.mod h1:MA5e5Lr8slmEg9bt0VpxxWqJlO4iwu3FBdHUzV7wQVg=
|
github.com/cilium/ebpf v0.0.0-20200110133405-4032b1d8aae3/go.mod h1:MA5e5Lr8slmEg9bt0VpxxWqJlO4iwu3FBdHUzV7wQVg=
|
||||||
github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLIdUjrmSXlK9pkrsDlLHbO8jiB8X8JnOc=
|
github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLIdUjrmSXlK9pkrsDlLHbO8jiB8X8JnOc=
|
||||||
github.com/cilium/ebpf v0.2.0 h1:Fv93L3KKckEcEHR3oApXVzyBTDA8WAm6VXhPE00N3f8=
|
|
||||||
github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs=
|
github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs=
|
||||||
|
github.com/cilium/ebpf v0.4.0 h1:QlHdikaxALkqWasW8hAC1mfR0jdmvbfaBdBPFmRSglA=
|
||||||
|
github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
|
||||||
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
||||||
github.com/containerd/aufs v0.0.0-20200908144142-dab0cbea06f4/go.mod h1:nukgQABAEopAHvB6j7cnP5zJ+/3aVcE7hCYqvIwAHyE=
|
github.com/containerd/aufs v0.0.0-20200908144142-dab0cbea06f4/go.mod h1:nukgQABAEopAHvB6j7cnP5zJ+/3aVcE7hCYqvIwAHyE=
|
||||||
github.com/containerd/aufs v0.0.0-20201003224125-76a6863f2989/go.mod h1:AkGGQs9NM2vtYHaUen+NljV0/baGCAPELGm2q9ZXpWU=
|
github.com/containerd/aufs v0.0.0-20201003224125-76a6863f2989/go.mod h1:AkGGQs9NM2vtYHaUen+NljV0/baGCAPELGm2q9ZXpWU=
|
||||||
github.com/containerd/aufs v0.0.0-20210316121734-20793ff83c97/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU=
|
github.com/containerd/aufs v0.0.0-20210316121734-20793ff83c97/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU=
|
||||||
github.com/containerd/aufs v0.0.0-20210416161429-fb0192dcb2c0 h1:naOo1n+31DqP+0v8OJsrZg32CCLHUlhY6dfnnZBlgtU=
|
github.com/containerd/aufs v1.0.0 h1:2oeJiwX5HstO7shSrPZjrohJZLzK36wvpdmzDRkL/LY=
|
||||||
github.com/containerd/aufs v0.0.0-20210416161429-fb0192dcb2c0/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU=
|
github.com/containerd/aufs v1.0.0/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU=
|
||||||
github.com/containerd/btrfs v0.0.0-20201111183144-404b9149801e/go.mod h1:jg2QkJcsabfHugurUvvPhS3E08Oxiuh5W/g1ybB4e0E=
|
github.com/containerd/btrfs v0.0.0-20201111183144-404b9149801e/go.mod h1:jg2QkJcsabfHugurUvvPhS3E08Oxiuh5W/g1ybB4e0E=
|
||||||
github.com/containerd/btrfs v0.0.0-20210316141732-918d888fb676 h1:jNaRXAhCLuQ2x3k4nZNxaZN27/BCMhLfVkCEokYPI5Q=
|
|
||||||
github.com/containerd/btrfs v0.0.0-20210316141732-918d888fb676/go.mod h1:zMcX3qkXTAi9GI50+0HOeuV8LU2ryCE/V2vG/ZBiTss=
|
github.com/containerd/btrfs v0.0.0-20210316141732-918d888fb676/go.mod h1:zMcX3qkXTAi9GI50+0HOeuV8LU2ryCE/V2vG/ZBiTss=
|
||||||
|
github.com/containerd/btrfs v1.0.0 h1:osn1exbzdub9L5SouXO5swW4ea/xVdJZ3wokxN5GrnA=
|
||||||
|
github.com/containerd/btrfs v1.0.0/go.mod h1:zMcX3qkXTAi9GI50+0HOeuV8LU2ryCE/V2vG/ZBiTss=
|
||||||
github.com/containerd/cgroups v0.0.0-20190717030353-c4b9ac5c7601/go.mod h1:X9rLEHIqSf/wfK8NsPqxJmeZgW4pcfzdXITDrUSJ6uI=
|
github.com/containerd/cgroups v0.0.0-20190717030353-c4b9ac5c7601/go.mod h1:X9rLEHIqSf/wfK8NsPqxJmeZgW4pcfzdXITDrUSJ6uI=
|
||||||
github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko=
|
github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko=
|
||||||
github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59/go.mod h1:pA0z1pT8KYB3TCXK/ocprsh7MAkoW8bZVzPdih9snmM=
|
github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59/go.mod h1:pA0z1pT8KYB3TCXK/ocprsh7MAkoW8bZVzPdih9snmM=
|
||||||
github.com/containerd/cgroups v0.0.0-20200710171044-318312a37340/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo=
|
github.com/containerd/cgroups v0.0.0-20200710171044-318312a37340/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo=
|
||||||
github.com/containerd/cgroups v0.0.0-20200824123100-0b889c03f102/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo=
|
github.com/containerd/cgroups v0.0.0-20200824123100-0b889c03f102/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo=
|
||||||
github.com/containerd/cgroups v0.0.0-20210114181951-8a68de567b68 h1:hkGVFjz+plgr5UfxZUTPFbUFIF/Km6/s+RVRIRHLrrY=
|
|
||||||
github.com/containerd/cgroups v0.0.0-20210114181951-8a68de567b68/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE=
|
github.com/containerd/cgroups v0.0.0-20210114181951-8a68de567b68/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE=
|
||||||
|
github.com/containerd/cgroups v1.0.0 h1:FbtJS7RiK+th7i6HmVgoZGYBFLMemWlpwEp9Yr4QPZc=
|
||||||
|
github.com/containerd/cgroups v1.0.0/go.mod h1:sgGgnAnNasYdJ1ypnikP2SO7SM0Lfgkgwk3TUc9bDO4=
|
||||||
github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
|
github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
|
||||||
github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
|
github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
|
||||||
github.com/containerd/console v0.0.0-20191206165004-02ecf6a7291e/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE=
|
github.com/containerd/console v0.0.0-20191206165004-02ecf6a7291e/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE=
|
||||||
@ -130,8 +137,9 @@ github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL
|
|||||||
github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
||||||
github.com/containerd/continuity v0.0.0-20200710164510-efbc4488d8fe/go.mod h1:cECdGN1O8G9bgKTlLhuPJimka6Xb/Gg7vYzCTNVxhvo=
|
github.com/containerd/continuity v0.0.0-20200710164510-efbc4488d8fe/go.mod h1:cECdGN1O8G9bgKTlLhuPJimka6Xb/Gg7vYzCTNVxhvo=
|
||||||
github.com/containerd/continuity v0.0.0-20201208142359-180525291bb7/go.mod h1:kR3BEg7bDFaEddKm54WSmrol1fKWDU1nKYkgrcgZT7Y=
|
github.com/containerd/continuity v0.0.0-20201208142359-180525291bb7/go.mod h1:kR3BEg7bDFaEddKm54WSmrol1fKWDU1nKYkgrcgZT7Y=
|
||||||
github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e h1:6JKvHHt396/qabvMhnhUZvWaHZzfVfldxE60TK8YLhg=
|
|
||||||
github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e/go.mod h1:EXlVlkqNba9rJe3j7w3Xa924itAMLgZH4UD/Q4PExuQ=
|
github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e/go.mod h1:EXlVlkqNba9rJe3j7w3Xa924itAMLgZH4UD/Q4PExuQ=
|
||||||
|
github.com/containerd/continuity v0.1.0 h1:UFRRY5JemiAhPZrr/uE0n8fMTLcZsUvySPr1+D7pgr8=
|
||||||
|
github.com/containerd/continuity v0.1.0/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUXrLh8lPo2knzsM=
|
||||||
github.com/containerd/fifo v0.0.0-20180307165137-3d5202aec260/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
|
github.com/containerd/fifo v0.0.0-20180307165137-3d5202aec260/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
|
||||||
github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
|
github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
|
||||||
github.com/containerd/fifo v0.0.0-20200410184934-f15a3290365b/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0=
|
github.com/containerd/fifo v0.0.0-20200410184934-f15a3290365b/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0=
|
||||||
@ -145,16 +153,18 @@ github.com/containerd/go-cni v1.0.2/go.mod h1:nrNABBHzu0ZwCug9Ije8hL2xBCYh/pjfMb
|
|||||||
github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0=
|
github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0=
|
||||||
github.com/containerd/go-runc v0.0.0-20190911050354-e029b79d8cda/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0=
|
github.com/containerd/go-runc v0.0.0-20190911050354-e029b79d8cda/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0=
|
||||||
github.com/containerd/go-runc v0.0.0-20200220073739-7016d3ce2328/go.mod h1:PpyHrqVs8FTi9vpyHwPwiNEGaACDxT/N/pLcvMSRA9g=
|
github.com/containerd/go-runc v0.0.0-20200220073739-7016d3ce2328/go.mod h1:PpyHrqVs8FTi9vpyHwPwiNEGaACDxT/N/pLcvMSRA9g=
|
||||||
github.com/containerd/go-runc v0.0.0-20201020171139-16b287bc67d0 h1:e+50zk22gvHLJKe8+d+xSMyA88PPQk/XfWuUw1BdnPA=
|
|
||||||
github.com/containerd/go-runc v0.0.0-20201020171139-16b287bc67d0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok=
|
github.com/containerd/go-runc v0.0.0-20201020171139-16b287bc67d0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok=
|
||||||
|
github.com/containerd/go-runc v1.0.0 h1:oU+lLv1ULm5taqgV/CJivypVODI4SUz1znWjv3nNYS0=
|
||||||
|
github.com/containerd/go-runc v1.0.0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok=
|
||||||
github.com/containerd/imgcrypt v1.0.1/go.mod h1:mdd8cEPW7TPgNG4FpuP3sGBiQ7Yi/zak9TYCG3juvb0=
|
github.com/containerd/imgcrypt v1.0.1/go.mod h1:mdd8cEPW7TPgNG4FpuP3sGBiQ7Yi/zak9TYCG3juvb0=
|
||||||
github.com/containerd/imgcrypt v1.0.4-0.20210301171431-0ae5c75f59ba/go.mod h1:6TNsg0ctmizkrOgXRNQjAPFWpMYRWuiB6dSF4Pfa5SA=
|
github.com/containerd/imgcrypt v1.0.4-0.20210301171431-0ae5c75f59ba/go.mod h1:6TNsg0ctmizkrOgXRNQjAPFWpMYRWuiB6dSF4Pfa5SA=
|
||||||
github.com/containerd/imgcrypt v1.1.1-0.20210312161619-7ed62a527887/go.mod h1:5AZJNI6sLHJljKuI9IHnw1pWqo/F0nGDOuR9zgTs7ow=
|
github.com/containerd/imgcrypt v1.1.1-0.20210312161619-7ed62a527887/go.mod h1:5AZJNI6sLHJljKuI9IHnw1pWqo/F0nGDOuR9zgTs7ow=
|
||||||
github.com/containerd/imgcrypt v1.1.1 h1:LBwiTfoUsdiEGAR1TpvxE+Gzt7469oVu87iR3mv3Byc=
|
github.com/containerd/imgcrypt v1.1.1 h1:LBwiTfoUsdiEGAR1TpvxE+Gzt7469oVu87iR3mv3Byc=
|
||||||
github.com/containerd/imgcrypt v1.1.1/go.mod h1:xpLnwiQmEUJPvQoAapeb2SNCxz7Xr6PJrXQb0Dpc4ms=
|
github.com/containerd/imgcrypt v1.1.1/go.mod h1:xpLnwiQmEUJPvQoAapeb2SNCxz7Xr6PJrXQb0Dpc4ms=
|
||||||
github.com/containerd/nri v0.0.0-20201007170849-eb1350a75164/go.mod h1:+2wGSDGFYfE5+So4M5syatU0N0f0LbWpuqyMi4/BE8c=
|
github.com/containerd/nri v0.0.0-20201007170849-eb1350a75164/go.mod h1:+2wGSDGFYfE5+So4M5syatU0N0f0LbWpuqyMi4/BE8c=
|
||||||
github.com/containerd/nri v0.0.0-20210316161719-dbaa18c31c14 h1:ap4DriuHs+kzozfFpPH+qccXB219gbChW/F4KW8IGZk=
|
|
||||||
github.com/containerd/nri v0.0.0-20210316161719-dbaa18c31c14/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY=
|
github.com/containerd/nri v0.0.0-20210316161719-dbaa18c31c14/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY=
|
||||||
|
github.com/containerd/nri v0.1.0 h1:6QioHRlThlKh2RkRTR4kIT3PKAcrLo3gIWnjkM4dQmQ=
|
||||||
|
github.com/containerd/nri v0.1.0/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY=
|
||||||
github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
|
github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
|
||||||
github.com/containerd/ttrpc v0.0.0-20190828172938-92c8520ef9f8/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
|
github.com/containerd/ttrpc v0.0.0-20190828172938-92c8520ef9f8/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
|
||||||
github.com/containerd/ttrpc v0.0.0-20191028202541-4f1b8fe65a5c/go.mod h1:LPm1u0xBw8r8NOKoOdNMeVHSawSsltak+Ihv+etqsE8=
|
github.com/containerd/ttrpc v0.0.0-20191028202541-4f1b8fe65a5c/go.mod h1:LPm1u0xBw8r8NOKoOdNMeVHSawSsltak+Ihv+etqsE8=
|
||||||
@ -170,8 +180,8 @@ github.com/containerd/zfs v0.0.0-20200918131355-0a33824f23a2/go.mod h1:8IgZOBdv8
|
|||||||
github.com/containerd/zfs v0.0.0-20210301145711-11e8f1707f62/go.mod h1:A9zfAbMlQwE+/is6hi0Xw8ktpL+6glmqZYtevJgaB8Y=
|
github.com/containerd/zfs v0.0.0-20210301145711-11e8f1707f62/go.mod h1:A9zfAbMlQwE+/is6hi0Xw8ktpL+6glmqZYtevJgaB8Y=
|
||||||
github.com/containerd/zfs v0.0.0-20210315114300-dde8f0fda960/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY=
|
github.com/containerd/zfs v0.0.0-20210315114300-dde8f0fda960/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY=
|
||||||
github.com/containerd/zfs v0.0.0-20210324211415-d5c4544f0433/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY=
|
github.com/containerd/zfs v0.0.0-20210324211415-d5c4544f0433/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY=
|
||||||
github.com/containerd/zfs v0.0.0-20210416085227-4140c9077d87 h1:04tsitu/xTkLWo80gnw+R8jhAEKjuuvt/NL7B1bMLWU=
|
github.com/containerd/zfs v1.0.0 h1:cXLJbx+4Jj7rNsTiqVfm6i+RNLx6FFA2fMmDlEf+Wm8=
|
||||||
github.com/containerd/zfs v0.0.0-20210416085227-4140c9077d87/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY=
|
github.com/containerd/zfs v1.0.0/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY=
|
||||||
github.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
|
github.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
|
||||||
github.com/containernetworking/cni v0.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
|
github.com/containernetworking/cni v0.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
|
||||||
github.com/containernetworking/cni v0.8.1 h1:7zpDnQ3T3s4ucOuJ/ZCLrYBxzkg0AELFfII3Epo9TmI=
|
github.com/containernetworking/cni v0.8.1 h1:7zpDnQ3T3s4ucOuJ/ZCLrYBxzkg0AELFfII3Epo9TmI=
|
||||||
@ -183,6 +193,8 @@ github.com/containers/ocicrypt v1.0.1/go.mod h1:MeJDzk1RJHv89LjsH0Sp5KTY3ZYkjXO/
|
|||||||
github.com/containers/ocicrypt v1.1.0/go.mod h1:b8AOe0YR67uU8OqfVNcznfFpAzu3rdgUV4GP9qXPfu4=
|
github.com/containers/ocicrypt v1.1.0/go.mod h1:b8AOe0YR67uU8OqfVNcznfFpAzu3rdgUV4GP9qXPfu4=
|
||||||
github.com/containers/ocicrypt v1.1.1 h1:prL8l9w3ntVqXvNH1CiNn5ENjcCnr38JqpSyvKKB4GI=
|
github.com/containers/ocicrypt v1.1.1 h1:prL8l9w3ntVqXvNH1CiNn5ENjcCnr38JqpSyvKKB4GI=
|
||||||
github.com/containers/ocicrypt v1.1.1/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B0oB3dj3jFxY=
|
github.com/containers/ocicrypt v1.1.1/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B0oB3dj3jFxY=
|
||||||
|
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||||
|
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||||
github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
|
github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
|
||||||
github.com/coreos/go-iptables v0.5.0/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
|
github.com/coreos/go-iptables v0.5.0/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
|
||||||
github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
|
github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
|
||||||
@ -212,6 +224,7 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
|||||||
github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0=
|
github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0=
|
||||||
github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
|
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||||
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
|
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
|
||||||
github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY=
|
github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY=
|
||||||
github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||||
@ -240,6 +253,8 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7
|
|||||||
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||||
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
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.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
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/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||||
@ -284,6 +299,7 @@ github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69
|
|||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
|
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=
|
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=
|
||||||
@ -328,11 +344,14 @@ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORR
|
|||||||
github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
|
github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
|
||||||
github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||||
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||||
|
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||||
|
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho=
|
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho=
|
||||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||||
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||||
github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||||
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
|
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
|
||||||
@ -342,6 +361,7 @@ github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uP
|
|||||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
|
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||||
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||||
@ -374,12 +394,14 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxv
|
|||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.3/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/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs=
|
|
||||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||||
|
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/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
|
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
|
||||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
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=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
|
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
|
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
|
||||||
@ -395,6 +417,7 @@ github.com/miekg/pkcs11 v1.0.3 h1:iMwmD7I5225wv84WxIG/bmxz9AXjWvTWIbM/TYHvWtw=
|
|||||||
github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
|
github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
|
||||||
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible h1:aKW/4cBs+yK6gpqU3K/oIwk9Q/XICqd3zOX/UFuvqmk=
|
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible h1:aKW/4cBs+yK6gpqU3K/oIwk9Q/XICqd3zOX/UFuvqmk=
|
||||||
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
|
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
|
||||||
|
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||||
github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A=
|
github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A=
|
||||||
github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
|
github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
|
||||||
@ -417,6 +440,7 @@ github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+
|
|||||||
github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM=
|
github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM=
|
||||||
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
|
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
|
||||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||||
|
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||||
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||||
github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
@ -457,6 +481,7 @@ github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mo
|
|||||||
github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE=
|
github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE=
|
||||||
github.com/opencontainers/selinux v1.8.0 h1:+77ba4ar4jsCbL1GLbFL8fFM57w6suPfSS9PDLDY7KM=
|
github.com/opencontainers/selinux v1.8.0 h1:+77ba4ar4jsCbL1GLbFL8fFM57w6suPfSS9PDLDY7KM=
|
||||||
github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo=
|
github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo=
|
||||||
|
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||||
github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM=
|
github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM=
|
||||||
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
|
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
|
||||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||||
@ -470,6 +495,7 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
|
|||||||
github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
|
github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
|
||||||
github.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
github.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||||
|
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
|
||||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||||
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
|
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
|
||||||
github.com/prometheus/client_golang v1.7.1 h1:NTGy1Ja9pByO+xAeH/qiWnLrKtr3hJPNjaVUwnjpdpA=
|
github.com/prometheus/client_golang v1.7.1 h1:NTGy1Ja9pByO+xAeH/qiWnLrKtr3hJPNjaVUwnjpdpA=
|
||||||
@ -481,12 +507,15 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:
|
|||||||
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
|
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
|
||||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||||
|
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||||
|
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||||
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
|
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
|
||||||
github.com/prometheus/common v0.10.0 h1:RyRA7RzGXQZiW+tGMr7sxa85G1z0yOpM1qq5c8lNawc=
|
github.com/prometheus/common v0.10.0 h1:RyRA7RzGXQZiW+tGMr7sxa85G1z0yOpM1qq5c8lNawc=
|
||||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||||
github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
|
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||||
github.com/prometheus/procfs v0.0.0-20190522114515-bc1a522cf7b1/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
github.com/prometheus/procfs v0.0.0-20190522114515-bc1a522cf7b1/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||||
github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
|
github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
|
||||||
@ -496,6 +525,7 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O
|
|||||||
github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||||
github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=
|
github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=
|
||||||
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||||
|
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
||||||
@ -517,15 +547,21 @@ github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic
|
|||||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||||
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||||
|
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||||
|
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||||
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
||||||
|
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||||
github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||||
|
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
||||||
|
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||||
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||||
github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||||
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
|
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
||||||
github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980 h1:lIOOHPEbXzO3vnmx2gok1Tfs31Q8GQqKLc8vVqyQq/I=
|
github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980 h1:lIOOHPEbXzO3vnmx2gok1Tfs31Q8GQqKLc8vVqyQq/I=
|
||||||
github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8=
|
github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8=
|
||||||
github.com/stretchr/objx v0.0.0-20180129172003-8a3f7159479f/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.0.0-20180129172003-8a3f7159479f/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
@ -546,6 +582,7 @@ github.com/tchap/go-patricia v2.2.6+incompatible h1:JvoDL7JSoIP2HDE8AbDH3zC8QBPx
|
|||||||
github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I=
|
github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I=
|
||||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||||
|
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||||
github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY=
|
github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY=
|
||||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||||
github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
|
github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
|
||||||
@ -561,11 +598,13 @@ github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2
|
|||||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||||
github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
|
github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
|
||||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||||
|
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs=
|
github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs=
|
||||||
github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA=
|
github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA=
|
||||||
github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=
|
github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=
|
||||||
|
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||||
go.etcd.io/bbolt v1.3.5 h1:XAzx9gjCb0Rxj7EoqcClPD1d5ZBxZJk0jbuoPHenBt0=
|
go.etcd.io/bbolt v1.3.5 h1:XAzx9gjCb0Rxj7EoqcClPD1d5ZBxZJk0jbuoPHenBt0=
|
||||||
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
||||||
|
@ -5,10 +5,10 @@ go 1.15
|
|||||||
require (
|
require (
|
||||||
github.com/Microsoft/hcsshim v0.8.16
|
github.com/Microsoft/hcsshim v0.8.16
|
||||||
github.com/Microsoft/hcsshim/test v0.0.0-20210408205431-da33ecd607e1
|
github.com/Microsoft/hcsshim/test v0.0.0-20210408205431-da33ecd607e1
|
||||||
github.com/containerd/cgroups v0.0.0-20210114181951-8a68de567b68
|
github.com/containerd/cgroups v1.0.0
|
||||||
// the actual version of containerd is replaced with the code at the root of this repository
|
// the actual version of containerd is replaced with the code at the root of this repository
|
||||||
github.com/containerd/containerd v1.5.0-rc.0
|
github.com/containerd/containerd v1.5.0-rc.0
|
||||||
github.com/containerd/go-runc v0.0.0-20201020171139-16b287bc67d0
|
github.com/containerd/go-runc v1.0.0
|
||||||
github.com/containerd/ttrpc v1.0.2
|
github.com/containerd/ttrpc v1.0.2
|
||||||
github.com/containerd/typeurl v1.0.2
|
github.com/containerd/typeurl v1.0.2
|
||||||
github.com/gogo/protobuf v1.3.2
|
github.com/gogo/protobuf v1.3.2
|
||||||
|
@ -45,6 +45,7 @@ github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+V
|
|||||||
github.com/Microsoft/hcsshim/test v0.0.0-20210408205431-da33ecd607e1 h1:pVKfKyPkXna29XlGjxSr9J0A7vNucOUHZ/2ClcTWalw=
|
github.com/Microsoft/hcsshim/test v0.0.0-20210408205431-da33ecd607e1 h1:pVKfKyPkXna29XlGjxSr9J0A7vNucOUHZ/2ClcTWalw=
|
||||||
github.com/Microsoft/hcsshim/test v0.0.0-20210408205431-da33ecd607e1/go.mod h1:Cmvnhlie15Ha2UYrJs9EhgSx76Bq9RV2FgfEiT78GhI=
|
github.com/Microsoft/hcsshim/test v0.0.0-20210408205431-da33ecd607e1/go.mod h1:Cmvnhlie15Ha2UYrJs9EhgSx76Bq9RV2FgfEiT78GhI=
|
||||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
||||||
|
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||||
@ -52,6 +53,7 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy
|
|||||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0=
|
github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0=
|
||||||
|
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||||
@ -60,34 +62,39 @@ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kB
|
|||||||
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||||
github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
|
github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
|
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw=
|
github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw=
|
||||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
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/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/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||||
github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLIdUjrmSXlK9pkrsDlLHbO8jiB8X8JnOc=
|
github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLIdUjrmSXlK9pkrsDlLHbO8jiB8X8JnOc=
|
||||||
github.com/cilium/ebpf v0.2.0 h1:Fv93L3KKckEcEHR3oApXVzyBTDA8WAm6VXhPE00N3f8=
|
|
||||||
github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs=
|
github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs=
|
||||||
|
github.com/cilium/ebpf v0.4.0 h1:QlHdikaxALkqWasW8hAC1mfR0jdmvbfaBdBPFmRSglA=
|
||||||
|
github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
|
||||||
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
||||||
github.com/containerd/aufs v0.0.0-20210416161429-fb0192dcb2c0/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU=
|
github.com/containerd/aufs v0.0.0-20210416161429-fb0192dcb2c0/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU=
|
||||||
github.com/containerd/btrfs v0.0.0-20210316141732-918d888fb676/go.mod h1:zMcX3qkXTAi9GI50+0HOeuV8LU2ryCE/V2vG/ZBiTss=
|
github.com/containerd/btrfs v0.0.0-20210316141732-918d888fb676/go.mod h1:zMcX3qkXTAi9GI50+0HOeuV8LU2ryCE/V2vG/ZBiTss=
|
||||||
github.com/containerd/cgroups v0.0.0-20200824123100-0b889c03f102/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo=
|
github.com/containerd/cgroups v0.0.0-20200824123100-0b889c03f102/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo=
|
||||||
github.com/containerd/cgroups v0.0.0-20210114181951-8a68de567b68 h1:hkGVFjz+plgr5UfxZUTPFbUFIF/Km6/s+RVRIRHLrrY=
|
|
||||||
github.com/containerd/cgroups v0.0.0-20210114181951-8a68de567b68/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE=
|
github.com/containerd/cgroups v0.0.0-20210114181951-8a68de567b68/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE=
|
||||||
|
github.com/containerd/cgroups v1.0.0 h1:FbtJS7RiK+th7i6HmVgoZGYBFLMemWlpwEp9Yr4QPZc=
|
||||||
|
github.com/containerd/cgroups v1.0.0/go.mod h1:sgGgnAnNasYdJ1ypnikP2SO7SM0Lfgkgwk3TUc9bDO4=
|
||||||
github.com/containerd/console v0.0.0-20191206165004-02ecf6a7291e/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE=
|
github.com/containerd/console v0.0.0-20191206165004-02ecf6a7291e/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE=
|
||||||
github.com/containerd/console v1.0.1/go.mod h1:XUsP6YE/mKtz6bxc+I8UiKKTP04qjQL4qcS3XoQ5xkw=
|
github.com/containerd/console v1.0.1/go.mod h1:XUsP6YE/mKtz6bxc+I8UiKKTP04qjQL4qcS3XoQ5xkw=
|
||||||
github.com/containerd/console v1.0.2 h1:Pi6D+aZXM+oUw1czuKgH5IJ+y0jhYcwBJfx5/Ghn9dE=
|
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.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ=
|
||||||
github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e h1:6JKvHHt396/qabvMhnhUZvWaHZzfVfldxE60TK8YLhg=
|
|
||||||
github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e/go.mod h1:EXlVlkqNba9rJe3j7w3Xa924itAMLgZH4UD/Q4PExuQ=
|
github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e/go.mod h1:EXlVlkqNba9rJe3j7w3Xa924itAMLgZH4UD/Q4PExuQ=
|
||||||
|
github.com/containerd/continuity v0.1.0 h1:UFRRY5JemiAhPZrr/uE0n8fMTLcZsUvySPr1+D7pgr8=
|
||||||
|
github.com/containerd/continuity v0.1.0/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUXrLh8lPo2knzsM=
|
||||||
github.com/containerd/fifo v1.0.0 h1:6PirWBr9/L7GDamKr+XM0IeUFXu5mf3M/BPpH9gaLBU=
|
github.com/containerd/fifo v1.0.0 h1:6PirWBr9/L7GDamKr+XM0IeUFXu5mf3M/BPpH9gaLBU=
|
||||||
github.com/containerd/fifo v1.0.0/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4=
|
github.com/containerd/fifo v1.0.0/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4=
|
||||||
github.com/containerd/go-cni v1.0.2/go.mod h1:nrNABBHzu0ZwCug9Ije8hL2xBCYh/pjfMb1aZGrrohk=
|
github.com/containerd/go-cni v1.0.2/go.mod h1:nrNABBHzu0ZwCug9Ije8hL2xBCYh/pjfMb1aZGrrohk=
|
||||||
github.com/containerd/go-runc v0.0.0-20200220073739-7016d3ce2328/go.mod h1:PpyHrqVs8FTi9vpyHwPwiNEGaACDxT/N/pLcvMSRA9g=
|
github.com/containerd/go-runc v0.0.0-20200220073739-7016d3ce2328/go.mod h1:PpyHrqVs8FTi9vpyHwPwiNEGaACDxT/N/pLcvMSRA9g=
|
||||||
github.com/containerd/go-runc v0.0.0-20201020171139-16b287bc67d0 h1:e+50zk22gvHLJKe8+d+xSMyA88PPQk/XfWuUw1BdnPA=
|
|
||||||
github.com/containerd/go-runc v0.0.0-20201020171139-16b287bc67d0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok=
|
github.com/containerd/go-runc v0.0.0-20201020171139-16b287bc67d0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok=
|
||||||
|
github.com/containerd/go-runc v1.0.0 h1:oU+lLv1ULm5taqgV/CJivypVODI4SUz1znWjv3nNYS0=
|
||||||
|
github.com/containerd/go-runc v1.0.0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok=
|
||||||
github.com/containerd/imgcrypt v1.1.1/go.mod h1:xpLnwiQmEUJPvQoAapeb2SNCxz7Xr6PJrXQb0Dpc4ms=
|
github.com/containerd/imgcrypt v1.1.1/go.mod h1:xpLnwiQmEUJPvQoAapeb2SNCxz7Xr6PJrXQb0Dpc4ms=
|
||||||
github.com/containerd/nri v0.0.0-20210316161719-dbaa18c31c14/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY=
|
github.com/containerd/nri v0.1.0/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY=
|
||||||
github.com/containerd/ttrpc v1.0.2 h1:2/O3oTZN36q2xRolk0a2WWGgh7/Vf/liElg5hFYLX9U=
|
github.com/containerd/ttrpc v1.0.2 h1:2/O3oTZN36q2xRolk0a2WWGgh7/Vf/liElg5hFYLX9U=
|
||||||
github.com/containerd/ttrpc v1.0.2/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y=
|
github.com/containerd/ttrpc v1.0.2/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y=
|
||||||
github.com/containerd/typeurl v1.0.1/go.mod h1:TB1hUtrpaiO88KEK56ijojHS1+NeF0izUACaJW2mdXg=
|
github.com/containerd/typeurl v1.0.1/go.mod h1:TB1hUtrpaiO88KEK56ijojHS1+NeF0izUACaJW2mdXg=
|
||||||
@ -98,6 +105,8 @@ github.com/containernetworking/cni v0.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ
|
|||||||
github.com/containernetworking/cni v0.8.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
|
github.com/containernetworking/cni v0.8.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
|
||||||
github.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRDjeJr6FLK6vuiUwoH7P8=
|
github.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRDjeJr6FLK6vuiUwoH7P8=
|
||||||
github.com/containers/ocicrypt v1.1.1/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B0oB3dj3jFxY=
|
github.com/containers/ocicrypt v1.1.1/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B0oB3dj3jFxY=
|
||||||
|
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||||
|
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||||
github.com/coreos/go-iptables v0.5.0/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
|
github.com/coreos/go-iptables v0.5.0/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
|
||||||
github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
|
github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
|
||||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||||
@ -122,6 +131,7 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
|||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
|
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||||
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8=
|
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8=
|
||||||
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=
|
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=
|
||||||
github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw=
|
github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw=
|
||||||
@ -139,6 +149,8 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7
|
|||||||
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||||
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
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.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||||
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
@ -174,6 +186,7 @@ github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69
|
|||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
|
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=
|
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=
|
||||||
@ -213,15 +226,19 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+
|
|||||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||||
github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
|
github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
|
||||||
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||||
|
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||||
|
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||||
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
|
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||||
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||||
@ -247,12 +264,14 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxv
|
|||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.3/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/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs=
|
|
||||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||||
|
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/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
|
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
|
||||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
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=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
|
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
|
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
|
||||||
@ -264,6 +283,7 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5
|
|||||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||||
github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
|
github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
|
||||||
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
|
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
|
||||||
|
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||||
github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
|
github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
|
||||||
github.com/moby/sys/mountinfo v0.4.1 h1:1O+1cHA1aujwEwwVMa2Xm2l+gIpUHyd3+D+d7LZh1kM=
|
github.com/moby/sys/mountinfo v0.4.1 h1:1O+1cHA1aujwEwwVMa2Xm2l+gIpUHyd3+D+d7LZh1kM=
|
||||||
@ -280,6 +300,7 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8m
|
|||||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||||
|
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||||
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||||
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
@ -303,6 +324,7 @@ github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d/go.m
|
|||||||
github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
|
github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
|
||||||
github.com/opencontainers/selinux v1.8.0 h1:+77ba4ar4jsCbL1GLbFL8fFM57w6suPfSS9PDLDY7KM=
|
github.com/opencontainers/selinux v1.8.0 h1:+77ba4ar4jsCbL1GLbFL8fFM57w6suPfSS9PDLDY7KM=
|
||||||
github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo=
|
github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo=
|
||||||
|
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||||
github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM=
|
github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM=
|
||||||
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
|
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
|
||||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||||
@ -314,6 +336,7 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
|
|||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
|
github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
|
||||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||||
|
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
|
||||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||||
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
|
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
|
||||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||||
@ -321,16 +344,20 @@ github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:
|
|||||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
|
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||||
|
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||||
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
|
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
|
||||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
|
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||||
github.com/prometheus/procfs v0.0.0-20190522114515-bc1a522cf7b1/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
github.com/prometheus/procfs v0.0.0-20190522114515-bc1a522cf7b1/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||||
github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
|
github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
|
||||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||||
github.com/prometheus/procfs v0.2.0 h1:wH4vA7pcjKuZzjF7lM8awk4fnuJO6idemZXoKnULUx4=
|
github.com/prometheus/procfs v0.2.0 h1:wH4vA7pcjKuZzjF7lM8awk4fnuJO6idemZXoKnULUx4=
|
||||||
github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||||
|
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
@ -344,14 +371,20 @@ github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrf
|
|||||||
github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
|
github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
|
||||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||||
|
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||||
|
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||||
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
||||||
|
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||||
github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||||
|
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
||||||
|
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||||
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||||
github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||||
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
|
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
||||||
github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8=
|
github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
@ -365,6 +398,7 @@ github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG
|
|||||||
github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I=
|
github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I=
|
||||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||||
|
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||||
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
|
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
|
||||||
github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho=
|
github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho=
|
||||||
@ -373,8 +407,10 @@ github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1
|
|||||||
github.com/willf/bitset v1.1.11 h1:N7Z7E9UvjW+sGsEl7k/SJrvY2reP1A07MrGuCjIOjRE=
|
github.com/willf/bitset v1.1.11 h1:N7Z7E9UvjW+sGsEl7k/SJrvY2reP1A07MrGuCjIOjRE=
|
||||||
github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI=
|
github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI=
|
||||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||||
|
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
|
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||||
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
||||||
go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg=
|
go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg=
|
||||||
@ -434,6 +470,7 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn
|
|||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
80
vendor/github.com/cilium/ebpf/ARCHITECTURE.md
generated
vendored
Normal file
80
vendor/github.com/cilium/ebpf/ARCHITECTURE.md
generated
vendored
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
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
Normal file
23
vendor/github.com/cilium/ebpf/CONTRIBUTING.md
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# 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
Normal file
67
vendor/github.com/cilium/ebpf/Makefile
generated
vendored
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
# 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 > "$@"
|
54
vendor/github.com/cilium/ebpf/README.md
generated
vendored
Normal file
54
vendor/github.com/cilium/ebpf/README.md
generated
vendored
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
# 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
|
||||||
|
embedding eBPF in Go
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
## 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
200
vendor/github.com/cilium/ebpf/abi.go
generated
vendored
@ -1,200 +0,0 @@
|
|||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
27
vendor/github.com/cilium/ebpf/asm/instruction.go
generated
vendored
27
vendor/github.com/cilium/ebpf/asm/instruction.go
generated
vendored
@ -1,12 +1,16 @@
|
|||||||
package asm
|
package asm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/sha1"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"math"
|
"math"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/cilium/ebpf/internal/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
// InstructionSize is the size of a BPF instruction in bytes
|
// InstructionSize is the size of a BPF instruction in bytes
|
||||||
@ -159,6 +163,9 @@ func (ins *Instruction) mapOffset() uint32 {
|
|||||||
return uint32(uint64(ins.Constant) >> 32)
|
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 {
|
func (ins *Instruction) isLoadFromMap() bool {
|
||||||
return ins.OpCode == LoadImmOp(DWord) && (ins.Src == PseudoMapFD || ins.Src == PseudoMapValue)
|
return ins.OpCode == LoadImmOp(DWord) && (ins.Src == PseudoMapFD || ins.Src == PseudoMapValue)
|
||||||
}
|
}
|
||||||
@ -390,6 +397,25 @@ func (insns Instructions) Marshal(w io.Writer, bo binary.ByteOrder) error {
|
|||||||
return nil
|
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
|
// Iterate allows iterating a BPF program while keeping track of
|
||||||
// various offsets.
|
// various offsets.
|
||||||
//
|
//
|
||||||
@ -417,6 +443,7 @@ func (iter *InstructionIterator) Next() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if iter.Ins != nil {
|
if iter.Ins != nil {
|
||||||
|
iter.Index++
|
||||||
iter.Offset += RawInstructionOffset(iter.Ins.OpCode.rawInstructions())
|
iter.Offset += RawInstructionOffset(iter.Ins.OpCode.rawInstructions())
|
||||||
}
|
}
|
||||||
iter.Ins = &iter.insns[0]
|
iter.Ins = &iter.insns[0]
|
||||||
|
311
vendor/github.com/cilium/ebpf/collection.go
generated
vendored
311
vendor/github.com/cilium/ebpf/collection.go
generated
vendored
@ -131,10 +131,11 @@ func (cs *CollectionSpec) RewriteConstants(consts map[string]interface{}) error
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assign the contents of a collection spec to a struct.
|
// Assign the contents of a CollectionSpec to a struct.
|
||||||
//
|
//
|
||||||
// This function is a short-cut to manually checking the presence
|
// This function is a short-cut to manually checking the presence
|
||||||
// of maps and programs in a collection spec.
|
// 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
|
// 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
|
// struct is updated with values from Programs or Maps if it
|
||||||
@ -173,21 +174,61 @@ func (cs *CollectionSpec) Assign(to interface{}) error {
|
|||||||
return assignValues(to, valueOf)
|
return assignValues(to, valueOf)
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadAndAssign creates a collection from a spec, and assigns it to a struct.
|
// LoadAndAssign maps and programs into the kernel and assign them to a struct.
|
||||||
//
|
//
|
||||||
// See Collection.Assign for details.
|
// 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.
|
||||||
func (cs *CollectionSpec) LoadAndAssign(to interface{}, opts *CollectionOptions) error {
|
func (cs *CollectionSpec) LoadAndAssign(to interface{}, opts *CollectionOptions) error {
|
||||||
if opts == nil {
|
if opts == nil {
|
||||||
opts = &CollectionOptions{}
|
opts = &CollectionOptions{}
|
||||||
}
|
}
|
||||||
|
|
||||||
coll, err := NewCollectionWithOptions(cs, *opts)
|
loadMap, loadProgram, done, cleanup := lazyLoadCollection(cs, opts)
|
||||||
if err != nil {
|
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 {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer coll.Close()
|
|
||||||
|
|
||||||
return coll.Assign(to)
|
done()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collection is a collection of Programs and Maps associated
|
// Collection is a collection of Programs and Maps associated
|
||||||
@ -198,28 +239,75 @@ type Collection struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewCollection creates a Collection from a specification.
|
// 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) {
|
func NewCollection(spec *CollectionSpec) (*Collection, error) {
|
||||||
return NewCollectionWithOptions(spec, CollectionOptions{})
|
return NewCollectionWithOptions(spec, CollectionOptions{})
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCollectionWithOptions creates a Collection from a specification.
|
// NewCollectionWithOptions creates a Collection from a specification.
|
||||||
//
|
func NewCollectionWithOptions(spec *CollectionSpec, opts CollectionOptions) (*Collection, error) {
|
||||||
// Only maps referenced by at least one of the programs are initialized.
|
loadMap, loadProgram, done, cleanup := lazyLoadCollection(spec, &opts)
|
||||||
func NewCollectionWithOptions(spec *CollectionSpec, opts CollectionOptions) (coll *Collection, err error) {
|
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(),
|
||||||
|
) {
|
||||||
var (
|
var (
|
||||||
maps = make(map[string]*Map)
|
maps = make(map[string]*Map)
|
||||||
progs = make(map[string]*Program)
|
progs = make(map[string]*Program)
|
||||||
btfs = make(map[*btf.Spec]*btf.Handle)
|
btfs = make(btfHandleCache)
|
||||||
|
skipMapsAndProgs = false
|
||||||
)
|
)
|
||||||
|
|
||||||
defer func() {
|
cleanup = func() {
|
||||||
for _, btf := range btfs {
|
btfs.close()
|
||||||
btf.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
if err == nil {
|
if skipMapsAndProgs {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,40 +318,43 @@ func NewCollectionWithOptions(spec *CollectionSpec, opts CollectionOptions) (col
|
|||||||
for _, p := range progs {
|
for _, p := range progs {
|
||||||
p.Close()
|
p.Close()
|
||||||
}
|
}
|
||||||
}()
|
|
||||||
|
|
||||||
loadBTF := func(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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for mapName, mapSpec := range spec.Maps {
|
done = func() (map[string]*Map, map[string]*Program) {
|
||||||
var handle *btf.Handle
|
skipMapsAndProgs = true
|
||||||
if mapSpec.BTF != nil {
|
return maps, progs
|
||||||
handle, err = loadBTF(btf.MapSpec(mapSpec.BTF))
|
}
|
||||||
if err != nil && !errors.Is(err, btf.ErrNotSupported) {
|
|
||||||
return nil, err
|
loadMap = func(mapName string) (*Map, error) {
|
||||||
}
|
if m := maps[mapName]; m != nil {
|
||||||
|
return m, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
m, err := newMapWithBTF(mapSpec, handle, opts.Maps)
|
mapSpec := coll.Maps[mapName]
|
||||||
|
if mapSpec == nil {
|
||||||
|
return nil, fmt.Errorf("missing map %s", mapName)
|
||||||
|
}
|
||||||
|
|
||||||
|
m, err := newMapWithOptions(mapSpec, opts.Maps, btfs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("map %s: %w", mapName, err)
|
return nil, fmt.Errorf("map %s: %w", mapName, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
maps[mapName] = m
|
maps[mapName] = m
|
||||||
|
return m, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
for progName, origProgSpec := range spec.Programs {
|
loadProgram = func(progName string) (*Program, error) {
|
||||||
progSpec := origProgSpec.Copy()
|
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()
|
||||||
|
|
||||||
// Rewrite any reference to a valid map.
|
// Rewrite any reference to a valid map.
|
||||||
for i := range progSpec.Instructions {
|
for i := range progSpec.Instructions {
|
||||||
@ -279,9 +370,9 @@ func NewCollectionWithOptions(spec *CollectionSpec, opts CollectionOptions) (col
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
m := maps[ins.Reference]
|
m, err := loadMap(ins.Reference)
|
||||||
if m == nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("program %s: missing map %s", progName, ins.Reference)
|
return nil, fmt.Errorf("program %s: %s", progName, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fd := m.FD()
|
fd := m.FD()
|
||||||
@ -293,25 +384,16 @@ func NewCollectionWithOptions(spec *CollectionSpec, opts CollectionOptions) (col
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var handle *btf.Handle
|
prog, err := newProgramWithOptions(progSpec, opts.Programs, btfs)
|
||||||
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 {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("program %s: %w", progName, err)
|
return nil, fmt.Errorf("program %s: %w", progName, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
progs[progName] = prog
|
progs[progName] = prog
|
||||||
|
return prog, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Collection{
|
return
|
||||||
progs,
|
|
||||||
maps,
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadCollection parses an object file and converts it to a collection.
|
// LoadCollection parses an object file and converts it to a collection.
|
||||||
@ -359,18 +441,8 @@ func (coll *Collection) DetachProgram(name string) *Program {
|
|||||||
|
|
||||||
// Assign the contents of a collection to a struct.
|
// Assign the contents of a collection to a struct.
|
||||||
//
|
//
|
||||||
// `to` must be a pointer to a struct like the following:
|
// Deprecated: use CollectionSpec.Assign instead. It provides the same
|
||||||
//
|
// functionality but creates only the maps and programs requested.
|
||||||
// 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 {
|
func (coll *Collection) Assign(to interface{}) error {
|
||||||
assignedMaps := make(map[string]struct{})
|
assignedMaps := make(map[string]struct{})
|
||||||
assignedPrograms := make(map[string]struct{})
|
assignedPrograms := make(map[string]struct{})
|
||||||
@ -411,28 +483,86 @@ func (coll *Collection) Assign(to interface{}) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func assignValues(to interface{}, valueOf func(reflect.Type, string) (reflect.Value, error)) error {
|
func assignValues(to interface{}, valueOf func(reflect.Type, string) (reflect.Value, error)) error {
|
||||||
v := reflect.ValueOf(to)
|
type structField struct {
|
||||||
if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct {
|
reflect.StructField
|
||||||
return fmt.Errorf("%T is not a pointer to a struct", to)
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
type elem struct {
|
type elem struct {
|
||||||
|
// Either *Map or *Program
|
||||||
typ reflect.Type
|
typ reflect.Type
|
||||||
name string
|
name string
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
assignedTo := make(map[elem]string)
|
||||||
s = v.Elem()
|
for _, field := range fields {
|
||||||
sT = s.Type()
|
|
||||||
assignedTo = make(map[elem]string)
|
|
||||||
)
|
|
||||||
for i := 0; i < sT.NumField(); i++ {
|
|
||||||
field := sT.Field(i)
|
|
||||||
|
|
||||||
name := field.Tag.Get("ebpf")
|
name := field.Tag.Get("ebpf")
|
||||||
if name == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if strings.Contains(name, ",") {
|
if strings.Contains(name, ",") {
|
||||||
return fmt.Errorf("field %s: ebpf tag contains a comma", field.Name)
|
return fmt.Errorf("field %s: ebpf tag contains a comma", field.Name)
|
||||||
}
|
}
|
||||||
@ -447,12 +577,11 @@ func assignValues(to interface{}, valueOf func(reflect.Type, string) (reflect.Va
|
|||||||
return fmt.Errorf("field %s: %w", field.Name, err)
|
return fmt.Errorf("field %s: %w", field.Name, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fieldValue := s.Field(i)
|
if !field.value.CanSet() {
|
||||||
if !fieldValue.CanSet() {
|
return fmt.Errorf("field %s: can't set value", field.Name)
|
||||||
return fmt.Errorf("can't set value of field %s", field.Name)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fieldValue.Set(value)
|
field.value.Set(value)
|
||||||
assignedTo[e] = field.Name
|
assignedTo[e] = field.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
632
vendor/github.com/cilium/ebpf/elf_reader.go
generated
vendored
632
vendor/github.com/cilium/ebpf/elf_reader.go
generated
vendored
@ -18,12 +18,14 @@ import (
|
|||||||
"github.com/cilium/ebpf/internal/unix"
|
"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 {
|
type elfCode struct {
|
||||||
*elf.File
|
*internal.SafeELFFile
|
||||||
symbols []elf.Symbol
|
sections map[elf.SectionIndex]*elfSection
|
||||||
symbolsPerSection map[elf.SectionIndex]map[uint64]elf.Symbol
|
license string
|
||||||
license string
|
version uint32
|
||||||
version uint32
|
btf *btf.Spec
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadCollectionSpec parses an ELF file into a CollectionSpec.
|
// LoadCollectionSpec parses an ELF file into a CollectionSpec.
|
||||||
@ -43,63 +45,52 @@ func LoadCollectionSpec(file string) (*CollectionSpec, error) {
|
|||||||
|
|
||||||
// LoadCollectionSpecFromReader parses an ELF file into a CollectionSpec.
|
// LoadCollectionSpecFromReader parses an ELF file into a CollectionSpec.
|
||||||
func LoadCollectionSpecFromReader(rd io.ReaderAt) (*CollectionSpec, error) {
|
func LoadCollectionSpecFromReader(rd io.ReaderAt) (*CollectionSpec, error) {
|
||||||
f, err := elf.NewFile(rd)
|
f, err := internal.NewSafeELFFile(rd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer f.Close()
|
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 (
|
var (
|
||||||
licenseSection *elf.Section
|
licenseSection *elf.Section
|
||||||
versionSection *elf.Section
|
versionSection *elf.Section
|
||||||
btfMaps = make(map[elf.SectionIndex]*elf.Section)
|
sections = make(map[elf.SectionIndex]*elfSection)
|
||||||
progSections = make(map[elf.SectionIndex]*elf.Section)
|
|
||||||
relSections = 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)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
for i, sec := range ec.Sections {
|
// 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)
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case strings.HasPrefix(sec.Name, "license"):
|
case strings.HasPrefix(sec.Name, "license"):
|
||||||
licenseSection = sec
|
licenseSection = sec
|
||||||
case strings.HasPrefix(sec.Name, "version"):
|
case strings.HasPrefix(sec.Name, "version"):
|
||||||
versionSection = sec
|
versionSection = sec
|
||||||
case strings.HasPrefix(sec.Name, "maps"):
|
case strings.HasPrefix(sec.Name, "maps"):
|
||||||
mapSections[elf.SectionIndex(i)] = sec
|
sections[idx] = newElfSection(sec, mapSection)
|
||||||
case sec.Name == ".maps":
|
case sec.Name == ".maps":
|
||||||
btfMaps[elf.SectionIndex(i)] = sec
|
sections[idx] = newElfSection(sec, btfMapSection)
|
||||||
case sec.Name == ".bss" || sec.Name == ".rodata" || sec.Name == ".data":
|
case sec.Name == ".bss" || sec.Name == ".data" || strings.HasPrefix(sec.Name, ".rodata"):
|
||||||
dataSections[elf.SectionIndex(i)] = sec
|
sections[idx] = newElfSection(sec, dataSection)
|
||||||
case sec.Type == elf.SHT_REL:
|
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
|
// Store relocations under the section index of the target
|
||||||
idx := elf.SectionIndex(sec.Info)
|
relSections[elf.SectionIndex(sec.Info)] = sec
|
||||||
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:
|
case sec.Type == elf.SHT_PROGBITS && (sec.Flags&elf.SHF_EXECINSTR) != 0 && sec.Size > 0:
|
||||||
progSections[elf.SectionIndex(i)] = sec
|
sections[idx] = newElfSection(sec, programSection)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ec.license, err = loadLicense(licenseSection)
|
license, err := loadLicense(licenseSection)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("load license: %w", err)
|
return nil, fmt.Errorf("load license: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ec.version, err = loadVersion(versionSection, ec.ByteOrder)
|
version, err := loadVersion(versionSection, f.ByteOrder)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("load version: %w", err)
|
return nil, fmt.Errorf("load version: %w", err)
|
||||||
}
|
}
|
||||||
@ -109,37 +100,90 @@ func LoadCollectionSpecFromReader(rd io.ReaderAt) (*CollectionSpec, error) {
|
|||||||
return nil, fmt.Errorf("load BTF: %w", err)
|
return nil, fmt.Errorf("load BTF: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
relocations, referencedSections, err := ec.loadRelocations(relSections)
|
// Assign symbols to all the sections we're interested in.
|
||||||
|
symbols, err := f.Symbols()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("load relocations: %w", err)
|
return nil, fmt.Errorf("load symbols: %v", 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)
|
maps := make(map[string]*MapSpec)
|
||||||
if err := ec.loadMaps(maps, mapSections); err != nil {
|
if err := ec.loadMaps(maps); err != nil {
|
||||||
return nil, fmt.Errorf("load maps: %w", err)
|
return nil, fmt.Errorf("load maps: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(btfMaps) > 0 {
|
if err := ec.loadBTFMaps(maps); err != nil {
|
||||||
if err := ec.loadBTFMaps(maps, btfMaps, btfSpec); err != nil {
|
return nil, fmt.Errorf("load BTF maps: %w", err)
|
||||||
return nil, fmt.Errorf("load BTF maps: %w", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(dataSections) > 0 {
|
if err := ec.loadDataSections(maps); err != nil {
|
||||||
for idx := range dataSections {
|
return nil, fmt.Errorf("load data sections: %w", err)
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
progs, err := ec.loadPrograms(progSections, relocations, btfSpec)
|
// Finally, collect programs and link them.
|
||||||
|
progs, err := ec.loadPrograms()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("load programs: %w", err)
|
return nil, fmt.Errorf("load programs: %w", err)
|
||||||
}
|
}
|
||||||
@ -171,26 +215,61 @@ func loadVersion(sec *elf.Section, bo binary.ByteOrder) (uint32, error) {
|
|||||||
return version, nil
|
return version, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
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) {
|
||||||
var (
|
var (
|
||||||
progs []*ProgramSpec
|
progs []*ProgramSpec
|
||||||
libs []*ProgramSpec
|
libs []*ProgramSpec
|
||||||
)
|
)
|
||||||
|
|
||||||
for idx, sec := range progSections {
|
for _, sec := range ec.sections {
|
||||||
syms := ec.symbolsPerSection[idx]
|
if sec.kind != programSection {
|
||||||
if len(syms) == 0 {
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(sec.symbols) == 0 {
|
||||||
return nil, fmt.Errorf("section %v: missing symbols", sec.Name)
|
return nil, fmt.Errorf("section %v: missing symbols", sec.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
funcSym, ok := syms[0]
|
funcSym, ok := sec.symbols[0]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("section %v: no label at start", sec.Name)
|
return nil, fmt.Errorf("section %v: no label at start", sec.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
insns, length, err := ec.loadInstructions(sec, syms, relocations[idx])
|
insns, length, err := ec.loadInstructions(sec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("program %s: can't unmarshal instructions: %w", funcSym.Name, err)
|
return nil, fmt.Errorf("program %s: %w", funcSym.Name, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
progType, attachType, attachTo := getProgType(sec.Name)
|
progType, attachType, attachTo := getProgType(sec.Name)
|
||||||
@ -206,8 +285,8 @@ func (ec *elfCode) loadPrograms(progSections map[elf.SectionIndex]*elf.Section,
|
|||||||
ByteOrder: ec.ByteOrder,
|
ByteOrder: ec.ByteOrder,
|
||||||
}
|
}
|
||||||
|
|
||||||
if btfSpec != nil {
|
if ec.btf != nil {
|
||||||
spec.BTF, err = btfSpec.Program(sec.Name, length)
|
spec.BTF, err = ec.btf.Program(sec.Name, length)
|
||||||
if err != nil && !errors.Is(err, btf.ErrNoExtendedInfo) {
|
if err != nil && !errors.Is(err, btf.ErrNoExtendedInfo) {
|
||||||
return nil, fmt.Errorf("program %s: %w", funcSym.Name, err)
|
return nil, fmt.Errorf("program %s: %w", funcSym.Name, err)
|
||||||
}
|
}
|
||||||
@ -235,7 +314,7 @@ func (ec *elfCode) loadPrograms(progSections map[elf.SectionIndex]*elf.Section,
|
|||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ec *elfCode) loadInstructions(section *elf.Section, symbols, relocations map[uint64]elf.Symbol) (asm.Instructions, uint64, error) {
|
func (ec *elfCode) loadInstructions(section *elfSection) (asm.Instructions, uint64, error) {
|
||||||
var (
|
var (
|
||||||
r = bufio.NewReader(section.Open())
|
r = bufio.NewReader(section.Open())
|
||||||
insns asm.Instructions
|
insns asm.Instructions
|
||||||
@ -251,11 +330,11 @@ func (ec *elfCode) loadInstructions(section *elf.Section, symbols, relocations m
|
|||||||
return nil, 0, fmt.Errorf("offset %d: %w", offset, err)
|
return nil, 0, fmt.Errorf("offset %d: %w", offset, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ins.Symbol = symbols[offset].Name
|
ins.Symbol = section.symbols[offset].Name
|
||||||
|
|
||||||
if rel, ok := relocations[offset]; ok {
|
if rel, ok := section.relocations[offset]; ok {
|
||||||
if err = ec.relocateInstruction(&ins, rel); err != nil {
|
if err = ec.relocateInstruction(&ins, rel); err != nil {
|
||||||
return nil, 0, fmt.Errorf("offset %d: can't relocate instruction: %w", offset, err)
|
return nil, 0, fmt.Errorf("offset %d: relocate instruction: %w", offset, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -271,69 +350,66 @@ func (ec *elfCode) relocateInstruction(ins *asm.Instruction, rel elf.Symbol) err
|
|||||||
name = rel.Name
|
name = rel.Name
|
||||||
)
|
)
|
||||||
|
|
||||||
if typ == elf.STT_SECTION {
|
target := ec.sections[rel.Section]
|
||||||
// Symbols with section type do not have a name set. Get it
|
|
||||||
// from the section itself.
|
switch target.kind {
|
||||||
idx := int(rel.Section)
|
case mapSection, btfMapSection:
|
||||||
if idx > len(ec.Sections) {
|
if bind != elf.STB_GLOBAL {
|
||||||
return errors.New("out-of-bounds section index")
|
return fmt.Errorf("possible erroneous static qualifier on map definition: found reference to %q", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
name = ec.Sections[idx].Name
|
if typ != elf.STT_OBJECT && typ != elf.STT_NOTYPE {
|
||||||
}
|
// STT_NOTYPE is generated on clang < 8 which doesn't tag
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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.
|
// relocations appropriately.
|
||||||
fallthrough
|
return fmt.Errorf("map load: incorrect relocation type %v", typ)
|
||||||
|
|
||||||
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("load: %s: unsupported relocation: %s", name, typ)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ins.Src = asm.PseudoMapFD
|
||||||
|
|
||||||
// Mark the instruction as needing an update when creating the
|
// Mark the instruction as needing an update when creating the
|
||||||
// collection.
|
// collection.
|
||||||
if err := ins.RewriteMapPtr(-1); err != nil {
|
if err := ins.RewriteMapPtr(-1); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
case ins.OpCode.JumpOp() == asm.Call:
|
case dataSection:
|
||||||
|
switch typ {
|
||||||
|
case elf.STT_SECTION:
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("incorrect relocation type %v for direct map load", 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)
|
||||||
|
}
|
||||||
|
|
||||||
if ins.Src != asm.PseudoCall {
|
if ins.Src != asm.PseudoCall {
|
||||||
return fmt.Errorf("call: %s: incorrect source register", name)
|
return fmt.Errorf("call: %s: incorrect source register", name)
|
||||||
}
|
}
|
||||||
@ -358,7 +434,7 @@ outer:
|
|||||||
return fmt.Errorf("call: %s: invalid offset %d", name, offset)
|
return fmt.Errorf("call: %s: invalid offset %d", name, offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
sym, ok := ec.symbolsPerSection[rel.Section][uint64(offset)]
|
sym, ok := target.symbols[uint64(offset)]
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("call: %s: no symbol at offset %d", name, offset)
|
return fmt.Errorf("call: %s: no symbol at offset %d", name, offset)
|
||||||
}
|
}
|
||||||
@ -370,31 +446,46 @@ outer:
|
|||||||
return fmt.Errorf("call: %s: invalid symbol type %s", name, typ)
|
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:
|
default:
|
||||||
return fmt.Errorf("relocation for unsupported instruction: %s", ins.OpCode)
|
return fmt.Errorf("relocation to %q: %w", target.Name, ErrNotSupported)
|
||||||
}
|
}
|
||||||
|
|
||||||
ins.Reference = name
|
ins.Reference = name
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ec *elfCode) loadMaps(maps map[string]*MapSpec, mapSections map[elf.SectionIndex]*elf.Section) error {
|
func (ec *elfCode) loadMaps(maps map[string]*MapSpec) error {
|
||||||
for idx, sec := range mapSections {
|
for _, sec := range ec.sections {
|
||||||
syms := ec.symbolsPerSection[idx]
|
if sec.kind != mapSection {
|
||||||
if len(syms) == 0 {
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
nSym := len(sec.symbols)
|
||||||
|
if nSym == 0 {
|
||||||
return fmt.Errorf("section %v: no symbols", sec.Name)
|
return fmt.Errorf("section %v: no symbols", sec.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if sec.Size%uint64(len(syms)) != 0 {
|
if sec.Size%uint64(nSym) != 0 {
|
||||||
return fmt.Errorf("section %v: map descriptors are not of equal size", sec.Name)
|
return fmt.Errorf("section %v: map descriptors are not of equal size", sec.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
r = bufio.NewReader(sec.Open())
|
r = bufio.NewReader(sec.Open())
|
||||||
size = sec.Size / uint64(len(syms))
|
size = sec.Size / uint64(nSym)
|
||||||
)
|
)
|
||||||
for i, offset := 0, uint64(0); i < len(syms); i, offset = i+1, offset+size {
|
for i, offset := 0, uint64(0); i < nSym; i, offset = i+1, offset+size {
|
||||||
mapSym, ok := syms[offset]
|
mapSym, ok := sec.symbols[offset]
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("section %s: missing symbol for map at offset %d", sec.Name, offset)
|
return fmt.Errorf("section %s: missing symbol for map at offset %d", sec.Name, offset)
|
||||||
}
|
}
|
||||||
@ -432,24 +523,46 @@ func (ec *elfCode) loadMaps(maps map[string]*MapSpec, mapSections map[elf.Sectio
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ec *elfCode) loadBTFMaps(maps map[string]*MapSpec, mapSections map[elf.SectionIndex]*elf.Section, spec *btf.Spec) error {
|
func (ec *elfCode) loadBTFMaps(maps map[string]*MapSpec) error {
|
||||||
if spec == nil {
|
for _, sec := range ec.sections {
|
||||||
return fmt.Errorf("missing BTF")
|
if sec.kind != btfMapSection {
|
||||||
}
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
for idx, sec := range mapSections {
|
if ec.btf == nil {
|
||||||
syms := ec.symbolsPerSection[idx]
|
return fmt.Errorf("missing BTF")
|
||||||
if len(syms) == 0 {
|
}
|
||||||
|
|
||||||
|
if len(sec.symbols) == 0 {
|
||||||
return fmt.Errorf("section %v: no symbols", sec.Name)
|
return fmt.Errorf("section %v: no symbols", sec.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, sym := range syms {
|
_, 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, sym := range sec.symbols {
|
||||||
name := sym.Name
|
name := sym.Name
|
||||||
if maps[name] != nil {
|
if maps[name] != nil {
|
||||||
return fmt.Errorf("section %v: map %v already exists", sec.Name, sym)
|
return fmt.Errorf("section %v: map %v already exists", sec.Name, sym)
|
||||||
}
|
}
|
||||||
|
|
||||||
mapSpec, err := mapSpecFromBTF(spec, name)
|
// A global Var is created by declaring a struct with a 'structure variable',
|
||||||
|
// as is common in eBPF C to declare eBPF maps. For example,
|
||||||
|
// `struct { ... } map_name ...;` emits a global variable `map_name`
|
||||||
|
// with the type of said struct (which can be anonymous).
|
||||||
|
var v btf.Var
|
||||||
|
if err := ec.btf.FindType(name, &v); err != nil {
|
||||||
|
return fmt.Errorf("cannot find global variable '%s' in BTF: %w", name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("map %v: %w", name, err)
|
return fmt.Errorf("map %v: %w", name, err)
|
||||||
}
|
}
|
||||||
@ -461,31 +574,21 @@ func (ec *elfCode) loadBTFMaps(maps map[string]*MapSpec, mapSections map[elf.Sec
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func mapSpecFromBTF(spec *btf.Spec, name string) (*MapSpec, error) {
|
// mapSpecFromBTF produces a MapSpec based on a btf.Struct def representing
|
||||||
btfMap, btfMapMembers, err := spec.Map(name)
|
// a BTF map definition. The name and spec arguments will be copied to the
|
||||||
if err != nil {
|
// resulting MapSpec, and inner must be true on any resursive invocations.
|
||||||
return nil, fmt.Errorf("can't get BTF: %w", err)
|
func mapSpecFromBTF(name string, def *btf.Struct, inner bool, spec *btf.Spec) (*MapSpec, error) {
|
||||||
}
|
|
||||||
|
|
||||||
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 (
|
var (
|
||||||
|
key, value btf.Type
|
||||||
|
keySize, valueSize uint32
|
||||||
mapType, flags, maxEntries uint32
|
mapType, flags, maxEntries uint32
|
||||||
pinType PinType
|
pinType PinType
|
||||||
|
innerMapSpec *MapSpec
|
||||||
|
err error
|
||||||
)
|
)
|
||||||
for _, member := range btfMapMembers {
|
|
||||||
|
for i, member := range def.Members {
|
||||||
switch member.Name {
|
switch member.Name {
|
||||||
case "type":
|
case "type":
|
||||||
mapType, err = uintFromBTF(member.Type)
|
mapType, err = uintFromBTF(member.Type)
|
||||||
@ -505,8 +608,48 @@ func mapSpecFromBTF(spec *btf.Spec, name string) (*MapSpec, error) {
|
|||||||
return nil, fmt.Errorf("can't get BTF map max entries: %w", err)
|
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":
|
case "key_size":
|
||||||
if _, isVoid := keyType.(*btf.Void); !isVoid {
|
// 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 {
|
||||||
return nil, errors.New("both key and key_size given")
|
return nil, errors.New("both key and key_size given")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -516,7 +659,9 @@ func mapSpecFromBTF(spec *btf.Spec, name string) (*MapSpec, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case "value_size":
|
case "value_size":
|
||||||
if _, isVoid := valueType.(*btf.Void); !isVoid {
|
// 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 {
|
||||||
return nil, errors.New("both value and value_size given")
|
return nil, errors.New("both value and value_size given")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -526,6 +671,10 @@ func mapSpecFromBTF(spec *btf.Spec, name string) (*MapSpec, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case "pinning":
|
case "pinning":
|
||||||
|
if inner {
|
||||||
|
return nil, errors.New("inner maps can't be pinned")
|
||||||
|
}
|
||||||
|
|
||||||
pinning, err := uintFromBTF(member.Type)
|
pinning, err := uintFromBTF(member.Type)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("can't get pinning: %w", err)
|
return nil, fmt.Errorf("can't get pinning: %w", err)
|
||||||
@ -533,12 +682,58 @@ func mapSpecFromBTF(spec *btf.Spec, name string) (*MapSpec, error) {
|
|||||||
|
|
||||||
pinType = PinType(pinning)
|
pinType = PinType(pinning)
|
||||||
|
|
||||||
case "key", "value":
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("unrecognized field %s in BTF map definition", member.Name)
|
return nil, fmt.Errorf("unrecognized field %s in BTF map definition", member.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bm := btf.NewMap(spec, key, value)
|
||||||
|
|
||||||
return &MapSpec{
|
return &MapSpec{
|
||||||
Name: SanitizeName(name, -1),
|
Name: SanitizeName(name, -1),
|
||||||
Type: MapType(mapType),
|
Type: MapType(mapType),
|
||||||
@ -546,8 +741,9 @@ func mapSpecFromBTF(spec *btf.Spec, name string) (*MapSpec, error) {
|
|||||||
ValueSize: valueSize,
|
ValueSize: valueSize,
|
||||||
MaxEntries: maxEntries,
|
MaxEntries: maxEntries,
|
||||||
Flags: flags,
|
Flags: flags,
|
||||||
BTF: btfMap,
|
BTF: &bm,
|
||||||
Pinning: pinType,
|
Pinning: pinType,
|
||||||
|
InnerMap: innerMapSpec,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -567,13 +763,40 @@ func uintFromBTF(typ btf.Type) (uint32, error) {
|
|||||||
return arr.Nelems, nil
|
return arr.Nelems, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ec *elfCode) loadDataSections(maps map[string]*MapSpec, dataSections map[elf.SectionIndex]*elf.Section, spec *btf.Spec) error {
|
// resolveBTFArrayMacro resolves the __array macro, which declares an array
|
||||||
if spec == nil {
|
// of pointers to a given type. This function returns the target Type of
|
||||||
return errors.New("data sections require BTF, make sure all consts are marked as static")
|
// 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)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, sec := range dataSections {
|
ptr, ok := arr.Type.(*btf.Pointer)
|
||||||
btfMap, err := spec.Datasec(sec.Name)
|
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)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -678,69 +901,30 @@ func getProgType(sectionName string) (ProgramType, AttachType, string) {
|
|||||||
return UnspecifiedProgram, AttachNone, ""
|
return UnspecifiedProgram, AttachNone, ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ec *elfCode) loadRelocations(sections map[elf.SectionIndex]*elf.Section) (map[elf.SectionIndex]map[uint64]elf.Symbol, map[elf.SectionIndex]bool, error) {
|
func (ec *elfCode) loadRelocations(sec *elf.Section, symbols []elf.Symbol) (map[uint64]elf.Symbol, error) {
|
||||||
result := make(map[elf.SectionIndex]map[uint64]elf.Symbol)
|
rels := make(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 {
|
if sec.Entsize < 16 {
|
||||||
return nil, nil, fmt.Errorf("section %s: relocations are less than 16 bytes", sec.Name)
|
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, 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]
|
|
||||||
}
|
|
||||||
|
|
||||||
result[idx] = rels
|
|
||||||
}
|
}
|
||||||
return result, targets, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func symbolsPerSection(symbols []elf.Symbol) map[elf.SectionIndex]map[uint64]elf.Symbol {
|
r := bufio.NewReader(sec.Open())
|
||||||
result := make(map[elf.SectionIndex]map[uint64]elf.Symbol)
|
for off := uint64(0); off < sec.Size; off += sec.Entsize {
|
||||||
for _, sym := range symbols {
|
ent := io.LimitReader(r, int64(sec.Entsize))
|
||||||
switch elf.ST_TYPE(sym.Info) {
|
|
||||||
case elf.STT_NOTYPE:
|
var rel elf.Rel64
|
||||||
// Older versions of LLVM doesn't tag
|
if binary.Read(ent, ec.ByteOrder, &rel) != nil {
|
||||||
// symbols correctly.
|
return nil, fmt.Errorf("can't parse relocation at offset %v", off)
|
||||||
break
|
|
||||||
case elf.STT_OBJECT:
|
|
||||||
break
|
|
||||||
case elf.STT_FUNC:
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if sym.Section == elf.SHN_UNDEF || sym.Section >= elf.SHN_LORESERVE {
|
symNo := int(elf.R_SYM64(rel.Info) - 1)
|
||||||
continue
|
if symNo >= len(symbols) {
|
||||||
|
return nil, fmt.Errorf("offset %d: symbol %d doesn't exist", off, symNo)
|
||||||
}
|
}
|
||||||
|
|
||||||
if sym.Name == "" {
|
symbol := symbols[symNo]
|
||||||
continue
|
rels[rel.Off] = symbol
|
||||||
}
|
|
||||||
|
|
||||||
idx := sym.Section
|
|
||||||
if _, ok := result[idx]; !ok {
|
|
||||||
result[idx] = make(map[uint64]elf.Symbol)
|
|
||||||
}
|
|
||||||
result[idx][sym.Value] = sym
|
|
||||||
}
|
}
|
||||||
return result
|
|
||||||
|
return rels, nil
|
||||||
}
|
}
|
||||||
|
21
vendor/github.com/cilium/ebpf/elf_reader_fuzz.go
generated
vendored
Normal file
21
vendor/github.com/cilium/ebpf/elf_reader_fuzz.go
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// +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,8 +1,9 @@
|
|||||||
module github.com/cilium/ebpf
|
module github.com/cilium/ebpf
|
||||||
|
|
||||||
go 1.14
|
go 1.15
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/google/go-cmp v0.5.2
|
github.com/frankban/quicktest v1.11.3
|
||||||
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9
|
github.com/google/go-cmp v0.5.4
|
||||||
|
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c
|
||||||
)
|
)
|
||||||
|
15
vendor/github.com/cilium/ebpf/go.sum
generated
vendored
15
vendor/github.com/cilium/ebpf/go.sum
generated
vendored
@ -1,6 +1,13 @@
|
|||||||
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
|
github.com/frankban/quicktest v1.11.3 h1:8sXhOn0uLys67V8EsXLc6eszDs8VXWxL3iRvebPhedY=
|
||||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
|
||||||
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9 h1:1/DFK4b7JH8DmkqhUk48onnSfrPzImPoVxuomtbT2nk=
|
github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M=
|
||||||
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
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=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
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=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
239
vendor/github.com/cilium/ebpf/info.go
generated
vendored
Normal file
239
vendor/github.com/cilium/ebpf/info.go
generated
vendored
Normal file
@ -0,0 +1,239 @@
|
|||||||
|
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,12 +29,14 @@ var (
|
|||||||
|
|
||||||
// Spec represents decoded BTF.
|
// Spec represents decoded BTF.
|
||||||
type Spec struct {
|
type Spec struct {
|
||||||
rawTypes []rawType
|
rawTypes []rawType
|
||||||
strings stringTable
|
strings stringTable
|
||||||
types map[string][]namedType
|
types []Type
|
||||||
funcInfos map[string]extInfo
|
namedTypes map[string][]namedType
|
||||||
lineInfos map[string]extInfo
|
funcInfos map[string]extInfo
|
||||||
byteOrder binary.ByteOrder
|
lineInfos map[string]extInfo
|
||||||
|
coreRelos map[string]bpfCoreRelos
|
||||||
|
byteOrder binary.ByteOrder
|
||||||
}
|
}
|
||||||
|
|
||||||
type btfHeader struct {
|
type btfHeader struct {
|
||||||
@ -53,7 +55,7 @@ type btfHeader struct {
|
|||||||
//
|
//
|
||||||
// Returns a nil Spec and no error if no BTF was present.
|
// Returns a nil Spec and no error if no BTF was present.
|
||||||
func LoadSpecFromReader(rd io.ReaderAt) (*Spec, error) {
|
func LoadSpecFromReader(rd io.ReaderAt) (*Spec, error) {
|
||||||
file, err := elf.NewFile(rd)
|
file, err := internal.NewSafeELFFile(rd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -80,6 +82,10 @@ func LoadSpecFromReader(rd io.ReaderAt) (*Spec, error) {
|
|||||||
continue
|
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
|
secName := file.Sections[symbol.Section].Name
|
||||||
if _, ok := sectionSizes[secName]; !ok {
|
if _, ok := sectionSizes[secName]; !ok {
|
||||||
continue
|
continue
|
||||||
@ -101,7 +107,7 @@ func LoadSpecFromReader(rd io.ReaderAt) (*Spec, error) {
|
|||||||
return spec, nil
|
return spec, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
spec.funcInfos, spec.lineInfos, err = parseExtInfos(btfExtSection.Open(), file.ByteOrder, spec.strings)
|
spec.funcInfos, spec.lineInfos, spec.coreRelos, err = parseExtInfos(btfExtSection.Open(), file.ByteOrder, spec.strings)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("can't read ext info: %w", err)
|
return nil, fmt.Errorf("can't read ext info: %w", err)
|
||||||
}
|
}
|
||||||
@ -109,7 +115,7 @@ func LoadSpecFromReader(rd io.ReaderAt) (*Spec, error) {
|
|||||||
return spec, nil
|
return spec, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func findBtfSections(file *elf.File) (*elf.Section, *elf.Section, map[string]uint32, error) {
|
func findBtfSections(file *internal.SafeELFFile) (*elf.Section, *elf.Section, map[string]uint32, error) {
|
||||||
var (
|
var (
|
||||||
btfSection *elf.Section
|
btfSection *elf.Section
|
||||||
btfExtSection *elf.Section
|
btfExtSection *elf.Section
|
||||||
@ -138,7 +144,7 @@ func findBtfSections(file *elf.File) (*elf.Section, *elf.Section, map[string]uin
|
|||||||
}
|
}
|
||||||
|
|
||||||
func loadSpecFromVmlinux(rd io.ReaderAt) (*Spec, error) {
|
func loadSpecFromVmlinux(rd io.ReaderAt) (*Spec, error) {
|
||||||
file, err := elf.NewFile(rd)
|
file, err := internal.NewSafeELFFile(rd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -165,16 +171,17 @@ func loadNakedSpec(btf io.ReadSeeker, bo binary.ByteOrder, sectionSizes map[stri
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
types, err := inflateRawTypes(rawTypes, rawStrings)
|
types, typesByName, err := inflateRawTypes(rawTypes, rawStrings)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Spec{
|
return &Spec{
|
||||||
rawTypes: rawTypes,
|
rawTypes: rawTypes,
|
||||||
types: types,
|
namedTypes: typesByName,
|
||||||
strings: rawStrings,
|
types: types,
|
||||||
byteOrder: bo,
|
strings: rawStrings,
|
||||||
|
byteOrder: bo,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -311,10 +318,14 @@ func fixupDatasec(rawTypes []rawType, rawStrings stringTable, sectionSizes map[s
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if name == ".kconfig" || name == ".ksym" {
|
if name == ".kconfig" || name == ".ksyms" {
|
||||||
return fmt.Errorf("reference to %s: %w", name, ErrNotSupported)
|
return fmt.Errorf("reference to %s: %w", name, ErrNotSupported)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if rawTypes[i].SizeType != 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
size, ok := sectionSizes[name]
|
size, ok := sectionSizes[name]
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("data section %s: missing size", name)
|
return fmt.Errorf("data section %s: missing size", name)
|
||||||
@ -421,64 +432,19 @@ func (s *Spec) Program(name string, length uint64) (*Program, error) {
|
|||||||
return nil, errors.New("length musn't be zero")
|
return nil, errors.New("length musn't be zero")
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.funcInfos == nil && s.lineInfos == nil {
|
if s.funcInfos == nil && s.lineInfos == nil && s.coreRelos == nil {
|
||||||
return nil, fmt.Errorf("BTF for section %s: %w", name, ErrNoExtendedInfo)
|
return nil, fmt.Errorf("BTF for section %s: %w", name, ErrNoExtendedInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
funcInfos, funcOK := s.funcInfos[name]
|
funcInfos, funcOK := s.funcInfos[name]
|
||||||
lineInfos, lineOK := s.lineInfos[name]
|
lineInfos, lineOK := s.lineInfos[name]
|
||||||
|
coreRelos, coreOK := s.coreRelos[name]
|
||||||
|
|
||||||
if !funcOK && !lineOK {
|
if !funcOK && !lineOK && !coreOK {
|
||||||
return nil, fmt.Errorf("no extended BTF info for section %s", name)
|
return nil, fmt.Errorf("no extended BTF info for section %s", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Program{s, length, funcInfos, lineInfos}, nil
|
return &Program{s, length, funcInfos, lineInfos, coreRelos}, 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.
|
// Datasec returns the BTF required to create maps which represent data sections.
|
||||||
@ -488,7 +454,8 @@ func (s *Spec) Datasec(name string) (*Map, error) {
|
|||||||
return nil, fmt.Errorf("data section %s: can't get BTF: %w", name, err)
|
return nil, fmt.Errorf("data section %s: can't get BTF: %w", name, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Map{s, &Void{}, &datasec}, nil
|
m := NewMap(s, &Void{}, &datasec)
|
||||||
|
return &m, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindType searches for a type with a specific name.
|
// FindType searches for a type with a specific name.
|
||||||
@ -503,7 +470,7 @@ func (s *Spec) FindType(name string, typ Type) error {
|
|||||||
candidate Type
|
candidate Type
|
||||||
)
|
)
|
||||||
|
|
||||||
for _, typ := range s.types[essentialName(name)] {
|
for _, typ := range s.namedTypes[essentialName(name)] {
|
||||||
if reflect.TypeOf(typ) != wanted {
|
if reflect.TypeOf(typ) != wanted {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -599,6 +566,23 @@ type Map struct {
|
|||||||
key, value Type
|
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
|
// MapSpec should be a method on Map, but is a free function
|
||||||
// to hide it from users of the ebpf package.
|
// to hide it from users of the ebpf package.
|
||||||
func MapSpec(m *Map) *Spec {
|
func MapSpec(m *Map) *Spec {
|
||||||
@ -622,6 +606,7 @@ type Program struct {
|
|||||||
spec *Spec
|
spec *Spec
|
||||||
length uint64
|
length uint64
|
||||||
funcInfos, lineInfos extInfo
|
funcInfos, lineInfos extInfo
|
||||||
|
coreRelos bpfCoreRelos
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProgramSpec returns the Spec needed for loading function and line infos into the kernel.
|
// ProgramSpec returns the Spec needed for loading function and line infos into the kernel.
|
||||||
@ -647,9 +632,10 @@ func ProgramAppend(s, other *Program) error {
|
|||||||
return fmt.Errorf("line infos: %w", err)
|
return fmt.Errorf("line infos: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
s.length += other.length
|
|
||||||
s.funcInfos = funcInfos
|
s.funcInfos = funcInfos
|
||||||
s.lineInfos = lineInfos
|
s.lineInfos = lineInfos
|
||||||
|
s.coreRelos = s.coreRelos.append(other.coreRelos, s.length)
|
||||||
|
s.length += other.length
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -679,6 +665,19 @@ func ProgramLineInfos(s *Program) (recordSize uint32, bytes []byte, err error) {
|
|||||||
return s.lineInfos.recordSize, bytes, nil
|
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 {
|
type bpfLoadBTFAttr struct {
|
||||||
btf internal.Pointer
|
btf internal.Pointer
|
||||||
logBuf internal.Pointer
|
logBuf internal.Pointer
|
||||||
@ -718,7 +717,7 @@ func marshalBTF(types interface{}, strings []byte, bo binary.ByteOrder) []byte {
|
|||||||
return buf.Bytes()
|
return buf.Bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
var haveBTF = internal.FeatureTest("BTF", "5.1", func() (bool, error) {
|
var haveBTF = internal.FeatureTest("BTF", "5.1", func() error {
|
||||||
var (
|
var (
|
||||||
types struct {
|
types struct {
|
||||||
Integer btfType
|
Integer btfType
|
||||||
@ -742,15 +741,24 @@ var haveBTF = internal.FeatureTest("BTF", "5.1", func() (bool, error) {
|
|||||||
btf: internal.NewSlicePointer(btf),
|
btf: internal.NewSlicePointer(btf),
|
||||||
btfSize: uint32(len(btf)),
|
btfSize: uint32(len(btf)),
|
||||||
})
|
})
|
||||||
if err == nil {
|
if errors.Is(err, unix.EINVAL) || errors.Is(err, unix.EPERM) {
|
||||||
fd.Close()
|
// Treat both EINVAL and EPERM as not supported: loading the program
|
||||||
|
// might still succeed without BTF.
|
||||||
|
return internal.ErrNotSupported
|
||||||
}
|
}
|
||||||
// Check for EINVAL specifically, rather than err != nil since we
|
if err != nil {
|
||||||
// otherwise misdetect due to insufficient permissions.
|
return err
|
||||||
return !errors.Is(err, unix.EINVAL), nil
|
}
|
||||||
|
|
||||||
|
fd.Close()
|
||||||
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
var haveFuncLinkage = internal.FeatureTest("BTF func linkage", "5.6", func() (bool, error) {
|
var haveFuncLinkage = internal.FeatureTest("BTF func linkage", "5.6", func() error {
|
||||||
|
if err := haveBTF(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
types struct {
|
types struct {
|
||||||
FuncProto btfType
|
FuncProto btfType
|
||||||
@ -771,11 +779,13 @@ var haveFuncLinkage = internal.FeatureTest("BTF func linkage", "5.6", func() (bo
|
|||||||
btf: internal.NewSlicePointer(btf),
|
btf: internal.NewSlicePointer(btf),
|
||||||
btfSize: uint32(len(btf)),
|
btfSize: uint32(len(btf)),
|
||||||
})
|
})
|
||||||
if err == nil {
|
if errors.Is(err, unix.EINVAL) {
|
||||||
fd.Close()
|
return internal.ErrNotSupported
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for EINVAL specifically, rather than err != nil since we
|
fd.Close()
|
||||||
// otherwise misdetect due to insufficient permissions.
|
return nil
|
||||||
return !errors.Is(err, unix.EINVAL), nil
|
|
||||||
})
|
})
|
||||||
|
388
vendor/github.com/cilium/ebpf/internal/btf/core.go
generated
vendored
Normal file
388
vendor/github.com/cilium/ebpf/internal/btf/core.go
generated
vendored
Normal file
@ -0,0 +1,388 @@
|
|||||||
|
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,57 +25,82 @@ type btfExtHeader struct {
|
|||||||
LineInfoLen uint32
|
LineInfoLen uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseExtInfos(r io.ReadSeeker, bo binary.ByteOrder, strings stringTable) (funcInfo, lineInfo map[string]extInfo, err error) {
|
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) {
|
||||||
var header btfExtHeader
|
var header btfExtHeader
|
||||||
|
var coreHeader btfExtCoreHeader
|
||||||
if err := binary.Read(r, bo, &header); err != nil {
|
if err := binary.Read(r, bo, &header); err != nil {
|
||||||
return nil, nil, fmt.Errorf("can't read header: %v", err)
|
return nil, nil, nil, fmt.Errorf("can't read header: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if header.Magic != btfMagic {
|
if header.Magic != btfMagic {
|
||||||
return nil, nil, fmt.Errorf("incorrect magic value %v", header.Magic)
|
return nil, nil, nil, fmt.Errorf("incorrect magic value %v", header.Magic)
|
||||||
}
|
}
|
||||||
|
|
||||||
if header.Version != 1 {
|
if header.Version != 1 {
|
||||||
return nil, nil, fmt.Errorf("unexpected version %v", header.Version)
|
return nil, nil, nil, fmt.Errorf("unexpected version %v", header.Version)
|
||||||
}
|
}
|
||||||
|
|
||||||
if header.Flags != 0 {
|
if header.Flags != 0 {
|
||||||
return nil, nil, fmt.Errorf("unsupported flags %v", header.Flags)
|
return nil, nil, nil, fmt.Errorf("unsupported flags %v", header.Flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
remainder := int64(header.HdrLen) - int64(binary.Size(&header))
|
remainder := int64(header.HdrLen) - int64(binary.Size(&header))
|
||||||
if remainder < 0 {
|
if remainder < 0 {
|
||||||
return nil, nil, errors.New("header is too short")
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
// Of course, the .BTF.ext header has different semantics than the
|
// Of course, the .BTF.ext header has different semantics than the
|
||||||
// .BTF ext header. We need to ignore non-null values.
|
// .BTF ext header. We need to ignore non-null values.
|
||||||
_, err = io.CopyN(ioutil.Discard, r, remainder)
|
_, err = io.CopyN(ioutil.Discard, r, remainder)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("header padding: %v", err)
|
return nil, nil, nil, fmt.Errorf("header padding: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := r.Seek(int64(header.HdrLen+header.FuncInfoOff), io.SeekStart); err != nil {
|
if _, err := r.Seek(int64(header.HdrLen+header.FuncInfoOff), io.SeekStart); err != nil {
|
||||||
return nil, nil, fmt.Errorf("can't seek to function info section: %v", err)
|
return nil, nil, nil, fmt.Errorf("can't seek to function info section: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
buf := bufio.NewReader(io.LimitReader(r, int64(header.FuncInfoLen)))
|
buf := bufio.NewReader(io.LimitReader(r, int64(header.FuncInfoLen)))
|
||||||
funcInfo, err = parseExtInfo(buf, bo, strings)
|
funcInfo, err = parseExtInfo(buf, bo, strings)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("function info: %w", err)
|
return nil, nil, nil, fmt.Errorf("function info: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := r.Seek(int64(header.HdrLen+header.LineInfoOff), io.SeekStart); err != nil {
|
if _, err := r.Seek(int64(header.HdrLen+header.LineInfoOff), io.SeekStart); err != nil {
|
||||||
return nil, nil, fmt.Errorf("can't seek to line info section: %v", err)
|
return nil, nil, nil, fmt.Errorf("can't seek to line info section: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = bufio.NewReader(io.LimitReader(r, int64(header.LineInfoLen)))
|
buf = bufio.NewReader(io.LimitReader(r, int64(header.LineInfoLen)))
|
||||||
lineInfo, err = parseExtInfo(buf, bo, strings)
|
lineInfo, err = parseExtInfo(buf, bo, strings)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("line info: %w", err)
|
return nil, nil, nil, fmt.Errorf("line info: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return funcInfo, lineInfo, nil
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
type btfExtInfoSec struct {
|
type btfExtInfoSec struct {
|
||||||
@ -147,20 +172,9 @@ func parseExtInfo(r io.Reader, bo binary.ByteOrder, strings stringTable) (map[st
|
|||||||
|
|
||||||
result := make(map[string]extInfo)
|
result := make(map[string]extInfo)
|
||||||
for {
|
for {
|
||||||
var infoHeader btfExtInfoSec
|
secName, infoHeader, err := parseExtInfoHeader(r, bo, strings)
|
||||||
if err := binary.Read(r, bo, &infoHeader); err == io.EOF {
|
if errors.Is(err, io.EOF) {
|
||||||
return result, nil
|
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
|
var records []extInfoRecord
|
||||||
@ -188,3 +202,80 @@ 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
|
||||||
|
}
|
||||||
|
279
vendor/github.com/cilium/ebpf/internal/btf/types.go
generated
vendored
279
vendor/github.com/cilium/ebpf/internal/btf/types.go
generated
vendored
@ -21,12 +21,14 @@ func (tid TypeID) ID() TypeID {
|
|||||||
type Type interface {
|
type Type interface {
|
||||||
ID() TypeID
|
ID() TypeID
|
||||||
|
|
||||||
|
String() string
|
||||||
|
|
||||||
// Make a copy of the type, without copying Type members.
|
// Make a copy of the type, without copying Type members.
|
||||||
copy() Type
|
copy() Type
|
||||||
|
|
||||||
// Enumerate all nested Types. Repeated calls must visit nested
|
// Enumerate all nested Types. Repeated calls must visit nested
|
||||||
// types in the same order.
|
// types in the same order.
|
||||||
walk(*copyStack)
|
walk(*typeDeque)
|
||||||
}
|
}
|
||||||
|
|
||||||
// namedType is a type with a name.
|
// namedType is a type with a name.
|
||||||
@ -50,9 +52,10 @@ func (n Name) name() string {
|
|||||||
type Void struct{}
|
type Void struct{}
|
||||||
|
|
||||||
func (v *Void) ID() TypeID { return 0 }
|
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) size() uint32 { return 0 }
|
||||||
func (v *Void) copy() Type { return (*Void)(nil) }
|
func (v *Void) copy() Type { return (*Void)(nil) }
|
||||||
func (v *Void) walk(*copyStack) {}
|
func (v *Void) walk(*typeDeque) {}
|
||||||
|
|
||||||
type IntEncoding byte
|
type IntEncoding byte
|
||||||
|
|
||||||
@ -78,21 +81,54 @@ type Int struct {
|
|||||||
|
|
||||||
var _ namedType = (*Int)(nil)
|
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) size() uint32 { return i.Size }
|
||||||
func (i *Int) walk(*copyStack) {}
|
func (i *Int) walk(*typeDeque) {}
|
||||||
func (i *Int) copy() Type {
|
func (i *Int) copy() Type {
|
||||||
cpy := *i
|
cpy := *i
|
||||||
return &cpy
|
return &cpy
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (i *Int) isBitfield() bool {
|
||||||
|
return i.Offset > 0
|
||||||
|
}
|
||||||
|
|
||||||
// Pointer is a pointer to another type.
|
// Pointer is a pointer to another type.
|
||||||
type Pointer struct {
|
type Pointer struct {
|
||||||
TypeID
|
TypeID
|
||||||
Target Type
|
Target Type
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Pointer) size() uint32 { return 8 }
|
func (p *Pointer) String() string {
|
||||||
func (p *Pointer) walk(cs *copyStack) { cs.push(&p.Target) }
|
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) copy() Type {
|
func (p *Pointer) copy() Type {
|
||||||
cpy := *p
|
cpy := *p
|
||||||
return &cpy
|
return &cpy
|
||||||
@ -105,7 +141,11 @@ type Array struct {
|
|||||||
Nelems uint32
|
Nelems uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
func (arr *Array) walk(cs *copyStack) { cs.push(&arr.Type) }
|
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) copy() Type {
|
func (arr *Array) copy() Type {
|
||||||
cpy := *arr
|
cpy := *arr
|
||||||
return &cpy
|
return &cpy
|
||||||
@ -120,11 +160,15 @@ type Struct struct {
|
|||||||
Members []Member
|
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) size() uint32 { return s.Size }
|
||||||
|
|
||||||
func (s *Struct) walk(cs *copyStack) {
|
func (s *Struct) walk(tdq *typeDeque) {
|
||||||
for i := range s.Members {
|
for i := range s.Members {
|
||||||
cs.push(&s.Members[i].Type)
|
tdq.push(&s.Members[i].Type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,11 +192,15 @@ type Union struct {
|
|||||||
Members []Member
|
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) size() uint32 { return u.Size }
|
||||||
|
|
||||||
func (u *Union) walk(cs *copyStack) {
|
func (u *Union) walk(tdq *typeDeque) {
|
||||||
for i := range u.Members {
|
for i := range u.Members {
|
||||||
cs.push(&u.Members[i].Type)
|
tdq.push(&u.Members[i].Type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,6 +242,10 @@ type Enum struct {
|
|||||||
Values []EnumValue
|
Values []EnumValue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *Enum) String() string {
|
||||||
|
return fmt.Sprintf("enum#%d[%q]", e.TypeID, e.Name)
|
||||||
|
}
|
||||||
|
|
||||||
// EnumValue is part of an Enum
|
// EnumValue is part of an Enum
|
||||||
//
|
//
|
||||||
// Is is not a valid Type
|
// Is is not a valid Type
|
||||||
@ -203,7 +255,7 @@ type EnumValue struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (e *Enum) size() uint32 { return 4 }
|
func (e *Enum) size() uint32 { return 4 }
|
||||||
func (e *Enum) walk(*copyStack) {}
|
func (e *Enum) walk(*typeDeque) {}
|
||||||
func (e *Enum) copy() Type {
|
func (e *Enum) copy() Type {
|
||||||
cpy := *e
|
cpy := *e
|
||||||
cpy.Values = make([]EnumValue, len(e.Values))
|
cpy.Values = make([]EnumValue, len(e.Values))
|
||||||
@ -211,13 +263,38 @@ func (e *Enum) copy() Type {
|
|||||||
return &cpy
|
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.
|
// Fwd is a forward declaration of a Type.
|
||||||
type Fwd struct {
|
type Fwd struct {
|
||||||
TypeID
|
TypeID
|
||||||
Name
|
Name
|
||||||
|
Kind FwdKind
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Fwd) walk(*copyStack) {}
|
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) copy() Type {
|
func (f *Fwd) copy() Type {
|
||||||
cpy := *f
|
cpy := *f
|
||||||
return &cpy
|
return &cpy
|
||||||
@ -230,7 +307,11 @@ type Typedef struct {
|
|||||||
Type Type
|
Type Type
|
||||||
}
|
}
|
||||||
|
|
||||||
func (td *Typedef) walk(cs *copyStack) { cs.push(&td.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) copy() Type {
|
func (td *Typedef) copy() Type {
|
||||||
cpy := *td
|
cpy := *td
|
||||||
return &cpy
|
return &cpy
|
||||||
@ -242,8 +323,12 @@ type Volatile struct {
|
|||||||
Type Type
|
Type Type
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Volatile) qualify() Type { return v.Type }
|
func (v *Volatile) String() string {
|
||||||
func (v *Volatile) walk(cs *copyStack) { cs.push(&v.Type) }
|
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) copy() Type {
|
func (v *Volatile) copy() Type {
|
||||||
cpy := *v
|
cpy := *v
|
||||||
return &cpy
|
return &cpy
|
||||||
@ -255,8 +340,12 @@ type Const struct {
|
|||||||
Type Type
|
Type Type
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Const) qualify() Type { return c.Type }
|
func (c *Const) String() string {
|
||||||
func (c *Const) walk(cs *copyStack) { cs.push(&c.Type) }
|
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) copy() Type {
|
func (c *Const) copy() Type {
|
||||||
cpy := *c
|
cpy := *c
|
||||||
return &cpy
|
return &cpy
|
||||||
@ -268,8 +357,12 @@ type Restrict struct {
|
|||||||
Type Type
|
Type Type
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Restrict) qualify() Type { return r.Type }
|
func (r *Restrict) String() string {
|
||||||
func (r *Restrict) walk(cs *copyStack) { cs.push(&r.Type) }
|
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) copy() Type {
|
func (r *Restrict) copy() Type {
|
||||||
cpy := *r
|
cpy := *r
|
||||||
return &cpy
|
return &cpy
|
||||||
@ -282,7 +375,11 @@ type Func struct {
|
|||||||
Type Type
|
Type Type
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Func) walk(cs *copyStack) { cs.push(&f.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) copy() Type {
|
func (f *Func) copy() Type {
|
||||||
cpy := *f
|
cpy := *f
|
||||||
return &cpy
|
return &cpy
|
||||||
@ -295,10 +392,20 @@ type FuncProto struct {
|
|||||||
Params []FuncParam
|
Params []FuncParam
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fp *FuncProto) walk(cs *copyStack) {
|
func (fp *FuncProto) String() string {
|
||||||
cs.push(&fp.Return)
|
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)
|
||||||
for i := range fp.Params {
|
for i := range fp.Params {
|
||||||
cs.push(&fp.Params[i].Type)
|
tdq.push(&fp.Params[i].Type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -321,7 +428,12 @@ type Var struct {
|
|||||||
Type Type
|
Type Type
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Var) walk(cs *copyStack) { cs.push(&v.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) copy() Type {
|
func (v *Var) copy() Type {
|
||||||
cpy := *v
|
cpy := *v
|
||||||
return &cpy
|
return &cpy
|
||||||
@ -335,11 +447,15 @@ type Datasec struct {
|
|||||||
Vars []VarSecinfo
|
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) size() uint32 { return ds.Size }
|
||||||
|
|
||||||
func (ds *Datasec) walk(cs *copyStack) {
|
func (ds *Datasec) walk(tdq *typeDeque) {
|
||||||
for i := range ds.Vars {
|
for i := range ds.Vars {
|
||||||
cs.push(&ds.Vars[i].Type)
|
tdq.push(&ds.Vars[i].Type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -351,6 +467,8 @@ func (ds *Datasec) copy() Type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// VarSecinfo describes variable in a Datasec
|
// VarSecinfo describes variable in a Datasec
|
||||||
|
//
|
||||||
|
// It is not a valid Type.
|
||||||
type VarSecinfo struct {
|
type VarSecinfo struct {
|
||||||
Type Type
|
Type Type
|
||||||
Offset uint32
|
Offset uint32
|
||||||
@ -438,7 +556,7 @@ func Sizeof(typ Type) (int, error) {
|
|||||||
func copyType(typ Type) Type {
|
func copyType(typ Type) Type {
|
||||||
var (
|
var (
|
||||||
copies = make(map[Type]Type)
|
copies = make(map[Type]Type)
|
||||||
work copyStack
|
work typeDeque
|
||||||
)
|
)
|
||||||
|
|
||||||
for t := &typ; t != nil; t = work.pop() {
|
for t := &typ; t != nil; t = work.pop() {
|
||||||
@ -459,34 +577,83 @@ func copyType(typ Type) Type {
|
|||||||
return typ
|
return typ
|
||||||
}
|
}
|
||||||
|
|
||||||
// copyStack keeps track of pointers to types which still
|
// typeDeque keeps track of pointers to types which still
|
||||||
// need to be visited.
|
// need to be visited.
|
||||||
type copyStack []*Type
|
type typeDeque struct {
|
||||||
|
types []*Type
|
||||||
// push adds a type to the stack.
|
read, write uint64
|
||||||
func (cs *copyStack) push(t *Type) {
|
mask uint64
|
||||||
*cs = append(*cs, t)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// pop returns the topmost Type, or nil.
|
// push adds a type to the stack.
|
||||||
func (cs *copyStack) pop() *Type {
|
func (dq *typeDeque) push(t *Type) {
|
||||||
n := len(*cs)
|
if dq.write-dq.read < uint64(len(dq.types)) {
|
||||||
if n == 0 {
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// shift returns the first element or null.
|
||||||
|
func (dq *typeDeque) shift() *Type {
|
||||||
|
if dq.read == dq.write {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
t := (*cs)[n-1]
|
index := dq.read & dq.mask
|
||||||
*cs = (*cs)[:n-1]
|
t := dq.types[index]
|
||||||
|
dq.types[index] = nil
|
||||||
|
dq.read++
|
||||||
return t
|
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
|
// inflateRawTypes takes a list of raw btf types linked via type IDs, and turns
|
||||||
// it into a graph of Types connected via pointers.
|
// it into a graph of Types connected via pointers.
|
||||||
//
|
//
|
||||||
// Returns a map of named types (so, where NameOff is non-zero). Since BTF ignores
|
// Returns a map of named types (so, where NameOff is non-zero) and a slice of types
|
||||||
// compilation units, multiple types may share the same name. A Type may form a
|
// indexed by TypeID. Since BTF ignores compilation units, multiple types may share
|
||||||
// cyclic graph by pointing at itself.
|
// 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) {
|
func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (types []Type, namedTypes map[string][]namedType, err error) {
|
||||||
type fixupDef struct {
|
type fixupDef struct {
|
||||||
id TypeID
|
id TypeID
|
||||||
expectedKind btfKind
|
expectedKind btfKind
|
||||||
@ -523,7 +690,7 @@ func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (namedTypes map
|
|||||||
return members, nil
|
return members, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
types := make([]Type, 0, len(rawTypes))
|
types = make([]Type, 0, len(rawTypes))
|
||||||
types = append(types, (*Void)(nil))
|
types = append(types, (*Void)(nil))
|
||||||
namedTypes = make(map[string][]namedType)
|
namedTypes = make(map[string][]namedType)
|
||||||
|
|
||||||
@ -537,7 +704,7 @@ func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (namedTypes map
|
|||||||
|
|
||||||
name, err := rawStrings.LookupName(raw.NameOff)
|
name, err := rawStrings.LookupName(raw.NameOff)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("can't get name for type id %d: %w", id, err)
|
return nil, nil, fmt.Errorf("get name for type id %d: %w", id, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch raw.Kind() {
|
switch raw.Kind() {
|
||||||
@ -562,14 +729,14 @@ func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (namedTypes map
|
|||||||
case kindStruct:
|
case kindStruct:
|
||||||
members, err := convertMembers(raw.data.([]btfMember), raw.KindFlag())
|
members, err := convertMembers(raw.data.([]btfMember), raw.KindFlag())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("struct %s (id %d): %w", name, id, err)
|
return nil, nil, fmt.Errorf("struct %s (id %d): %w", name, id, err)
|
||||||
}
|
}
|
||||||
typ = &Struct{id, name, raw.Size(), members}
|
typ = &Struct{id, name, raw.Size(), members}
|
||||||
|
|
||||||
case kindUnion:
|
case kindUnion:
|
||||||
members, err := convertMembers(raw.data.([]btfMember), raw.KindFlag())
|
members, err := convertMembers(raw.data.([]btfMember), raw.KindFlag())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("union %s (id %d): %w", name, id, err)
|
return nil, nil, fmt.Errorf("union %s (id %d): %w", name, id, err)
|
||||||
}
|
}
|
||||||
typ = &Union{id, name, raw.Size(), members}
|
typ = &Union{id, name, raw.Size(), members}
|
||||||
|
|
||||||
@ -579,7 +746,7 @@ func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (namedTypes map
|
|||||||
for i, btfVal := range rawvals {
|
for i, btfVal := range rawvals {
|
||||||
name, err := rawStrings.LookupName(btfVal.NameOff)
|
name, err := rawStrings.LookupName(btfVal.NameOff)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("can't get name for enum value %d: %s", i, err)
|
return nil, nil, fmt.Errorf("get name for enum value %d: %s", i, err)
|
||||||
}
|
}
|
||||||
vals = append(vals, EnumValue{
|
vals = append(vals, EnumValue{
|
||||||
Name: name,
|
Name: name,
|
||||||
@ -589,7 +756,11 @@ func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (namedTypes map
|
|||||||
typ = &Enum{id, name, vals}
|
typ = &Enum{id, name, vals}
|
||||||
|
|
||||||
case kindForward:
|
case kindForward:
|
||||||
typ = &Fwd{id, name}
|
if raw.KindFlag() {
|
||||||
|
typ = &Fwd{id, name, FwdUnion}
|
||||||
|
} else {
|
||||||
|
typ = &Fwd{id, name, FwdStruct}
|
||||||
|
}
|
||||||
|
|
||||||
case kindTypedef:
|
case kindTypedef:
|
||||||
typedef := &Typedef{id, name, nil}
|
typedef := &Typedef{id, name, nil}
|
||||||
@ -622,7 +793,7 @@ func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (namedTypes map
|
|||||||
for i, param := range rawparams {
|
for i, param := range rawparams {
|
||||||
name, err := rawStrings.LookupName(param.NameOff)
|
name, err := rawStrings.LookupName(param.NameOff)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("can't get name for func proto parameter %d: %s", i, err)
|
return nil, nil, fmt.Errorf("get name for func proto parameter %d: %s", i, err)
|
||||||
}
|
}
|
||||||
params = append(params, FuncParam{
|
params = append(params, FuncParam{
|
||||||
Name: name,
|
Name: name,
|
||||||
@ -656,7 +827,7 @@ func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (namedTypes map
|
|||||||
typ = &Datasec{id, name, raw.SizeType, vars}
|
typ = &Datasec{id, name, raw.SizeType, vars}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("type id %d: unknown kind: %v", id, raw.Kind())
|
return nil, nil, fmt.Errorf("type id %d: unknown kind: %v", id, raw.Kind())
|
||||||
}
|
}
|
||||||
|
|
||||||
types = append(types, typ)
|
types = append(types, typ)
|
||||||
@ -671,7 +842,7 @@ func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (namedTypes map
|
|||||||
for _, fixup := range fixups {
|
for _, fixup := range fixups {
|
||||||
i := int(fixup.id)
|
i := int(fixup.id)
|
||||||
if i >= len(types) {
|
if i >= len(types) {
|
||||||
return nil, fmt.Errorf("reference to invalid type id: %d", fixup.id)
|
return nil, nil, fmt.Errorf("reference to invalid type id: %d", fixup.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default void (id 0) to unknown
|
// Default void (id 0) to unknown
|
||||||
@ -681,13 +852,13 @@ func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (namedTypes map
|
|||||||
}
|
}
|
||||||
|
|
||||||
if expected := fixup.expectedKind; expected != kindUnknown && rawKind != expected {
|
if expected := fixup.expectedKind; expected != kindUnknown && rawKind != expected {
|
||||||
return nil, fmt.Errorf("expected type id %d to have kind %s, found %s", fixup.id, expected, rawKind)
|
return nil, nil, fmt.Errorf("expected type id %d to have kind %s, found %s", fixup.id, expected, rawKind)
|
||||||
}
|
}
|
||||||
|
|
||||||
*fixup.typ = types[i]
|
*fixup.typ = types[i]
|
||||||
}
|
}
|
||||||
|
|
||||||
return namedTypes, nil
|
return types, namedTypes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// essentialName returns name without a ___ suffix.
|
// essentialName returns name without a ___ suffix.
|
||||||
|
52
vendor/github.com/cilium/ebpf/internal/elf.go
generated
vendored
Normal file
52
vendor/github.com/cilium/ebpf/internal/elf.go
generated
vendored
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
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
|
||||||
|
}
|
48
vendor/github.com/cilium/ebpf/internal/feature.go
generated
vendored
48
vendor/github.com/cilium/ebpf/internal/feature.go
generated
vendored
@ -32,7 +32,7 @@ func (ufe *UnsupportedFeatureError) Is(target error) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type featureTest struct {
|
type featureTest struct {
|
||||||
sync.Mutex
|
sync.RWMutex
|
||||||
successful bool
|
successful bool
|
||||||
result error
|
result error
|
||||||
}
|
}
|
||||||
@ -42,10 +42,10 @@ type featureTest struct {
|
|||||||
//
|
//
|
||||||
// The return values have the following semantics:
|
// 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
|
// err != nil: the test couldn't be executed
|
||||||
// err == nil && available: the feature is available
|
type FeatureTestFn func() error
|
||||||
// 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.
|
// FeatureTest wraps a function so that it is run at most once.
|
||||||
//
|
//
|
||||||
@ -61,32 +61,40 @@ func FeatureTest(name, version string, fn FeatureTestFn) func() error {
|
|||||||
|
|
||||||
ft := new(featureTest)
|
ft := new(featureTest)
|
||||||
return func() error {
|
return func() error {
|
||||||
|
ft.RLock()
|
||||||
|
if ft.successful {
|
||||||
|
defer ft.RUnlock()
|
||||||
|
return ft.result
|
||||||
|
}
|
||||||
|
ft.RUnlock()
|
||||||
ft.Lock()
|
ft.Lock()
|
||||||
defer ft.Unlock()
|
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 {
|
if ft.successful {
|
||||||
return ft.result
|
return ft.result
|
||||||
}
|
}
|
||||||
|
err := fn()
|
||||||
available, err := fn()
|
switch {
|
||||||
if errors.Is(err, ErrNotSupported) {
|
case 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{
|
ft.result = &UnsupportedFeatureError{
|
||||||
MinimumVersion: v,
|
MinimumVersion: v,
|
||||||
Name: name,
|
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
|
return ft.result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
13
vendor/github.com/cilium/ebpf/internal/syscall.go
generated
vendored
13
vendor/github.com/cilium/ebpf/internal/syscall.go
generated
vendored
@ -91,6 +91,19 @@ func BPFProgDetach(attr *BPFProgDetachAttr) error {
|
|||||||
return err
|
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 {
|
type bpfObjAttr struct {
|
||||||
fileName Pointer
|
fileName Pointer
|
||||||
fd uint32
|
fd uint32
|
||||||
|
26
vendor/github.com/cilium/ebpf/internal/unix/types_linux.go
generated
vendored
26
vendor/github.com/cilium/ebpf/internal/unix/types_linux.go
generated
vendored
@ -10,16 +10,21 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ENOENT = linux.ENOENT
|
ENOENT = linux.ENOENT
|
||||||
EEXIST = linux.EEXIST
|
EEXIST = linux.EEXIST
|
||||||
EAGAIN = linux.EAGAIN
|
EAGAIN = linux.EAGAIN
|
||||||
ENOSPC = linux.ENOSPC
|
ENOSPC = linux.ENOSPC
|
||||||
EINVAL = linux.EINVAL
|
EINVAL = linux.EINVAL
|
||||||
EPOLLIN = linux.EPOLLIN
|
EPOLLIN = linux.EPOLLIN
|
||||||
EINTR = linux.EINTR
|
EINTR = linux.EINTR
|
||||||
EPERM = linux.EPERM
|
EPERM = linux.EPERM
|
||||||
ESRCH = linux.ESRCH
|
ESRCH = linux.ESRCH
|
||||||
ENODEV = linux.ENODEV
|
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
|
||||||
BPF_F_NUMA_NODE = linux.BPF_F_NUMA_NODE
|
BPF_F_NUMA_NODE = linux.BPF_F_NUMA_NODE
|
||||||
BPF_F_RDONLY_PROG = linux.BPF_F_RDONLY_PROG
|
BPF_F_RDONLY_PROG = linux.BPF_F_RDONLY_PROG
|
||||||
BPF_F_WRONLY_PROG = linux.BPF_F_WRONLY_PROG
|
BPF_F_WRONLY_PROG = linux.BPF_F_WRONLY_PROG
|
||||||
@ -41,6 +46,7 @@ const (
|
|||||||
PERF_FLAG_FD_CLOEXEC = linux.PERF_FLAG_FD_CLOEXEC
|
PERF_FLAG_FD_CLOEXEC = linux.PERF_FLAG_FD_CLOEXEC
|
||||||
RLIM_INFINITY = linux.RLIM_INFINITY
|
RLIM_INFINITY = linux.RLIM_INFINITY
|
||||||
RLIMIT_MEMLOCK = linux.RLIMIT_MEMLOCK
|
RLIMIT_MEMLOCK = linux.RLIMIT_MEMLOCK
|
||||||
|
BPF_STATS_RUN_TIME = linux.BPF_STATS_RUN_TIME
|
||||||
)
|
)
|
||||||
|
|
||||||
// Statfs_t is a wrapper
|
// Statfs_t is a wrapper
|
||||||
|
24
vendor/github.com/cilium/ebpf/internal/unix/types_other.go
generated
vendored
24
vendor/github.com/cilium/ebpf/internal/unix/types_other.go
generated
vendored
@ -11,15 +11,20 @@ import (
|
|||||||
var errNonLinux = fmt.Errorf("unsupported platform %s/%s", runtime.GOOS, runtime.GOARCH)
|
var errNonLinux = fmt.Errorf("unsupported platform %s/%s", runtime.GOOS, runtime.GOARCH)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ENOENT = syscall.ENOENT
|
ENOENT = syscall.ENOENT
|
||||||
EEXIST = syscall.EEXIST
|
EEXIST = syscall.EEXIST
|
||||||
EAGAIN = syscall.EAGAIN
|
EAGAIN = syscall.EAGAIN
|
||||||
ENOSPC = syscall.ENOSPC
|
ENOSPC = syscall.ENOSPC
|
||||||
EINVAL = syscall.EINVAL
|
EINVAL = syscall.EINVAL
|
||||||
EINTR = syscall.EINTR
|
EINTR = syscall.EINTR
|
||||||
EPERM = syscall.EPERM
|
EPERM = syscall.EPERM
|
||||||
ESRCH = syscall.ESRCH
|
ESRCH = syscall.ESRCH
|
||||||
ENODEV = syscall.ENODEV
|
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
|
||||||
BPF_F_NUMA_NODE = 0
|
BPF_F_NUMA_NODE = 0
|
||||||
BPF_F_RDONLY_PROG = 0
|
BPF_F_RDONLY_PROG = 0
|
||||||
BPF_F_WRONLY_PROG = 0
|
BPF_F_WRONLY_PROG = 0
|
||||||
@ -42,6 +47,7 @@ const (
|
|||||||
PERF_FLAG_FD_CLOEXEC = 0x8
|
PERF_FLAG_FD_CLOEXEC = 0x8
|
||||||
RLIM_INFINITY = 0x7fffffffffffffff
|
RLIM_INFINITY = 0x7fffffffffffffff
|
||||||
RLIMIT_MEMLOCK = 8
|
RLIMIT_MEMLOCK = 8
|
||||||
|
BPF_STATS_RUN_TIME = 0
|
||||||
)
|
)
|
||||||
|
|
||||||
// Statfs_t is a wrapper
|
// Statfs_t is a wrapper
|
||||||
|
169
vendor/github.com/cilium/ebpf/link/cgroup.go
generated
vendored
Normal file
169
vendor/github.com/cilium/ebpf/link/cgroup.go
generated
vendored
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
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) (Link, error) {
|
||||||
|
link, err := LoadPinnedRawLink(fileName)
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
type linkCgroup struct {
|
||||||
|
*RawLink
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ Link = (*linkCgroup)(nil)
|
||||||
|
|
||||||
|
func (cg *linkCgroup) isLink() {}
|
||||||
|
|
||||||
|
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
Normal file
2
vendor/github.com/cilium/ebpf/link/doc.go
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
// Package link allows attaching eBPF programs to various kernel hooks.
|
||||||
|
package link
|
91
vendor/github.com/cilium/ebpf/link/iter.go
generated
vendored
Normal file
91
vendor/github.com/cilium/ebpf/link/iter.go
generated
vendored
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
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) (*Iter, error) {
|
||||||
|
link, err := LoadPinnedRawLink(fileName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Iter{link}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iter represents an attached bpf_iter.
|
||||||
|
type Iter struct {
|
||||||
|
link *RawLink
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ Link = (*Iter)(nil)
|
||||||
|
|
||||||
|
func (it *Iter) isLink() {}
|
||||||
|
|
||||||
|
// FD returns the underlying file descriptor.
|
||||||
|
func (it *Iter) FD() int {
|
||||||
|
return it.link.FD()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close implements Link.
|
||||||
|
func (it *Iter) Close() error {
|
||||||
|
return it.link.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pin implements Link.
|
||||||
|
func (it *Iter) Pin(fileName string) error {
|
||||||
|
return it.link.Pin(fileName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update implements Link.
|
||||||
|
func (it *Iter) Update(new *ebpf.Program) error {
|
||||||
|
return it.link.Update(new)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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.link.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
|
||||||
|
}
|
214
vendor/github.com/cilium/ebpf/link/link.go
generated
vendored
Normal file
214
vendor/github.com/cilium/ebpf/link/link.go
generated
vendored
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
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
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
func LoadPinnedRawLink(fileName string) (*RawLink, error) {
|
||||||
|
return loadPinnedRawLink(fileName, UnspecifiedType)
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadPinnedRawLink(fileName string, typ Type) (*RawLink, error) {
|
||||||
|
fd, err := internal.BPFObjGet(fileName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("load pinned link: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
link := &RawLink{fd}
|
||||||
|
if typ == 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 != typ {
|
||||||
|
link.Close()
|
||||||
|
return nil, fmt.Errorf("link type %v doesn't match %v", info.Type, typ)
|
||||||
|
}
|
||||||
|
|
||||||
|
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.BPFObjPin(fileName, l.fd); err != nil {
|
||||||
|
return fmt.Errorf("can't pin link: %s", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update implements Link.
|
||||||
|
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
Normal file
60
vendor/github.com/cilium/ebpf/link/netns.go
generated
vendored
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
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) (*NetNsLink, error) {
|
||||||
|
link, err := loadPinnedRawLink(fileName, NetNsType)
|
||||||
|
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
|
||||||
|
}
|
76
vendor/github.com/cilium/ebpf/link/program.go
generated
vendored
Normal file
76
vendor/github.com/cilium/ebpf/link/program.go
generated
vendored
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
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
|
||||||
|
}
|
57
vendor/github.com/cilium/ebpf/link/raw_tracepoint.go
generated
vendored
Normal file
57
vendor/github.com/cilium/ebpf/link/raw_tracepoint.go
generated
vendored
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
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)
|
||||||
|
}
|
173
vendor/github.com/cilium/ebpf/link/syscalls.go
generated
vendored
Normal file
173
vendor/github.com/cilium/ebpf/link/syscalls.go
generated
vendored
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
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
|
||||||
|
}
|
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
|
// Rewrite bpf to bpf call
|
||||||
callOffset, ok := symbolOffsets[ins.Reference]
|
callOffset, ok := symbolOffsets[ins.Reference]
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("instruction %d: reference to missing symbol %s", i, ins.Reference)
|
return fmt.Errorf("instruction %d: reference to missing symbol %q", i, ins.Reference)
|
||||||
}
|
}
|
||||||
|
|
||||||
ins.Constant = int64(callOffset - offset - 1)
|
ins.Constant = int64(callOffset - offset - 1)
|
||||||
@ -122,7 +122,7 @@ func fixupJumpsAndCalls(insns asm.Instructions) error {
|
|||||||
// Rewrite jump to label
|
// Rewrite jump to label
|
||||||
jumpOffset, ok := symbolOffsets[ins.Reference]
|
jumpOffset, ok := symbolOffsets[ins.Reference]
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("instruction %d: reference to missing symbol %s", i, ins.Reference)
|
return fmt.Errorf("instruction %d: reference to missing symbol %q", i, ins.Reference)
|
||||||
}
|
}
|
||||||
|
|
||||||
ins.Offset = int16(jumpOffset - offset - 1)
|
ins.Offset = int16(jumpOffset - offset - 1)
|
||||||
|
604
vendor/github.com/cilium/ebpf/map.go
generated
vendored
604
vendor/github.com/cilium/ebpf/map.go
generated
vendored
@ -5,6 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/cilium/ebpf/internal"
|
"github.com/cilium/ebpf/internal"
|
||||||
@ -90,20 +91,20 @@ type MapKV struct {
|
|||||||
|
|
||||||
func (ms *MapSpec) checkCompatibility(m *Map) error {
|
func (ms *MapSpec) checkCompatibility(m *Map) error {
|
||||||
switch {
|
switch {
|
||||||
case m.abi.Type != ms.Type:
|
case m.typ != ms.Type:
|
||||||
return fmt.Errorf("expected type %v, got %v", ms.Type, m.abi.Type)
|
return fmt.Errorf("expected type %v, got %v", ms.Type, m.typ)
|
||||||
|
|
||||||
case m.abi.KeySize != ms.KeySize:
|
case m.keySize != ms.KeySize:
|
||||||
return fmt.Errorf("expected key size %v, got %v", ms.KeySize, m.abi.KeySize)
|
return fmt.Errorf("expected key size %v, got %v", ms.KeySize, m.keySize)
|
||||||
|
|
||||||
case m.abi.ValueSize != ms.ValueSize:
|
case m.valueSize != ms.ValueSize:
|
||||||
return fmt.Errorf("expected value size %v, got %v", ms.ValueSize, m.abi.ValueSize)
|
return fmt.Errorf("expected value size %v, got %v", ms.ValueSize, m.valueSize)
|
||||||
|
|
||||||
case m.abi.MaxEntries != ms.MaxEntries:
|
case m.maxEntries != ms.MaxEntries:
|
||||||
return fmt.Errorf("expected max entries %v, got %v", ms.MaxEntries, m.abi.MaxEntries)
|
return fmt.Errorf("expected max entries %v, got %v", ms.MaxEntries, m.maxEntries)
|
||||||
|
|
||||||
case m.abi.Flags != ms.Flags:
|
case m.flags != ms.Flags:
|
||||||
return fmt.Errorf("expected flags %v, got %v", ms.Flags, m.abi.Flags)
|
return fmt.Errorf("expected flags %v, got %v", ms.Flags, m.flags)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -118,9 +119,14 @@ func (ms *MapSpec) checkCompatibility(m *Map) error {
|
|||||||
// Implement encoding.BinaryMarshaler or encoding.BinaryUnmarshaler
|
// Implement encoding.BinaryMarshaler or encoding.BinaryUnmarshaler
|
||||||
// if you require custom encoding.
|
// if you require custom encoding.
|
||||||
type Map struct {
|
type Map struct {
|
||||||
name string
|
name string
|
||||||
fd *internal.FD
|
fd *internal.FD
|
||||||
abi MapABI
|
typ MapType
|
||||||
|
keySize uint32
|
||||||
|
valueSize uint32
|
||||||
|
maxEntries uint32
|
||||||
|
flags uint32
|
||||||
|
pinnedPath string
|
||||||
// Per CPU maps return values larger than the size in the spec
|
// Per CPU maps return values larger than the size in the spec
|
||||||
fullValueSize int
|
fullValueSize int
|
||||||
}
|
}
|
||||||
@ -132,14 +138,18 @@ func NewMapFromFD(fd int) (*Map, error) {
|
|||||||
if fd < 0 {
|
if fd < 0 {
|
||||||
return nil, errors.New("invalid fd")
|
return nil, errors.New("invalid fd")
|
||||||
}
|
}
|
||||||
bpfFd := internal.NewFD(uint32(fd))
|
|
||||||
|
|
||||||
name, abi, err := newMapABIFromFd(bpfFd)
|
return newMapFromFD(internal.NewFD(uint32(fd)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func newMapFromFD(fd *internal.FD) (*Map, error) {
|
||||||
|
info, err := newMapInfoFromFd(fd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
bpfFd.Forget()
|
fd.Close()
|
||||||
return nil, err
|
return nil, fmt.Errorf("get map info: %s", err)
|
||||||
}
|
}
|
||||||
return newMap(bpfFd, name, abi)
|
|
||||||
|
return newMap(fd, info.Name, info.Type, info.KeySize, info.ValueSize, info.MaxEntries, info.Flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewMap creates a new Map.
|
// NewMap creates a new Map.
|
||||||
@ -158,19 +168,13 @@ func NewMap(spec *MapSpec) (*Map, error) {
|
|||||||
// sufficiently high for locking memory during map creation. This can be done
|
// sufficiently high for locking memory during map creation. This can be done
|
||||||
// by calling unix.Setrlimit with unix.RLIMIT_MEMLOCK prior to calling NewMapWithOptions.
|
// by calling unix.Setrlimit with unix.RLIMIT_MEMLOCK prior to calling NewMapWithOptions.
|
||||||
func NewMapWithOptions(spec *MapSpec, opts MapOptions) (*Map, error) {
|
func NewMapWithOptions(spec *MapSpec, opts MapOptions) (*Map, error) {
|
||||||
if spec.BTF == nil {
|
btfs := make(btfHandleCache)
|
||||||
return newMapWithBTF(spec, nil, opts)
|
defer btfs.close()
|
||||||
}
|
|
||||||
|
|
||||||
handle, err := btf.NewHandle(btf.MapSpec(spec.BTF))
|
return newMapWithOptions(spec, opts, btfs)
|
||||||
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) {
|
func newMapWithOptions(spec *MapSpec, opts MapOptions, btfs btfHandleCache) (*Map, error) {
|
||||||
switch spec.Pinning {
|
switch spec.Pinning {
|
||||||
case PinByName:
|
case PinByName:
|
||||||
if spec.Name == "" || opts.PinPath == "" {
|
if spec.Name == "" || opts.PinPath == "" {
|
||||||
@ -205,7 +209,11 @@ func newMapWithBTF(spec *MapSpec, handle *btf.Handle, opts MapOptions) (*Map, er
|
|||||||
return nil, fmt.Errorf("%s requires InnerMap", spec.Type)
|
return nil, fmt.Errorf("%s requires InnerMap", spec.Type)
|
||||||
}
|
}
|
||||||
|
|
||||||
template, err := createMap(spec.InnerMap, nil, handle, opts)
|
if spec.InnerMap.Pinning != PinNone {
|
||||||
|
return nil, errors.New("inner maps cannot be pinned")
|
||||||
|
}
|
||||||
|
|
||||||
|
template, err := createMap(spec.InnerMap, nil, opts, btfs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -214,7 +222,7 @@ func newMapWithBTF(spec *MapSpec, handle *btf.Handle, opts MapOptions) (*Map, er
|
|||||||
innerFd = template.fd
|
innerFd = template.fd
|
||||||
}
|
}
|
||||||
|
|
||||||
m, err := createMap(spec, innerFd, handle, opts)
|
m, err := createMap(spec, innerFd, opts, btfs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -229,14 +237,14 @@ func newMapWithBTF(spec *MapSpec, handle *btf.Handle, opts MapOptions) (*Map, er
|
|||||||
return m, nil
|
return m, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func createMap(spec *MapSpec, inner *internal.FD, handle *btf.Handle, opts MapOptions) (_ *Map, err error) {
|
func createMap(spec *MapSpec, inner *internal.FD, opts MapOptions, btfs btfHandleCache) (_ *Map, err error) {
|
||||||
closeOnError := func(closer io.Closer) {
|
closeOnError := func(closer io.Closer) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
closer.Close()
|
closer.Close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abi := newMapABIFromSpec(spec)
|
spec = spec.Copy()
|
||||||
|
|
||||||
switch spec.Type {
|
switch spec.Type {
|
||||||
case ArrayOfMaps:
|
case ArrayOfMaps:
|
||||||
@ -246,43 +254,43 @@ func createMap(spec *MapSpec, inner *internal.FD, handle *btf.Handle, opts MapOp
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if abi.ValueSize != 0 && abi.ValueSize != 4 {
|
if spec.ValueSize != 0 && spec.ValueSize != 4 {
|
||||||
return nil, errors.New("ValueSize must be zero or four for map of map")
|
return nil, errors.New("ValueSize must be zero or four for map of map")
|
||||||
}
|
}
|
||||||
abi.ValueSize = 4
|
spec.ValueSize = 4
|
||||||
|
|
||||||
case PerfEventArray:
|
case PerfEventArray:
|
||||||
if abi.KeySize != 0 && abi.KeySize != 4 {
|
if spec.KeySize != 0 && spec.KeySize != 4 {
|
||||||
return nil, errors.New("KeySize must be zero or four for perf event array")
|
return nil, errors.New("KeySize must be zero or four for perf event array")
|
||||||
}
|
}
|
||||||
abi.KeySize = 4
|
spec.KeySize = 4
|
||||||
|
|
||||||
if abi.ValueSize != 0 && abi.ValueSize != 4 {
|
if spec.ValueSize != 0 && spec.ValueSize != 4 {
|
||||||
return nil, errors.New("ValueSize must be zero or four for perf event array")
|
return nil, errors.New("ValueSize must be zero or four for perf event array")
|
||||||
}
|
}
|
||||||
abi.ValueSize = 4
|
spec.ValueSize = 4
|
||||||
|
|
||||||
if abi.MaxEntries == 0 {
|
if spec.MaxEntries == 0 {
|
||||||
n, err := internal.PossibleCPUs()
|
n, err := internal.PossibleCPUs()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("perf event array: %w", err)
|
return nil, fmt.Errorf("perf event array: %w", err)
|
||||||
}
|
}
|
||||||
abi.MaxEntries = uint32(n)
|
spec.MaxEntries = uint32(n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if abi.Flags&(unix.BPF_F_RDONLY_PROG|unix.BPF_F_WRONLY_PROG) > 0 || spec.Freeze {
|
if spec.Flags&(unix.BPF_F_RDONLY_PROG|unix.BPF_F_WRONLY_PROG) > 0 || spec.Freeze {
|
||||||
if err := haveMapMutabilityModifiers(); err != nil {
|
if err := haveMapMutabilityModifiers(); err != nil {
|
||||||
return nil, fmt.Errorf("map create: %w", err)
|
return nil, fmt.Errorf("map create: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
attr := bpfMapCreateAttr{
|
attr := bpfMapCreateAttr{
|
||||||
mapType: abi.Type,
|
mapType: spec.Type,
|
||||||
keySize: abi.KeySize,
|
keySize: spec.KeySize,
|
||||||
valueSize: abi.ValueSize,
|
valueSize: spec.ValueSize,
|
||||||
maxEntries: abi.MaxEntries,
|
maxEntries: spec.MaxEntries,
|
||||||
flags: abi.Flags,
|
flags: spec.Flags,
|
||||||
numaNode: spec.NumaNode,
|
numaNode: spec.NumaNode,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -294,25 +302,40 @@ func createMap(spec *MapSpec, inner *internal.FD, handle *btf.Handle, opts MapOp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
if haveObjName() == nil {
|
||||||
attr.mapName = newBPFObjName(spec.Name)
|
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)
|
fd, err := bpfMapCreate(&attr)
|
||||||
if err != nil {
|
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)
|
return nil, fmt.Errorf("map create: %w", err)
|
||||||
}
|
}
|
||||||
defer closeOnError(fd)
|
defer closeOnError(fd)
|
||||||
|
|
||||||
m, err := newMap(fd, spec.Name, abi)
|
m, err := newMap(fd, spec.Name, spec.Type, spec.KeySize, spec.ValueSize, spec.MaxEntries, spec.Flags)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("map create: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := m.populate(spec.Contents); err != nil {
|
if err := m.populate(spec.Contents); err != nil {
|
||||||
@ -328,15 +351,20 @@ func createMap(spec *MapSpec, inner *internal.FD, handle *btf.Handle, opts MapOp
|
|||||||
return m, nil
|
return m, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func newMap(fd *internal.FD, name string, abi *MapABI) (*Map, error) {
|
func newMap(fd *internal.FD, name string, typ MapType, keySize, valueSize, maxEntries, flags uint32) (*Map, error) {
|
||||||
m := &Map{
|
m := &Map{
|
||||||
name,
|
name,
|
||||||
fd,
|
fd,
|
||||||
*abi,
|
typ,
|
||||||
int(abi.ValueSize),
|
keySize,
|
||||||
|
valueSize,
|
||||||
|
maxEntries,
|
||||||
|
flags,
|
||||||
|
"",
|
||||||
|
int(valueSize),
|
||||||
}
|
}
|
||||||
|
|
||||||
if !abi.Type.hasPerCPUValue() {
|
if !typ.hasPerCPUValue() {
|
||||||
return m, nil
|
return m, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -345,47 +373,45 @@ func newMap(fd *internal.FD, name string, abi *MapABI) (*Map, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
m.fullValueSize = align(int(abi.ValueSize), 8) * possibleCPUs
|
m.fullValueSize = align(int(valueSize), 8) * possibleCPUs
|
||||||
return m, nil
|
return m, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Map) String() string {
|
func (m *Map) String() string {
|
||||||
if m.name != "" {
|
if m.name != "" {
|
||||||
return fmt.Sprintf("%s(%s)#%v", m.abi.Type, m.name, m.fd)
|
return fmt.Sprintf("%s(%s)#%v", m.typ, m.name, m.fd)
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("%s#%v", m.abi.Type, m.fd)
|
return fmt.Sprintf("%s#%v", m.typ, m.fd)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type returns the underlying type of the map.
|
// Type returns the underlying type of the map.
|
||||||
func (m *Map) Type() MapType {
|
func (m *Map) Type() MapType {
|
||||||
return m.abi.Type
|
return m.typ
|
||||||
}
|
}
|
||||||
|
|
||||||
// KeySize returns the size of the map key in bytes.
|
// KeySize returns the size of the map key in bytes.
|
||||||
func (m *Map) KeySize() uint32 {
|
func (m *Map) KeySize() uint32 {
|
||||||
return m.abi.KeySize
|
return m.keySize
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValueSize returns the size of the map value in bytes.
|
// ValueSize returns the size of the map value in bytes.
|
||||||
func (m *Map) ValueSize() uint32 {
|
func (m *Map) ValueSize() uint32 {
|
||||||
return m.abi.ValueSize
|
return m.valueSize
|
||||||
}
|
}
|
||||||
|
|
||||||
// MaxEntries returns the maximum number of elements the map can hold.
|
// MaxEntries returns the maximum number of elements the map can hold.
|
||||||
func (m *Map) MaxEntries() uint32 {
|
func (m *Map) MaxEntries() uint32 {
|
||||||
return m.abi.MaxEntries
|
return m.maxEntries
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flags returns the flags of the map.
|
// Flags returns the flags of the map.
|
||||||
func (m *Map) Flags() uint32 {
|
func (m *Map) Flags() uint32 {
|
||||||
return m.abi.Flags
|
return m.flags
|
||||||
}
|
}
|
||||||
|
|
||||||
// ABI gets the ABI of the Map.
|
// Info returns metadata about the map.
|
||||||
//
|
func (m *Map) Info() (*MapInfo, error) {
|
||||||
// Deprecated: use Type, KeySize, ValueSize, MaxEntries and Flags instead.
|
return newMapInfoFromFd(m.fd)
|
||||||
func (m *Map) ABI() MapABI {
|
|
||||||
return m.abi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lookup retrieves a value from a Map.
|
// Lookup retrieves a value from a Map.
|
||||||
@ -393,54 +419,14 @@ func (m *Map) ABI() MapABI {
|
|||||||
// Calls Close() on valueOut if it is of type **Map or **Program,
|
// Calls Close() on valueOut if it is of type **Map or **Program,
|
||||||
// and *valueOut is not nil.
|
// and *valueOut is not nil.
|
||||||
//
|
//
|
||||||
// Returns an error if the key doesn't exist, see IsNotExist.
|
// Returns an error if the key doesn't exist, see ErrKeyNotExist.
|
||||||
func (m *Map) Lookup(key, valueOut interface{}) error {
|
func (m *Map) Lookup(key, valueOut interface{}) error {
|
||||||
valuePtr, valueBytes := makeBuffer(valueOut, m.fullValueSize)
|
valuePtr, valueBytes := makeBuffer(valueOut, m.fullValueSize)
|
||||||
|
|
||||||
if err := m.lookup(key, valuePtr); err != nil {
|
if err := m.lookup(key, valuePtr); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if valueBytes == nil {
|
return m.unmarshalValue(valueOut, valueBytes)
|
||||||
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.
|
// LookupAndDelete retrieves and deletes a value from a Map.
|
||||||
@ -449,7 +435,7 @@ func (m *Map) Lookup(key, valueOut interface{}) error {
|
|||||||
func (m *Map) LookupAndDelete(key, valueOut interface{}) error {
|
func (m *Map) LookupAndDelete(key, valueOut interface{}) error {
|
||||||
valuePtr, valueBytes := makeBuffer(valueOut, m.fullValueSize)
|
valuePtr, valueBytes := makeBuffer(valueOut, m.fullValueSize)
|
||||||
|
|
||||||
keyPtr, err := marshalPtr(key, int(m.abi.KeySize))
|
keyPtr, err := m.marshalKey(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("can't marshal key: %w", err)
|
return fmt.Errorf("can't marshal key: %w", err)
|
||||||
}
|
}
|
||||||
@ -458,7 +444,7 @@ func (m *Map) LookupAndDelete(key, valueOut interface{}) error {
|
|||||||
return fmt.Errorf("lookup and delete failed: %w", err)
|
return fmt.Errorf("lookup and delete failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return unmarshalBytes(valueOut, valueBytes)
|
return m.unmarshalValue(valueOut, valueBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// LookupBytes gets a value from Map.
|
// LookupBytes gets a value from Map.
|
||||||
@ -477,7 +463,7 @@ func (m *Map) LookupBytes(key interface{}) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *Map) lookup(key interface{}, valueOut internal.Pointer) error {
|
func (m *Map) lookup(key interface{}, valueOut internal.Pointer) error {
|
||||||
keyPtr, err := marshalPtr(key, int(m.abi.KeySize))
|
keyPtr, err := m.marshalKey(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("can't marshal key: %w", err)
|
return fmt.Errorf("can't marshal key: %w", err)
|
||||||
}
|
}
|
||||||
@ -511,17 +497,12 @@ func (m *Map) Put(key, value interface{}) error {
|
|||||||
|
|
||||||
// Update changes the value of a key.
|
// Update changes the value of a key.
|
||||||
func (m *Map) Update(key, value interface{}, flags MapUpdateFlags) error {
|
func (m *Map) Update(key, value interface{}, flags MapUpdateFlags) error {
|
||||||
keyPtr, err := marshalPtr(key, int(m.abi.KeySize))
|
keyPtr, err := m.marshalKey(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("can't marshal key: %w", err)
|
return fmt.Errorf("can't marshal key: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var valuePtr internal.Pointer
|
valuePtr, err := m.marshalValue(value)
|
||||||
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 {
|
if err != nil {
|
||||||
return fmt.Errorf("can't marshal value: %w", err)
|
return fmt.Errorf("can't marshal value: %w", err)
|
||||||
}
|
}
|
||||||
@ -537,7 +518,7 @@ func (m *Map) Update(key, value interface{}, flags MapUpdateFlags) error {
|
|||||||
//
|
//
|
||||||
// Returns ErrKeyNotExist if the key does not exist.
|
// Returns ErrKeyNotExist if the key does not exist.
|
||||||
func (m *Map) Delete(key interface{}) error {
|
func (m *Map) Delete(key interface{}) error {
|
||||||
keyPtr, err := marshalPtr(key, int(m.abi.KeySize))
|
keyPtr, err := m.marshalKey(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("can't marshal key: %w", err)
|
return fmt.Errorf("can't marshal key: %w", err)
|
||||||
}
|
}
|
||||||
@ -554,17 +535,13 @@ func (m *Map) Delete(key interface{}) error {
|
|||||||
//
|
//
|
||||||
// Returns ErrKeyNotExist if there is no next key.
|
// Returns ErrKeyNotExist if there is no next key.
|
||||||
func (m *Map) NextKey(key, nextKeyOut interface{}) error {
|
func (m *Map) NextKey(key, nextKeyOut interface{}) error {
|
||||||
nextKeyPtr, nextKeyBytes := makeBuffer(nextKeyOut, int(m.abi.KeySize))
|
nextKeyPtr, nextKeyBytes := makeBuffer(nextKeyOut, int(m.keySize))
|
||||||
|
|
||||||
if err := m.nextKey(key, nextKeyPtr); err != nil {
|
if err := m.nextKey(key, nextKeyPtr); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if nextKeyBytes == nil {
|
if err := m.unmarshalKey(nextKeyOut, nextKeyBytes); err != nil {
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := unmarshalBytes(nextKeyOut, nextKeyBytes); err != nil {
|
|
||||||
return fmt.Errorf("can't unmarshal next key: %w", err)
|
return fmt.Errorf("can't unmarshal next key: %w", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -578,7 +555,7 @@ func (m *Map) NextKey(key, nextKeyOut interface{}) error {
|
|||||||
//
|
//
|
||||||
// Returns nil if there are no more keys.
|
// Returns nil if there are no more keys.
|
||||||
func (m *Map) NextKeyBytes(key interface{}) ([]byte, error) {
|
func (m *Map) NextKeyBytes(key interface{}) ([]byte, error) {
|
||||||
nextKey := make([]byte, m.abi.KeySize)
|
nextKey := make([]byte, m.keySize)
|
||||||
nextKeyPtr := internal.NewSlicePointer(nextKey)
|
nextKeyPtr := internal.NewSlicePointer(nextKey)
|
||||||
|
|
||||||
err := m.nextKey(key, nextKeyPtr)
|
err := m.nextKey(key, nextKeyPtr)
|
||||||
@ -596,7 +573,7 @@ func (m *Map) nextKey(key interface{}, nextKeyOut internal.Pointer) error {
|
|||||||
)
|
)
|
||||||
|
|
||||||
if key != nil {
|
if key != nil {
|
||||||
keyPtr, err = marshalPtr(key, int(m.abi.KeySize))
|
keyPtr, err = m.marshalKey(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("can't marshal key: %w", err)
|
return fmt.Errorf("can't marshal key: %w", err)
|
||||||
}
|
}
|
||||||
@ -608,6 +585,158 @@ func (m *Map) nextKey(key interface{}, nextKeyOut internal.Pointer) error {
|
|||||||
return nil
|
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.
|
// Iterate traverses a map.
|
||||||
//
|
//
|
||||||
// It's safe to create multiple iterators at the same time.
|
// It's safe to create multiple iterators at the same time.
|
||||||
@ -647,6 +776,7 @@ func (m *Map) FD() int {
|
|||||||
//
|
//
|
||||||
// Closing the duplicate does not affect the original, and vice versa.
|
// Closing the duplicate does not affect the original, and vice versa.
|
||||||
// Changes made to the map are reflected by both instances however.
|
// 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.
|
// Cloning a nil Map returns nil.
|
||||||
func (m *Map) Clone() (*Map, error) {
|
func (m *Map) Clone() (*Map, error) {
|
||||||
@ -659,14 +789,53 @@ func (m *Map) Clone() (*Map, error) {
|
|||||||
return nil, fmt.Errorf("can't clone map: %w", err)
|
return nil, fmt.Errorf("can't clone map: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return newMap(dup, m.name, &m.abi)
|
return &Map{
|
||||||
|
m.name,
|
||||||
|
dup,
|
||||||
|
m.typ,
|
||||||
|
m.keySize,
|
||||||
|
m.valueSize,
|
||||||
|
m.maxEntries,
|
||||||
|
m.flags,
|
||||||
|
"",
|
||||||
|
m.fullValueSize,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pin persists the map past the lifetime of the process that created it.
|
// 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 override the path.
|
||||||
|
// You can Clone a map to pin it to a different path.
|
||||||
//
|
//
|
||||||
// This requires bpffs to be mounted above fileName. See https://docs.cilium.io/en/k8s-doc/admin/#admin-mount-bpffs
|
// 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 {
|
func (m *Map) Pin(fileName string) error {
|
||||||
return internal.BPFObjPin(fileName, m.fd)
|
if err := 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 := 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 {
|
||||||
|
if m.pinnedPath == "" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Freeze prevents a map to be modified from user space.
|
// Freeze prevents a map to be modified from user space.
|
||||||
@ -692,45 +861,147 @@ func (m *Map) populate(contents []MapKV) error {
|
|||||||
return nil
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
(*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
|
||||||
|
}
|
||||||
|
|
||||||
|
(*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 load a Map from a BPF file.
|
// 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) {
|
func LoadPinnedMap(fileName string) (*Map, error) {
|
||||||
fd, err := internal.BPFObjGet(fileName)
|
fd, err := internal.BPFObjGet(fileName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
name, abi, err := newMapABIFromFd(fd)
|
|
||||||
if err != nil {
|
m, err := newMapFromFD(fd)
|
||||||
_ = fd.Close()
|
if err == nil {
|
||||||
return nil, err
|
m.pinnedPath = fileName
|
||||||
}
|
}
|
||||||
return newMap(fd, name, abi)
|
|
||||||
}
|
return m, err
|
||||||
|
|
||||||
// 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) {
|
func unmarshalMap(buf []byte) (*Map, error) {
|
||||||
if len(buf) != 4 {
|
if len(buf) != 4 {
|
||||||
return nil, errors.New("map id requires 4 byte value")
|
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)
|
id := internal.NativeEndian.Uint32(buf)
|
||||||
return NewMapFromID(MapID(id))
|
return NewMapFromID(MapID(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarshalBinary implements BinaryMarshaler.
|
// marshalMap marshals the fd of a map into a buffer in host endianness.
|
||||||
func (m *Map) MarshalBinary() ([]byte, error) {
|
func marshalMap(m *Map, length int) ([]byte, error) {
|
||||||
|
if length != 4 {
|
||||||
|
return nil, fmt.Errorf("can't marshal map to %d bytes", length)
|
||||||
|
}
|
||||||
|
|
||||||
fd, err := m.fd.Value()
|
fd, err := m.fd.Value()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -810,8 +1081,8 @@ type MapIterator struct {
|
|||||||
func newMapIterator(target *Map) *MapIterator {
|
func newMapIterator(target *Map) *MapIterator {
|
||||||
return &MapIterator{
|
return &MapIterator{
|
||||||
target: target,
|
target: target,
|
||||||
maxEntries: target.abi.MaxEntries,
|
maxEntries: target.maxEntries,
|
||||||
prevBytes: make([]byte, int(target.abi.KeySize)),
|
prevBytes: make([]byte, target.keySize),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -830,7 +1101,9 @@ func (mi *MapIterator) Next(keyOut, valueOut interface{}) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
for ; mi.count < mi.maxEntries; mi.count++ {
|
// For array-like maps NextKeyBytes returns nil only on after maxEntries
|
||||||
|
// iterations.
|
||||||
|
for mi.count <= mi.maxEntries {
|
||||||
var nextBytes []byte
|
var nextBytes []byte
|
||||||
nextBytes, mi.err = mi.target.NextKeyBytes(mi.prevKey)
|
nextBytes, mi.err = mi.target.NextKeyBytes(mi.prevKey)
|
||||||
if mi.err != nil {
|
if mi.err != nil {
|
||||||
@ -849,6 +1122,7 @@ func (mi *MapIterator) Next(keyOut, valueOut interface{}) bool {
|
|||||||
copy(mi.prevBytes, nextBytes)
|
copy(mi.prevBytes, nextBytes)
|
||||||
mi.prevKey = mi.prevBytes
|
mi.prevKey = mi.prevBytes
|
||||||
|
|
||||||
|
mi.count++
|
||||||
mi.err = mi.target.Lookup(nextBytes, valueOut)
|
mi.err = mi.target.Lookup(nextBytes, valueOut)
|
||||||
if errors.Is(mi.err, ErrKeyNotExist) {
|
if errors.Is(mi.err, ErrKeyNotExist) {
|
||||||
// Even though the key should be valid, we couldn't look up
|
// Even though the key should be valid, we couldn't look up
|
||||||
@ -865,7 +1139,7 @@ func (mi *MapIterator) Next(keyOut, valueOut interface{}) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
mi.err = unmarshalBytes(keyOut, nextBytes)
|
mi.err = mi.target.unmarshalKey(keyOut, nextBytes)
|
||||||
return mi.err == nil
|
return mi.err == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -899,18 +1173,12 @@ func NewMapFromID(id MapID) (*Map, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
name, abi, err := newMapABIFromFd(fd)
|
return newMapFromFD(fd)
|
||||||
if err != nil {
|
|
||||||
_ = fd.Close()
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return newMap(fd, name, abi)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ID returns the systemwide unique ID of the map.
|
// ID returns the systemwide unique ID of the map.
|
||||||
//
|
//
|
||||||
// Requires at least Linux 4.13.
|
// Deprecated: use MapInfo.ID() instead.
|
||||||
func (m *Map) ID() (MapID, error) {
|
func (m *Map) ID() (MapID, error) {
|
||||||
info, err := bpfGetMapInfoByFD(m.fd)
|
info, err := bpfGetMapInfoByFD(m.fd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
27
vendor/github.com/cilium/ebpf/marshalers.go
generated
vendored
27
vendor/github.com/cilium/ebpf/marshalers.go
generated
vendored
@ -13,14 +13,12 @@ import (
|
|||||||
"github.com/cilium/ebpf/internal"
|
"github.com/cilium/ebpf/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// marshalPtr converts an arbitrary value into a pointer suitable
|
||||||
|
// to be passed to the kernel.
|
||||||
|
//
|
||||||
|
// As an optimization, it returns the original value if it is an
|
||||||
|
// unsafe.Pointer.
|
||||||
func marshalPtr(data interface{}, length int) (internal.Pointer, error) {
|
func marshalPtr(data interface{}, length int) (internal.Pointer, error) {
|
||||||
if data == nil {
|
|
||||||
if length == 0 {
|
|
||||||
return internal.NewPointer(nil), nil
|
|
||||||
}
|
|
||||||
return internal.Pointer{}, errors.New("can't use nil as key of map")
|
|
||||||
}
|
|
||||||
|
|
||||||
if ptr, ok := data.(unsafe.Pointer); ok {
|
if ptr, ok := data.(unsafe.Pointer); ok {
|
||||||
return internal.NewPointer(ptr), nil
|
return internal.NewPointer(ptr), nil
|
||||||
}
|
}
|
||||||
@ -33,6 +31,13 @@ func marshalPtr(data interface{}, length int) (internal.Pointer, error) {
|
|||||||
return internal.NewSlicePointer(buf), nil
|
return internal.NewSlicePointer(buf), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// marshalBytes converts an arbitrary value into a byte buffer.
|
||||||
|
//
|
||||||
|
// Prefer using Map.marshalKey and Map.marshalValue if possible, since
|
||||||
|
// those have special cases that allow more types to be encoded.
|
||||||
|
//
|
||||||
|
// Returns an error if the given value isn't representable in exactly
|
||||||
|
// length bytes.
|
||||||
func marshalBytes(data interface{}, length int) (buf []byte, err error) {
|
func marshalBytes(data interface{}, length int) (buf []byte, err error) {
|
||||||
switch value := data.(type) {
|
switch value := data.(type) {
|
||||||
case encoding.BinaryMarshaler:
|
case encoding.BinaryMarshaler:
|
||||||
@ -43,6 +48,8 @@ func marshalBytes(data interface{}, length int) (buf []byte, err error) {
|
|||||||
buf = value
|
buf = value
|
||||||
case unsafe.Pointer:
|
case unsafe.Pointer:
|
||||||
err = errors.New("can't marshal from unsafe.Pointer")
|
err = errors.New("can't marshal from unsafe.Pointer")
|
||||||
|
case Map, *Map, Program, *Program:
|
||||||
|
err = fmt.Errorf("can't marshal %T", value)
|
||||||
default:
|
default:
|
||||||
var wr bytes.Buffer
|
var wr bytes.Buffer
|
||||||
err = binary.Write(&wr, internal.NativeEndian, value)
|
err = binary.Write(&wr, internal.NativeEndian, value)
|
||||||
@ -70,6 +77,10 @@ func makeBuffer(dst interface{}, length int) (internal.Pointer, []byte) {
|
|||||||
return internal.NewSlicePointer(buf), buf
|
return internal.NewSlicePointer(buf), buf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// unmarshalBytes converts a byte buffer into an arbitrary value.
|
||||||
|
//
|
||||||
|
// Prefer using Map.unmarshalKey and Map.unmarshalValue if possible, since
|
||||||
|
// those have special cases that allow more types to be encoded.
|
||||||
func unmarshalBytes(data interface{}, buf []byte) error {
|
func unmarshalBytes(data interface{}, buf []byte) error {
|
||||||
switch value := data.(type) {
|
switch value := data.(type) {
|
||||||
case unsafe.Pointer:
|
case unsafe.Pointer:
|
||||||
@ -83,6 +94,8 @@ func unmarshalBytes(data interface{}, buf []byte) error {
|
|||||||
copy(dst, buf)
|
copy(dst, buf)
|
||||||
runtime.KeepAlive(value)
|
runtime.KeepAlive(value)
|
||||||
return nil
|
return nil
|
||||||
|
case Map, *Map, Program, *Program:
|
||||||
|
return fmt.Errorf("can't unmarshal into %T", value)
|
||||||
case encoding.BinaryUnmarshaler:
|
case encoding.BinaryUnmarshaler:
|
||||||
return value.UnmarshalBinary(buf)
|
return value.UnmarshalBinary(buf)
|
||||||
case *string:
|
case *string:
|
||||||
|
42
vendor/github.com/cilium/ebpf/pinning.go
generated
vendored
Normal file
42
vendor/github.com/cilium/ebpf/pinning.go
generated
vendored
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package ebpf
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/cilium/ebpf/internal"
|
||||||
|
)
|
||||||
|
|
||||||
|
func pin(currentPath, newPath string, fd *internal.FD) error {
|
||||||
|
if newPath == "" {
|
||||||
|
return errors.New("given pinning path cannot be empty")
|
||||||
|
}
|
||||||
|
if currentPath == "" {
|
||||||
|
return internal.BPFObjPin(newPath, fd)
|
||||||
|
}
|
||||||
|
if currentPath == newPath {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
var err error
|
||||||
|
// Object is now moved to the new pinning path.
|
||||||
|
if err = os.Rename(currentPath, newPath); err == nil {
|
||||||
|
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 internal.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
|
||||||
|
}
|
328
vendor/github.com/cilium/ebpf/prog.go
generated
vendored
328
vendor/github.com/cilium/ebpf/prog.go
generated
vendored
@ -6,6 +6,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -18,7 +19,7 @@ import (
|
|||||||
// ErrNotSupported is returned whenever the kernel doesn't support a feature.
|
// ErrNotSupported is returned whenever the kernel doesn't support a feature.
|
||||||
var ErrNotSupported = internal.ErrNotSupported
|
var ErrNotSupported = internal.ErrNotSupported
|
||||||
|
|
||||||
// ProgramID represents the unique ID of an eBPF program
|
// ProgramID represents the unique ID of an eBPF program.
|
||||||
type ProgramID uint32
|
type ProgramID uint32
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -42,7 +43,7 @@ type ProgramOptions struct {
|
|||||||
LogSize int
|
LogSize int
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProgramSpec defines a Program
|
// ProgramSpec defines a Program.
|
||||||
type ProgramSpec struct {
|
type ProgramSpec struct {
|
||||||
// Name is passed to the kernel as a debug aid. Must only contain
|
// Name is passed to the kernel as a debug aid. Must only contain
|
||||||
// alpha numeric and '_' characters.
|
// alpha numeric and '_' characters.
|
||||||
@ -87,6 +88,13 @@ func (ps *ProgramSpec) Copy() *ProgramSpec {
|
|||||||
return &cpy
|
return &cpy
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tag calculates the kernel tag for a series of instructions.
|
||||||
|
//
|
||||||
|
// Use asm.Instructions.Tag if you need to calculate for non-native endianness.
|
||||||
|
func (ps *ProgramSpec) Tag() (string, error) {
|
||||||
|
return ps.Instructions.Tag(internal.NativeEndian)
|
||||||
|
}
|
||||||
|
|
||||||
// Program represents BPF program loaded into the kernel.
|
// Program represents BPF program loaded into the kernel.
|
||||||
//
|
//
|
||||||
// It is not safe to close a Program which is used by other goroutines.
|
// It is not safe to close a Program which is used by other goroutines.
|
||||||
@ -97,8 +105,8 @@ type Program struct {
|
|||||||
|
|
||||||
fd *internal.FD
|
fd *internal.FD
|
||||||
name string
|
name string
|
||||||
abi ProgramABI
|
pinnedPath string
|
||||||
attachType AttachType
|
typ ProgramType
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewProgram creates a new Program.
|
// NewProgram creates a new Program.
|
||||||
@ -114,88 +122,13 @@ func NewProgram(spec *ProgramSpec) (*Program, error) {
|
|||||||
// Loading a program for the first time will perform
|
// Loading a program for the first time will perform
|
||||||
// feature detection by loading small, temporary programs.
|
// feature detection by loading small, temporary programs.
|
||||||
func NewProgramWithOptions(spec *ProgramSpec, opts ProgramOptions) (*Program, error) {
|
func NewProgramWithOptions(spec *ProgramSpec, opts ProgramOptions) (*Program, error) {
|
||||||
if spec.BTF == nil {
|
btfs := make(btfHandleCache)
|
||||||
return newProgramWithBTF(spec, nil, opts)
|
defer btfs.close()
|
||||||
}
|
|
||||||
|
|
||||||
handle, err := btf.NewHandle(btf.ProgramSpec(spec.BTF))
|
return newProgramWithOptions(spec, opts, btfs)
|
||||||
if err != nil && !errors.Is(err, btf.ErrNotSupported) {
|
|
||||||
return nil, fmt.Errorf("can't load BTF: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return newProgramWithBTF(spec, handle, opts)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func newProgramWithBTF(spec *ProgramSpec, btf *btf.Handle, opts ProgramOptions) (*Program, error) {
|
func newProgramWithOptions(spec *ProgramSpec, opts ProgramOptions, btfs btfHandleCache) (*Program, error) {
|
||||||
attr, err := convertProgramSpec(spec, btf)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
logSize := DefaultVerifierLogSize
|
|
||||||
if opts.LogSize > 0 {
|
|
||||||
logSize = opts.LogSize
|
|
||||||
}
|
|
||||||
|
|
||||||
var logBuf []byte
|
|
||||||
if opts.LogLevel > 0 {
|
|
||||||
logBuf = make([]byte, logSize)
|
|
||||||
attr.logLevel = opts.LogLevel
|
|
||||||
attr.logSize = uint32(len(logBuf))
|
|
||||||
attr.logBuf = internal.NewSlicePointer(logBuf)
|
|
||||||
}
|
|
||||||
|
|
||||||
fd, err := bpfProgLoad(attr)
|
|
||||||
if err == nil {
|
|
||||||
prog := newProgram(fd, spec.Name, &ProgramABI{spec.Type})
|
|
||||||
prog.VerifierLog = internal.CString(logBuf)
|
|
||||||
return prog, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
logErr := err
|
|
||||||
if opts.LogLevel == 0 {
|
|
||||||
// Re-run with the verifier enabled to get better error messages.
|
|
||||||
logBuf = make([]byte, logSize)
|
|
||||||
attr.logLevel = 1
|
|
||||||
attr.logSize = uint32(len(logBuf))
|
|
||||||
attr.logBuf = internal.NewSlicePointer(logBuf)
|
|
||||||
|
|
||||||
_, logErr = bpfProgLoad(attr)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = internal.ErrorWithLog(err, logBuf, logErr)
|
|
||||||
return nil, fmt.Errorf("can't load program: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewProgramFromFD creates a program from a raw fd.
|
|
||||||
//
|
|
||||||
// You should not use fd after calling this function.
|
|
||||||
//
|
|
||||||
// Requires at least Linux 4.11.
|
|
||||||
func NewProgramFromFD(fd int) (*Program, error) {
|
|
||||||
if fd < 0 {
|
|
||||||
return nil, errors.New("invalid fd")
|
|
||||||
}
|
|
||||||
bpfFd := internal.NewFD(uint32(fd))
|
|
||||||
|
|
||||||
name, abi, err := newProgramABIFromFd(bpfFd)
|
|
||||||
if err != nil {
|
|
||||||
bpfFd.Forget()
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return newProgram(bpfFd, name, abi), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func newProgram(fd *internal.FD, name string, abi *ProgramABI) *Program {
|
|
||||||
return &Program{
|
|
||||||
name: name,
|
|
||||||
fd: fd,
|
|
||||||
abi: *abi,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func convertProgramSpec(spec *ProgramSpec, handle *btf.Handle) (*bpfProgLoadAttr, error) {
|
|
||||||
if len(spec.Instructions) == 0 {
|
if len(spec.Instructions) == 0 {
|
||||||
return nil, errors.New("Instructions cannot be empty")
|
return nil, errors.New("Instructions cannot be empty")
|
||||||
}
|
}
|
||||||
@ -236,24 +169,39 @@ func convertProgramSpec(spec *ProgramSpec, handle *btf.Handle) (*bpfProgLoadAttr
|
|||||||
attr.progName = newBPFObjName(spec.Name)
|
attr.progName = newBPFObjName(spec.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if handle != nil && spec.BTF != nil {
|
var btfDisabled bool
|
||||||
attr.progBTFFd = uint32(handle.FD())
|
if spec.BTF != nil {
|
||||||
|
if relos, err := btf.ProgramRelocations(spec.BTF, nil); err != nil {
|
||||||
recSize, bytes, err := btf.ProgramLineInfos(spec.BTF)
|
return nil, fmt.Errorf("CO-RE relocations: %s", err)
|
||||||
if err != nil {
|
} else if len(relos) > 0 {
|
||||||
return nil, fmt.Errorf("can't get BTF line infos: %w", err)
|
return nil, fmt.Errorf("applying CO-RE relocations: %w", ErrNotSupported)
|
||||||
}
|
}
|
||||||
attr.lineInfoRecSize = recSize
|
|
||||||
attr.lineInfoCnt = uint32(uint64(len(bytes)) / uint64(recSize))
|
|
||||||
attr.lineInfo = internal.NewSlicePointer(bytes)
|
|
||||||
|
|
||||||
recSize, bytes, err = btf.ProgramFuncInfos(spec.BTF)
|
handle, err := btfs.load(btf.ProgramSpec(spec.BTF))
|
||||||
if err != nil {
|
btfDisabled = errors.Is(err, btf.ErrNotSupported)
|
||||||
return nil, fmt.Errorf("can't get BTF function infos: %w", err)
|
if err != nil && !btfDisabled {
|
||||||
|
return nil, fmt.Errorf("load BTF: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if handle != nil {
|
||||||
|
attr.progBTFFd = uint32(handle.FD())
|
||||||
|
|
||||||
|
recSize, bytes, err := btf.ProgramLineInfos(spec.BTF)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("get BTF line infos: %w", err)
|
||||||
|
}
|
||||||
|
attr.lineInfoRecSize = recSize
|
||||||
|
attr.lineInfoCnt = uint32(uint64(len(bytes)) / uint64(recSize))
|
||||||
|
attr.lineInfo = internal.NewSlicePointer(bytes)
|
||||||
|
|
||||||
|
recSize, bytes, err = btf.ProgramFuncInfos(spec.BTF)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("get BTF function infos: %w", err)
|
||||||
|
}
|
||||||
|
attr.funcInfoRecSize = recSize
|
||||||
|
attr.funcInfoCnt = uint32(uint64(len(bytes)) / uint64(recSize))
|
||||||
|
attr.funcInfo = internal.NewSlicePointer(bytes)
|
||||||
}
|
}
|
||||||
attr.funcInfoRecSize = recSize
|
|
||||||
attr.funcInfoCnt = uint32(uint64(len(bytes)) / uint64(recSize))
|
|
||||||
attr.funcInfo = internal.NewSlicePointer(bytes)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if spec.AttachTo != "" {
|
if spec.AttachTo != "" {
|
||||||
@ -266,26 +214,100 @@ func convertProgramSpec(spec *ProgramSpec, handle *btf.Handle) (*bpfProgLoadAttr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return attr, nil
|
logSize := DefaultVerifierLogSize
|
||||||
|
if opts.LogSize > 0 {
|
||||||
|
logSize = opts.LogSize
|
||||||
|
}
|
||||||
|
|
||||||
|
var logBuf []byte
|
||||||
|
if opts.LogLevel > 0 {
|
||||||
|
logBuf = make([]byte, logSize)
|
||||||
|
attr.logLevel = opts.LogLevel
|
||||||
|
attr.logSize = uint32(len(logBuf))
|
||||||
|
attr.logBuf = internal.NewSlicePointer(logBuf)
|
||||||
|
}
|
||||||
|
|
||||||
|
fd, err := bpfProgLoad(attr)
|
||||||
|
if err == nil {
|
||||||
|
return &Program{internal.CString(logBuf), fd, spec.Name, "", spec.Type}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
logErr := err
|
||||||
|
if opts.LogLevel == 0 {
|
||||||
|
// Re-run with the verifier enabled to get better error messages.
|
||||||
|
logBuf = make([]byte, logSize)
|
||||||
|
attr.logLevel = 1
|
||||||
|
attr.logSize = uint32(len(logBuf))
|
||||||
|
attr.logBuf = internal.NewSlicePointer(logBuf)
|
||||||
|
|
||||||
|
_, logErr = bpfProgLoad(attr)
|
||||||
|
}
|
||||||
|
|
||||||
|
if errors.Is(logErr, unix.EPERM) && logBuf[0] == 0 {
|
||||||
|
// EPERM due to RLIMIT_MEMLOCK happens before the verifier, so we can
|
||||||
|
// check that the log is empty to reduce false positives.
|
||||||
|
return nil, fmt.Errorf("load program: RLIMIT_MEMLOCK may be too low: %w", logErr)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = internal.ErrorWithLog(err, logBuf, logErr)
|
||||||
|
if btfDisabled {
|
||||||
|
return nil, fmt.Errorf("load program without BTF: %w", err)
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("load program: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewProgramFromFD creates a program from a raw fd.
|
||||||
|
//
|
||||||
|
// You should not use fd after calling this function.
|
||||||
|
//
|
||||||
|
// Requires at least Linux 4.10.
|
||||||
|
func NewProgramFromFD(fd int) (*Program, error) {
|
||||||
|
if fd < 0 {
|
||||||
|
return nil, errors.New("invalid fd")
|
||||||
|
}
|
||||||
|
|
||||||
|
return newProgramFromFD(internal.NewFD(uint32(fd)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewProgramFromID returns the program for a given id.
|
||||||
|
//
|
||||||
|
// Returns ErrNotExist, if there is no eBPF program with the given id.
|
||||||
|
func NewProgramFromID(id ProgramID) (*Program, error) {
|
||||||
|
fd, err := bpfObjGetFDByID(internal.BPF_PROG_GET_FD_BY_ID, uint32(id))
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("get program by id: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return newProgramFromFD(fd)
|
||||||
|
}
|
||||||
|
|
||||||
|
func newProgramFromFD(fd *internal.FD) (*Program, error) {
|
||||||
|
info, err := newProgramInfoFromFd(fd)
|
||||||
|
if err != nil {
|
||||||
|
fd.Close()
|
||||||
|
return nil, fmt.Errorf("discover program type: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Program{"", fd, "", "", info.Type}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Program) String() string {
|
func (p *Program) String() string {
|
||||||
if p.name != "" {
|
if p.name != "" {
|
||||||
return fmt.Sprintf("%s(%s)#%v", p.abi.Type, p.name, p.fd)
|
return fmt.Sprintf("%s(%s)#%v", p.typ, p.name, p.fd)
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("%s#%v", p.abi.Type, p.fd)
|
return fmt.Sprintf("%s(%v)", p.typ, p.fd)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type returns the underlying type of the program.
|
// Type returns the underlying type of the program.
|
||||||
func (p *Program) Type() ProgramType {
|
func (p *Program) Type() ProgramType {
|
||||||
return p.abi.Type
|
return p.typ
|
||||||
}
|
}
|
||||||
|
|
||||||
// ABI gets the ABI of the Program.
|
// Info returns metadata about the program.
|
||||||
//
|
//
|
||||||
// Deprecated: use Type instead.
|
// Requires at least 4.10.
|
||||||
func (p *Program) ABI() ProgramABI {
|
func (p *Program) Info() (*ProgramInfo, error) {
|
||||||
return p.abi
|
return newProgramInfoFromFd(p.fd)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FD gets the file descriptor of the Program.
|
// FD gets the file descriptor of the Program.
|
||||||
@ -317,19 +339,42 @@ func (p *Program) Clone() (*Program, error) {
|
|||||||
return nil, fmt.Errorf("can't clone program: %w", err)
|
return nil, fmt.Errorf("can't clone program: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return newProgram(dup, p.name, &p.abi), nil
|
return &Program{p.VerifierLog, dup, p.name, "", p.typ}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pin persists the Program past the lifetime of the process that created it
|
// Pin persists the Program on the BPF virtual file system 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
|
// This requires bpffs to be mounted above fileName. See https://docs.cilium.io/en/k8s-doc/admin/#admin-mount-bpffs
|
||||||
func (p *Program) Pin(fileName string) error {
|
func (p *Program) Pin(fileName string) error {
|
||||||
if err := internal.BPFObjPin(fileName, p.fd); err != nil {
|
if err := pin(p.pinnedPath, fileName, p.fd); err != nil {
|
||||||
return fmt.Errorf("can't pin program: %w", err)
|
return err
|
||||||
}
|
}
|
||||||
|
p.pinnedPath = fileName
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unpin removes the persisted state for the Program from the BPF virtual filesystem.
|
||||||
|
//
|
||||||
|
// Failed calls to Unpin will not alter the state returned by IsPinned.
|
||||||
|
//
|
||||||
|
// Unpinning an unpinned Program returns nil.
|
||||||
|
func (p *Program) Unpin() error {
|
||||||
|
if err := unpin(p.pinnedPath); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
p.pinnedPath = ""
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsPinned returns true if the Program has a non-empty pinned path.
|
||||||
|
func (p *Program) IsPinned() bool {
|
||||||
|
if p.pinnedPath == "" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// Close unloads the program from the kernel.
|
// Close unloads the program from the kernel.
|
||||||
func (p *Program) Close() error {
|
func (p *Program) Close() error {
|
||||||
if p == nil {
|
if p == nil {
|
||||||
@ -373,7 +418,7 @@ func (p *Program) Benchmark(in []byte, repeat int, reset func()) (uint32, time.D
|
|||||||
return ret, total, nil
|
return ret, total, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var haveProgTestRun = internal.FeatureTest("BPF_PROG_TEST_RUN", "4.12", func() (bool, error) {
|
var haveProgTestRun = internal.FeatureTest("BPF_PROG_TEST_RUN", "4.12", func() error {
|
||||||
prog, err := NewProgram(&ProgramSpec{
|
prog, err := NewProgram(&ProgramSpec{
|
||||||
Type: SocketFilter,
|
Type: SocketFilter,
|
||||||
Instructions: asm.Instructions{
|
Instructions: asm.Instructions{
|
||||||
@ -384,7 +429,7 @@ var haveProgTestRun = internal.FeatureTest("BPF_PROG_TEST_RUN", "4.12", func() (
|
|||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// This may be because we lack sufficient permissions, etc.
|
// This may be because we lack sufficient permissions, etc.
|
||||||
return false, err
|
return err
|
||||||
}
|
}
|
||||||
defer prog.Close()
|
defer prog.Close()
|
||||||
|
|
||||||
@ -397,10 +442,16 @@ var haveProgTestRun = internal.FeatureTest("BPF_PROG_TEST_RUN", "4.12", func() (
|
|||||||
}
|
}
|
||||||
|
|
||||||
err = bpfProgTestRun(&attr)
|
err = bpfProgTestRun(&attr)
|
||||||
|
if errors.Is(err, unix.EINVAL) {
|
||||||
// Check for EINVAL specifically, rather than err != nil since we
|
// Check for EINVAL specifically, rather than err != nil since we
|
||||||
// otherwise misdetect due to insufficient permissions.
|
// otherwise misdetect due to insufficient permissions.
|
||||||
return !errors.Is(err, unix.EINVAL), nil
|
return internal.ErrNotSupported
|
||||||
|
}
|
||||||
|
if errors.Is(err, unix.EINTR) {
|
||||||
|
// We know that PROG_TEST_RUN is supported if we get EINTR.
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return err
|
||||||
})
|
})
|
||||||
|
|
||||||
func (p *Program) testRun(in []byte, repeat int, reset func()) (uint32, []byte, time.Duration, error) {
|
func (p *Program) testRun(in []byte, repeat int, reset func()) (uint32, []byte, time.Duration, error) {
|
||||||
@ -479,8 +530,11 @@ func unmarshalProgram(buf []byte) (*Program, error) {
|
|||||||
return NewProgramFromID(ProgramID(id))
|
return NewProgramFromID(ProgramID(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarshalBinary implements BinaryMarshaler.
|
func marshalProgram(p *Program, length int) ([]byte, error) {
|
||||||
func (p *Program) MarshalBinary() ([]byte, error) {
|
if length != 4 {
|
||||||
|
return nil, fmt.Errorf("can't marshal program to %d bytes", length)
|
||||||
|
}
|
||||||
|
|
||||||
value, err := p.fd.Value()
|
value, err := p.fd.Value()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -549,22 +603,22 @@ func LoadPinnedProgram(fileName string) (*Program, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
name, abi, err := newProgramABIFromFd(fd)
|
info, err := newProgramInfoFromFd(fd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = fd.Close()
|
_ = fd.Close()
|
||||||
return nil, fmt.Errorf("can't get ABI for %s: %w", fileName, err)
|
return nil, fmt.Errorf("info for %s: %w", fileName, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return newProgram(fd, name, abi), nil
|
return &Program{"", fd, filepath.Base(fileName), "", info.Type}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SanitizeName replaces all invalid characters in name.
|
// SanitizeName replaces all invalid characters in name with replacement.
|
||||||
|
// Passing a negative value for replacement will delete characters instead
|
||||||
|
// of replacing them. Use this to automatically generate valid names for maps
|
||||||
|
// and programs at runtime.
|
||||||
//
|
//
|
||||||
// Use this to automatically generate valid names for maps and
|
// The set of allowed characters depends on the running kernel version.
|
||||||
// programs at run time.
|
// Dots are only allowed as of kernel 5.2.
|
||||||
//
|
|
||||||
// Passing a negative value for replacement will delete characters
|
|
||||||
// instead of replacing them.
|
|
||||||
func SanitizeName(name string, replacement rune) string {
|
func SanitizeName(name string, replacement rune) string {
|
||||||
return strings.Map(func(char rune) rune {
|
return strings.Map(func(char rune) rune {
|
||||||
if invalidBPFObjNameChar(char) {
|
if invalidBPFObjNameChar(char) {
|
||||||
@ -582,25 +636,9 @@ func ProgramGetNextID(startID ProgramID) (ProgramID, error) {
|
|||||||
return ProgramID(id), err
|
return ProgramID(id), err
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewProgramFromID returns the program for a given id.
|
|
||||||
//
|
|
||||||
// Returns ErrNotExist, if there is no eBPF program with the given id.
|
|
||||||
func NewProgramFromID(id ProgramID) (*Program, error) {
|
|
||||||
fd, err := bpfObjGetFDByID(internal.BPF_PROG_GET_FD_BY_ID, uint32(id))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
name, abi, err := newProgramABIFromFd(fd)
|
|
||||||
if err != nil {
|
|
||||||
_ = fd.Close()
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return newProgram(fd, name, abi), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ID returns the systemwide unique ID of the program.
|
// ID returns the systemwide unique ID of the program.
|
||||||
|
//
|
||||||
|
// Deprecated: use ProgramInfo.ID() instead.
|
||||||
func (p *Program) ID() (ProgramID, error) {
|
func (p *Program) ID() (ProgramID, error) {
|
||||||
info, err := bpfGetProgInfoByFD(p.fd)
|
info, err := bpfGetProgInfoByFD(p.fd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
29
vendor/github.com/cilium/ebpf/readme.md
generated
vendored
29
vendor/github.com/cilium/ebpf/readme.md
generated
vendored
@ -1,29 +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 embedding eBPF in Go.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
## 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](http://elixir.free-electrons.com/linux/latest/source/Documentation/networking/filter.txt)
|
|
||||||
* [eBPF features by Linux version](https://github.com/iovisor/bcc/blob/master/docs/kernel-versions.md)
|
|
20
vendor/github.com/cilium/ebpf/run-tests.sh
generated
vendored
20
vendor/github.com/cilium/ebpf/run-tests.sh
generated
vendored
@ -16,16 +16,16 @@ if [[ "${1:-}" = "--in-vm" ]]; then
|
|||||||
export GOSUMDB=off
|
export GOSUMDB=off
|
||||||
export GOCACHE=/run/go-cache
|
export GOCACHE=/run/go-cache
|
||||||
|
|
||||||
elfs=""
|
|
||||||
if [[ -d "/run/input/bpf" ]]; then
|
if [[ -d "/run/input/bpf" ]]; then
|
||||||
elfs="/run/input/bpf"
|
export KERNEL_SELFTESTS="/run/input/bpf"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
readonly output="${1}"
|
||||||
|
shift
|
||||||
|
|
||||||
echo Running tests...
|
echo Running tests...
|
||||||
# TestLibBPFCompat runs separately to pass the "-elfs" flag only for it: https://github.com/cilium/ebpf/pull/119
|
go test -v -coverpkg=./... -coverprofile="$output/coverage.txt" -count 1 ./...
|
||||||
go test -v -count 1 -run TestLibBPFCompat -elfs "$elfs"
|
touch "$output/success"
|
||||||
go test -v -count 1 ./...
|
|
||||||
touch "$1/success"
|
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -82,11 +82,9 @@ if [[ ! -e "${output}/success" ]]; then
|
|||||||
exit 1
|
exit 1
|
||||||
else
|
else
|
||||||
echo "Test successful on ${kernel_version}"
|
echo "Test successful on ${kernel_version}"
|
||||||
# if [[ -v CODECOV_TOKEN ]]; then
|
if [[ -v COVERALLS_TOKEN ]]; then
|
||||||
# curl --fail -s https://codecov.io/bash > "${tmp_dir}/codecov.sh"
|
goveralls -coverprofile="${output}/coverage.txt" -service=semaphore -repotoken "$COVERALLS_TOKEN"
|
||||||
# chmod +x "${tmp_dir}/codecov.sh"
|
fi
|
||||||
# "${tmp_dir}/codecov.sh" -f "${output}/coverage.txt"
|
|
||||||
# fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
$sudo rm -r "${input}"
|
$sudo rm -r "${input}"
|
||||||
|
200
vendor/github.com/cilium/ebpf/syscalls.go
generated
vendored
200
vendor/github.com/cilium/ebpf/syscalls.go
generated
vendored
@ -3,7 +3,6 @@ package ebpf
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/cilium/ebpf/internal"
|
"github.com/cilium/ebpf/internal"
|
||||||
@ -12,9 +11,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Generic errors returned by BPF syscalls.
|
// Generic errors returned by BPF syscalls.
|
||||||
var (
|
var ErrNotExist = errors.New("requested object does not exist")
|
||||||
ErrNotExist = errors.New("requested object does not exist")
|
|
||||||
)
|
|
||||||
|
|
||||||
// bpfObjName is a null-terminated string made up of
|
// bpfObjName is a null-terminated string made up of
|
||||||
// 'A-Za-z0-9_' characters.
|
// 'A-Za-z0-9_' characters.
|
||||||
@ -27,18 +24,20 @@ func newBPFObjName(name string) bpfObjName {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// invalidBPFObjNameChar returns true if char may not appear in
|
||||||
|
// a BPF object name.
|
||||||
func invalidBPFObjNameChar(char rune) bool {
|
func invalidBPFObjNameChar(char rune) bool {
|
||||||
dotAllowed := objNameAllowsDot() == nil
|
dotAllowed := objNameAllowsDot() == nil
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case char >= 'A' && char <= 'Z':
|
case char >= 'A' && char <= 'Z':
|
||||||
fallthrough
|
return false
|
||||||
case char >= 'a' && char <= 'z':
|
case char >= 'a' && char <= 'z':
|
||||||
fallthrough
|
return false
|
||||||
case char >= '0' && char <= '9':
|
case char >= '0' && char <= '9':
|
||||||
fallthrough
|
return false
|
||||||
case dotAllowed && char == '.':
|
case dotAllowed && char == '.':
|
||||||
fallthrough
|
return false
|
||||||
case char == '_':
|
case char == '_':
|
||||||
return false
|
return false
|
||||||
default:
|
default:
|
||||||
@ -69,14 +68,32 @@ type bpfMapOpAttr struct {
|
|||||||
flags uint64
|
flags uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type bpfBatchMapOpAttr struct {
|
||||||
|
inBatch internal.Pointer
|
||||||
|
outBatch internal.Pointer
|
||||||
|
keys internal.Pointer
|
||||||
|
values internal.Pointer
|
||||||
|
count uint32
|
||||||
|
mapFd uint32
|
||||||
|
elemFlags uint64
|
||||||
|
flags uint64
|
||||||
|
}
|
||||||
|
|
||||||
type bpfMapInfo struct {
|
type bpfMapInfo struct {
|
||||||
mapType uint32
|
map_type uint32 // since 4.12 1e2709769086
|
||||||
id uint32
|
id uint32
|
||||||
keySize uint32
|
key_size uint32
|
||||||
valueSize uint32
|
value_size uint32
|
||||||
maxEntries uint32
|
max_entries uint32
|
||||||
flags uint32
|
map_flags uint32
|
||||||
mapName bpfObjName // since 4.15 ad5b177bd73f
|
name bpfObjName // since 4.15 ad5b177bd73f
|
||||||
|
ifindex uint32 // since 4.16 52775b33bb50
|
||||||
|
btf_vmlinux_value_type_id uint32 // since 5.6 85d33df357b6
|
||||||
|
netns_dev uint64 // since 4.16 52775b33bb50
|
||||||
|
netns_ino uint64
|
||||||
|
btf_id uint32 // since 4.18 78958fca7ead
|
||||||
|
btf_key_type_id uint32 // since 4.18 9b2cf328b2ec
|
||||||
|
btf_value_type_id uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
type bpfProgLoadAttr struct {
|
type bpfProgLoadAttr struct {
|
||||||
@ -104,18 +121,40 @@ type bpfProgLoadAttr struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type bpfProgInfo struct {
|
type bpfProgInfo struct {
|
||||||
progType uint32
|
prog_type uint32
|
||||||
id uint32
|
id uint32
|
||||||
tag [unix.BPF_TAG_SIZE]byte
|
tag [unix.BPF_TAG_SIZE]byte
|
||||||
jitedLen uint32
|
jited_prog_len uint32
|
||||||
xlatedLen uint32
|
xlated_prog_len uint32
|
||||||
jited internal.Pointer
|
jited_prog_insns internal.Pointer
|
||||||
xlated internal.Pointer
|
xlated_prog_insns internal.Pointer
|
||||||
loadTime uint64 // since 4.15 cb4d2b3f03d8
|
load_time uint64 // since 4.15 cb4d2b3f03d8
|
||||||
createdByUID uint32
|
created_by_uid uint32
|
||||||
nrMapIDs uint32
|
nr_map_ids uint32
|
||||||
mapIds internal.Pointer
|
map_ids internal.Pointer
|
||||||
name bpfObjName
|
name bpfObjName // since 4.15 067cae47771c
|
||||||
|
ifindex uint32
|
||||||
|
gpl_compatible uint32
|
||||||
|
netns_dev uint64
|
||||||
|
netns_ino uint64
|
||||||
|
nr_jited_ksyms uint32
|
||||||
|
nr_jited_func_lens uint32
|
||||||
|
jited_ksyms internal.Pointer
|
||||||
|
jited_func_lens internal.Pointer
|
||||||
|
btf_id uint32
|
||||||
|
func_info_rec_size uint32
|
||||||
|
func_info internal.Pointer
|
||||||
|
nr_func_info uint32
|
||||||
|
nr_line_info uint32
|
||||||
|
line_info internal.Pointer
|
||||||
|
jited_line_info internal.Pointer
|
||||||
|
nr_jited_line_info uint32
|
||||||
|
line_info_rec_size uint32
|
||||||
|
jited_line_info_rec_size uint32
|
||||||
|
nr_prog_tags uint32
|
||||||
|
prog_tags internal.Pointer
|
||||||
|
run_time_ns uint64
|
||||||
|
run_cnt uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
type bpfProgTestRunAttr struct {
|
type bpfProgTestRunAttr struct {
|
||||||
@ -168,10 +207,6 @@ func bpfProgTestRun(attr *bpfProgTestRunAttr) error {
|
|||||||
|
|
||||||
func bpfMapCreate(attr *bpfMapCreateAttr) (*internal.FD, error) {
|
func bpfMapCreate(attr *bpfMapCreateAttr) (*internal.FD, error) {
|
||||||
fd, err := internal.BPF(internal.BPF_MAP_CREATE, unsafe.Pointer(attr), unsafe.Sizeof(*attr))
|
fd, err := internal.BPF(internal.BPF_MAP_CREATE, unsafe.Pointer(attr), unsafe.Sizeof(*attr))
|
||||||
if errors.Is(err, os.ErrPermission) {
|
|
||||||
return nil, errors.New("permission denied or insufficient rlimit to lock memory for map")
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -179,35 +214,25 @@ func bpfMapCreate(attr *bpfMapCreateAttr) (*internal.FD, error) {
|
|||||||
return internal.NewFD(uint32(fd)), nil
|
return internal.NewFD(uint32(fd)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var haveNestedMaps = internal.FeatureTest("nested maps", "4.12", func() (bool, error) {
|
var haveNestedMaps = internal.FeatureTest("nested maps", "4.12", func() error {
|
||||||
inner, err := bpfMapCreate(&bpfMapCreateAttr{
|
_, err := bpfMapCreate(&bpfMapCreateAttr{
|
||||||
mapType: Array,
|
|
||||||
keySize: 4,
|
|
||||||
valueSize: 4,
|
|
||||||
maxEntries: 1,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
defer inner.Close()
|
|
||||||
|
|
||||||
innerFd, _ := inner.Value()
|
|
||||||
nested, err := bpfMapCreate(&bpfMapCreateAttr{
|
|
||||||
mapType: ArrayOfMaps,
|
mapType: ArrayOfMaps,
|
||||||
keySize: 4,
|
keySize: 4,
|
||||||
valueSize: 4,
|
valueSize: 4,
|
||||||
maxEntries: 1,
|
maxEntries: 1,
|
||||||
innerMapFd: innerFd,
|
// Invalid file descriptor.
|
||||||
|
innerMapFd: ^uint32(0),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if errors.Is(err, unix.EINVAL) {
|
||||||
return false, nil
|
return internal.ErrNotSupported
|
||||||
}
|
}
|
||||||
|
if errors.Is(err, unix.EBADF) {
|
||||||
_ = nested.Close()
|
return nil
|
||||||
return true, nil
|
}
|
||||||
|
return err
|
||||||
})
|
})
|
||||||
|
|
||||||
var haveMapMutabilityModifiers = internal.FeatureTest("read- and write-only maps", "5.2", func() (bool, error) {
|
var haveMapMutabilityModifiers = internal.FeatureTest("read- and write-only maps", "5.2", func() error {
|
||||||
// This checks BPF_F_RDONLY_PROG and BPF_F_WRONLY_PROG. Since
|
// This checks BPF_F_RDONLY_PROG and BPF_F_WRONLY_PROG. Since
|
||||||
// BPF_MAP_FREEZE appeared in 5.2 as well we don't do a separate check.
|
// BPF_MAP_FREEZE appeared in 5.2 as well we don't do a separate check.
|
||||||
m, err := bpfMapCreate(&bpfMapCreateAttr{
|
m, err := bpfMapCreate(&bpfMapCreateAttr{
|
||||||
@ -218,10 +243,10 @@ var haveMapMutabilityModifiers = internal.FeatureTest("read- and write-only maps
|
|||||||
flags: unix.BPF_F_RDONLY_PROG,
|
flags: unix.BPF_F_RDONLY_PROG,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, nil
|
return internal.ErrNotSupported
|
||||||
}
|
}
|
||||||
_ = m.Close()
|
_ = m.Close()
|
||||||
return true, nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
func bpfMapLookupElem(m *internal.FD, key, valueOut internal.Pointer) error {
|
func bpfMapLookupElem(m *internal.FD, key, valueOut internal.Pointer) error {
|
||||||
@ -307,6 +332,29 @@ func objGetNextID(cmd internal.BPFCmd, start uint32) (uint32, error) {
|
|||||||
return attr.nextID, wrapObjError(err)
|
return attr.nextID, wrapObjError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func bpfMapBatch(cmd internal.BPFCmd, m *internal.FD, inBatch, outBatch, keys, values internal.Pointer, count uint32, opts *BatchOptions) (uint32, error) {
|
||||||
|
fd, err := m.Value()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
attr := bpfBatchMapOpAttr{
|
||||||
|
inBatch: inBatch,
|
||||||
|
outBatch: outBatch,
|
||||||
|
keys: keys,
|
||||||
|
values: values,
|
||||||
|
count: count,
|
||||||
|
mapFd: fd,
|
||||||
|
}
|
||||||
|
if opts != nil {
|
||||||
|
attr.elemFlags = opts.ElemFlags
|
||||||
|
attr.flags = opts.Flags
|
||||||
|
}
|
||||||
|
_, err = internal.BPF(cmd, unsafe.Pointer(&attr), unsafe.Sizeof(attr))
|
||||||
|
// always return count even on an error, as things like update might partially be fulfilled.
|
||||||
|
return attr.count, wrapMapError(err)
|
||||||
|
}
|
||||||
|
|
||||||
func wrapObjError(err error) error {
|
func wrapObjError(err error) error {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return nil
|
return nil
|
||||||
@ -331,6 +379,10 @@ func wrapMapError(err error) error {
|
|||||||
return ErrKeyExist
|
return ErrKeyExist
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if errors.Is(err, unix.ENOTSUPP) {
|
||||||
|
return ErrNotSupported
|
||||||
|
}
|
||||||
|
|
||||||
return errors.New(err.Error())
|
return errors.New(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -364,7 +416,7 @@ func bpfGetMapInfoByFD(fd *internal.FD) (*bpfMapInfo, error) {
|
|||||||
return &info, nil
|
return &info, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var haveObjName = internal.FeatureTest("object names", "4.15", func() (bool, error) {
|
var haveObjName = internal.FeatureTest("object names", "4.15", func() error {
|
||||||
attr := bpfMapCreateAttr{
|
attr := bpfMapCreateAttr{
|
||||||
mapType: Array,
|
mapType: Array,
|
||||||
keySize: 4,
|
keySize: 4,
|
||||||
@ -375,16 +427,16 @@ var haveObjName = internal.FeatureTest("object names", "4.15", func() (bool, err
|
|||||||
|
|
||||||
fd, err := bpfMapCreate(&attr)
|
fd, err := bpfMapCreate(&attr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, nil
|
return internal.ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = fd.Close()
|
_ = fd.Close()
|
||||||
return true, nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
var objNameAllowsDot = internal.FeatureTest("dot in object names", "5.2", func() (bool, error) {
|
var objNameAllowsDot = internal.FeatureTest("dot in object names", "5.2", func() error {
|
||||||
if err := haveObjName(); err != nil {
|
if err := haveObjName(); err != nil {
|
||||||
return false, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
attr := bpfMapCreateAttr{
|
attr := bpfMapCreateAttr{
|
||||||
@ -397,11 +449,37 @@ var objNameAllowsDot = internal.FeatureTest("dot in object names", "5.2", func()
|
|||||||
|
|
||||||
fd, err := bpfMapCreate(&attr)
|
fd, err := bpfMapCreate(&attr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, nil
|
return internal.ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = fd.Close()
|
_ = fd.Close()
|
||||||
return true, nil
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
var haveBatchAPI = internal.FeatureTest("map batch api", "5.6", func() error {
|
||||||
|
var maxEntries uint32 = 2
|
||||||
|
attr := bpfMapCreateAttr{
|
||||||
|
mapType: Hash,
|
||||||
|
keySize: 4,
|
||||||
|
valueSize: 4,
|
||||||
|
maxEntries: maxEntries,
|
||||||
|
}
|
||||||
|
|
||||||
|
fd, err := bpfMapCreate(&attr)
|
||||||
|
if err != nil {
|
||||||
|
return internal.ErrNotSupported
|
||||||
|
}
|
||||||
|
defer fd.Close()
|
||||||
|
keys := []uint32{1, 2}
|
||||||
|
values := []uint32{3, 4}
|
||||||
|
kp, _ := marshalPtr(keys, 8)
|
||||||
|
vp, _ := marshalPtr(values, 8)
|
||||||
|
nilPtr := internal.NewPointer(nil)
|
||||||
|
_, err = bpfMapBatch(internal.BPF_MAP_UPDATE_BATCH, fd, nilPtr, nilPtr, kp, vp, maxEntries, nil)
|
||||||
|
if err != nil {
|
||||||
|
return internal.ErrNotSupported
|
||||||
|
}
|
||||||
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
func bpfObjGetFDByID(cmd internal.BPFCmd, id uint32) (*internal.FD, error) {
|
func bpfObjGetFDByID(cmd internal.BPFCmd, id uint32) (*internal.FD, error) {
|
||||||
|
29
vendor/github.com/cilium/ebpf/types.go
generated
vendored
29
vendor/github.com/cilium/ebpf/types.go
generated
vendored
@ -85,10 +85,19 @@ const (
|
|||||||
|
|
||||||
// hasPerCPUValue returns true if the Map stores a value per CPU.
|
// hasPerCPUValue returns true if the Map stores a value per CPU.
|
||||||
func (mt MapType) hasPerCPUValue() bool {
|
func (mt MapType) hasPerCPUValue() bool {
|
||||||
if mt == PerCPUHash || mt == PerCPUArray || mt == LRUCPUHash {
|
return mt == PerCPUHash || mt == PerCPUArray || mt == LRUCPUHash
|
||||||
return true
|
}
|
||||||
}
|
|
||||||
return false
|
// canStoreMap returns true if the map type accepts a map fd
|
||||||
|
// for update and returns a map id for lookup.
|
||||||
|
func (mt MapType) canStoreMap() bool {
|
||||||
|
return mt == ArrayOfMaps || mt == HashOfMaps
|
||||||
|
}
|
||||||
|
|
||||||
|
// canStoreProgram returns true if the map type accepts a program fd
|
||||||
|
// for update and returns a program id for lookup.
|
||||||
|
func (mt MapType) canStoreProgram() bool {
|
||||||
|
return mt == ProgramArray
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProgramType of the eBPF program
|
// ProgramType of the eBPF program
|
||||||
@ -134,7 +143,7 @@ const (
|
|||||||
// Will cause invalid argument (EINVAL) at program load time if set incorrectly.
|
// Will cause invalid argument (EINVAL) at program load time if set incorrectly.
|
||||||
type AttachType uint32
|
type AttachType uint32
|
||||||
|
|
||||||
// AttachNone is an alias for AttachCGroupInetIngress for readability reasons
|
// AttachNone is an alias for AttachCGroupInetIngress for readability reasons.
|
||||||
const AttachNone AttachType = 0
|
const AttachNone AttachType = 0
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -192,3 +201,13 @@ const (
|
|||||||
// Pin an object by using its name as the filename.
|
// Pin an object by using its name as the filename.
|
||||||
PinByName
|
PinByName
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// BatchOptions batch map operations options
|
||||||
|
//
|
||||||
|
// Mirrors libbpf struct bpf_map_batch_opts
|
||||||
|
// Currently BPF_F_FLAG is the only supported
|
||||||
|
// flag (for ElemFlags).
|
||||||
|
type BatchOptions struct {
|
||||||
|
ElemFlags uint64
|
||||||
|
Flags uint64
|
||||||
|
}
|
||||||
|
6
vendor/github.com/containerd/cgroups/go.mod
generated
vendored
6
vendor/github.com/containerd/cgroups/go.mod
generated
vendored
@ -3,7 +3,7 @@ module github.com/containerd/cgroups
|
|||||||
go 1.13
|
go 1.13
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/cilium/ebpf v0.2.0
|
github.com/cilium/ebpf v0.4.0
|
||||||
github.com/coreos/go-systemd/v22 v22.1.0
|
github.com/coreos/go-systemd/v22 v22.1.0
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
|
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
|
||||||
github.com/docker/go-units v0.4.0
|
github.com/docker/go-units v0.4.0
|
||||||
@ -12,7 +12,7 @@ require (
|
|||||||
github.com/opencontainers/runtime-spec v1.0.2
|
github.com/opencontainers/runtime-spec v1.0.2
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/sirupsen/logrus v1.7.0
|
github.com/sirupsen/logrus v1.7.0
|
||||||
github.com/stretchr/testify v1.2.2
|
github.com/stretchr/testify v1.6.1
|
||||||
github.com/urfave/cli v1.22.2
|
github.com/urfave/cli v1.22.2
|
||||||
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9
|
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c
|
||||||
)
|
)
|
||||||
|
27
vendor/github.com/containerd/cgroups/go.sum
generated
vendored
27
vendor/github.com/containerd/cgroups/go.sum
generated
vendored
@ -1,23 +1,31 @@
|
|||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/cilium/ebpf v0.2.0 h1:Fv93L3KKckEcEHR3oApXVzyBTDA8WAm6VXhPE00N3f8=
|
github.com/cilium/ebpf v0.4.0 h1:QlHdikaxALkqWasW8hAC1mfR0jdmvbfaBdBPFmRSglA=
|
||||||
github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs=
|
github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
|
||||||
github.com/coreos/go-systemd/v22 v22.1.0 h1:kq/SbG2BCKLkDKkjQf5OWwKWUKj1lgs3lFI4PxnR5lg=
|
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/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
|
github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
|
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
|
||||||
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||||
|
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/godbus/dbus/v5 v5.0.3 h1:ZqHaoEF7TBzh4jzPmqVhE/5A1z9of6orkAe5uHoAeME=
|
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/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||||
github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
|
github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
|
||||||
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||||
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
|
github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M=
|
||||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
|
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=
|
||||||
github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0=
|
github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0=
|
||||||
github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
@ -30,15 +38,20 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5I
|
|||||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||||
github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
|
github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
|
||||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
|
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||||
|
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo=
|
github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo=
|
||||||
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9 h1:1/DFK4b7JH8DmkqhUk48onnSfrPzImPoVxuomtbT2nk=
|
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c h1:VwygUrnw9jn88c4u8GD3rZQbqrP/tgas88tPUbBxQrk=
|
||||||
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
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=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
18
vendor/github.com/containerd/cgroups/v2/ebpf.go
generated
vendored
18
vendor/github.com/containerd/cgroups/v2/ebpf.go
generated
vendored
@ -19,6 +19,7 @@ package v2
|
|||||||
import (
|
import (
|
||||||
"github.com/cilium/ebpf"
|
"github.com/cilium/ebpf"
|
||||||
"github.com/cilium/ebpf/asm"
|
"github.com/cilium/ebpf/asm"
|
||||||
|
"github.com/cilium/ebpf/link"
|
||||||
"github.com/opencontainers/runtime-spec/specs-go"
|
"github.com/opencontainers/runtime-spec/specs-go"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
@ -42,12 +43,23 @@ func LoadAttachCgroupDeviceFilter(insts asm.Instructions, license string, dirFD
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nilCloser, err
|
return nilCloser, err
|
||||||
}
|
}
|
||||||
if err := prog.Attach(dirFD, ebpf.AttachCGroupDevice, unix.BPF_F_ALLOW_MULTI); err != nil {
|
err = link.RawAttachProgram(link.RawAttachProgramOptions{
|
||||||
|
Target: dirFD,
|
||||||
|
Program: prog,
|
||||||
|
Attach: ebpf.AttachCGroupDevice,
|
||||||
|
Flags: unix.BPF_F_ALLOW_MULTI,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
return nilCloser, errors.Wrap(err, "failed to call BPF_PROG_ATTACH (BPF_CGROUP_DEVICE, BPF_F_ALLOW_MULTI)")
|
return nilCloser, errors.Wrap(err, "failed to call BPF_PROG_ATTACH (BPF_CGROUP_DEVICE, BPF_F_ALLOW_MULTI)")
|
||||||
}
|
}
|
||||||
closer := func() error {
|
closer := func() error {
|
||||||
if err := prog.Detach(dirFD, ebpf.AttachCGroupDevice, unix.BPF_F_ALLOW_MULTI); err != nil {
|
err = link.RawDetachProgram(link.RawDetachProgramOptions{
|
||||||
return errors.Wrap(err, "failed to call BPF_PROG_DETACH (BPF_CGROUP_DEVICE, BPF_F_ALLOW_MULTI)")
|
Target: dirFD,
|
||||||
|
Program: prog,
|
||||||
|
Attach: ebpf.AttachCGroupDevice,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "failed to call BPF_PROG_DETACH (BPF_CGROUP_DEVICE)")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
19
vendor/github.com/containerd/continuity/fs/copy.go
generated
vendored
19
vendor/github.com/containerd/continuity/fs/copy.go
generated
vendored
@ -39,6 +39,8 @@ type XAttrErrorHandler func(dst, src, xattrKey string, err error) error
|
|||||||
|
|
||||||
type copyDirOpts struct {
|
type copyDirOpts struct {
|
||||||
xeh XAttrErrorHandler
|
xeh XAttrErrorHandler
|
||||||
|
// xex contains a set of xattrs to exclude when copying
|
||||||
|
xex map[string]struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
type CopyDirOpt func(*copyDirOpts) error
|
type CopyDirOpt func(*copyDirOpts) error
|
||||||
@ -61,6 +63,19 @@ func WithAllowXAttrErrors() CopyDirOpt {
|
|||||||
return WithXAttrErrorHandler(xeh)
|
return WithXAttrErrorHandler(xeh)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithXAttrExclude allows for exclusion of specified xattr during CopyDir operation.
|
||||||
|
func WithXAttrExclude(keys ...string) CopyDirOpt {
|
||||||
|
return func(o *copyDirOpts) error {
|
||||||
|
if o.xex == nil {
|
||||||
|
o.xex = make(map[string]struct{}, len(keys))
|
||||||
|
}
|
||||||
|
for _, key := range keys {
|
||||||
|
o.xex[key] = struct{}{}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// CopyDir copies the directory from src to dst.
|
// CopyDir copies the directory from src to dst.
|
||||||
// Most efficient copy of files is attempted.
|
// Most efficient copy of files is attempted.
|
||||||
func CopyDir(dst, src string, opts ...CopyDirOpt) error {
|
func CopyDir(dst, src string, opts ...CopyDirOpt) error {
|
||||||
@ -104,7 +119,7 @@ func copyDirectory(dst, src string, inodes map[uint64]string, o *copyDirOpts) er
|
|||||||
return errors.Wrapf(err, "failed to copy file info for %s", dst)
|
return errors.Wrapf(err, "failed to copy file info for %s", dst)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := copyXAttrs(dst, src, o.xeh); err != nil {
|
if err := copyXAttrs(dst, src, o.xex, o.xeh); err != nil {
|
||||||
return errors.Wrap(err, "failed to copy xattrs")
|
return errors.Wrap(err, "failed to copy xattrs")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,7 +165,7 @@ func copyDirectory(dst, src string, inodes map[uint64]string, o *copyDirOpts) er
|
|||||||
return errors.Wrap(err, "failed to copy file info")
|
return errors.Wrap(err, "failed to copy file info")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := copyXAttrs(target, source, o.xeh); err != nil {
|
if err := copyXAttrs(target, source, o.xex, o.xeh); err != nil {
|
||||||
return errors.Wrap(err, "failed to copy xattrs")
|
return errors.Wrap(err, "failed to copy xattrs")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
17
vendor/github.com/containerd/continuity/fs/copy_linux.go
generated
vendored
17
vendor/github.com/containerd/continuity/fs/copy_linux.go
generated
vendored
@ -104,21 +104,24 @@ func copyFileContent(dst, src *os.File) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func copyXAttrs(dst, src string, xeh XAttrErrorHandler) error {
|
func copyXAttrs(dst, src string, excludes map[string]struct{}, errorHandler XAttrErrorHandler) error {
|
||||||
xattrKeys, err := sysx.LListxattr(src)
|
xattrKeys, err := sysx.LListxattr(src)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
e := errors.Wrapf(err, "failed to list xattrs on %s", src)
|
e := errors.Wrapf(err, "failed to list xattrs on %s", src)
|
||||||
if xeh != nil {
|
if errorHandler != nil {
|
||||||
e = xeh(dst, src, "", e)
|
e = errorHandler(dst, src, "", e)
|
||||||
}
|
}
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
for _, xattr := range xattrKeys {
|
for _, xattr := range xattrKeys {
|
||||||
|
if _, exclude := excludes[xattr]; exclude {
|
||||||
|
continue
|
||||||
|
}
|
||||||
data, err := sysx.LGetxattr(src, xattr)
|
data, err := sysx.LGetxattr(src, xattr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
e := errors.Wrapf(err, "failed to get xattr %q on %s", xattr, src)
|
e := errors.Wrapf(err, "failed to get xattr %q on %s", xattr, src)
|
||||||
if xeh != nil {
|
if errorHandler != nil {
|
||||||
if e = xeh(dst, src, xattr, e); e == nil {
|
if e = errorHandler(dst, src, xattr, e); e == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -126,8 +129,8 @@ func copyXAttrs(dst, src string, xeh XAttrErrorHandler) error {
|
|||||||
}
|
}
|
||||||
if err := sysx.LSetxattr(dst, xattr, data, 0); err != nil {
|
if err := sysx.LSetxattr(dst, xattr, data, 0); err != nil {
|
||||||
e := errors.Wrapf(err, "failed to set xattr %q on %s", xattr, dst)
|
e := errors.Wrapf(err, "failed to set xattr %q on %s", xattr, dst)
|
||||||
if xeh != nil {
|
if errorHandler != nil {
|
||||||
if e = xeh(dst, src, xattr, e); e == nil {
|
if e = errorHandler(dst, src, xattr, e); e == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
17
vendor/github.com/containerd/continuity/fs/copy_unix.go
generated
vendored
17
vendor/github.com/containerd/continuity/fs/copy_unix.go
generated
vendored
@ -67,21 +67,24 @@ func copyFileContent(dst, src *os.File) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func copyXAttrs(dst, src string, xeh XAttrErrorHandler) error {
|
func copyXAttrs(dst, src string, excludes map[string]struct{}, errorHandler XAttrErrorHandler) error {
|
||||||
xattrKeys, err := sysx.LListxattr(src)
|
xattrKeys, err := sysx.LListxattr(src)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
e := errors.Wrapf(err, "failed to list xattrs on %s", src)
|
e := errors.Wrapf(err, "failed to list xattrs on %s", src)
|
||||||
if xeh != nil {
|
if errorHandler != nil {
|
||||||
e = xeh(dst, src, "", e)
|
e = errorHandler(dst, src, "", e)
|
||||||
}
|
}
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
for _, xattr := range xattrKeys {
|
for _, xattr := range xattrKeys {
|
||||||
|
if _, exclude := excludes[xattr]; exclude {
|
||||||
|
continue
|
||||||
|
}
|
||||||
data, err := sysx.LGetxattr(src, xattr)
|
data, err := sysx.LGetxattr(src, xattr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
e := errors.Wrapf(err, "failed to get xattr %q on %s", xattr, src)
|
e := errors.Wrapf(err, "failed to get xattr %q on %s", xattr, src)
|
||||||
if xeh != nil {
|
if errorHandler != nil {
|
||||||
if e = xeh(dst, src, xattr, e); e == nil {
|
if e = errorHandler(dst, src, xattr, e); e == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -89,8 +92,8 @@ func copyXAttrs(dst, src string, xeh XAttrErrorHandler) error {
|
|||||||
}
|
}
|
||||||
if err := sysx.LSetxattr(dst, xattr, data, 0); err != nil {
|
if err := sysx.LSetxattr(dst, xattr, data, 0); err != nil {
|
||||||
e := errors.Wrapf(err, "failed to set xattr %q on %s", xattr, dst)
|
e := errors.Wrapf(err, "failed to set xattr %q on %s", xattr, dst)
|
||||||
if xeh != nil {
|
if errorHandler != nil {
|
||||||
if e = xeh(dst, src, xattr, e); e == nil {
|
if e = errorHandler(dst, src, xattr, e); e == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
2
vendor/github.com/containerd/continuity/fs/copy_windows.go
generated
vendored
2
vendor/github.com/containerd/continuity/fs/copy_windows.go
generated
vendored
@ -40,7 +40,7 @@ func copyFileContent(dst, src *os.File) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func copyXAttrs(dst, src string, xeh XAttrErrorHandler) error {
|
func copyXAttrs(dst, src string, excludes map[string]struct{}, errorHandler XAttrErrorHandler) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
3
vendor/github.com/containerd/continuity/fs/fstest/file_unix.go
generated
vendored
3
vendor/github.com/containerd/continuity/fs/fstest/file_unix.go
generated
vendored
@ -29,7 +29,8 @@ import (
|
|||||||
// SetXAttr sets the xatter for the file
|
// SetXAttr sets the xatter for the file
|
||||||
func SetXAttr(name, key, value string) Applier {
|
func SetXAttr(name, key, value string) Applier {
|
||||||
return applyFn(func(root string) error {
|
return applyFn(func(root string) error {
|
||||||
return sysx.LSetxattr(name, key, []byte(value), 0)
|
path := filepath.Join(root, name)
|
||||||
|
return sysx.LSetxattr(path, key, []byte(value), 0)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
12
vendor/github.com/containerd/continuity/go.mod
generated
vendored
12
vendor/github.com/containerd/continuity/go.mod
generated
vendored
@ -5,15 +5,11 @@ go 1.13
|
|||||||
require (
|
require (
|
||||||
bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898
|
bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898
|
||||||
github.com/dustin/go-humanize v1.0.0
|
github.com/dustin/go-humanize v1.0.0
|
||||||
github.com/golang/protobuf v1.2.0
|
github.com/golang/protobuf v1.3.5
|
||||||
github.com/inconshreveable/mousetrap v1.0.0 // indirect
|
|
||||||
github.com/opencontainers/go-digest v1.0.0
|
github.com/opencontainers/go-digest v1.0.0
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/sirupsen/logrus v1.7.0
|
github.com/sirupsen/logrus v1.7.0
|
||||||
github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee
|
github.com/spf13/cobra v1.0.0
|
||||||
github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95 // indirect
|
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a
|
||||||
github.com/stretchr/testify v1.4.0 // indirect
|
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c
|
||||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd // indirect
|
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f
|
|
||||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3
|
|
||||||
)
|
)
|
||||||
|
142
vendor/github.com/containerd/continuity/go.sum
generated
vendored
142
vendor/github.com/containerd/continuity/go.sum
generated
vendored
@ -1,38 +1,148 @@
|
|||||||
bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898 h1:SC+c6A1qTFstO9qmB86mPV2IpYme/2ZoEQ0hrP+wo+Q=
|
bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898 h1:SC+c6A1qTFstO9qmB86mPV2IpYme/2ZoEQ0hrP+wo+Q=
|
||||||
bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8=
|
bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
|
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||||
|
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||||
|
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
|
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||||
|
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||||
|
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||||
|
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||||
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
|
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||||
|
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||||
|
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||||
|
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||||
|
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||||
|
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
|
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||||
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
||||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||||
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
|
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
|
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||||
|
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||||
|
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||||
|
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||||
|
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||||
|
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||||
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
|
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
|
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/golang/protobuf v1.3.5 h1:F768QJ1E9tib+q5Sc8MkdJi1RxLTbRcTf8LJV56aRls=
|
||||||
|
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||||
|
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||||
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
|
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||||
|
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||||
|
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||||
|
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||||
|
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||||
|
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||||
|
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||||
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/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.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
|
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||||
|
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||||
|
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||||
|
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||||
|
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||||
|
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||||
|
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||||
|
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||||
|
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
|
||||||
|
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||||
|
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
|
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||||
|
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||||
|
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
|
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||||
|
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||||
|
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||||
|
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
|
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||||
|
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||||
github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
|
github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
|
||||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||||
github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee h1:GQkkv3XSnxhAMjdq2wLfEnptEVr+2BNvmHizILHn+d4=
|
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||||
github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||||
github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95 h1:j8jxLbQ0+T1DFggy6XoGvyUnrJWPR/JybflPvu5rwS4=
|
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||||
github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8=
|
||||||
|
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
||||||
|
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||||
|
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
|
||||||
|
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||||
|
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
||||||
|
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA=
|
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
|
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||||
|
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||||
|
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||||
|
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||||
|
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
|
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/net v0.0.0-20190522155817-f3200d17e092 h1:4QSRKanuywn15aTZvI/mIDEgPQpswuFndXpOj3rKEco=
|
||||||
|
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a h1:DcqTD9SDLc+1P/r1EmRBwnVsrOwW+kk2vWf9n+1sGhs=
|
||||||
|
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3 h1:kzM6+9dur93BcC2kVlYl34cHU+TYZLanmpSJHVMmL64=
|
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c h1:VwygUrnw9jn88c4u8GD3rZQbqrP/tgas88tPUbBxQrk=
|
||||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
|
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
|
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||||
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
|
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||||
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||||
|
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||||
|
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
|
117
vendor/github.com/containerd/continuity/proto/manifest.pb.go
generated
vendored
117
vendor/github.com/containerd/continuity/proto/manifest.pb.go
generated
vendored
@ -1,6 +1,5 @@
|
|||||||
// Code generated by protoc-gen-go.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// source: manifest.proto
|
// source: manifest.proto
|
||||||
// DO NOT EDIT!
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Package proto is a generated protocol buffer package.
|
Package proto is a generated protocol buffer package.
|
||||||
@ -97,6 +96,83 @@ func (m *Resource) String() string { return proto1.CompactTextString(
|
|||||||
func (*Resource) ProtoMessage() {}
|
func (*Resource) ProtoMessage() {}
|
||||||
func (*Resource) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
|
func (*Resource) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
|
||||||
|
|
||||||
|
func (m *Resource) GetPath() []string {
|
||||||
|
if m != nil {
|
||||||
|
return m.Path
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Resource) GetUid() int64 {
|
||||||
|
if m != nil {
|
||||||
|
return m.Uid
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Resource) GetGid() int64 {
|
||||||
|
if m != nil {
|
||||||
|
return m.Gid
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Resource) GetUser() string {
|
||||||
|
if m != nil {
|
||||||
|
return m.User
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Resource) GetGroup() string {
|
||||||
|
if m != nil {
|
||||||
|
return m.Group
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Resource) GetMode() uint32 {
|
||||||
|
if m != nil {
|
||||||
|
return m.Mode
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Resource) GetSize() uint64 {
|
||||||
|
if m != nil {
|
||||||
|
return m.Size
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Resource) GetDigest() []string {
|
||||||
|
if m != nil {
|
||||||
|
return m.Digest
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Resource) GetTarget() string {
|
||||||
|
if m != nil {
|
||||||
|
return m.Target
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Resource) GetMajor() uint64 {
|
||||||
|
if m != nil {
|
||||||
|
return m.Major
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Resource) GetMinor() uint64 {
|
||||||
|
if m != nil {
|
||||||
|
return m.Minor
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
func (m *Resource) GetXattr() []*XAttr {
|
func (m *Resource) GetXattr() []*XAttr {
|
||||||
if m != nil {
|
if m != nil {
|
||||||
return m.Xattr
|
return m.Xattr
|
||||||
@ -124,6 +200,20 @@ func (m *XAttr) String() string { return proto1.CompactTextString(m)
|
|||||||
func (*XAttr) ProtoMessage() {}
|
func (*XAttr) ProtoMessage() {}
|
||||||
func (*XAttr) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
|
func (*XAttr) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
|
||||||
|
|
||||||
|
func (m *XAttr) GetName() string {
|
||||||
|
if m != nil {
|
||||||
|
return m.Name
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *XAttr) GetData() []byte {
|
||||||
|
if m != nil {
|
||||||
|
return m.Data
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// ADSEntry encodes information for a Windows Alternate Data Stream.
|
// ADSEntry encodes information for a Windows Alternate Data Stream.
|
||||||
type ADSEntry struct {
|
type ADSEntry struct {
|
||||||
// Name specifices the stream name.
|
// Name specifices the stream name.
|
||||||
@ -147,6 +237,27 @@ func (m *ADSEntry) String() string { return proto1.CompactTextString(
|
|||||||
func (*ADSEntry) ProtoMessage() {}
|
func (*ADSEntry) ProtoMessage() {}
|
||||||
func (*ADSEntry) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
|
func (*ADSEntry) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
|
||||||
|
|
||||||
|
func (m *ADSEntry) GetName() string {
|
||||||
|
if m != nil {
|
||||||
|
return m.Name
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *ADSEntry) GetData() []byte {
|
||||||
|
if m != nil {
|
||||||
|
return m.Data
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *ADSEntry) GetDigest() string {
|
||||||
|
if m != nil {
|
||||||
|
return m.Digest
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
proto1.RegisterType((*Manifest)(nil), "proto.Manifest")
|
proto1.RegisterType((*Manifest)(nil), "proto.Manifest")
|
||||||
proto1.RegisterType((*Resource)(nil), "proto.Resource")
|
proto1.RegisterType((*Resource)(nil), "proto.Resource")
|
||||||
@ -158,7 +269,7 @@ func init() { proto1.RegisterFile("manifest.proto", fileDescriptor0) }
|
|||||||
|
|
||||||
var fileDescriptor0 = []byte{
|
var fileDescriptor0 = []byte{
|
||||||
// 317 bytes of a gzipped FileDescriptorProto
|
// 317 bytes of a gzipped FileDescriptorProto
|
||||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x8c, 0x90, 0x4f, 0x4b, 0xf3, 0x40,
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x90, 0x4f, 0x4b, 0xf3, 0x40,
|
||||||
0x10, 0xc6, 0x49, 0x93, 0xf4, 0x4d, 0xa7, 0xed, 0xab, 0x2c, 0x52, 0xe6, 0x18, 0x73, 0x0a, 0x08,
|
0x10, 0xc6, 0x49, 0x93, 0xf4, 0x4d, 0xa7, 0xed, 0xab, 0x2c, 0x52, 0xe6, 0x18, 0x73, 0x0a, 0x08,
|
||||||
0x15, 0xf4, 0xe0, 0xb9, 0xa2, 0x17, 0xc1, 0xcb, 0x7a, 0xf1, 0xba, 0xba, 0x6b, 0x5c, 0x21, 0xd9,
|
0x15, 0xf4, 0xe0, 0xb9, 0xa2, 0x17, 0xc1, 0xcb, 0x7a, 0xf1, 0xba, 0xba, 0x6b, 0x5c, 0x21, 0xd9,
|
||||||
0xb0, 0xd9, 0x80, 0xfa, 0xe5, 0xfc, 0x6a, 0x32, 0xb3, 0x69, 0xd1, 0x9b, 0xa7, 0x3c, 0xcf, 0x6f,
|
0xb0, 0xd9, 0x80, 0xfa, 0xe5, 0xfc, 0x6a, 0x32, 0xb3, 0x69, 0xd1, 0x9b, 0xa7, 0x3c, 0xcf, 0x6f,
|
||||||
|
67
vendor/github.com/containerd/nri/README.md
generated
vendored
67
vendor/github.com/containerd/nri/README.md
generated
vendored
@ -38,18 +38,18 @@ The config's default location will be `/etc/nri/resource.d/*.conf`.
|
|||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"version": "0.1",
|
"version": "0.1",
|
||||||
"plugins": [
|
"plugins": [
|
||||||
{
|
{
|
||||||
"type": "konfine",
|
"type": "konfine",
|
||||||
"conf": {
|
"conf": {
|
||||||
"systemReserved": [0,1]
|
"systemReserved": [0, 1]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "clearcfs"
|
"type": "clearcfs"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -59,23 +59,22 @@ Input to a plugin is provided via `STDIN` as a `json` payload.
|
|||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"version": "0.1",
|
"version": "0.1",
|
||||||
"state": "create",
|
"state": "create",
|
||||||
"id": "redis",
|
"id": "redis",
|
||||||
"pid": 1234,
|
"pid": 1234,
|
||||||
"spec": {
|
"spec": {
|
||||||
"resources": {
|
"resources": {},
|
||||||
},
|
"cgroupsPath": "default/redis",
|
||||||
"cgroupsPath": "default/redis",
|
"namespaces": {
|
||||||
"namespaces": {
|
"pid": "/proc/44/ns/pid",
|
||||||
"pid": "/proc/44/ns/pid",
|
"mount": "/proc/44/ns/mnt",
|
||||||
"mount": "/proc/44/ns/mnt",
|
"net": "/proc/44/ns/net"
|
||||||
"net": "/proc/44/ns/net",
|
},
|
||||||
},
|
"annotations": {
|
||||||
"annotations": {
|
"qos.class": "ls"
|
||||||
"qos.class: "ls"
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -83,11 +82,11 @@ Input to a plugin is provided via `STDIN` as a `json` payload.
|
|||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"version": "0.1",
|
"version": "0.1",
|
||||||
"state": "create",
|
"state": "create",
|
||||||
"id": "redis",
|
"id": "redis",
|
||||||
"pid": 1234,
|
"pid": 1234,
|
||||||
"cgroupsPath": "qos-ls/default/redis"
|
"cgroupsPath": "qos-ls/default/redis"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
17
vendor/modules.txt
vendored
17
vendor/modules.txt
vendored
@ -45,20 +45,21 @@ github.com/Microsoft/hcsshim/pkg/ociwclayer
|
|||||||
github.com/beorn7/perks/quantile
|
github.com/beorn7/perks/quantile
|
||||||
# github.com/cespare/xxhash/v2 v2.1.1
|
# github.com/cespare/xxhash/v2 v2.1.1
|
||||||
github.com/cespare/xxhash/v2
|
github.com/cespare/xxhash/v2
|
||||||
# github.com/cilium/ebpf v0.2.0
|
# github.com/cilium/ebpf v0.4.0
|
||||||
github.com/cilium/ebpf
|
github.com/cilium/ebpf
|
||||||
github.com/cilium/ebpf/asm
|
github.com/cilium/ebpf/asm
|
||||||
github.com/cilium/ebpf/internal
|
github.com/cilium/ebpf/internal
|
||||||
github.com/cilium/ebpf/internal/btf
|
github.com/cilium/ebpf/internal/btf
|
||||||
github.com/cilium/ebpf/internal/unix
|
github.com/cilium/ebpf/internal/unix
|
||||||
# github.com/containerd/aufs v0.0.0-20210416161429-fb0192dcb2c0
|
github.com/cilium/ebpf/link
|
||||||
|
# github.com/containerd/aufs v1.0.0
|
||||||
## explicit
|
## explicit
|
||||||
github.com/containerd/aufs
|
github.com/containerd/aufs
|
||||||
github.com/containerd/aufs/plugin
|
github.com/containerd/aufs/plugin
|
||||||
# github.com/containerd/btrfs v0.0.0-20210316141732-918d888fb676
|
# github.com/containerd/btrfs v1.0.0
|
||||||
## explicit
|
## explicit
|
||||||
github.com/containerd/btrfs
|
github.com/containerd/btrfs
|
||||||
# github.com/containerd/cgroups v0.0.0-20210114181951-8a68de567b68
|
# github.com/containerd/cgroups v1.0.0
|
||||||
## explicit
|
## explicit
|
||||||
github.com/containerd/cgroups
|
github.com/containerd/cgroups
|
||||||
github.com/containerd/cgroups/stats/v1
|
github.com/containerd/cgroups/stats/v1
|
||||||
@ -67,7 +68,7 @@ github.com/containerd/cgroups/v2/stats
|
|||||||
# github.com/containerd/console v1.0.2
|
# github.com/containerd/console v1.0.2
|
||||||
## explicit
|
## explicit
|
||||||
github.com/containerd/console
|
github.com/containerd/console
|
||||||
# github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e
|
# github.com/containerd/continuity v0.1.0
|
||||||
## explicit
|
## explicit
|
||||||
github.com/containerd/continuity
|
github.com/containerd/continuity
|
||||||
github.com/containerd/continuity/devices
|
github.com/containerd/continuity/devices
|
||||||
@ -85,14 +86,14 @@ github.com/containerd/fifo
|
|||||||
# github.com/containerd/go-cni v1.0.2
|
# github.com/containerd/go-cni v1.0.2
|
||||||
## explicit
|
## explicit
|
||||||
github.com/containerd/go-cni
|
github.com/containerd/go-cni
|
||||||
# github.com/containerd/go-runc v0.0.0-20201020171139-16b287bc67d0
|
# github.com/containerd/go-runc v1.0.0
|
||||||
## explicit
|
## explicit
|
||||||
github.com/containerd/go-runc
|
github.com/containerd/go-runc
|
||||||
# github.com/containerd/imgcrypt v1.1.1
|
# github.com/containerd/imgcrypt v1.1.1
|
||||||
## explicit
|
## explicit
|
||||||
github.com/containerd/imgcrypt
|
github.com/containerd/imgcrypt
|
||||||
github.com/containerd/imgcrypt/images/encryption
|
github.com/containerd/imgcrypt/images/encryption
|
||||||
# github.com/containerd/nri v0.0.0-20210316161719-dbaa18c31c14
|
# github.com/containerd/nri v0.1.0
|
||||||
## explicit
|
## explicit
|
||||||
github.com/containerd/nri
|
github.com/containerd/nri
|
||||||
github.com/containerd/nri/types/v1
|
github.com/containerd/nri/types/v1
|
||||||
@ -103,7 +104,7 @@ github.com/containerd/ttrpc/plugin
|
|||||||
# github.com/containerd/typeurl v1.0.2
|
# github.com/containerd/typeurl v1.0.2
|
||||||
## explicit
|
## explicit
|
||||||
github.com/containerd/typeurl
|
github.com/containerd/typeurl
|
||||||
# github.com/containerd/zfs v0.0.0-20210416085227-4140c9077d87
|
# github.com/containerd/zfs v1.0.0
|
||||||
## explicit
|
## explicit
|
||||||
github.com/containerd/zfs
|
github.com/containerd/zfs
|
||||||
github.com/containerd/zfs/plugin
|
github.com/containerd/zfs/plugin
|
||||||
|
Loading…
Reference in New Issue
Block a user