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 (
|
||||
github.com/Microsoft/go-winio v0.4.17
|
||||
github.com/Microsoft/hcsshim v0.8.16
|
||||
github.com/containerd/aufs v0.0.0-20210416161429-fb0192dcb2c0
|
||||
github.com/containerd/btrfs v0.0.0-20210316141732-918d888fb676
|
||||
github.com/containerd/cgroups v0.0.0-20210114181951-8a68de567b68
|
||||
github.com/containerd/aufs v1.0.0
|
||||
github.com/containerd/btrfs v1.0.0
|
||||
github.com/containerd/cgroups v1.0.0
|
||||
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/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/nri v0.0.0-20210316161719-dbaa18c31c14
|
||||
github.com/containerd/nri v0.1.0
|
||||
github.com/containerd/ttrpc 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/coreos/go-systemd/v22 v22.1.0
|
||||
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-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY=
|
||||
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/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=
|
||||
@ -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-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/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/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=
|
||||
@ -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/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/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/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
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/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.2.0 h1:Fv93L3KKckEcEHR3oApXVzyBTDA8WAm6VXhPE00N3f8=
|
||||
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/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-20210316121734-20793ff83c97/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU=
|
||||
github.com/containerd/aufs v0.0.0-20210416161429-fb0192dcb2c0 h1:naOo1n+31DqP+0v8OJsrZg32CCLHUlhY6dfnnZBlgtU=
|
||||
github.com/containerd/aufs v0.0.0-20210416161429-fb0192dcb2c0/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU=
|
||||
github.com/containerd/aufs v1.0.0 h1:2oeJiwX5HstO7shSrPZjrohJZLzK36wvpdmzDRkL/LY=
|
||||
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-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 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-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-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-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 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-20181022165439-0650fd9eeb50/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
|
||||
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-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-20210208174643-50096c924a4e h1:6JKvHHt396/qabvMhnhUZvWaHZzfVfldxE60TK8YLhg=
|
||||
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-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
|
||||
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-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-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 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.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 h1:LBwiTfoUsdiEGAR1TpvxE+Gzt7469oVu87iR3mv3Byc=
|
||||
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-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.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-20190828172938-92c8520ef9f8/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
|
||||
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-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-20210416085227-4140c9077d87 h1:04tsitu/xTkLWo80gnw+R8jhAEKjuuvt/NL7B1bMLWU=
|
||||
github.com/containerd/zfs v0.0.0-20210416085227-4140c9077d87/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY=
|
||||
github.com/containerd/zfs v1.0.0 h1:cXLJbx+4Jj7rNsTiqVfm6i+RNLx6FFA2fMmDlEf+Wm8=
|
||||
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.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
|
||||
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.1 h1:prL8l9w3ntVqXvNH1CiNn5ENjcCnr38JqpSyvKKB4GI=
|
||||
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.5.0/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
|
||||
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/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/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/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=
|
||||
@ -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/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/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.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||
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/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-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-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
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/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 v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
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/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-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/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/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=
|
||||
@ -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/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/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/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=
|
||||
@ -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/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.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs=
|
||||
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.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
|
||||
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/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-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
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/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/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
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/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/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
|
||||
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/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=
|
||||
@ -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.8.0 h1:+77ba4ar4jsCbL1GLbFL8fFM57w6suPfSS9PDLDY7KM=
|
||||
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/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
|
||||
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/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.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
|
||||
github.com/prometheus/client_golang v1.7.1 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/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
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.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/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-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.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
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.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=
|
||||
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/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
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/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/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/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.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 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.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/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/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8=
|
||||
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/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/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/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
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/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/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.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/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=
|
||||
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.5 h1:XAzx9gjCb0Rxj7EoqcClPD1d5ZBxZJk0jbuoPHenBt0=
|
||||
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
||||
|
@ -5,10 +5,10 @@ go 1.15
|
||||
require (
|
||||
github.com/Microsoft/hcsshim v0.8.16
|
||||
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
|
||||
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/typeurl v1.0.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/go.mod h1:Cmvnhlie15Ha2UYrJs9EhgSx76Bq9RV2FgfEiT78GhI=
|
||||
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/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=
|
||||
@ -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-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/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/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=
|
||||
@ -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/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/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
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/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/cilium/ebpf v0.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.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/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/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 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 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/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.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/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4=
|
||||
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-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 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/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/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y=
|
||||
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/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRDjeJr6FLK6vuiUwoH7P8=
|
||||
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-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
|
||||
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/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/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-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/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/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.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
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/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-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-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
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/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 v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
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/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-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/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/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/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/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=
|
||||
@ -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/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.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs=
|
||||
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.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
|
||||
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/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-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
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/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/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
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.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/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/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/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=
|
||||
@ -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/selinux v1.8.0 h1:+77ba4ar4jsCbL1GLbFL8fFM57w6suPfSS9PDLDY7KM=
|
||||
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/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
|
||||
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/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.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
|
||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
@ -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-20190812154241-14fe0d1b01d4/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.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/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.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
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.2.0 h1:wH4vA7pcjKuZzjF7lM8awk4fnuJO6idemZXoKnULUx4=
|
||||
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/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
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/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
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/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.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 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.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
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/stretchr/objx v0.1.0/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/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/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/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
|
||||
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/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI=
|
||||
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.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.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
||||
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-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-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-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=
|
||||
|
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
|
||||
|
||||
import (
|
||||
"crypto/sha1"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"strings"
|
||||
|
||||
"github.com/cilium/ebpf/internal/unix"
|
||||
)
|
||||
|
||||
// InstructionSize is the size of a BPF instruction in bytes
|
||||
@ -159,6 +163,9 @@ func (ins *Instruction) mapOffset() uint32 {
|
||||
return uint32(uint64(ins.Constant) >> 32)
|
||||
}
|
||||
|
||||
// isLoadFromMap returns true if the instruction loads from a map.
|
||||
//
|
||||
// This covers both loading the map pointer and direct map value loads.
|
||||
func (ins *Instruction) isLoadFromMap() bool {
|
||||
return ins.OpCode == LoadImmOp(DWord) && (ins.Src == PseudoMapFD || ins.Src == PseudoMapValue)
|
||||
}
|
||||
@ -390,6 +397,25 @@ func (insns Instructions) Marshal(w io.Writer, bo binary.ByteOrder) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Tag calculates the kernel tag for a series of instructions.
|
||||
//
|
||||
// It mirrors bpf_prog_calc_tag in the kernel and so can be compared
|
||||
// to ProgramInfo.Tag to figure out whether a loaded program matches
|
||||
// certain instructions.
|
||||
func (insns Instructions) Tag(bo binary.ByteOrder) (string, error) {
|
||||
h := sha1.New()
|
||||
for i, ins := range insns {
|
||||
if ins.isLoadFromMap() {
|
||||
ins.Constant = 0
|
||||
}
|
||||
_, err := ins.Marshal(h, bo)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("instruction %d: %w", i, err)
|
||||
}
|
||||
}
|
||||
return hex.EncodeToString(h.Sum(nil)[:unix.BPF_TAG_SIZE]), nil
|
||||
}
|
||||
|
||||
// Iterate allows iterating a BPF program while keeping track of
|
||||
// various offsets.
|
||||
//
|
||||
@ -417,6 +443,7 @@ func (iter *InstructionIterator) Next() bool {
|
||||
}
|
||||
|
||||
if iter.Ins != nil {
|
||||
iter.Index++
|
||||
iter.Offset += RawInstructionOffset(iter.Ins.OpCode.rawInstructions())
|
||||
}
|
||||
iter.Ins = &iter.insns[0]
|
||||
|
297
vendor/github.com/cilium/ebpf/collection.go
generated
vendored
297
vendor/github.com/cilium/ebpf/collection.go
generated
vendored
@ -131,10 +131,11 @@ func (cs *CollectionSpec) RewriteConstants(consts map[string]interface{}) error
|
||||
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
|
||||
// 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
|
||||
// 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)
|
||||
}
|
||||
|
||||
// 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 {
|
||||
if opts == nil {
|
||||
opts = &CollectionOptions{}
|
||||
}
|
||||
|
||||
coll, err := NewCollectionWithOptions(cs, *opts)
|
||||
loadMap, loadProgram, done, cleanup := lazyLoadCollection(cs, opts)
|
||||
defer cleanup()
|
||||
|
||||
valueOf := func(typ reflect.Type, name string) (reflect.Value, error) {
|
||||
switch typ {
|
||||
case reflect.TypeOf((*Program)(nil)):
|
||||
p, err := loadProgram(name)
|
||||
if err != nil {
|
||||
return reflect.Value{}, err
|
||||
}
|
||||
return reflect.ValueOf(p), nil
|
||||
case reflect.TypeOf((*Map)(nil)):
|
||||
m, err := loadMap(name)
|
||||
if err != nil {
|
||||
return reflect.Value{}, err
|
||||
}
|
||||
return reflect.ValueOf(m), nil
|
||||
default:
|
||||
return reflect.Value{}, fmt.Errorf("unsupported type %s", typ)
|
||||
}
|
||||
}
|
||||
|
||||
if err := assignValues(to, valueOf); err != nil {
|
||||
return err
|
||||
}
|
||||
defer coll.Close()
|
||||
|
||||
return coll.Assign(to)
|
||||
done()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Collection is a collection of Programs and Maps associated
|
||||
@ -198,41 +239,39 @@ type Collection struct {
|
||||
}
|
||||
|
||||
// NewCollection creates a Collection from a specification.
|
||||
//
|
||||
// Only maps referenced by at least one of the programs are initialized.
|
||||
func NewCollection(spec *CollectionSpec) (*Collection, error) {
|
||||
return NewCollectionWithOptions(spec, CollectionOptions{})
|
||||
}
|
||||
|
||||
// NewCollectionWithOptions creates a Collection from a specification.
|
||||
//
|
||||
// Only maps referenced by at least one of the programs are initialized.
|
||||
func NewCollectionWithOptions(spec *CollectionSpec, opts CollectionOptions) (coll *Collection, err error) {
|
||||
var (
|
||||
maps = make(map[string]*Map)
|
||||
progs = make(map[string]*Program)
|
||||
btfs = make(map[*btf.Spec]*btf.Handle)
|
||||
)
|
||||
func NewCollectionWithOptions(spec *CollectionSpec, opts CollectionOptions) (*Collection, error) {
|
||||
loadMap, loadProgram, done, cleanup := lazyLoadCollection(spec, &opts)
|
||||
defer cleanup()
|
||||
|
||||
defer func() {
|
||||
for _, btf := range btfs {
|
||||
btf.Close()
|
||||
for mapName := range spec.Maps {
|
||||
_, err := loadMap(mapName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
return
|
||||
for progName := range spec.Programs {
|
||||
_, err := loadProgram(progName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
for _, m := range maps {
|
||||
m.Close()
|
||||
maps, progs := done()
|
||||
return &Collection{
|
||||
progs,
|
||||
maps,
|
||||
}, nil
|
||||
}
|
||||
|
||||
for _, p := range progs {
|
||||
p.Close()
|
||||
}
|
||||
}()
|
||||
type btfHandleCache map[*btf.Spec]*btf.Handle
|
||||
|
||||
loadBTF := func(spec *btf.Spec) (*btf.Handle, error) {
|
||||
func (btfs btfHandleCache) load(spec *btf.Spec) (*btf.Handle, error) {
|
||||
if btfs[spec] != nil {
|
||||
return btfs[spec], nil
|
||||
}
|
||||
@ -246,24 +285,76 @@ func NewCollectionWithOptions(spec *CollectionSpec, opts CollectionOptions) (col
|
||||
return handle, nil
|
||||
}
|
||||
|
||||
for mapName, mapSpec := range spec.Maps {
|
||||
var handle *btf.Handle
|
||||
if mapSpec.BTF != nil {
|
||||
handle, err = loadBTF(btf.MapSpec(mapSpec.BTF))
|
||||
if err != nil && !errors.Is(err, btf.ErrNotSupported) {
|
||||
return nil, err
|
||||
func (btfs btfHandleCache) close() {
|
||||
for _, handle := range btfs {
|
||||
handle.Close()
|
||||
}
|
||||
}
|
||||
|
||||
m, err := newMapWithBTF(mapSpec, handle, opts.Maps)
|
||||
func lazyLoadCollection(coll *CollectionSpec, opts *CollectionOptions) (
|
||||
loadMap func(string) (*Map, error),
|
||||
loadProgram func(string) (*Program, error),
|
||||
done func() (map[string]*Map, map[string]*Program),
|
||||
cleanup func(),
|
||||
) {
|
||||
var (
|
||||
maps = make(map[string]*Map)
|
||||
progs = make(map[string]*Program)
|
||||
btfs = make(btfHandleCache)
|
||||
skipMapsAndProgs = false
|
||||
)
|
||||
|
||||
cleanup = func() {
|
||||
btfs.close()
|
||||
|
||||
if skipMapsAndProgs {
|
||||
return
|
||||
}
|
||||
|
||||
for _, m := range maps {
|
||||
m.Close()
|
||||
}
|
||||
|
||||
for _, p := range progs {
|
||||
p.Close()
|
||||
}
|
||||
}
|
||||
|
||||
done = func() (map[string]*Map, map[string]*Program) {
|
||||
skipMapsAndProgs = true
|
||||
return maps, progs
|
||||
}
|
||||
|
||||
loadMap = func(mapName string) (*Map, error) {
|
||||
if m := maps[mapName]; m != nil {
|
||||
return m, nil
|
||||
}
|
||||
|
||||
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 {
|
||||
return nil, fmt.Errorf("map %s: %w", mapName, err)
|
||||
}
|
||||
|
||||
maps[mapName] = m
|
||||
return m, nil
|
||||
}
|
||||
|
||||
for progName, origProgSpec := range spec.Programs {
|
||||
progSpec := origProgSpec.Copy()
|
||||
loadProgram = func(progName string) (*Program, error) {
|
||||
if prog := progs[progName]; prog != nil {
|
||||
return prog, nil
|
||||
}
|
||||
|
||||
progSpec := coll.Programs[progName]
|
||||
if progSpec == nil {
|
||||
return nil, fmt.Errorf("unknown program %s", progName)
|
||||
}
|
||||
|
||||
progSpec = progSpec.Copy()
|
||||
|
||||
// Rewrite any reference to a valid map.
|
||||
for i := range progSpec.Instructions {
|
||||
@ -279,9 +370,9 @@ func NewCollectionWithOptions(spec *CollectionSpec, opts CollectionOptions) (col
|
||||
continue
|
||||
}
|
||||
|
||||
m := maps[ins.Reference]
|
||||
if m == nil {
|
||||
return nil, fmt.Errorf("program %s: missing map %s", progName, ins.Reference)
|
||||
m, err := loadMap(ins.Reference)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("program %s: %s", progName, err)
|
||||
}
|
||||
|
||||
fd := m.FD()
|
||||
@ -293,25 +384,16 @@ func NewCollectionWithOptions(spec *CollectionSpec, opts CollectionOptions) (col
|
||||
}
|
||||
}
|
||||
|
||||
var handle *btf.Handle
|
||||
if progSpec.BTF != nil {
|
||||
handle, err = loadBTF(btf.ProgramSpec(progSpec.BTF))
|
||||
if err != nil && !errors.Is(err, btf.ErrNotSupported) {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
prog, err := newProgramWithBTF(progSpec, handle, opts.Programs)
|
||||
prog, err := newProgramWithOptions(progSpec, opts.Programs, btfs)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("program %s: %w", progName, err)
|
||||
}
|
||||
|
||||
progs[progName] = prog
|
||||
return prog, nil
|
||||
}
|
||||
|
||||
return &Collection{
|
||||
progs,
|
||||
maps,
|
||||
}, nil
|
||||
return
|
||||
}
|
||||
|
||||
// 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.
|
||||
//
|
||||
// `to` must be a pointer to a struct like the following:
|
||||
//
|
||||
// struct {
|
||||
// Foo *ebpf.Program `ebpf:"xdp_foo"`
|
||||
// Bar *ebpf.Map `ebpf:"bar_map"`
|
||||
// Ignored int
|
||||
// }
|
||||
//
|
||||
// See CollectionSpec.Assign for the semantics of this function.
|
||||
//
|
||||
// DetachMap and DetachProgram is invoked for all assigned elements
|
||||
// if the function is successful.
|
||||
// Deprecated: use CollectionSpec.Assign instead. It provides the same
|
||||
// functionality but creates only the maps and programs requested.
|
||||
func (coll *Collection) Assign(to interface{}) error {
|
||||
assignedMaps := make(map[string]struct{})
|
||||
assignedPrograms := make(map[string]struct{})
|
||||
@ -411,28 +483,86 @@ func (coll *Collection) Assign(to interface{}) error {
|
||||
}
|
||||
|
||||
func assignValues(to interface{}, valueOf func(reflect.Type, string) (reflect.Value, error)) error {
|
||||
v := reflect.ValueOf(to)
|
||||
if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct {
|
||||
return fmt.Errorf("%T is not a pointer to a struct", to)
|
||||
type structField struct {
|
||||
reflect.StructField
|
||||
value reflect.Value
|
||||
}
|
||||
|
||||
var (
|
||||
fields []structField
|
||||
visitedTypes = make(map[reflect.Type]bool)
|
||||
flattenStruct func(reflect.Value) error
|
||||
)
|
||||
|
||||
flattenStruct = func(structVal reflect.Value) error {
|
||||
structType := structVal.Type()
|
||||
if structType.Kind() != reflect.Struct {
|
||||
return fmt.Errorf("%s is not a struct", structType)
|
||||
}
|
||||
|
||||
if visitedTypes[structType] {
|
||||
return fmt.Errorf("recursion on type %s", structType)
|
||||
}
|
||||
|
||||
for i := 0; i < structType.NumField(); i++ {
|
||||
field := structField{structType.Field(i), structVal.Field(i)}
|
||||
|
||||
name := field.Tag.Get("ebpf")
|
||||
if name != "" {
|
||||
fields = append(fields, field)
|
||||
continue
|
||||
}
|
||||
|
||||
var err error
|
||||
switch field.Type.Kind() {
|
||||
case reflect.Ptr:
|
||||
if field.Type.Elem().Kind() != reflect.Struct {
|
||||
continue
|
||||
}
|
||||
|
||||
if field.value.IsNil() {
|
||||
return fmt.Errorf("nil pointer to %s", structType)
|
||||
}
|
||||
|
||||
err = flattenStruct(field.value.Elem())
|
||||
|
||||
case reflect.Struct:
|
||||
err = flattenStruct(field.value)
|
||||
|
||||
default:
|
||||
continue
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("field %s: %s", field.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
toValue := reflect.ValueOf(to)
|
||||
if toValue.Type().Kind() != reflect.Ptr {
|
||||
return fmt.Errorf("%T is not a pointer to struct", to)
|
||||
}
|
||||
|
||||
if toValue.IsNil() {
|
||||
return fmt.Errorf("nil pointer to %T", to)
|
||||
}
|
||||
|
||||
if err := flattenStruct(toValue.Elem()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
type elem struct {
|
||||
// Either *Map or *Program
|
||||
typ reflect.Type
|
||||
name string
|
||||
}
|
||||
|
||||
var (
|
||||
s = v.Elem()
|
||||
sT = s.Type()
|
||||
assignedTo = make(map[elem]string)
|
||||
)
|
||||
for i := 0; i < sT.NumField(); i++ {
|
||||
field := sT.Field(i)
|
||||
|
||||
assignedTo := make(map[elem]string)
|
||||
for _, field := range fields {
|
||||
name := field.Tag.Get("ebpf")
|
||||
if name == "" {
|
||||
continue
|
||||
}
|
||||
if strings.Contains(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)
|
||||
}
|
||||
|
||||
fieldValue := s.Field(i)
|
||||
if !fieldValue.CanSet() {
|
||||
return fmt.Errorf("can't set value of field %s", field.Name)
|
||||
if !field.value.CanSet() {
|
||||
return fmt.Errorf("field %s: can't set value", field.Name)
|
||||
}
|
||||
|
||||
fieldValue.Set(value)
|
||||
field.value.Set(value)
|
||||
assignedTo[e] = field.Name
|
||||
}
|
||||
|
||||
|
596
vendor/github.com/cilium/ebpf/elf_reader.go
generated
vendored
596
vendor/github.com/cilium/ebpf/elf_reader.go
generated
vendored
@ -18,12 +18,14 @@ import (
|
||||
"github.com/cilium/ebpf/internal/unix"
|
||||
)
|
||||
|
||||
// elfCode is a convenience to reduce the amount of arguments that have to
|
||||
// be passed around explicitly. You should treat it's contents as immutable.
|
||||
type elfCode struct {
|
||||
*elf.File
|
||||
symbols []elf.Symbol
|
||||
symbolsPerSection map[elf.SectionIndex]map[uint64]elf.Symbol
|
||||
*internal.SafeELFFile
|
||||
sections map[elf.SectionIndex]*elfSection
|
||||
license string
|
||||
version uint32
|
||||
btf *btf.Spec
|
||||
}
|
||||
|
||||
// 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.
|
||||
func LoadCollectionSpecFromReader(rd io.ReaderAt) (*CollectionSpec, error) {
|
||||
f, err := elf.NewFile(rd)
|
||||
f, err := internal.NewSafeELFFile(rd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
symbols, err := f.Symbols()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load symbols: %v", err)
|
||||
}
|
||||
|
||||
ec := &elfCode{f, symbols, symbolsPerSection(symbols), "", 0}
|
||||
|
||||
var (
|
||||
licenseSection *elf.Section
|
||||
versionSection *elf.Section
|
||||
btfMaps = make(map[elf.SectionIndex]*elf.Section)
|
||||
progSections = make(map[elf.SectionIndex]*elf.Section)
|
||||
sections = make(map[elf.SectionIndex]*elfSection)
|
||||
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 {
|
||||
case strings.HasPrefix(sec.Name, "license"):
|
||||
licenseSection = sec
|
||||
case strings.HasPrefix(sec.Name, "version"):
|
||||
versionSection = sec
|
||||
case strings.HasPrefix(sec.Name, "maps"):
|
||||
mapSections[elf.SectionIndex(i)] = sec
|
||||
sections[idx] = newElfSection(sec, mapSection)
|
||||
case sec.Name == ".maps":
|
||||
btfMaps[elf.SectionIndex(i)] = sec
|
||||
case sec.Name == ".bss" || sec.Name == ".rodata" || sec.Name == ".data":
|
||||
dataSections[elf.SectionIndex(i)] = sec
|
||||
sections[idx] = newElfSection(sec, btfMapSection)
|
||||
case sec.Name == ".bss" || sec.Name == ".data" || strings.HasPrefix(sec.Name, ".rodata"):
|
||||
sections[idx] = newElfSection(sec, dataSection)
|
||||
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
|
||||
idx := elf.SectionIndex(sec.Info)
|
||||
if relSections[idx] != nil {
|
||||
return nil, fmt.Errorf("section %d has multiple relocation sections", sec.Info)
|
||||
}
|
||||
relSections[idx] = sec
|
||||
relSections[elf.SectionIndex(sec.Info)] = sec
|
||||
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 {
|
||||
return nil, fmt.Errorf("load license: %w", err)
|
||||
}
|
||||
|
||||
ec.version, err = loadVersion(versionSection, ec.ByteOrder)
|
||||
version, err := loadVersion(versionSection, f.ByteOrder)
|
||||
if err != nil {
|
||||
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)
|
||||
}
|
||||
|
||||
relocations, referencedSections, err := ec.loadRelocations(relSections)
|
||||
// Assign symbols to all the sections we're interested in.
|
||||
symbols, err := f.Symbols()
|
||||
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)
|
||||
if err := ec.loadMaps(maps, mapSections); err != nil {
|
||||
if err := ec.loadMaps(maps); err != nil {
|
||||
return nil, fmt.Errorf("load maps: %w", err)
|
||||
}
|
||||
|
||||
if len(btfMaps) > 0 {
|
||||
if err := ec.loadBTFMaps(maps, btfMaps, btfSpec); err != nil {
|
||||
if err := ec.loadBTFMaps(maps); err != nil {
|
||||
return nil, fmt.Errorf("load BTF maps: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if len(dataSections) > 0 {
|
||||
for idx := range dataSections {
|
||||
if !referencedSections[idx] {
|
||||
// Prune data sections which are not referenced by any
|
||||
// instructions.
|
||||
delete(dataSections, idx)
|
||||
}
|
||||
}
|
||||
|
||||
if err := ec.loadDataSections(maps, dataSections, btfSpec); err != nil {
|
||||
if err := ec.loadDataSections(maps); 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 {
|
||||
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
|
||||
}
|
||||
|
||||
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 (
|
||||
progs []*ProgramSpec
|
||||
libs []*ProgramSpec
|
||||
)
|
||||
|
||||
for idx, sec := range progSections {
|
||||
syms := ec.symbolsPerSection[idx]
|
||||
if len(syms) == 0 {
|
||||
for _, sec := range ec.sections {
|
||||
if sec.kind != programSection {
|
||||
continue
|
||||
}
|
||||
|
||||
if len(sec.symbols) == 0 {
|
||||
return nil, fmt.Errorf("section %v: missing symbols", sec.Name)
|
||||
}
|
||||
|
||||
funcSym, ok := syms[0]
|
||||
funcSym, ok := sec.symbols[0]
|
||||
if !ok {
|
||||
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 {
|
||||
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)
|
||||
@ -206,8 +285,8 @@ func (ec *elfCode) loadPrograms(progSections map[elf.SectionIndex]*elf.Section,
|
||||
ByteOrder: ec.ByteOrder,
|
||||
}
|
||||
|
||||
if btfSpec != nil {
|
||||
spec.BTF, err = btfSpec.Program(sec.Name, length)
|
||||
if ec.btf != nil {
|
||||
spec.BTF, err = ec.btf.Program(sec.Name, length)
|
||||
if err != nil && !errors.Is(err, btf.ErrNoExtendedInfo) {
|
||||
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
|
||||
}
|
||||
|
||||
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 (
|
||||
r = bufio.NewReader(section.Open())
|
||||
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)
|
||||
}
|
||||
|
||||
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 {
|
||||
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
|
||||
)
|
||||
|
||||
if typ == elf.STT_SECTION {
|
||||
// Symbols with section type do not have a name set. Get it
|
||||
// from the section itself.
|
||||
idx := int(rel.Section)
|
||||
if idx > len(ec.Sections) {
|
||||
return errors.New("out-of-bounds section index")
|
||||
}
|
||||
target := ec.sections[rel.Section]
|
||||
|
||||
name = ec.Sections[idx].Name
|
||||
}
|
||||
|
||||
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.
|
||||
fallthrough
|
||||
|
||||
case elf.STT_OBJECT:
|
||||
switch target.kind {
|
||||
case mapSection, btfMapSection:
|
||||
if bind != elf.STB_GLOBAL {
|
||||
return fmt.Errorf("load: %s: unsupported binding: %s", name, bind)
|
||||
return fmt.Errorf("possible erroneous static qualifier on map definition: found reference to %q", name)
|
||||
}
|
||||
|
||||
if typ != elf.STT_OBJECT && typ != elf.STT_NOTYPE {
|
||||
// STT_NOTYPE is generated on clang < 8 which doesn't tag
|
||||
// relocations appropriately.
|
||||
return fmt.Errorf("map load: incorrect relocation type %v", typ)
|
||||
}
|
||||
|
||||
ins.Src = asm.PseudoMapFD
|
||||
|
||||
default:
|
||||
return fmt.Errorf("load: %s: unsupported relocation: %s", name, typ)
|
||||
}
|
||||
|
||||
// Mark the instruction as needing an update when creating the
|
||||
// collection.
|
||||
if err := ins.RewriteMapPtr(-1); err != nil {
|
||||
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 {
|
||||
return fmt.Errorf("call: %s: incorrect source register", name)
|
||||
}
|
||||
@ -358,7 +434,7 @@ outer:
|
||||
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 {
|
||||
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)
|
||||
}
|
||||
|
||||
case undefSection:
|
||||
if bind != elf.STB_GLOBAL {
|
||||
return fmt.Errorf("asm relocation: %s: unsupported binding: %s", name, bind)
|
||||
}
|
||||
|
||||
if typ != elf.STT_NOTYPE {
|
||||
return fmt.Errorf("asm relocation: %s: unsupported type %s", name, typ)
|
||||
}
|
||||
|
||||
// There is nothing to do here but set ins.Reference.
|
||||
|
||||
default:
|
||||
return fmt.Errorf("relocation for unsupported instruction: %s", ins.OpCode)
|
||||
return fmt.Errorf("relocation to %q: %w", target.Name, ErrNotSupported)
|
||||
}
|
||||
|
||||
ins.Reference = name
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ec *elfCode) loadMaps(maps map[string]*MapSpec, mapSections map[elf.SectionIndex]*elf.Section) error {
|
||||
for idx, sec := range mapSections {
|
||||
syms := ec.symbolsPerSection[idx]
|
||||
if len(syms) == 0 {
|
||||
func (ec *elfCode) loadMaps(maps map[string]*MapSpec) error {
|
||||
for _, sec := range ec.sections {
|
||||
if sec.kind != mapSection {
|
||||
continue
|
||||
}
|
||||
|
||||
nSym := len(sec.symbols)
|
||||
if nSym == 0 {
|
||||
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)
|
||||
}
|
||||
|
||||
var (
|
||||
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 {
|
||||
mapSym, ok := syms[offset]
|
||||
for i, offset := 0, uint64(0); i < nSym; i, offset = i+1, offset+size {
|
||||
mapSym, ok := sec.symbols[offset]
|
||||
if !ok {
|
||||
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
|
||||
}
|
||||
|
||||
func (ec *elfCode) loadBTFMaps(maps map[string]*MapSpec, mapSections map[elf.SectionIndex]*elf.Section, spec *btf.Spec) error {
|
||||
if spec == nil {
|
||||
func (ec *elfCode) loadBTFMaps(maps map[string]*MapSpec) error {
|
||||
for _, sec := range ec.sections {
|
||||
if sec.kind != btfMapSection {
|
||||
continue
|
||||
}
|
||||
|
||||
if ec.btf == nil {
|
||||
return fmt.Errorf("missing BTF")
|
||||
}
|
||||
|
||||
for idx, sec := range mapSections {
|
||||
syms := ec.symbolsPerSection[idx]
|
||||
if len(syms) == 0 {
|
||||
if len(sec.symbols) == 0 {
|
||||
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
|
||||
if maps[name] != nil {
|
||||
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 {
|
||||
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
|
||||
}
|
||||
|
||||
func mapSpecFromBTF(spec *btf.Spec, name string) (*MapSpec, error) {
|
||||
btfMap, btfMapMembers, err := spec.Map(name)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't get BTF: %w", err)
|
||||
}
|
||||
|
||||
keyType := btf.MapKey(btfMap)
|
||||
size, err := btf.Sizeof(keyType)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't get size of BTF key: %w", err)
|
||||
}
|
||||
keySize := uint32(size)
|
||||
|
||||
valueType := btf.MapValue(btfMap)
|
||||
size, err = btf.Sizeof(valueType)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't get size of BTF value: %w", err)
|
||||
}
|
||||
valueSize := uint32(size)
|
||||
// mapSpecFromBTF produces a MapSpec based on a btf.Struct def representing
|
||||
// a BTF map definition. The name and spec arguments will be copied to the
|
||||
// resulting MapSpec, and inner must be true on any resursive invocations.
|
||||
func mapSpecFromBTF(name string, def *btf.Struct, inner bool, spec *btf.Spec) (*MapSpec, error) {
|
||||
|
||||
var (
|
||||
key, value btf.Type
|
||||
keySize, valueSize uint32
|
||||
mapType, flags, maxEntries uint32
|
||||
pinType PinType
|
||||
innerMapSpec *MapSpec
|
||||
err error
|
||||
)
|
||||
for _, member := range btfMapMembers {
|
||||
|
||||
for i, member := range def.Members {
|
||||
switch member.Name {
|
||||
case "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)
|
||||
}
|
||||
|
||||
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":
|
||||
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")
|
||||
}
|
||||
|
||||
@ -516,7 +659,9 @@ func mapSpecFromBTF(spec *btf.Spec, name string) (*MapSpec, error) {
|
||||
}
|
||||
|
||||
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")
|
||||
}
|
||||
|
||||
@ -526,6 +671,10 @@ func mapSpecFromBTF(spec *btf.Spec, name string) (*MapSpec, error) {
|
||||
}
|
||||
|
||||
case "pinning":
|
||||
if inner {
|
||||
return nil, errors.New("inner maps can't be pinned")
|
||||
}
|
||||
|
||||
pinning, err := uintFromBTF(member.Type)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't get pinning: %w", err)
|
||||
@ -533,12 +682,58 @@ func mapSpecFromBTF(spec *btf.Spec, name string) (*MapSpec, error) {
|
||||
|
||||
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:
|
||||
return nil, fmt.Errorf("unrecognized field %s in BTF map definition", member.Name)
|
||||
}
|
||||
}
|
||||
|
||||
bm := btf.NewMap(spec, key, value)
|
||||
|
||||
return &MapSpec{
|
||||
Name: SanitizeName(name, -1),
|
||||
Type: MapType(mapType),
|
||||
@ -546,8 +741,9 @@ func mapSpecFromBTF(spec *btf.Spec, name string) (*MapSpec, error) {
|
||||
ValueSize: valueSize,
|
||||
MaxEntries: maxEntries,
|
||||
Flags: flags,
|
||||
BTF: btfMap,
|
||||
BTF: &bm,
|
||||
Pinning: pinType,
|
||||
InnerMap: innerMapSpec,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -567,13 +763,40 @@ func uintFromBTF(typ btf.Type) (uint32, error) {
|
||||
return arr.Nelems, nil
|
||||
}
|
||||
|
||||
func (ec *elfCode) loadDataSections(maps map[string]*MapSpec, dataSections map[elf.SectionIndex]*elf.Section, spec *btf.Spec) error {
|
||||
if spec == nil {
|
||||
// resolveBTFArrayMacro resolves the __array macro, which declares an array
|
||||
// of pointers to a given type. This function returns the target Type of
|
||||
// the pointers in the array.
|
||||
func resolveBTFArrayMacro(typ btf.Type) (btf.Type, error) {
|
||||
arr, ok := typ.(*btf.Array)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("not an array: %v", typ)
|
||||
}
|
||||
|
||||
ptr, ok := arr.Type.(*btf.Pointer)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("not an array of pointers: %v", typ)
|
||||
}
|
||||
|
||||
return ptr.Target, nil
|
||||
}
|
||||
|
||||
func (ec *elfCode) loadDataSections(maps map[string]*MapSpec) error {
|
||||
for _, sec := range ec.sections {
|
||||
if sec.kind != dataSection {
|
||||
continue
|
||||
}
|
||||
|
||||
if sec.references == 0 {
|
||||
// Prune data sections which are not referenced by any
|
||||
// instructions.
|
||||
continue
|
||||
}
|
||||
|
||||
if ec.btf == nil {
|
||||
return errors.New("data sections require BTF, make sure all consts are marked as static")
|
||||
}
|
||||
|
||||
for _, sec := range dataSections {
|
||||
btfMap, err := spec.Datasec(sec.Name)
|
||||
btfMap, err := ec.btf.Datasec(sec.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -678,14 +901,11 @@ func getProgType(sectionName string) (ProgramType, AttachType, string) {
|
||||
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) {
|
||||
result := make(map[elf.SectionIndex]map[uint64]elf.Symbol)
|
||||
targets := make(map[elf.SectionIndex]bool)
|
||||
for idx, sec := range sections {
|
||||
func (ec *elfCode) loadRelocations(sec *elf.Section, symbols []elf.Symbol) (map[uint64]elf.Symbol, error) {
|
||||
rels := make(map[uint64]elf.Symbol)
|
||||
|
||||
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())
|
||||
@ -694,53 +914,17 @@ func (ec *elfCode) loadRelocations(sections map[elf.SectionIndex]*elf.Section) (
|
||||
|
||||
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)
|
||||
return 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)
|
||||
if symNo >= len(symbols) {
|
||||
return nil, fmt.Errorf("offset %d: symbol %d doesn't exist", off, symNo)
|
||||
}
|
||||
|
||||
symbol := ec.symbols[symNo]
|
||||
targets[symbol.Section] = true
|
||||
rels[rel.Off] = ec.symbols[symNo]
|
||||
symbol := symbols[symNo]
|
||||
rels[rel.Off] = symbol
|
||||
}
|
||||
|
||||
result[idx] = rels
|
||||
}
|
||||
return result, targets, nil
|
||||
}
|
||||
|
||||
func symbolsPerSection(symbols []elf.Symbol) map[elf.SectionIndex]map[uint64]elf.Symbol {
|
||||
result := make(map[elf.SectionIndex]map[uint64]elf.Symbol)
|
||||
for _, sym := range symbols {
|
||||
switch elf.ST_TYPE(sym.Info) {
|
||||
case elf.STT_NOTYPE:
|
||||
// Older versions of LLVM doesn't tag
|
||||
// symbols correctly.
|
||||
break
|
||||
case elf.STT_OBJECT:
|
||||
break
|
||||
case elf.STT_FUNC:
|
||||
break
|
||||
default:
|
||||
continue
|
||||
}
|
||||
|
||||
if sym.Section == elf.SHN_UNDEF || sym.Section >= elf.SHN_LORESERVE {
|
||||
continue
|
||||
}
|
||||
|
||||
if sym.Name == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
idx := sym.Section
|
||||
if _, ok := result[idx]; !ok {
|
||||
result[idx] = make(map[uint64]elf.Symbol)
|
||||
}
|
||||
result[idx][sym.Value] = sym
|
||||
}
|
||||
return result
|
||||
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
|
||||
|
||||
go 1.14
|
||||
go 1.15
|
||||
|
||||
require (
|
||||
github.com/google/go-cmp v0.5.2
|
||||
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9
|
||||
github.com/frankban/quicktest v1.11.3
|
||||
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/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9 h1:1/DFK4b7JH8DmkqhUk48onnSfrPzImPoVxuomtbT2nk=
|
||||
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
github.com/frankban/quicktest v1.11.3 h1:8sXhOn0uLys67V8EsXLc6eszDs8VXWxL3iRvebPhedY=
|
||||
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
|
||||
github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M=
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c h1:VwygUrnw9jn88c4u8GD3rZQbqrP/tgas88tPUbBxQrk=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
239
vendor/github.com/cilium/ebpf/info.go
generated
vendored
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
|
||||
}
|
152
vendor/github.com/cilium/ebpf/internal/btf/btf.go
generated
vendored
152
vendor/github.com/cilium/ebpf/internal/btf/btf.go
generated
vendored
@ -31,9 +31,11 @@ var (
|
||||
type Spec struct {
|
||||
rawTypes []rawType
|
||||
strings stringTable
|
||||
types map[string][]namedType
|
||||
types []Type
|
||||
namedTypes map[string][]namedType
|
||||
funcInfos map[string]extInfo
|
||||
lineInfos map[string]extInfo
|
||||
coreRelos map[string]bpfCoreRelos
|
||||
byteOrder binary.ByteOrder
|
||||
}
|
||||
|
||||
@ -53,7 +55,7 @@ type btfHeader struct {
|
||||
//
|
||||
// Returns a nil Spec and no error if no BTF was present.
|
||||
func LoadSpecFromReader(rd io.ReaderAt) (*Spec, error) {
|
||||
file, err := elf.NewFile(rd)
|
||||
file, err := internal.NewSafeELFFile(rd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -80,6 +82,10 @@ func LoadSpecFromReader(rd io.ReaderAt) (*Spec, error) {
|
||||
continue
|
||||
}
|
||||
|
||||
if int(symbol.Section) >= len(file.Sections) {
|
||||
return nil, fmt.Errorf("symbol %s: invalid section %d", symbol.Name, symbol.Section)
|
||||
}
|
||||
|
||||
secName := file.Sections[symbol.Section].Name
|
||||
if _, ok := sectionSizes[secName]; !ok {
|
||||
continue
|
||||
@ -101,7 +107,7 @@ func LoadSpecFromReader(rd io.ReaderAt) (*Spec, error) {
|
||||
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 {
|
||||
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
|
||||
}
|
||||
|
||||
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 (
|
||||
btfSection *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) {
|
||||
file, err := elf.NewFile(rd)
|
||||
file, err := internal.NewSafeELFFile(rd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -165,13 +171,14 @@ func loadNakedSpec(btf io.ReadSeeker, bo binary.ByteOrder, sectionSizes map[stri
|
||||
return nil, err
|
||||
}
|
||||
|
||||
types, err := inflateRawTypes(rawTypes, rawStrings)
|
||||
types, typesByName, err := inflateRawTypes(rawTypes, rawStrings)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Spec{
|
||||
rawTypes: rawTypes,
|
||||
namedTypes: typesByName,
|
||||
types: types,
|
||||
strings: rawStrings,
|
||||
byteOrder: bo,
|
||||
@ -311,10 +318,14 @@ func fixupDatasec(rawTypes []rawType, rawStrings stringTable, sectionSizes map[s
|
||||
return err
|
||||
}
|
||||
|
||||
if name == ".kconfig" || name == ".ksym" {
|
||||
if name == ".kconfig" || name == ".ksyms" {
|
||||
return fmt.Errorf("reference to %s: %w", name, ErrNotSupported)
|
||||
}
|
||||
|
||||
if rawTypes[i].SizeType != 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
size, ok := sectionSizes[name]
|
||||
if !ok {
|
||||
return fmt.Errorf("data section %s: missing size", name)
|
||||
@ -421,64 +432,19 @@ func (s *Spec) Program(name string, length uint64) (*Program, error) {
|
||||
return nil, errors.New("length musn't be zero")
|
||||
}
|
||||
|
||||
if s.funcInfos == nil && s.lineInfos == nil {
|
||||
if s.funcInfos == nil && s.lineInfos == nil && s.coreRelos == nil {
|
||||
return nil, fmt.Errorf("BTF for section %s: %w", name, ErrNoExtendedInfo)
|
||||
}
|
||||
|
||||
funcInfos, funcOK := s.funcInfos[name]
|
||||
lineInfos, lineOK := s.lineInfos[name]
|
||||
coreRelos, coreOK := s.coreRelos[name]
|
||||
|
||||
if !funcOK && !lineOK {
|
||||
if !funcOK && !lineOK && !coreOK {
|
||||
return nil, fmt.Errorf("no extended BTF info for section %s", name)
|
||||
}
|
||||
|
||||
return &Program{s, length, funcInfos, lineInfos}, nil
|
||||
}
|
||||
|
||||
// Map finds the BTF for a map.
|
||||
//
|
||||
// Returns an error if there is no BTF for the given name.
|
||||
func (s *Spec) Map(name string) (*Map, []Member, error) {
|
||||
var mapVar Var
|
||||
if err := s.FindType(name, &mapVar); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
mapStruct, ok := mapVar.Type.(*Struct)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("expected struct, have %s", mapVar.Type)
|
||||
}
|
||||
|
||||
var key, value Type
|
||||
for _, member := range mapStruct.Members {
|
||||
switch member.Name {
|
||||
case "key":
|
||||
key = member.Type
|
||||
if pk, isPtr := key.(*Pointer); !isPtr {
|
||||
return nil, nil, fmt.Errorf("key type is not a pointer: %T", key)
|
||||
} else {
|
||||
key = pk.Target
|
||||
}
|
||||
|
||||
case "value":
|
||||
value = member.Type
|
||||
if vk, isPtr := value.(*Pointer); !isPtr {
|
||||
return nil, nil, fmt.Errorf("value type is not a pointer: %T", value)
|
||||
} else {
|
||||
value = vk.Target
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if key == nil {
|
||||
key = (*Void)(nil)
|
||||
}
|
||||
|
||||
if value == nil {
|
||||
value = (*Void)(nil)
|
||||
}
|
||||
|
||||
return &Map{s, key, value}, mapStruct.Members, nil
|
||||
return &Program{s, length, funcInfos, lineInfos, coreRelos}, nil
|
||||
}
|
||||
|
||||
// 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 &Map{s, &Void{}, &datasec}, nil
|
||||
m := NewMap(s, &Void{}, &datasec)
|
||||
return &m, nil
|
||||
}
|
||||
|
||||
// FindType searches for a type with a specific name.
|
||||
@ -503,7 +470,7 @@ func (s *Spec) FindType(name string, typ Type) error {
|
||||
candidate Type
|
||||
)
|
||||
|
||||
for _, typ := range s.types[essentialName(name)] {
|
||||
for _, typ := range s.namedTypes[essentialName(name)] {
|
||||
if reflect.TypeOf(typ) != wanted {
|
||||
continue
|
||||
}
|
||||
@ -599,6 +566,23 @@ type Map struct {
|
||||
key, value Type
|
||||
}
|
||||
|
||||
// NewMap returns a new Map containing the given values.
|
||||
// The key and value arguments are initialized to Void if nil values are given.
|
||||
func NewMap(spec *Spec, key Type, value Type) Map {
|
||||
if key == nil {
|
||||
key = &Void{}
|
||||
}
|
||||
if value == nil {
|
||||
value = &Void{}
|
||||
}
|
||||
|
||||
return Map{
|
||||
spec: spec,
|
||||
key: key,
|
||||
value: value,
|
||||
}
|
||||
}
|
||||
|
||||
// MapSpec should be a method on Map, but is a free function
|
||||
// to hide it from users of the ebpf package.
|
||||
func MapSpec(m *Map) *Spec {
|
||||
@ -622,6 +606,7 @@ type Program struct {
|
||||
spec *Spec
|
||||
length uint64
|
||||
funcInfos, lineInfos extInfo
|
||||
coreRelos bpfCoreRelos
|
||||
}
|
||||
|
||||
// ProgramSpec returns the Spec needed for loading function and line infos into the kernel.
|
||||
@ -647,9 +632,10 @@ func ProgramAppend(s, other *Program) error {
|
||||
return fmt.Errorf("line infos: %w", err)
|
||||
}
|
||||
|
||||
s.length += other.length
|
||||
s.funcInfos = funcInfos
|
||||
s.lineInfos = lineInfos
|
||||
s.coreRelos = s.coreRelos.append(other.coreRelos, s.length)
|
||||
s.length += other.length
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -679,6 +665,19 @@ func ProgramLineInfos(s *Program) (recordSize uint32, bytes []byte, err error) {
|
||||
return s.lineInfos.recordSize, bytes, nil
|
||||
}
|
||||
|
||||
// ProgramRelocations returns the CO-RE relocations required to adjust the
|
||||
// program to the target.
|
||||
//
|
||||
// This is a free function instead of a method to hide it from users
|
||||
// of package ebpf.
|
||||
func ProgramRelocations(s *Program, target *Spec) (map[uint64]Relocation, error) {
|
||||
if len(s.coreRelos) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return coreRelocate(s.spec, target, s.coreRelos)
|
||||
}
|
||||
|
||||
type bpfLoadBTFAttr struct {
|
||||
btf internal.Pointer
|
||||
logBuf internal.Pointer
|
||||
@ -718,7 +717,7 @@ func marshalBTF(types interface{}, strings []byte, bo binary.ByteOrder) []byte {
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
var haveBTF = internal.FeatureTest("BTF", "5.1", func() (bool, error) {
|
||||
var haveBTF = internal.FeatureTest("BTF", "5.1", func() error {
|
||||
var (
|
||||
types struct {
|
||||
Integer btfType
|
||||
@ -742,15 +741,24 @@ var haveBTF = internal.FeatureTest("BTF", "5.1", func() (bool, error) {
|
||||
btf: internal.NewSlicePointer(btf),
|
||||
btfSize: uint32(len(btf)),
|
||||
})
|
||||
if err == nil {
|
||||
fd.Close()
|
||||
if errors.Is(err, unix.EINVAL) || errors.Is(err, unix.EPERM) {
|
||||
// Treat both EINVAL and EPERM as not supported: loading the program
|
||||
// might still succeed without BTF.
|
||||
return internal.ErrNotSupported
|
||||
}
|
||||
// Check for EINVAL specifically, rather than err != nil since we
|
||||
// otherwise misdetect due to insufficient permissions.
|
||||
return !errors.Is(err, unix.EINVAL), nil
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
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 (
|
||||
types struct {
|
||||
FuncProto btfType
|
||||
@ -771,11 +779,13 @@ var haveFuncLinkage = internal.FeatureTest("BTF func linkage", "5.6", func() (bo
|
||||
btf: internal.NewSlicePointer(btf),
|
||||
btfSize: uint32(len(btf)),
|
||||
})
|
||||
if err == nil {
|
||||
fd.Close()
|
||||
if errors.Is(err, unix.EINVAL) {
|
||||
return internal.ErrNotSupported
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Check for EINVAL specifically, rather than err != nil since we
|
||||
// otherwise misdetect due to insufficient permissions.
|
||||
return !errors.Is(err, unix.EINVAL), nil
|
||||
fd.Close()
|
||||
return 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
|
||||
}
|
||||
|
||||
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 coreHeader btfExtCoreHeader
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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))
|
||||
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
|
||||
// .BTF ext header. We need to ignore non-null values.
|
||||
_, err = io.CopyN(ioutil.Discard, r, remainder)
|
||||
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 {
|
||||
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)))
|
||||
funcInfo, err = parseExtInfo(buf, bo, strings)
|
||||
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 {
|
||||
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)))
|
||||
lineInfo, err = parseExtInfo(buf, bo, strings)
|
||||
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 {
|
||||
@ -147,20 +172,9 @@ func parseExtInfo(r io.Reader, bo binary.ByteOrder, strings stringTable) (map[st
|
||||
|
||||
result := make(map[string]extInfo)
|
||||
for {
|
||||
var infoHeader btfExtInfoSec
|
||||
if err := binary.Read(r, bo, &infoHeader); err == io.EOF {
|
||||
secName, infoHeader, err := parseExtInfoHeader(r, bo, strings)
|
||||
if errors.Is(err, io.EOF) {
|
||||
return result, nil
|
||||
} else if err != nil {
|
||||
return nil, fmt.Errorf("can't read ext info header: %v", err)
|
||||
}
|
||||
|
||||
secName, err := strings.Lookup(infoHeader.SecNameOff)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't get section name: %w", err)
|
||||
}
|
||||
|
||||
if infoHeader.NumInfo == 0 {
|
||||
return nil, fmt.Errorf("section %s has invalid number of records", secName)
|
||||
}
|
||||
|
||||
var records []extInfoRecord
|
||||
@ -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
|
||||
}
|
||||
|
271
vendor/github.com/cilium/ebpf/internal/btf/types.go
generated
vendored
271
vendor/github.com/cilium/ebpf/internal/btf/types.go
generated
vendored
@ -21,12 +21,14 @@ func (tid TypeID) ID() TypeID {
|
||||
type Type interface {
|
||||
ID() TypeID
|
||||
|
||||
String() string
|
||||
|
||||
// Make a copy of the type, without copying Type members.
|
||||
copy() Type
|
||||
|
||||
// Enumerate all nested Types. Repeated calls must visit nested
|
||||
// types in the same order.
|
||||
walk(*copyStack)
|
||||
walk(*typeDeque)
|
||||
}
|
||||
|
||||
// namedType is a type with a name.
|
||||
@ -50,9 +52,10 @@ func (n Name) name() string {
|
||||
type Void struct{}
|
||||
|
||||
func (v *Void) ID() TypeID { return 0 }
|
||||
func (v *Void) String() string { return "void#0" }
|
||||
func (v *Void) size() uint32 { return 0 }
|
||||
func (v *Void) copy() Type { return (*Void)(nil) }
|
||||
func (v *Void) walk(*copyStack) {}
|
||||
func (v *Void) walk(*typeDeque) {}
|
||||
|
||||
type IntEncoding byte
|
||||
|
||||
@ -78,21 +81,54 @@ type Int struct {
|
||||
|
||||
var _ namedType = (*Int)(nil)
|
||||
|
||||
func (i *Int) String() string {
|
||||
var s strings.Builder
|
||||
|
||||
switch {
|
||||
case i.Encoding&Char != 0:
|
||||
s.WriteString("char")
|
||||
case i.Encoding&Bool != 0:
|
||||
s.WriteString("bool")
|
||||
default:
|
||||
if i.Encoding&Signed == 0 {
|
||||
s.WriteRune('u')
|
||||
}
|
||||
s.WriteString("int")
|
||||
fmt.Fprintf(&s, "%d", i.Size*8)
|
||||
}
|
||||
|
||||
fmt.Fprintf(&s, "#%d", i.TypeID)
|
||||
|
||||
if i.Bits > 0 {
|
||||
fmt.Fprintf(&s, "[bits=%d]", i.Bits)
|
||||
}
|
||||
|
||||
return s.String()
|
||||
}
|
||||
|
||||
func (i *Int) size() uint32 { return i.Size }
|
||||
func (i *Int) walk(*copyStack) {}
|
||||
func (i *Int) walk(*typeDeque) {}
|
||||
func (i *Int) copy() Type {
|
||||
cpy := *i
|
||||
return &cpy
|
||||
}
|
||||
|
||||
func (i *Int) isBitfield() bool {
|
||||
return i.Offset > 0
|
||||
}
|
||||
|
||||
// Pointer is a pointer to another type.
|
||||
type Pointer struct {
|
||||
TypeID
|
||||
Target Type
|
||||
}
|
||||
|
||||
func (p *Pointer) String() string {
|
||||
return fmt.Sprintf("pointer#%d[target=#%d]", p.TypeID, p.Target.ID())
|
||||
}
|
||||
|
||||
func (p *Pointer) size() uint32 { return 8 }
|
||||
func (p *Pointer) walk(cs *copyStack) { cs.push(&p.Target) }
|
||||
func (p *Pointer) walk(tdq *typeDeque) { tdq.push(&p.Target) }
|
||||
func (p *Pointer) copy() Type {
|
||||
cpy := *p
|
||||
return &cpy
|
||||
@ -105,7 +141,11 @@ type Array struct {
|
||||
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 {
|
||||
cpy := *arr
|
||||
return &cpy
|
||||
@ -120,11 +160,15 @@ type Struct struct {
|
||||
Members []Member
|
||||
}
|
||||
|
||||
func (s *Struct) String() string {
|
||||
return fmt.Sprintf("struct#%d[%q]", s.TypeID, s.Name)
|
||||
}
|
||||
|
||||
func (s *Struct) size() uint32 { return s.Size }
|
||||
|
||||
func (s *Struct) walk(cs *copyStack) {
|
||||
func (s *Struct) walk(tdq *typeDeque) {
|
||||
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
|
||||
}
|
||||
|
||||
func (u *Union) String() string {
|
||||
return fmt.Sprintf("union#%d[%q]", u.TypeID, u.Name)
|
||||
}
|
||||
|
||||
func (u *Union) size() uint32 { return u.Size }
|
||||
|
||||
func (u *Union) walk(cs *copyStack) {
|
||||
func (u *Union) walk(tdq *typeDeque) {
|
||||
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
|
||||
}
|
||||
|
||||
func (e *Enum) String() string {
|
||||
return fmt.Sprintf("enum#%d[%q]", e.TypeID, e.Name)
|
||||
}
|
||||
|
||||
// EnumValue is part of an Enum
|
||||
//
|
||||
// Is is not a valid Type
|
||||
@ -203,7 +255,7 @@ type EnumValue struct {
|
||||
}
|
||||
|
||||
func (e *Enum) size() uint32 { return 4 }
|
||||
func (e *Enum) walk(*copyStack) {}
|
||||
func (e *Enum) walk(*typeDeque) {}
|
||||
func (e *Enum) copy() Type {
|
||||
cpy := *e
|
||||
cpy.Values = make([]EnumValue, len(e.Values))
|
||||
@ -211,13 +263,38 @@ func (e *Enum) copy() Type {
|
||||
return &cpy
|
||||
}
|
||||
|
||||
// FwdKind is the type of forward declaration.
|
||||
type FwdKind int
|
||||
|
||||
// Valid types of forward declaration.
|
||||
const (
|
||||
FwdStruct FwdKind = iota
|
||||
FwdUnion
|
||||
)
|
||||
|
||||
func (fk FwdKind) String() string {
|
||||
switch fk {
|
||||
case FwdStruct:
|
||||
return "struct"
|
||||
case FwdUnion:
|
||||
return "union"
|
||||
default:
|
||||
return fmt.Sprintf("%T(%d)", fk, int(fk))
|
||||
}
|
||||
}
|
||||
|
||||
// Fwd is a forward declaration of a Type.
|
||||
type Fwd struct {
|
||||
TypeID
|
||||
Name
|
||||
Kind FwdKind
|
||||
}
|
||||
|
||||
func (f *Fwd) 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 {
|
||||
cpy := *f
|
||||
return &cpy
|
||||
@ -230,7 +307,11 @@ type Typedef struct {
|
||||
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 {
|
||||
cpy := *td
|
||||
return &cpy
|
||||
@ -242,8 +323,12 @@ type Volatile struct {
|
||||
Type Type
|
||||
}
|
||||
|
||||
func (v *Volatile) String() string {
|
||||
return fmt.Sprintf("volatile#%d[#%d]", v.TypeID, v.Type.ID())
|
||||
}
|
||||
|
||||
func (v *Volatile) qualify() Type { return v.Type }
|
||||
func (v *Volatile) walk(cs *copyStack) { cs.push(&v.Type) }
|
||||
func (v *Volatile) walk(tdq *typeDeque) { tdq.push(&v.Type) }
|
||||
func (v *Volatile) copy() Type {
|
||||
cpy := *v
|
||||
return &cpy
|
||||
@ -255,8 +340,12 @@ type Const struct {
|
||||
Type Type
|
||||
}
|
||||
|
||||
func (c *Const) String() string {
|
||||
return fmt.Sprintf("const#%d[#%d]", c.TypeID, c.Type.ID())
|
||||
}
|
||||
|
||||
func (c *Const) qualify() Type { return c.Type }
|
||||
func (c *Const) walk(cs *copyStack) { cs.push(&c.Type) }
|
||||
func (c *Const) walk(tdq *typeDeque) { tdq.push(&c.Type) }
|
||||
func (c *Const) copy() Type {
|
||||
cpy := *c
|
||||
return &cpy
|
||||
@ -268,8 +357,12 @@ type Restrict struct {
|
||||
Type Type
|
||||
}
|
||||
|
||||
func (r *Restrict) String() string {
|
||||
return fmt.Sprintf("restrict#%d[#%d]", r.TypeID, r.Type.ID())
|
||||
}
|
||||
|
||||
func (r *Restrict) qualify() Type { return r.Type }
|
||||
func (r *Restrict) walk(cs *copyStack) { cs.push(&r.Type) }
|
||||
func (r *Restrict) walk(tdq *typeDeque) { tdq.push(&r.Type) }
|
||||
func (r *Restrict) copy() Type {
|
||||
cpy := *r
|
||||
return &cpy
|
||||
@ -282,7 +375,11 @@ type Func struct {
|
||||
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 {
|
||||
cpy := *f
|
||||
return &cpy
|
||||
@ -295,10 +392,20 @@ type FuncProto struct {
|
||||
Params []FuncParam
|
||||
}
|
||||
|
||||
func (fp *FuncProto) walk(cs *copyStack) {
|
||||
cs.push(&fp.Return)
|
||||
func (fp *FuncProto) String() string {
|
||||
var s strings.Builder
|
||||
fmt.Fprintf(&s, "proto#%d[", fp.TypeID)
|
||||
for _, param := range fp.Params {
|
||||
fmt.Fprintf(&s, "%q=#%d, ", param.Name, param.Type.ID())
|
||||
}
|
||||
fmt.Fprintf(&s, "return=#%d]", fp.Return.ID())
|
||||
return s.String()
|
||||
}
|
||||
|
||||
func (fp *FuncProto) walk(tdq *typeDeque) {
|
||||
tdq.push(&fp.Return)
|
||||
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
|
||||
}
|
||||
|
||||
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 {
|
||||
cpy := *v
|
||||
return &cpy
|
||||
@ -335,11 +447,15 @@ type Datasec struct {
|
||||
Vars []VarSecinfo
|
||||
}
|
||||
|
||||
func (ds *Datasec) String() string {
|
||||
return fmt.Sprintf("section#%d[%q]", ds.TypeID, ds.Name)
|
||||
}
|
||||
|
||||
func (ds *Datasec) size() uint32 { return ds.Size }
|
||||
|
||||
func (ds *Datasec) walk(cs *copyStack) {
|
||||
func (ds *Datasec) walk(tdq *typeDeque) {
|
||||
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
|
||||
//
|
||||
// It is not a valid Type.
|
||||
type VarSecinfo struct {
|
||||
Type Type
|
||||
Offset uint32
|
||||
@ -438,7 +556,7 @@ func Sizeof(typ Type) (int, error) {
|
||||
func copyType(typ Type) Type {
|
||||
var (
|
||||
copies = make(map[Type]Type)
|
||||
work copyStack
|
||||
work typeDeque
|
||||
)
|
||||
|
||||
for t := &typ; t != nil; t = work.pop() {
|
||||
@ -459,34 +577,83 @@ func copyType(typ Type) Type {
|
||||
return typ
|
||||
}
|
||||
|
||||
// copyStack keeps track of pointers to types which still
|
||||
// typeDeque keeps track of pointers to types which still
|
||||
// need to be visited.
|
||||
type copyStack []*Type
|
||||
|
||||
// push adds a type to the stack.
|
||||
func (cs *copyStack) push(t *Type) {
|
||||
*cs = append(*cs, t)
|
||||
type typeDeque struct {
|
||||
types []*Type
|
||||
read, write uint64
|
||||
mask uint64
|
||||
}
|
||||
|
||||
// pop returns the topmost Type, or nil.
|
||||
func (cs *copyStack) pop() *Type {
|
||||
n := len(*cs)
|
||||
if n == 0 {
|
||||
// push adds a type to the stack.
|
||||
func (dq *typeDeque) push(t *Type) {
|
||||
if dq.write-dq.read < uint64(len(dq.types)) {
|
||||
dq.types[dq.write&dq.mask] = t
|
||||
dq.write++
|
||||
return
|
||||
}
|
||||
|
||||
new := len(dq.types) * 2
|
||||
if new == 0 {
|
||||
new = 8
|
||||
}
|
||||
|
||||
types := make([]*Type, new)
|
||||
pivot := dq.read & dq.mask
|
||||
n := copy(types, dq.types[pivot:])
|
||||
n += copy(types[n:], dq.types[:pivot])
|
||||
types[n] = t
|
||||
|
||||
dq.types = types
|
||||
dq.mask = uint64(new) - 1
|
||||
dq.read, dq.write = 0, uint64(n+1)
|
||||
}
|
||||
|
||||
// shift returns the first element or null.
|
||||
func (dq *typeDeque) shift() *Type {
|
||||
if dq.read == dq.write {
|
||||
return nil
|
||||
}
|
||||
|
||||
t := (*cs)[n-1]
|
||||
*cs = (*cs)[:n-1]
|
||||
index := dq.read & dq.mask
|
||||
t := dq.types[index]
|
||||
dq.types[index] = nil
|
||||
dq.read++
|
||||
return t
|
||||
}
|
||||
|
||||
// pop returns the last element or null.
|
||||
func (dq *typeDeque) pop() *Type {
|
||||
if dq.read == dq.write {
|
||||
return nil
|
||||
}
|
||||
|
||||
dq.write--
|
||||
index := dq.write & dq.mask
|
||||
t := dq.types[index]
|
||||
dq.types[index] = nil
|
||||
return t
|
||||
}
|
||||
|
||||
// all returns all elements.
|
||||
//
|
||||
// The deque is empty after calling this method.
|
||||
func (dq *typeDeque) all() []*Type {
|
||||
length := dq.write - dq.read
|
||||
types := make([]*Type, 0, length)
|
||||
for t := dq.shift(); t != nil; t = dq.shift() {
|
||||
types = append(types, t)
|
||||
}
|
||||
return types
|
||||
}
|
||||
|
||||
// inflateRawTypes takes a list of raw btf types linked via type IDs, and turns
|
||||
// it into a graph of Types connected via pointers.
|
||||
//
|
||||
// Returns a map of named types (so, where NameOff is non-zero). Since BTF ignores
|
||||
// compilation units, multiple types may share the same name. A Type may form a
|
||||
// cyclic graph by pointing at itself.
|
||||
func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (namedTypes map[string][]namedType, err error) {
|
||||
// Returns a map of named types (so, where NameOff is non-zero) and a slice of types
|
||||
// indexed by TypeID. Since BTF ignores compilation units, multiple types may share
|
||||
// the same name. A Type may form a cyclic graph by pointing at itself.
|
||||
func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (types []Type, namedTypes map[string][]namedType, err error) {
|
||||
type fixupDef struct {
|
||||
id TypeID
|
||||
expectedKind btfKind
|
||||
@ -523,7 +690,7 @@ func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (namedTypes map
|
||||
return members, nil
|
||||
}
|
||||
|
||||
types := make([]Type, 0, len(rawTypes))
|
||||
types = make([]Type, 0, len(rawTypes))
|
||||
types = append(types, (*Void)(nil))
|
||||
namedTypes = make(map[string][]namedType)
|
||||
|
||||
@ -537,7 +704,7 @@ func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (namedTypes map
|
||||
|
||||
name, err := rawStrings.LookupName(raw.NameOff)
|
||||
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() {
|
||||
@ -562,14 +729,14 @@ func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (namedTypes map
|
||||
case kindStruct:
|
||||
members, err := convertMembers(raw.data.([]btfMember), raw.KindFlag())
|
||||
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}
|
||||
|
||||
case kindUnion:
|
||||
members, err := convertMembers(raw.data.([]btfMember), raw.KindFlag())
|
||||
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}
|
||||
|
||||
@ -579,7 +746,7 @@ func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (namedTypes map
|
||||
for i, btfVal := range rawvals {
|
||||
name, err := rawStrings.LookupName(btfVal.NameOff)
|
||||
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{
|
||||
Name: name,
|
||||
@ -589,7 +756,11 @@ func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (namedTypes map
|
||||
typ = &Enum{id, name, vals}
|
||||
|
||||
case kindForward:
|
||||
typ = &Fwd{id, name}
|
||||
if raw.KindFlag() {
|
||||
typ = &Fwd{id, name, FwdUnion}
|
||||
} else {
|
||||
typ = &Fwd{id, name, FwdStruct}
|
||||
}
|
||||
|
||||
case kindTypedef:
|
||||
typedef := &Typedef{id, name, nil}
|
||||
@ -622,7 +793,7 @@ func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (namedTypes map
|
||||
for i, param := range rawparams {
|
||||
name, err := rawStrings.LookupName(param.NameOff)
|
||||
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{
|
||||
Name: name,
|
||||
@ -656,7 +827,7 @@ func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (namedTypes map
|
||||
typ = &Datasec{id, name, raw.SizeType, vars}
|
||||
|
||||
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)
|
||||
@ -671,7 +842,7 @@ func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (namedTypes map
|
||||
for _, fixup := range fixups {
|
||||
i := int(fixup.id)
|
||||
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
|
||||
@ -681,13 +852,13 @@ func inflateRawTypes(rawTypes []rawType, rawStrings stringTable) (namedTypes map
|
||||
}
|
||||
|
||||
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]
|
||||
}
|
||||
|
||||
return namedTypes, nil
|
||||
return types, namedTypes, nil
|
||||
}
|
||||
|
||||
// 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 {
|
||||
sync.Mutex
|
||||
sync.RWMutex
|
||||
successful bool
|
||||
result error
|
||||
}
|
||||
@ -42,10 +42,10 @@ type featureTest struct {
|
||||
//
|
||||
// The return values have the following semantics:
|
||||
//
|
||||
// err == ErrNotSupported: the feature is not available
|
||||
// err == nil: the feature is available
|
||||
// err != nil: the test couldn't be executed
|
||||
// err == nil && available: the feature is available
|
||||
// err == nil && !available: the feature isn't available
|
||||
type FeatureTestFn func() (available bool, err error)
|
||||
type FeatureTestFn func() error
|
||||
|
||||
// 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)
|
||||
return func() error {
|
||||
ft.RLock()
|
||||
if ft.successful {
|
||||
defer ft.RUnlock()
|
||||
return ft.result
|
||||
}
|
||||
ft.RUnlock()
|
||||
ft.Lock()
|
||||
defer ft.Unlock()
|
||||
|
||||
// check one more time on the off
|
||||
// chance that two go routines
|
||||
// were able to call into the write
|
||||
// lock
|
||||
if ft.successful {
|
||||
return ft.result
|
||||
}
|
||||
|
||||
available, err := fn()
|
||||
if errors.Is(err, ErrNotSupported) {
|
||||
// The feature test aborted because a dependent feature
|
||||
// is missing, which we should cache.
|
||||
available = false
|
||||
} else if err != nil {
|
||||
// We couldn't execute the feature test to a point
|
||||
// where it could make a determination.
|
||||
// Don't cache the result, just return it.
|
||||
return fmt.Errorf("can't detect support for %s: %w", name, err)
|
||||
}
|
||||
|
||||
ft.successful = true
|
||||
if !available {
|
||||
err := fn()
|
||||
switch {
|
||||
case errors.Is(err, ErrNotSupported):
|
||||
ft.result = &UnsupportedFeatureError{
|
||||
MinimumVersion: v,
|
||||
Name: name,
|
||||
}
|
||||
fallthrough
|
||||
|
||||
case err == nil:
|
||||
ft.successful = true
|
||||
|
||||
default:
|
||||
// We couldn't execute the feature test to a point
|
||||
// where it could make a determination.
|
||||
// Don't cache the result, just return it.
|
||||
return fmt.Errorf("detect support for %s: %w", name, err)
|
||||
}
|
||||
|
||||
return ft.result
|
||||
}
|
||||
}
|
||||
|
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
|
||||
}
|
||||
|
||||
type BPFEnableStatsAttr struct {
|
||||
StatsType uint32
|
||||
}
|
||||
|
||||
func BPFEnableStats(attr *BPFEnableStatsAttr) (*FD, error) {
|
||||
ptr, err := BPF(BPF_ENABLE_STATS, unsafe.Pointer(attr), unsafe.Sizeof(*attr))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("enable stats: %w", err)
|
||||
}
|
||||
return NewFD(uint32(ptr)), nil
|
||||
|
||||
}
|
||||
|
||||
type bpfObjAttr struct {
|
||||
fileName Pointer
|
||||
fd uint32
|
||||
|
6
vendor/github.com/cilium/ebpf/internal/unix/types_linux.go
generated
vendored
6
vendor/github.com/cilium/ebpf/internal/unix/types_linux.go
generated
vendored
@ -20,6 +20,11 @@ const (
|
||||
EPERM = linux.EPERM
|
||||
ESRCH = linux.ESRCH
|
||||
ENODEV = linux.ENODEV
|
||||
// ENOTSUPP is not the same as ENOTSUP or EOPNOTSUP
|
||||
ENOTSUPP = syscall.Errno(0x20c)
|
||||
|
||||
EBADF = linux.EBADF
|
||||
BPF_F_NO_PREALLOC = linux.BPF_F_NO_PREALLOC
|
||||
BPF_F_NUMA_NODE = linux.BPF_F_NUMA_NODE
|
||||
BPF_F_RDONLY_PROG = linux.BPF_F_RDONLY_PROG
|
||||
BPF_F_WRONLY_PROG = linux.BPF_F_WRONLY_PROG
|
||||
@ -41,6 +46,7 @@ const (
|
||||
PERF_FLAG_FD_CLOEXEC = linux.PERF_FLAG_FD_CLOEXEC
|
||||
RLIM_INFINITY = linux.RLIM_INFINITY
|
||||
RLIMIT_MEMLOCK = linux.RLIMIT_MEMLOCK
|
||||
BPF_STATS_RUN_TIME = linux.BPF_STATS_RUN_TIME
|
||||
)
|
||||
|
||||
// Statfs_t is a wrapper
|
||||
|
6
vendor/github.com/cilium/ebpf/internal/unix/types_other.go
generated
vendored
6
vendor/github.com/cilium/ebpf/internal/unix/types_other.go
generated
vendored
@ -20,6 +20,11 @@ const (
|
||||
EPERM = syscall.EPERM
|
||||
ESRCH = syscall.ESRCH
|
||||
ENODEV = syscall.ENODEV
|
||||
EBADF = syscall.Errno(0)
|
||||
// ENOTSUPP is not the same as ENOTSUP or EOPNOTSUP
|
||||
ENOTSUPP = syscall.Errno(0x20c)
|
||||
|
||||
BPF_F_NO_PREALLOC = 0
|
||||
BPF_F_NUMA_NODE = 0
|
||||
BPF_F_RDONLY_PROG = 0
|
||||
BPF_F_WRONLY_PROG = 0
|
||||
@ -42,6 +47,7 @@ const (
|
||||
PERF_FLAG_FD_CLOEXEC = 0x8
|
||||
RLIM_INFINITY = 0x7fffffffffffffff
|
||||
RLIMIT_MEMLOCK = 8
|
||||
BPF_STATS_RUN_TIME = 0
|
||||
)
|
||||
|
||||
// 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
|
||||
callOffset, ok := symbolOffsets[ins.Reference]
|
||||
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)
|
||||
@ -122,7 +122,7 @@ func fixupJumpsAndCalls(insns asm.Instructions) error {
|
||||
// Rewrite jump to label
|
||||
jumpOffset, ok := symbolOffsets[ins.Reference]
|
||||
if !ok {
|
||||
return fmt.Errorf("instruction %d: reference to missing symbol %s", i, ins.Reference)
|
||||
return fmt.Errorf("instruction %d: reference to missing symbol %q", i, ins.Reference)
|
||||
}
|
||||
|
||||
ins.Offset = int16(jumpOffset - offset - 1)
|
||||
|
602
vendor/github.com/cilium/ebpf/map.go
generated
vendored
602
vendor/github.com/cilium/ebpf/map.go
generated
vendored
@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/cilium/ebpf/internal"
|
||||
@ -90,20 +91,20 @@ type MapKV struct {
|
||||
|
||||
func (ms *MapSpec) checkCompatibility(m *Map) error {
|
||||
switch {
|
||||
case m.abi.Type != ms.Type:
|
||||
return fmt.Errorf("expected type %v, got %v", ms.Type, m.abi.Type)
|
||||
case m.typ != ms.Type:
|
||||
return fmt.Errorf("expected type %v, got %v", ms.Type, m.typ)
|
||||
|
||||
case m.abi.KeySize != ms.KeySize:
|
||||
return fmt.Errorf("expected key size %v, got %v", ms.KeySize, m.abi.KeySize)
|
||||
case m.keySize != ms.KeySize:
|
||||
return fmt.Errorf("expected key size %v, got %v", ms.KeySize, m.keySize)
|
||||
|
||||
case m.abi.ValueSize != ms.ValueSize:
|
||||
return fmt.Errorf("expected value size %v, got %v", ms.ValueSize, m.abi.ValueSize)
|
||||
case m.valueSize != ms.ValueSize:
|
||||
return fmt.Errorf("expected value size %v, got %v", ms.ValueSize, m.valueSize)
|
||||
|
||||
case m.abi.MaxEntries != ms.MaxEntries:
|
||||
return fmt.Errorf("expected max entries %v, got %v", ms.MaxEntries, m.abi.MaxEntries)
|
||||
case m.maxEntries != ms.MaxEntries:
|
||||
return fmt.Errorf("expected max entries %v, got %v", ms.MaxEntries, m.maxEntries)
|
||||
|
||||
case m.abi.Flags != ms.Flags:
|
||||
return fmt.Errorf("expected flags %v, got %v", ms.Flags, m.abi.Flags)
|
||||
case m.flags != ms.Flags:
|
||||
return fmt.Errorf("expected flags %v, got %v", ms.Flags, m.flags)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -120,7 +121,12 @@ func (ms *MapSpec) checkCompatibility(m *Map) error {
|
||||
type Map struct {
|
||||
name string
|
||||
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
|
||||
fullValueSize int
|
||||
}
|
||||
@ -132,14 +138,18 @@ func NewMapFromFD(fd int) (*Map, error) {
|
||||
if fd < 0 {
|
||||
return nil, errors.New("invalid fd")
|
||||
}
|
||||
bpfFd := internal.NewFD(uint32(fd))
|
||||
|
||||
name, abi, err := newMapABIFromFd(bpfFd)
|
||||
if err != nil {
|
||||
bpfFd.Forget()
|
||||
return nil, err
|
||||
return newMapFromFD(internal.NewFD(uint32(fd)))
|
||||
}
|
||||
return newMap(bpfFd, name, abi)
|
||||
|
||||
func newMapFromFD(fd *internal.FD) (*Map, error) {
|
||||
info, err := newMapInfoFromFd(fd)
|
||||
if err != nil {
|
||||
fd.Close()
|
||||
return nil, fmt.Errorf("get map info: %s", err)
|
||||
}
|
||||
|
||||
return newMap(fd, info.Name, info.Type, info.KeySize, info.ValueSize, info.MaxEntries, info.Flags)
|
||||
}
|
||||
|
||||
// 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
|
||||
// by calling unix.Setrlimit with unix.RLIMIT_MEMLOCK prior to calling NewMapWithOptions.
|
||||
func NewMapWithOptions(spec *MapSpec, opts MapOptions) (*Map, error) {
|
||||
if spec.BTF == nil {
|
||||
return newMapWithBTF(spec, nil, opts)
|
||||
btfs := make(btfHandleCache)
|
||||
defer btfs.close()
|
||||
|
||||
return newMapWithOptions(spec, opts, btfs)
|
||||
}
|
||||
|
||||
handle, err := btf.NewHandle(btf.MapSpec(spec.BTF))
|
||||
if err != nil && !errors.Is(err, btf.ErrNotSupported) {
|
||||
return nil, fmt.Errorf("can't load BTF: %w", err)
|
||||
}
|
||||
|
||||
return newMapWithBTF(spec, handle, opts)
|
||||
}
|
||||
|
||||
func newMapWithBTF(spec *MapSpec, handle *btf.Handle, opts MapOptions) (*Map, error) {
|
||||
func newMapWithOptions(spec *MapSpec, opts MapOptions, btfs btfHandleCache) (*Map, error) {
|
||||
switch spec.Pinning {
|
||||
case PinByName:
|
||||
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)
|
||||
}
|
||||
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
@ -214,7 +222,7 @@ func newMapWithBTF(spec *MapSpec, handle *btf.Handle, opts MapOptions) (*Map, er
|
||||
innerFd = template.fd
|
||||
}
|
||||
|
||||
m, err := createMap(spec, innerFd, handle, opts)
|
||||
m, err := createMap(spec, innerFd, opts, btfs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -229,14 +237,14 @@ func newMapWithBTF(spec *MapSpec, handle *btf.Handle, opts MapOptions) (*Map, er
|
||||
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) {
|
||||
if err != nil {
|
||||
closer.Close()
|
||||
}
|
||||
}
|
||||
|
||||
abi := newMapABIFromSpec(spec)
|
||||
spec = spec.Copy()
|
||||
|
||||
switch spec.Type {
|
||||
case ArrayOfMaps:
|
||||
@ -246,43 +254,43 @@ func createMap(spec *MapSpec, inner *internal.FD, handle *btf.Handle, opts MapOp
|
||||
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")
|
||||
}
|
||||
abi.ValueSize = 4
|
||||
spec.ValueSize = 4
|
||||
|
||||
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")
|
||||
}
|
||||
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")
|
||||
}
|
||||
abi.ValueSize = 4
|
||||
spec.ValueSize = 4
|
||||
|
||||
if abi.MaxEntries == 0 {
|
||||
if spec.MaxEntries == 0 {
|
||||
n, err := internal.PossibleCPUs()
|
||||
if err != nil {
|
||||
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 {
|
||||
return nil, fmt.Errorf("map create: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
attr := bpfMapCreateAttr{
|
||||
mapType: abi.Type,
|
||||
keySize: abi.KeySize,
|
||||
valueSize: abi.ValueSize,
|
||||
maxEntries: abi.MaxEntries,
|
||||
flags: abi.Flags,
|
||||
mapType: spec.Type,
|
||||
keySize: spec.KeySize,
|
||||
valueSize: spec.ValueSize,
|
||||
maxEntries: spec.MaxEntries,
|
||||
flags: spec.Flags,
|
||||
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 {
|
||||
attr.mapName = newBPFObjName(spec.Name)
|
||||
}
|
||||
|
||||
var btfDisabled bool
|
||||
if spec.BTF != nil {
|
||||
handle, err := btfs.load(btf.MapSpec(spec.BTF))
|
||||
btfDisabled = errors.Is(err, btf.ErrNotSupported)
|
||||
if err != nil && !btfDisabled {
|
||||
return nil, fmt.Errorf("load BTF: %w", err)
|
||||
}
|
||||
|
||||
if handle != nil {
|
||||
attr.btfFd = uint32(handle.FD())
|
||||
attr.btfKeyTypeID = btf.MapKey(spec.BTF).ID()
|
||||
attr.btfValueTypeID = btf.MapValue(spec.BTF).ID()
|
||||
}
|
||||
}
|
||||
|
||||
fd, err := bpfMapCreate(&attr)
|
||||
if err != nil {
|
||||
if errors.Is(err, unix.EPERM) {
|
||||
return nil, fmt.Errorf("map create: RLIMIT_MEMLOCK may be too low: %w", err)
|
||||
}
|
||||
if btfDisabled {
|
||||
return nil, fmt.Errorf("map create without BTF: %w", err)
|
||||
}
|
||||
return nil, fmt.Errorf("map create: %w", err)
|
||||
}
|
||||
defer closeOnError(fd)
|
||||
|
||||
m, err := newMap(fd, spec.Name, abi)
|
||||
m, err := newMap(fd, spec.Name, spec.Type, spec.KeySize, spec.ValueSize, spec.MaxEntries, spec.Flags)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, fmt.Errorf("map create: %w", err)
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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{
|
||||
name,
|
||||
fd,
|
||||
*abi,
|
||||
int(abi.ValueSize),
|
||||
typ,
|
||||
keySize,
|
||||
valueSize,
|
||||
maxEntries,
|
||||
flags,
|
||||
"",
|
||||
int(valueSize),
|
||||
}
|
||||
|
||||
if !abi.Type.hasPerCPUValue() {
|
||||
if !typ.hasPerCPUValue() {
|
||||
return m, nil
|
||||
}
|
||||
|
||||
@ -345,47 +373,45 @@ func newMap(fd *internal.FD, name string, abi *MapABI) (*Map, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
m.fullValueSize = align(int(abi.ValueSize), 8) * possibleCPUs
|
||||
m.fullValueSize = align(int(valueSize), 8) * possibleCPUs
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (m *Map) String() string {
|
||||
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.
|
||||
func (m *Map) Type() MapType {
|
||||
return m.abi.Type
|
||||
return m.typ
|
||||
}
|
||||
|
||||
// KeySize returns the size of the map key in bytes.
|
||||
func (m *Map) KeySize() uint32 {
|
||||
return m.abi.KeySize
|
||||
return m.keySize
|
||||
}
|
||||
|
||||
// ValueSize returns the size of the map value in bytes.
|
||||
func (m *Map) ValueSize() uint32 {
|
||||
return m.abi.ValueSize
|
||||
return m.valueSize
|
||||
}
|
||||
|
||||
// MaxEntries returns the maximum number of elements the map can hold.
|
||||
func (m *Map) MaxEntries() uint32 {
|
||||
return m.abi.MaxEntries
|
||||
return m.maxEntries
|
||||
}
|
||||
|
||||
// Flags returns the flags of the map.
|
||||
func (m *Map) Flags() uint32 {
|
||||
return m.abi.Flags
|
||||
return m.flags
|
||||
}
|
||||
|
||||
// ABI gets the ABI of the Map.
|
||||
//
|
||||
// Deprecated: use Type, KeySize, ValueSize, MaxEntries and Flags instead.
|
||||
func (m *Map) ABI() MapABI {
|
||||
return m.abi
|
||||
// Info returns metadata about the map.
|
||||
func (m *Map) Info() (*MapInfo, error) {
|
||||
return newMapInfoFromFd(m.fd)
|
||||
}
|
||||
|
||||
// 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,
|
||||
// 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 {
|
||||
valuePtr, valueBytes := makeBuffer(valueOut, m.fullValueSize)
|
||||
|
||||
if err := m.lookup(key, valuePtr); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if valueBytes == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if m.abi.Type.hasPerCPUValue() {
|
||||
return unmarshalPerCPUValue(valueOut, int(m.abi.ValueSize), valueBytes)
|
||||
}
|
||||
|
||||
switch value := valueOut.(type) {
|
||||
case **Map:
|
||||
m, err := unmarshalMap(valueBytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
(*value).Close()
|
||||
*value = m
|
||||
return nil
|
||||
case *Map:
|
||||
return fmt.Errorf("can't unmarshal into %T, need %T", value, (**Map)(nil))
|
||||
case Map:
|
||||
return fmt.Errorf("can't unmarshal into %T, need %T", value, (**Map)(nil))
|
||||
|
||||
case **Program:
|
||||
p, err := unmarshalProgram(valueBytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
(*value).Close()
|
||||
*value = p
|
||||
return nil
|
||||
case *Program:
|
||||
return fmt.Errorf("can't unmarshal into %T, need %T", value, (**Program)(nil))
|
||||
case Program:
|
||||
return fmt.Errorf("can't unmarshal into %T, need %T", value, (**Program)(nil))
|
||||
|
||||
default:
|
||||
return unmarshalBytes(valueOut, valueBytes)
|
||||
}
|
||||
return m.unmarshalValue(valueOut, valueBytes)
|
||||
}
|
||||
|
||||
// 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 {
|
||||
valuePtr, valueBytes := makeBuffer(valueOut, m.fullValueSize)
|
||||
|
||||
keyPtr, err := marshalPtr(key, int(m.abi.KeySize))
|
||||
keyPtr, err := m.marshalKey(key)
|
||||
if err != nil {
|
||||
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 unmarshalBytes(valueOut, valueBytes)
|
||||
return m.unmarshalValue(valueOut, valueBytes)
|
||||
}
|
||||
|
||||
// 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 {
|
||||
keyPtr, err := marshalPtr(key, int(m.abi.KeySize))
|
||||
keyPtr, err := m.marshalKey(key)
|
||||
if err != nil {
|
||||
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.
|
||||
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 {
|
||||
return fmt.Errorf("can't marshal key: %w", err)
|
||||
}
|
||||
|
||||
var valuePtr internal.Pointer
|
||||
if m.abi.Type.hasPerCPUValue() {
|
||||
valuePtr, err = marshalPerCPUValue(value, int(m.abi.ValueSize))
|
||||
} else {
|
||||
valuePtr, err = marshalPtr(value, int(m.abi.ValueSize))
|
||||
}
|
||||
valuePtr, err := m.marshalValue(value)
|
||||
if err != nil {
|
||||
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.
|
||||
func (m *Map) Delete(key interface{}) error {
|
||||
keyPtr, err := marshalPtr(key, int(m.abi.KeySize))
|
||||
keyPtr, err := m.marshalKey(key)
|
||||
if err != nil {
|
||||
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.
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
|
||||
if nextKeyBytes == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := unmarshalBytes(nextKeyOut, nextKeyBytes); err != nil {
|
||||
if err := m.unmarshalKey(nextKeyOut, nextKeyBytes); err != nil {
|
||||
return fmt.Errorf("can't unmarshal next key: %w", err)
|
||||
}
|
||||
return nil
|
||||
@ -578,7 +555,7 @@ func (m *Map) NextKey(key, nextKeyOut interface{}) error {
|
||||
//
|
||||
// Returns nil if there are no more keys.
|
||||
func (m *Map) NextKeyBytes(key interface{}) ([]byte, error) {
|
||||
nextKey := make([]byte, m.abi.KeySize)
|
||||
nextKey := make([]byte, m.keySize)
|
||||
nextKeyPtr := internal.NewSlicePointer(nextKey)
|
||||
|
||||
err := m.nextKey(key, nextKeyPtr)
|
||||
@ -596,7 +573,7 @@ func (m *Map) nextKey(key interface{}, nextKeyOut internal.Pointer) error {
|
||||
)
|
||||
|
||||
if key != nil {
|
||||
keyPtr, err = marshalPtr(key, int(m.abi.KeySize))
|
||||
keyPtr, err = m.marshalKey(key)
|
||||
if err != nil {
|
||||
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
|
||||
}
|
||||
|
||||
// BatchLookup looks up many elements in a map at once.
|
||||
//
|
||||
// "keysOut" and "valuesOut" must be of type slice, a pointer
|
||||
// to a slice or buffer will not work.
|
||||
// "prevKey" is the key to start the batch lookup from, it will
|
||||
// *not* be included in the results. Use nil to start at the first key.
|
||||
//
|
||||
// ErrKeyNotExist is returned when the batch lookup has reached
|
||||
// the end of all possible results, even when partial results
|
||||
// are returned. It should be used to evaluate when lookup is "done".
|
||||
func (m *Map) BatchLookup(prevKey, nextKeyOut, keysOut, valuesOut interface{}, opts *BatchOptions) (int, error) {
|
||||
return m.batchLookup(internal.BPF_MAP_LOOKUP_BATCH, prevKey, nextKeyOut, keysOut, valuesOut, opts)
|
||||
}
|
||||
|
||||
// BatchLookupAndDelete looks up many elements in a map at once,
|
||||
//
|
||||
// It then deletes all those elements.
|
||||
// "keysOut" and "valuesOut" must be of type slice, a pointer
|
||||
// to a slice or buffer will not work.
|
||||
// "prevKey" is the key to start the batch lookup from, it will
|
||||
// *not* be included in the results. Use nil to start at the first key.
|
||||
//
|
||||
// ErrKeyNotExist is returned when the batch lookup has reached
|
||||
// the end of all possible results, even when partial results
|
||||
// are returned. It should be used to evaluate when lookup is "done".
|
||||
func (m *Map) BatchLookupAndDelete(prevKey, nextKeyOut, keysOut, valuesOut interface{}, opts *BatchOptions) (int, error) {
|
||||
return m.batchLookup(internal.BPF_MAP_LOOKUP_AND_DELETE_BATCH, prevKey, nextKeyOut, keysOut, valuesOut, opts)
|
||||
}
|
||||
|
||||
func (m *Map) batchLookup(cmd internal.BPFCmd, startKey, nextKeyOut, keysOut, valuesOut interface{}, opts *BatchOptions) (int, error) {
|
||||
if err := haveBatchAPI(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if m.typ.hasPerCPUValue() {
|
||||
return 0, ErrNotSupported
|
||||
}
|
||||
keysValue := reflect.ValueOf(keysOut)
|
||||
if keysValue.Kind() != reflect.Slice {
|
||||
return 0, fmt.Errorf("keys must be a slice")
|
||||
}
|
||||
valuesValue := reflect.ValueOf(valuesOut)
|
||||
if valuesValue.Kind() != reflect.Slice {
|
||||
return 0, fmt.Errorf("valuesOut must be a slice")
|
||||
}
|
||||
count := keysValue.Len()
|
||||
if count != valuesValue.Len() {
|
||||
return 0, fmt.Errorf("keysOut and valuesOut must be the same length")
|
||||
}
|
||||
keyBuf := make([]byte, count*int(m.keySize))
|
||||
keyPtr := internal.NewSlicePointer(keyBuf)
|
||||
valueBuf := make([]byte, count*int(m.fullValueSize))
|
||||
valuePtr := internal.NewSlicePointer(valueBuf)
|
||||
|
||||
var (
|
||||
startPtr internal.Pointer
|
||||
err error
|
||||
retErr error
|
||||
)
|
||||
if startKey != nil {
|
||||
startPtr, err = marshalPtr(startKey, int(m.keySize))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
nextPtr, nextBuf := makeBuffer(nextKeyOut, int(m.keySize))
|
||||
|
||||
ct, err := bpfMapBatch(cmd, m.fd, startPtr, nextPtr, keyPtr, valuePtr, uint32(count), opts)
|
||||
if err != nil {
|
||||
if !errors.Is(err, ErrKeyNotExist) {
|
||||
return 0, err
|
||||
}
|
||||
retErr = ErrKeyNotExist
|
||||
}
|
||||
|
||||
err = m.unmarshalKey(nextKeyOut, nextBuf)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
err = unmarshalBytes(keysOut, keyBuf)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
err = unmarshalBytes(valuesOut, valueBuf)
|
||||
if err != nil {
|
||||
retErr = err
|
||||
}
|
||||
return int(ct), retErr
|
||||
}
|
||||
|
||||
// BatchUpdate updates the map with multiple keys and values
|
||||
// simultaneously.
|
||||
// "keys" and "values" must be of type slice, a pointer
|
||||
// to a slice or buffer will not work.
|
||||
func (m *Map) BatchUpdate(keys, values interface{}, opts *BatchOptions) (int, error) {
|
||||
if err := haveBatchAPI(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if m.typ.hasPerCPUValue() {
|
||||
return 0, ErrNotSupported
|
||||
}
|
||||
keysValue := reflect.ValueOf(keys)
|
||||
if keysValue.Kind() != reflect.Slice {
|
||||
return 0, fmt.Errorf("keys must be a slice")
|
||||
}
|
||||
valuesValue := reflect.ValueOf(values)
|
||||
if valuesValue.Kind() != reflect.Slice {
|
||||
return 0, fmt.Errorf("values must be a slice")
|
||||
}
|
||||
var (
|
||||
count = keysValue.Len()
|
||||
valuePtr internal.Pointer
|
||||
err error
|
||||
)
|
||||
if count != valuesValue.Len() {
|
||||
return 0, fmt.Errorf("keys and values must be the same length")
|
||||
}
|
||||
keyPtr, err := marshalPtr(keys, count*int(m.keySize))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
valuePtr, err = marshalPtr(values, count*int(m.valueSize))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
var nilPtr internal.Pointer
|
||||
ct, err := bpfMapBatch(internal.BPF_MAP_UPDATE_BATCH, m.fd, nilPtr, nilPtr, keyPtr, valuePtr, uint32(count), opts)
|
||||
return int(ct), err
|
||||
}
|
||||
|
||||
// BatchDelete batch deletes entries in the map by keys.
|
||||
// "keys" must be of type slice, a pointer to a slice or buffer will not work.
|
||||
func (m *Map) BatchDelete(keys interface{}, opts *BatchOptions) (int, error) {
|
||||
if err := haveBatchAPI(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if m.typ.hasPerCPUValue() {
|
||||
return 0, ErrNotSupported
|
||||
}
|
||||
keysValue := reflect.ValueOf(keys)
|
||||
if keysValue.Kind() != reflect.Slice {
|
||||
return 0, fmt.Errorf("keys must be a slice")
|
||||
}
|
||||
count := keysValue.Len()
|
||||
keyPtr, err := marshalPtr(keys, count*int(m.keySize))
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("cannot marshal keys: %v", err)
|
||||
}
|
||||
var nilPtr internal.Pointer
|
||||
ct, err := bpfMapBatch(internal.BPF_MAP_DELETE_BATCH, m.fd, nilPtr, nilPtr, keyPtr, nilPtr, uint32(count), opts)
|
||||
return int(ct), err
|
||||
}
|
||||
|
||||
// Iterate traverses a map.
|
||||
//
|
||||
// It's safe to create multiple iterators at the same time.
|
||||
@ -647,6 +776,7 @@ func (m *Map) FD() int {
|
||||
//
|
||||
// Closing the duplicate does not affect the original, and vice versa.
|
||||
// Changes made to the map are reflected by both instances however.
|
||||
// If the original map was pinned, the cloned map will not be pinned by default.
|
||||
//
|
||||
// Cloning a nil Map returns nil.
|
||||
func (m *Map) Clone() (*Map, error) {
|
||||
@ -659,14 +789,53 @@ func (m *Map) Clone() (*Map, error) {
|
||||
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
|
||||
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.
|
||||
@ -692,45 +861,147 @@ func (m *Map) populate(contents []MapKV) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Map) marshalKey(data interface{}) (internal.Pointer, error) {
|
||||
if data == nil {
|
||||
if m.keySize == 0 {
|
||||
// Queues have a key length of zero, so passing nil here is valid.
|
||||
return internal.NewPointer(nil), nil
|
||||
}
|
||||
return internal.Pointer{}, errors.New("can't use nil as key of map")
|
||||
}
|
||||
|
||||
return marshalPtr(data, int(m.keySize))
|
||||
}
|
||||
|
||||
func (m *Map) unmarshalKey(data interface{}, buf []byte) error {
|
||||
if buf == nil {
|
||||
// This is from a makeBuffer call, nothing do do here.
|
||||
return nil
|
||||
}
|
||||
|
||||
return unmarshalBytes(data, buf)
|
||||
}
|
||||
|
||||
func (m *Map) marshalValue(data interface{}) (internal.Pointer, error) {
|
||||
if m.typ.hasPerCPUValue() {
|
||||
return marshalPerCPUValue(data, int(m.valueSize))
|
||||
}
|
||||
|
||||
var (
|
||||
buf []byte
|
||||
err error
|
||||
)
|
||||
|
||||
switch value := data.(type) {
|
||||
case *Map:
|
||||
if !m.typ.canStoreMap() {
|
||||
return internal.Pointer{}, fmt.Errorf("can't store map in %s", m.typ)
|
||||
}
|
||||
buf, err = marshalMap(value, int(m.valueSize))
|
||||
|
||||
case *Program:
|
||||
if !m.typ.canStoreProgram() {
|
||||
return internal.Pointer{}, fmt.Errorf("can't store program in %s", m.typ)
|
||||
}
|
||||
buf, err = marshalProgram(value, int(m.valueSize))
|
||||
|
||||
default:
|
||||
return marshalPtr(data, int(m.valueSize))
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return internal.Pointer{}, err
|
||||
}
|
||||
|
||||
return internal.NewSlicePointer(buf), nil
|
||||
}
|
||||
|
||||
func (m *Map) unmarshalValue(value interface{}, buf []byte) error {
|
||||
if buf == nil {
|
||||
// This is from a makeBuffer call, nothing do do here.
|
||||
return nil
|
||||
}
|
||||
|
||||
if m.typ.hasPerCPUValue() {
|
||||
return unmarshalPerCPUValue(value, int(m.valueSize), buf)
|
||||
}
|
||||
|
||||
switch value := value.(type) {
|
||||
case **Map:
|
||||
if !m.typ.canStoreMap() {
|
||||
return fmt.Errorf("can't read a map from %s", m.typ)
|
||||
}
|
||||
|
||||
other, err := unmarshalMap(buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
(*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.
|
||||
//
|
||||
// The function is not compatible with nested maps.
|
||||
// Use LoadPinnedMapExplicit in these situations.
|
||||
func LoadPinnedMap(fileName string) (*Map, error) {
|
||||
fd, err := internal.BPFObjGet(fileName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
name, abi, err := newMapABIFromFd(fd)
|
||||
if err != nil {
|
||||
_ = fd.Close()
|
||||
return nil, err
|
||||
}
|
||||
return newMap(fd, name, abi)
|
||||
|
||||
m, err := newMapFromFD(fd)
|
||||
if err == nil {
|
||||
m.pinnedPath = fileName
|
||||
}
|
||||
|
||||
// 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)
|
||||
return m, err
|
||||
}
|
||||
|
||||
// unmarshalMap creates a map from a map ID encoded in host endianness.
|
||||
func unmarshalMap(buf []byte) (*Map, error) {
|
||||
if len(buf) != 4 {
|
||||
return nil, errors.New("map id requires 4 byte value")
|
||||
}
|
||||
|
||||
// Looking up an entry in a nested map or prog array returns an id,
|
||||
// not an fd.
|
||||
id := internal.NativeEndian.Uint32(buf)
|
||||
return NewMapFromID(MapID(id))
|
||||
}
|
||||
|
||||
// MarshalBinary implements BinaryMarshaler.
|
||||
func (m *Map) MarshalBinary() ([]byte, error) {
|
||||
// marshalMap marshals the fd of a map into a buffer in host endianness.
|
||||
func marshalMap(m *Map, length int) ([]byte, error) {
|
||||
if length != 4 {
|
||||
return nil, fmt.Errorf("can't marshal map to %d bytes", length)
|
||||
}
|
||||
|
||||
fd, err := m.fd.Value()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -810,8 +1081,8 @@ type MapIterator struct {
|
||||
func newMapIterator(target *Map) *MapIterator {
|
||||
return &MapIterator{
|
||||
target: target,
|
||||
maxEntries: target.abi.MaxEntries,
|
||||
prevBytes: make([]byte, int(target.abi.KeySize)),
|
||||
maxEntries: target.maxEntries,
|
||||
prevBytes: make([]byte, target.keySize),
|
||||
}
|
||||
}
|
||||
|
||||
@ -830,7 +1101,9 @@ func (mi *MapIterator) Next(keyOut, valueOut interface{}) bool {
|
||||
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
|
||||
nextBytes, mi.err = mi.target.NextKeyBytes(mi.prevKey)
|
||||
if mi.err != nil {
|
||||
@ -849,6 +1122,7 @@ func (mi *MapIterator) Next(keyOut, valueOut interface{}) bool {
|
||||
copy(mi.prevBytes, nextBytes)
|
||||
mi.prevKey = mi.prevBytes
|
||||
|
||||
mi.count++
|
||||
mi.err = mi.target.Lookup(nextBytes, valueOut)
|
||||
if errors.Is(mi.err, ErrKeyNotExist) {
|
||||
// Even though the key should be valid, we couldn't look up
|
||||
@ -865,7 +1139,7 @@ func (mi *MapIterator) Next(keyOut, valueOut interface{}) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
mi.err = unmarshalBytes(keyOut, nextBytes)
|
||||
mi.err = mi.target.unmarshalKey(keyOut, nextBytes)
|
||||
return mi.err == nil
|
||||
}
|
||||
|
||||
@ -899,18 +1173,12 @@ func NewMapFromID(id MapID) (*Map, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
name, abi, err := newMapABIFromFd(fd)
|
||||
if err != nil {
|
||||
_ = fd.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return newMap(fd, name, abi)
|
||||
return newMapFromFD(fd)
|
||||
}
|
||||
|
||||
// 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) {
|
||||
info, err := bpfGetMapInfoByFD(m.fd)
|
||||
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"
|
||||
)
|
||||
|
||||
// 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) {
|
||||
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 {
|
||||
return internal.NewPointer(ptr), nil
|
||||
}
|
||||
@ -33,6 +31,13 @@ func marshalPtr(data interface{}, length int) (internal.Pointer, error) {
|
||||
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) {
|
||||
switch value := data.(type) {
|
||||
case encoding.BinaryMarshaler:
|
||||
@ -43,6 +48,8 @@ func marshalBytes(data interface{}, length int) (buf []byte, err error) {
|
||||
buf = value
|
||||
case 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:
|
||||
var wr bytes.Buffer
|
||||
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
|
||||
}
|
||||
|
||||
// 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 {
|
||||
switch value := data.(type) {
|
||||
case unsafe.Pointer:
|
||||
@ -83,6 +94,8 @@ func unmarshalBytes(data interface{}, buf []byte) error {
|
||||
copy(dst, buf)
|
||||
runtime.KeepAlive(value)
|
||||
return nil
|
||||
case Map, *Map, Program, *Program:
|
||||
return fmt.Errorf("can't unmarshal into %T", value)
|
||||
case encoding.BinaryUnmarshaler:
|
||||
return value.UnmarshalBinary(buf)
|
||||
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
|
||||
}
|
302
vendor/github.com/cilium/ebpf/prog.go
generated
vendored
302
vendor/github.com/cilium/ebpf/prog.go
generated
vendored
@ -6,6 +6,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@ -18,7 +19,7 @@ import (
|
||||
// ErrNotSupported is returned whenever the kernel doesn't support a feature.
|
||||
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
|
||||
|
||||
const (
|
||||
@ -42,7 +43,7 @@ type ProgramOptions struct {
|
||||
LogSize int
|
||||
}
|
||||
|
||||
// ProgramSpec defines a Program
|
||||
// ProgramSpec defines a Program.
|
||||
type ProgramSpec struct {
|
||||
// Name is passed to the kernel as a debug aid. Must only contain
|
||||
// alpha numeric and '_' characters.
|
||||
@ -87,6 +88,13 @@ func (ps *ProgramSpec) Copy() *ProgramSpec {
|
||||
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.
|
||||
//
|
||||
// It is not safe to close a Program which is used by other goroutines.
|
||||
@ -97,8 +105,8 @@ type Program struct {
|
||||
|
||||
fd *internal.FD
|
||||
name string
|
||||
abi ProgramABI
|
||||
attachType AttachType
|
||||
pinnedPath string
|
||||
typ ProgramType
|
||||
}
|
||||
|
||||
// NewProgram creates a new Program.
|
||||
@ -114,88 +122,13 @@ func NewProgram(spec *ProgramSpec) (*Program, error) {
|
||||
// Loading a program for the first time will perform
|
||||
// feature detection by loading small, temporary programs.
|
||||
func NewProgramWithOptions(spec *ProgramSpec, opts ProgramOptions) (*Program, error) {
|
||||
if spec.BTF == nil {
|
||||
return newProgramWithBTF(spec, nil, opts)
|
||||
btfs := make(btfHandleCache)
|
||||
defer btfs.close()
|
||||
|
||||
return newProgramWithOptions(spec, opts, btfs)
|
||||
}
|
||||
|
||||
handle, err := btf.NewHandle(btf.ProgramSpec(spec.BTF))
|
||||
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) {
|
||||
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) {
|
||||
func newProgramWithOptions(spec *ProgramSpec, opts ProgramOptions, btfs btfHandleCache) (*Program, error) {
|
||||
if len(spec.Instructions) == 0 {
|
||||
return nil, errors.New("Instructions cannot be empty")
|
||||
}
|
||||
@ -236,12 +169,26 @@ func convertProgramSpec(spec *ProgramSpec, handle *btf.Handle) (*bpfProgLoadAttr
|
||||
attr.progName = newBPFObjName(spec.Name)
|
||||
}
|
||||
|
||||
if handle != nil && spec.BTF != nil {
|
||||
var btfDisabled bool
|
||||
if spec.BTF != nil {
|
||||
if relos, err := btf.ProgramRelocations(spec.BTF, nil); err != nil {
|
||||
return nil, fmt.Errorf("CO-RE relocations: %s", err)
|
||||
} else if len(relos) > 0 {
|
||||
return nil, fmt.Errorf("applying CO-RE relocations: %w", ErrNotSupported)
|
||||
}
|
||||
|
||||
handle, err := btfs.load(btf.ProgramSpec(spec.BTF))
|
||||
btfDisabled = errors.Is(err, btf.ErrNotSupported)
|
||||
if err != nil && !btfDisabled {
|
||||
return nil, fmt.Errorf("load BTF: %w", err)
|
||||
}
|
||||
|
||||
if handle != nil {
|
||||
attr.progBTFFd = uint32(handle.FD())
|
||||
|
||||
recSize, bytes, err := btf.ProgramLineInfos(spec.BTF)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't get BTF line infos: %w", err)
|
||||
return nil, fmt.Errorf("get BTF line infos: %w", err)
|
||||
}
|
||||
attr.lineInfoRecSize = recSize
|
||||
attr.lineInfoCnt = uint32(uint64(len(bytes)) / uint64(recSize))
|
||||
@ -249,12 +196,13 @@ func convertProgramSpec(spec *ProgramSpec, handle *btf.Handle) (*bpfProgLoadAttr
|
||||
|
||||
recSize, bytes, err = btf.ProgramFuncInfos(spec.BTF)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't get BTF function infos: %w", err)
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
if spec.AttachTo != "" {
|
||||
target, err := resolveBTFType(spec.AttachTo, spec.Type, spec.AttachType)
|
||||
@ -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 {
|
||||
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.
|
||||
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.
|
||||
func (p *Program) ABI() ProgramABI {
|
||||
return p.abi
|
||||
// Requires at least 4.10.
|
||||
func (p *Program) Info() (*ProgramInfo, error) {
|
||||
return newProgramInfoFromFd(p.fd)
|
||||
}
|
||||
|
||||
// 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 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
|
||||
func (p *Program) Pin(fileName string) error {
|
||||
if err := internal.BPFObjPin(fileName, p.fd); err != nil {
|
||||
return fmt.Errorf("can't pin program: %w", err)
|
||||
if err := pin(p.pinnedPath, fileName, p.fd); err != nil {
|
||||
return err
|
||||
}
|
||||
p.pinnedPath = fileName
|
||||
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.
|
||||
func (p *Program) Close() error {
|
||||
if p == nil {
|
||||
@ -373,7 +418,7 @@ func (p *Program) Benchmark(in []byte, repeat int, reset func()) (uint32, time.D
|
||||
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{
|
||||
Type: SocketFilter,
|
||||
Instructions: asm.Instructions{
|
||||
@ -384,7 +429,7 @@ var haveProgTestRun = internal.FeatureTest("BPF_PROG_TEST_RUN", "4.12", func() (
|
||||
})
|
||||
if err != nil {
|
||||
// This may be because we lack sufficient permissions, etc.
|
||||
return false, err
|
||||
return err
|
||||
}
|
||||
defer prog.Close()
|
||||
|
||||
@ -397,10 +442,16 @@ var haveProgTestRun = internal.FeatureTest("BPF_PROG_TEST_RUN", "4.12", func() (
|
||||
}
|
||||
|
||||
err = bpfProgTestRun(&attr)
|
||||
|
||||
if errors.Is(err, unix.EINVAL) {
|
||||
// Check for EINVAL specifically, rather than err != nil since we
|
||||
// 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) {
|
||||
@ -479,8 +530,11 @@ func unmarshalProgram(buf []byte) (*Program, error) {
|
||||
return NewProgramFromID(ProgramID(id))
|
||||
}
|
||||
|
||||
// MarshalBinary implements BinaryMarshaler.
|
||||
func (p *Program) MarshalBinary() ([]byte, error) {
|
||||
func marshalProgram(p *Program, length int) ([]byte, error) {
|
||||
if length != 4 {
|
||||
return nil, fmt.Errorf("can't marshal program to %d bytes", length)
|
||||
}
|
||||
|
||||
value, err := p.fd.Value()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -549,22 +603,22 @@ func LoadPinnedProgram(fileName string) (*Program, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
name, abi, err := newProgramABIFromFd(fd)
|
||||
info, err := newProgramInfoFromFd(fd)
|
||||
if err != nil {
|
||||
_ = 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
|
||||
// programs at run time.
|
||||
//
|
||||
// Passing a negative value for replacement will delete characters
|
||||
// instead of replacing them.
|
||||
// The set of allowed characters depends on the running kernel version.
|
||||
// Dots are only allowed as of kernel 5.2.
|
||||
func SanitizeName(name string, replacement rune) string {
|
||||
return strings.Map(func(char rune) rune {
|
||||
if invalidBPFObjNameChar(char) {
|
||||
@ -582,25 +636,9 @@ func ProgramGetNextID(startID ProgramID) (ProgramID, error) {
|
||||
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.
|
||||
//
|
||||
// Deprecated: use ProgramInfo.ID() instead.
|
||||
func (p *Program) ID() (ProgramID, error) {
|
||||
info, err := bpfGetProgInfoByFD(p.fd)
|
||||
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 GOCACHE=/run/go-cache
|
||||
|
||||
elfs=""
|
||||
if [[ -d "/run/input/bpf" ]]; then
|
||||
elfs="/run/input/bpf"
|
||||
export KERNEL_SELFTESTS="/run/input/bpf"
|
||||
fi
|
||||
|
||||
readonly output="${1}"
|
||||
shift
|
||||
|
||||
echo Running tests...
|
||||
# TestLibBPFCompat runs separately to pass the "-elfs" flag only for it: https://github.com/cilium/ebpf/pull/119
|
||||
go test -v -count 1 -run TestLibBPFCompat -elfs "$elfs"
|
||||
go test -v -count 1 ./...
|
||||
touch "$1/success"
|
||||
go test -v -coverpkg=./... -coverprofile="$output/coverage.txt" -count 1 ./...
|
||||
touch "$output/success"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
@ -82,11 +82,9 @@ if [[ ! -e "${output}/success" ]]; then
|
||||
exit 1
|
||||
else
|
||||
echo "Test successful on ${kernel_version}"
|
||||
# if [[ -v CODECOV_TOKEN ]]; then
|
||||
# curl --fail -s https://codecov.io/bash > "${tmp_dir}/codecov.sh"
|
||||
# chmod +x "${tmp_dir}/codecov.sh"
|
||||
# "${tmp_dir}/codecov.sh" -f "${output}/coverage.txt"
|
||||
# fi
|
||||
if [[ -v COVERALLS_TOKEN ]]; then
|
||||
goveralls -coverprofile="${output}/coverage.txt" -service=semaphore -repotoken "$COVERALLS_TOKEN"
|
||||
fi
|
||||
fi
|
||||
|
||||
$sudo rm -r "${input}"
|
||||
|
194
vendor/github.com/cilium/ebpf/syscalls.go
generated
vendored
194
vendor/github.com/cilium/ebpf/syscalls.go
generated
vendored
@ -3,7 +3,6 @@ package ebpf
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"unsafe"
|
||||
|
||||
"github.com/cilium/ebpf/internal"
|
||||
@ -12,9 +11,7 @@ import (
|
||||
)
|
||||
|
||||
// Generic errors returned by BPF syscalls.
|
||||
var (
|
||||
ErrNotExist = errors.New("requested object does not exist")
|
||||
)
|
||||
var ErrNotExist = errors.New("requested object does not exist")
|
||||
|
||||
// bpfObjName is a null-terminated string made up of
|
||||
// 'A-Za-z0-9_' characters.
|
||||
@ -27,18 +24,20 @@ func newBPFObjName(name string) bpfObjName {
|
||||
return result
|
||||
}
|
||||
|
||||
// invalidBPFObjNameChar returns true if char may not appear in
|
||||
// a BPF object name.
|
||||
func invalidBPFObjNameChar(char rune) bool {
|
||||
dotAllowed := objNameAllowsDot() == nil
|
||||
|
||||
switch {
|
||||
case char >= 'A' && char <= 'Z':
|
||||
fallthrough
|
||||
return false
|
||||
case char >= 'a' && char <= 'z':
|
||||
fallthrough
|
||||
return false
|
||||
case char >= '0' && char <= '9':
|
||||
fallthrough
|
||||
return false
|
||||
case dotAllowed && char == '.':
|
||||
fallthrough
|
||||
return false
|
||||
case char == '_':
|
||||
return false
|
||||
default:
|
||||
@ -69,14 +68,32 @@ type bpfMapOpAttr struct {
|
||||
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 {
|
||||
mapType uint32
|
||||
map_type uint32 // since 4.12 1e2709769086
|
||||
id uint32
|
||||
keySize uint32
|
||||
valueSize uint32
|
||||
maxEntries uint32
|
||||
flags uint32
|
||||
mapName bpfObjName // since 4.15 ad5b177bd73f
|
||||
key_size uint32
|
||||
value_size uint32
|
||||
max_entries uint32
|
||||
map_flags uint32
|
||||
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 {
|
||||
@ -104,18 +121,40 @@ type bpfProgLoadAttr struct {
|
||||
}
|
||||
|
||||
type bpfProgInfo struct {
|
||||
progType uint32
|
||||
prog_type uint32
|
||||
id uint32
|
||||
tag [unix.BPF_TAG_SIZE]byte
|
||||
jitedLen uint32
|
||||
xlatedLen uint32
|
||||
jited internal.Pointer
|
||||
xlated internal.Pointer
|
||||
loadTime uint64 // since 4.15 cb4d2b3f03d8
|
||||
createdByUID uint32
|
||||
nrMapIDs uint32
|
||||
mapIds internal.Pointer
|
||||
name bpfObjName
|
||||
jited_prog_len uint32
|
||||
xlated_prog_len uint32
|
||||
jited_prog_insns internal.Pointer
|
||||
xlated_prog_insns internal.Pointer
|
||||
load_time uint64 // since 4.15 cb4d2b3f03d8
|
||||
created_by_uid uint32
|
||||
nr_map_ids uint32
|
||||
map_ids internal.Pointer
|
||||
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 {
|
||||
@ -168,10 +207,6 @@ func bpfProgTestRun(attr *bpfProgTestRunAttr) error {
|
||||
|
||||
func bpfMapCreate(attr *bpfMapCreateAttr) (*internal.FD, error) {
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
@ -179,35 +214,25 @@ func bpfMapCreate(attr *bpfMapCreateAttr) (*internal.FD, error) {
|
||||
return internal.NewFD(uint32(fd)), nil
|
||||
}
|
||||
|
||||
var haveNestedMaps = internal.FeatureTest("nested maps", "4.12", func() (bool, error) {
|
||||
inner, 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{
|
||||
var haveNestedMaps = internal.FeatureTest("nested maps", "4.12", func() error {
|
||||
_, err := bpfMapCreate(&bpfMapCreateAttr{
|
||||
mapType: ArrayOfMaps,
|
||||
keySize: 4,
|
||||
valueSize: 4,
|
||||
maxEntries: 1,
|
||||
innerMapFd: innerFd,
|
||||
// Invalid file descriptor.
|
||||
innerMapFd: ^uint32(0),
|
||||
})
|
||||
if err != nil {
|
||||
return false, nil
|
||||
if errors.Is(err, unix.EINVAL) {
|
||||
return internal.ErrNotSupported
|
||||
}
|
||||
|
||||
_ = nested.Close()
|
||||
return true, nil
|
||||
if errors.Is(err, unix.EBADF) {
|
||||
return 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
|
||||
// BPF_MAP_FREEZE appeared in 5.2 as well we don't do a separate check.
|
||||
m, err := bpfMapCreate(&bpfMapCreateAttr{
|
||||
@ -218,10 +243,10 @@ var haveMapMutabilityModifiers = internal.FeatureTest("read- and write-only maps
|
||||
flags: unix.BPF_F_RDONLY_PROG,
|
||||
})
|
||||
if err != nil {
|
||||
return false, nil
|
||||
return internal.ErrNotSupported
|
||||
}
|
||||
_ = m.Close()
|
||||
return true, nil
|
||||
return nil
|
||||
})
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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 {
|
||||
if err == nil {
|
||||
return nil
|
||||
@ -331,6 +379,10 @@ func wrapMapError(err error) error {
|
||||
return ErrKeyExist
|
||||
}
|
||||
|
||||
if errors.Is(err, unix.ENOTSUPP) {
|
||||
return ErrNotSupported
|
||||
}
|
||||
|
||||
return errors.New(err.Error())
|
||||
}
|
||||
|
||||
@ -364,7 +416,7 @@ func bpfGetMapInfoByFD(fd *internal.FD) (*bpfMapInfo, error) {
|
||||
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{
|
||||
mapType: Array,
|
||||
keySize: 4,
|
||||
@ -375,16 +427,16 @@ var haveObjName = internal.FeatureTest("object names", "4.15", func() (bool, err
|
||||
|
||||
fd, err := bpfMapCreate(&attr)
|
||||
if err != nil {
|
||||
return false, nil
|
||||
return internal.ErrNotSupported
|
||||
}
|
||||
|
||||
_ = 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 {
|
||||
return false, err
|
||||
return err
|
||||
}
|
||||
|
||||
attr := bpfMapCreateAttr{
|
||||
@ -397,11 +449,37 @@ var objNameAllowsDot = internal.FeatureTest("dot in object names", "5.2", func()
|
||||
|
||||
fd, err := bpfMapCreate(&attr)
|
||||
if err != nil {
|
||||
return false, nil
|
||||
return internal.ErrNotSupported
|
||||
}
|
||||
|
||||
_ = 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) {
|
||||
|
27
vendor/github.com/cilium/ebpf/types.go
generated
vendored
27
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.
|
||||
func (mt MapType) hasPerCPUValue() bool {
|
||||
if mt == PerCPUHash || mt == PerCPUArray || mt == LRUCPUHash {
|
||||
return true
|
||||
return mt == PerCPUHash || mt == PerCPUArray || mt == LRUCPUHash
|
||||
}
|
||||
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
|
||||
@ -134,7 +143,7 @@ const (
|
||||
// Will cause invalid argument (EINVAL) at program load time if set incorrectly.
|
||||
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 (
|
||||
@ -192,3 +201,13 @@ const (
|
||||
// Pin an object by using its name as the filename.
|
||||
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
|
||||
|
||||
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/cpuguy83/go-md2man/v2 v2.0.0 // indirect
|
||||
github.com/docker/go-units v0.4.0
|
||||
@ -12,7 +12,7 @@ require (
|
||||
github.com/opencontainers/runtime-spec v1.0.2
|
||||
github.com/pkg/errors v0.9.1
|
||||
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
|
||||
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/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.4.0 h1:QlHdikaxALkqWasW8hAC1mfR0jdmvbfaBdBPFmRSglA=
|
||||
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/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 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
|
||||
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/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/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/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
|
||||
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.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M=
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/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/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/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
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/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
|
||||
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.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/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-20200124204421-9fbb57f87de9 h1:1/DFK4b7JH8DmkqhUk48onnSfrPzImPoVxuomtbT2nk=
|
||||
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
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/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/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/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 (
|
||||
"github.com/cilium/ebpf"
|
||||
"github.com/cilium/ebpf/asm"
|
||||
"github.com/cilium/ebpf/link"
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sys/unix"
|
||||
@ -42,12 +43,23 @@ func LoadAttachCgroupDeviceFilter(insts asm.Instructions, license string, dirFD
|
||||
if err != nil {
|
||||
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)")
|
||||
}
|
||||
closer := func() error {
|
||||
if err := prog.Detach(dirFD, ebpf.AttachCGroupDevice, unix.BPF_F_ALLOW_MULTI); err != nil {
|
||||
return errors.Wrap(err, "failed to call BPF_PROG_DETACH (BPF_CGROUP_DEVICE, BPF_F_ALLOW_MULTI)")
|
||||
err = link.RawDetachProgram(link.RawDetachProgramOptions{
|
||||
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
|
||||
}
|
||||
|
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 {
|
||||
xeh XAttrErrorHandler
|
||||
// xex contains a set of xattrs to exclude when copying
|
||||
xex map[string]struct{}
|
||||
}
|
||||
|
||||
type CopyDirOpt func(*copyDirOpts) error
|
||||
@ -61,6 +63,19 @@ func WithAllowXAttrErrors() CopyDirOpt {
|
||||
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.
|
||||
// Most efficient copy of files is attempted.
|
||||
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)
|
||||
}
|
||||
|
||||
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")
|
||||
}
|
||||
|
||||
@ -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")
|
||||
}
|
||||
|
||||
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")
|
||||
}
|
||||
}
|
||||
|
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
|
||||
}
|
||||
|
||||
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)
|
||||
if err != nil {
|
||||
e := errors.Wrapf(err, "failed to list xattrs on %s", src)
|
||||
if xeh != nil {
|
||||
e = xeh(dst, src, "", e)
|
||||
if errorHandler != nil {
|
||||
e = errorHandler(dst, src, "", e)
|
||||
}
|
||||
return e
|
||||
}
|
||||
for _, xattr := range xattrKeys {
|
||||
if _, exclude := excludes[xattr]; exclude {
|
||||
continue
|
||||
}
|
||||
data, err := sysx.LGetxattr(src, xattr)
|
||||
if err != nil {
|
||||
e := errors.Wrapf(err, "failed to get xattr %q on %s", xattr, src)
|
||||
if xeh != nil {
|
||||
if e = xeh(dst, src, xattr, e); e == nil {
|
||||
if errorHandler != nil {
|
||||
if e = errorHandler(dst, src, xattr, e); e == nil {
|
||||
continue
|
||||
}
|
||||
}
|
||||
@ -126,8 +129,8 @@ func copyXAttrs(dst, src string, xeh XAttrErrorHandler) error {
|
||||
}
|
||||
if err := sysx.LSetxattr(dst, xattr, data, 0); err != nil {
|
||||
e := errors.Wrapf(err, "failed to set xattr %q on %s", xattr, dst)
|
||||
if xeh != nil {
|
||||
if e = xeh(dst, src, xattr, e); e == nil {
|
||||
if errorHandler != nil {
|
||||
if e = errorHandler(dst, src, xattr, e); e == nil {
|
||||
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
|
||||
}
|
||||
|
||||
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)
|
||||
if err != nil {
|
||||
e := errors.Wrapf(err, "failed to list xattrs on %s", src)
|
||||
if xeh != nil {
|
||||
e = xeh(dst, src, "", e)
|
||||
if errorHandler != nil {
|
||||
e = errorHandler(dst, src, "", e)
|
||||
}
|
||||
return e
|
||||
}
|
||||
for _, xattr := range xattrKeys {
|
||||
if _, exclude := excludes[xattr]; exclude {
|
||||
continue
|
||||
}
|
||||
data, err := sysx.LGetxattr(src, xattr)
|
||||
if err != nil {
|
||||
e := errors.Wrapf(err, "failed to get xattr %q on %s", xattr, src)
|
||||
if xeh != nil {
|
||||
if e = xeh(dst, src, xattr, e); e == nil {
|
||||
if errorHandler != nil {
|
||||
if e = errorHandler(dst, src, xattr, e); e == nil {
|
||||
continue
|
||||
}
|
||||
}
|
||||
@ -89,8 +92,8 @@ func copyXAttrs(dst, src string, xeh XAttrErrorHandler) error {
|
||||
}
|
||||
if err := sysx.LSetxattr(dst, xattr, data, 0); err != nil {
|
||||
e := errors.Wrapf(err, "failed to set xattr %q on %s", xattr, dst)
|
||||
if xeh != nil {
|
||||
if e = xeh(dst, src, xattr, e); e == nil {
|
||||
if errorHandler != nil {
|
||||
if e = errorHandler(dst, src, xattr, e); e == nil {
|
||||
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
|
||||
}
|
||||
|
||||
func copyXAttrs(dst, src string, xeh XAttrErrorHandler) error {
|
||||
func copyXAttrs(dst, src string, excludes map[string]struct{}, errorHandler XAttrErrorHandler) error {
|
||||
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
|
||||
func SetXAttr(name, key, value string) Applier {
|
||||
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 (
|
||||
bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898
|
||||
github.com/dustin/go-humanize v1.0.0
|
||||
github.com/golang/protobuf v1.2.0
|
||||
github.com/inconshreveable/mousetrap v1.0.0 // indirect
|
||||
github.com/golang/protobuf v1.3.5
|
||||
github.com/opencontainers/go-digest v1.0.0
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/sirupsen/logrus v1.7.0
|
||||
github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee
|
||||
github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95 // indirect
|
||||
github.com/stretchr/testify v1.4.0 // indirect
|
||||
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
|
||||
github.com/spf13/cobra v1.0.0
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c
|
||||
)
|
||||
|
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/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/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/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.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/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/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/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
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/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/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee h1:GQkkv3XSnxhAMjdq2wLfEnptEVr+2BNvmHizILHn+d4=
|
||||
github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95 h1:j8jxLbQ0+T1DFggy6XoGvyUnrJWPR/JybflPvu5rwS4=
|
||||
github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
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/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
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.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
|
||||
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/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=
|
||||
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-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-20201201145000-ef89a241ccb3 h1:kzM6+9dur93BcC2kVlYl34cHU+TYZLanmpSJHVMmL64=
|
||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
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/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/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=
|
||||
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
|
||||
// DO NOT EDIT!
|
||||
|
||||
/*
|
||||
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) 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 {
|
||||
if m != nil {
|
||||
return m.Xattr
|
||||
@ -124,6 +200,20 @@ func (m *XAttr) String() string { return proto1.CompactTextString(m)
|
||||
func (*XAttr) ProtoMessage() {}
|
||||
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.
|
||||
type ADSEntry struct {
|
||||
// Name specifices the stream name.
|
||||
@ -147,6 +237,27 @@ func (m *ADSEntry) String() string { return proto1.CompactTextString(
|
||||
func (*ADSEntry) ProtoMessage() {}
|
||||
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() {
|
||||
proto1.RegisterType((*Manifest)(nil), "proto.Manifest")
|
||||
proto1.RegisterType((*Resource)(nil), "proto.Resource")
|
||||
@ -158,7 +269,7 @@ func init() { proto1.RegisterFile("manifest.proto", fileDescriptor0) }
|
||||
|
||||
var fileDescriptor0 = []byte{
|
||||
// 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,
|
||||
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,
|
||||
|
7
vendor/github.com/containerd/nri/README.md
generated
vendored
7
vendor/github.com/containerd/nri/README.md
generated
vendored
@ -64,16 +64,15 @@ Input to a plugin is provided via `STDIN` as a `json` payload.
|
||||
"id": "redis",
|
||||
"pid": 1234,
|
||||
"spec": {
|
||||
"resources": {
|
||||
},
|
||||
"resources": {},
|
||||
"cgroupsPath": "default/redis",
|
||||
"namespaces": {
|
||||
"pid": "/proc/44/ns/pid",
|
||||
"mount": "/proc/44/ns/mnt",
|
||||
"net": "/proc/44/ns/net",
|
||||
"net": "/proc/44/ns/net"
|
||||
},
|
||||
"annotations": {
|
||||
"qos.class: "ls"
|
||||
"qos.class": "ls"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
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/cespare/xxhash/v2 v2.1.1
|
||||
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/asm
|
||||
github.com/cilium/ebpf/internal
|
||||
github.com/cilium/ebpf/internal/btf
|
||||
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
|
||||
github.com/containerd/aufs
|
||||
github.com/containerd/aufs/plugin
|
||||
# github.com/containerd/btrfs v0.0.0-20210316141732-918d888fb676
|
||||
# github.com/containerd/btrfs v1.0.0
|
||||
## explicit
|
||||
github.com/containerd/btrfs
|
||||
# github.com/containerd/cgroups v0.0.0-20210114181951-8a68de567b68
|
||||
# github.com/containerd/cgroups v1.0.0
|
||||
## explicit
|
||||
github.com/containerd/cgroups
|
||||
github.com/containerd/cgroups/stats/v1
|
||||
@ -67,7 +68,7 @@ github.com/containerd/cgroups/v2/stats
|
||||
# github.com/containerd/console v1.0.2
|
||||
## explicit
|
||||
github.com/containerd/console
|
||||
# github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e
|
||||
# github.com/containerd/continuity v0.1.0
|
||||
## explicit
|
||||
github.com/containerd/continuity
|
||||
github.com/containerd/continuity/devices
|
||||
@ -85,14 +86,14 @@ github.com/containerd/fifo
|
||||
# github.com/containerd/go-cni v1.0.2
|
||||
## explicit
|
||||
github.com/containerd/go-cni
|
||||
# github.com/containerd/go-runc v0.0.0-20201020171139-16b287bc67d0
|
||||
# github.com/containerd/go-runc v1.0.0
|
||||
## explicit
|
||||
github.com/containerd/go-runc
|
||||
# github.com/containerd/imgcrypt v1.1.1
|
||||
## explicit
|
||||
github.com/containerd/imgcrypt
|
||||
github.com/containerd/imgcrypt/images/encryption
|
||||
# github.com/containerd/nri v0.0.0-20210316161719-dbaa18c31c14
|
||||
# github.com/containerd/nri v0.1.0
|
||||
## explicit
|
||||
github.com/containerd/nri
|
||||
github.com/containerd/nri/types/v1
|
||||
@ -103,7 +104,7 @@ github.com/containerd/ttrpc/plugin
|
||||
# github.com/containerd/typeurl v1.0.2
|
||||
## explicit
|
||||
github.com/containerd/typeurl
|
||||
# github.com/containerd/zfs v0.0.0-20210416085227-4140c9077d87
|
||||
# github.com/containerd/zfs v1.0.0
|
||||
## explicit
|
||||
github.com/containerd/zfs
|
||||
github.com/containerd/zfs/plugin
|
||||
|
Loading…
Reference in New Issue
Block a user