From 3ef337ae3a0f52cf7deba829452e803491c21bbe Mon Sep 17 00:00:00 2001 From: Derek McGowan Date: Mon, 19 Apr 2021 10:32:55 -0700 Subject: [PATCH] Update containerd vendors to tags Signed-off-by: Derek McGowan --- go.mod | 14 +- go.sum | 61 +- integration/client/go.mod | 4 +- integration/client/go.sum | 49 +- vendor/github.com/cilium/ebpf/ARCHITECTURE.md | 80 +++ vendor/github.com/cilium/ebpf/CONTRIBUTING.md | 23 + vendor/github.com/cilium/ebpf/Makefile | 67 ++ vendor/github.com/cilium/ebpf/README.md | 54 ++ vendor/github.com/cilium/ebpf/abi.go | 200 ------ .../github.com/cilium/ebpf/asm/instruction.go | 27 + vendor/github.com/cilium/ebpf/collection.go | 311 ++++++--- vendor/github.com/cilium/ebpf/elf_reader.go | 632 +++++++++++------- .../github.com/cilium/ebpf/elf_reader_fuzz.go | 21 + vendor/github.com/cilium/ebpf/go.mod | 7 +- vendor/github.com/cilium/ebpf/go.sum | 15 +- vendor/github.com/cilium/ebpf/info.go | 239 +++++++ .../cilium/ebpf/internal/btf/btf.go | 170 ++--- .../cilium/ebpf/internal/btf/core.go | 388 +++++++++++ .../cilium/ebpf/internal/btf/ext_info.go | 141 +++- .../cilium/ebpf/internal/btf/types.go | 279 ++++++-- vendor/github.com/cilium/ebpf/internal/elf.go | 52 ++ .../cilium/ebpf/internal/feature.go | 48 +- .../cilium/ebpf/internal/syscall.go | 13 + .../cilium/ebpf/internal/unix/types_linux.go | 26 +- .../cilium/ebpf/internal/unix/types_other.go | 24 +- vendor/github.com/cilium/ebpf/link/cgroup.go | 169 +++++ vendor/github.com/cilium/ebpf/link/doc.go | 2 + vendor/github.com/cilium/ebpf/link/iter.go | 91 +++ vendor/github.com/cilium/ebpf/link/link.go | 214 ++++++ vendor/github.com/cilium/ebpf/link/netns.go | 60 ++ vendor/github.com/cilium/ebpf/link/program.go | 76 +++ .../cilium/ebpf/link/raw_tracepoint.go | 57 ++ .../github.com/cilium/ebpf/link/syscalls.go | 173 +++++ vendor/github.com/cilium/ebpf/linker.go | 4 +- vendor/github.com/cilium/ebpf/map.go | 604 ++++++++++++----- vendor/github.com/cilium/ebpf/marshalers.go | 27 +- vendor/github.com/cilium/ebpf/pinning.go | 42 ++ vendor/github.com/cilium/ebpf/prog.go | 328 +++++---- vendor/github.com/cilium/ebpf/readme.md | 29 - vendor/github.com/cilium/ebpf/run-tests.sh | 20 +- vendor/github.com/cilium/ebpf/syscalls.go | 200 ++++-- vendor/github.com/cilium/ebpf/types.go | 29 +- vendor/github.com/containerd/cgroups/go.mod | 6 +- vendor/github.com/containerd/cgroups/go.sum | 27 +- .../github.com/containerd/cgroups/v2/ebpf.go | 18 +- .../containerd/continuity/fs/copy.go | 19 +- .../containerd/continuity/fs/copy_linux.go | 17 +- .../containerd/continuity/fs/copy_unix.go | 17 +- .../containerd/continuity/fs/copy_windows.go | 2 +- .../continuity/fs/fstest/file_unix.go | 3 +- .../github.com/containerd/continuity/go.mod | 12 +- .../github.com/containerd/continuity/go.sum | 142 +++- .../continuity/proto/manifest.pb.go | 117 +++- vendor/github.com/containerd/nri/README.md | 67 +- vendor/modules.txt | 17 +- 55 files changed, 4260 insertions(+), 1274 deletions(-) create mode 100644 vendor/github.com/cilium/ebpf/ARCHITECTURE.md create mode 100644 vendor/github.com/cilium/ebpf/CONTRIBUTING.md create mode 100644 vendor/github.com/cilium/ebpf/Makefile create mode 100644 vendor/github.com/cilium/ebpf/README.md delete mode 100644 vendor/github.com/cilium/ebpf/abi.go create mode 100644 vendor/github.com/cilium/ebpf/elf_reader_fuzz.go create mode 100644 vendor/github.com/cilium/ebpf/info.go create mode 100644 vendor/github.com/cilium/ebpf/internal/btf/core.go create mode 100644 vendor/github.com/cilium/ebpf/internal/elf.go create mode 100644 vendor/github.com/cilium/ebpf/link/cgroup.go create mode 100644 vendor/github.com/cilium/ebpf/link/doc.go create mode 100644 vendor/github.com/cilium/ebpf/link/iter.go create mode 100644 vendor/github.com/cilium/ebpf/link/link.go create mode 100644 vendor/github.com/cilium/ebpf/link/netns.go create mode 100644 vendor/github.com/cilium/ebpf/link/program.go create mode 100644 vendor/github.com/cilium/ebpf/link/raw_tracepoint.go create mode 100644 vendor/github.com/cilium/ebpf/link/syscalls.go create mode 100644 vendor/github.com/cilium/ebpf/pinning.go delete mode 100644 vendor/github.com/cilium/ebpf/readme.md diff --git a/go.mod b/go.mod index 8db55ecc6..d973a1691 100644 --- a/go.mod +++ b/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 diff --git a/go.sum b/go.sum index 85003c3f0..1fbd0a73c 100644 --- a/go.sum +++ b/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= diff --git a/integration/client/go.mod b/integration/client/go.mod index 52294c4ac..ddc160ae9 100644 --- a/integration/client/go.mod +++ b/integration/client/go.mod @@ -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 diff --git a/integration/client/go.sum b/integration/client/go.sum index 93231bdd5..e951b119c 100644 --- a/integration/client/go.sum +++ b/integration/client/go.sum @@ -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= diff --git a/vendor/github.com/cilium/ebpf/ARCHITECTURE.md b/vendor/github.com/cilium/ebpf/ARCHITECTURE.md new file mode 100644 index 000000000..aee9c0a0d --- /dev/null +++ b/vendor/github.com/cilium/ebpf/ARCHITECTURE.md @@ -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. diff --git a/vendor/github.com/cilium/ebpf/CONTRIBUTING.md b/vendor/github.com/cilium/ebpf/CONTRIBUTING.md new file mode 100644 index 000000000..97c794f3a --- /dev/null +++ b/vendor/github.com/cilium/ebpf/CONTRIBUTING.md @@ -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 ./... \ No newline at end of file diff --git a/vendor/github.com/cilium/ebpf/Makefile b/vendor/github.com/cilium/ebpf/Makefile new file mode 100644 index 000000000..5d4195833 --- /dev/null +++ b/vendor/github.com/cilium/ebpf/Makefile @@ -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 > "$@" diff --git a/vendor/github.com/cilium/ebpf/README.md b/vendor/github.com/cilium/ebpf/README.md new file mode 100644 index 000000000..7f504d334 --- /dev/null +++ b/vendor/github.com/cilium/ebpf/README.md @@ -0,0 +1,54 @@ +# eBPF + +[![PkgGoDev](https://pkg.go.dev/badge/github.com/cilium/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 diff --git a/vendor/github.com/cilium/ebpf/abi.go b/vendor/github.com/cilium/ebpf/abi.go deleted file mode 100644 index f86a17ee7..000000000 --- a/vendor/github.com/cilium/ebpf/abi.go +++ /dev/null @@ -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 - } -} diff --git a/vendor/github.com/cilium/ebpf/asm/instruction.go b/vendor/github.com/cilium/ebpf/asm/instruction.go index 890dc008a..5d9d820e5 100644 --- a/vendor/github.com/cilium/ebpf/asm/instruction.go +++ b/vendor/github.com/cilium/ebpf/asm/instruction.go @@ -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] diff --git a/vendor/github.com/cilium/ebpf/collection.go b/vendor/github.com/cilium/ebpf/collection.go index 81ee2bd1a..8e3629003 100644 --- a/vendor/github.com/cilium/ebpf/collection.go +++ b/vendor/github.com/cilium/ebpf/collection.go @@ -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) - if err != nil { + 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,28 +239,75 @@ 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) { +func NewCollectionWithOptions(spec *CollectionSpec, opts CollectionOptions) (*Collection, error) { + loadMap, loadProgram, done, cleanup := lazyLoadCollection(spec, &opts) + defer cleanup() + + for mapName := range spec.Maps { + _, err := loadMap(mapName) + if err != nil { + return nil, err + } + } + + for progName := range spec.Programs { + _, err := loadProgram(progName) + if err != nil { + return nil, err + } + } + + maps, progs := done() + return &Collection{ + progs, + maps, + }, nil +} + +type btfHandleCache map[*btf.Spec]*btf.Handle + +func (btfs btfHandleCache) load(spec *btf.Spec) (*btf.Handle, error) { + if btfs[spec] != nil { + return btfs[spec], nil + } + + handle, err := btf.NewHandle(spec) + if err != nil { + return nil, err + } + + btfs[spec] = handle + return handle, nil +} + +func (btfs btfHandleCache) close() { + for _, handle := range btfs { + handle.Close() + } +} + +func lazyLoadCollection(coll *CollectionSpec, opts *CollectionOptions) ( + loadMap func(string) (*Map, error), + loadProgram func(string) (*Program, error), + done func() (map[string]*Map, map[string]*Program), + cleanup func(), +) { var ( - maps = make(map[string]*Map) - progs = make(map[string]*Program) - btfs = make(map[*btf.Spec]*btf.Handle) + maps = make(map[string]*Map) + progs = make(map[string]*Program) + btfs = make(btfHandleCache) + skipMapsAndProgs = false ) - defer func() { - for _, btf := range btfs { - btf.Close() - } + cleanup = func() { + btfs.close() - if err == nil { + if skipMapsAndProgs { return } @@ -230,40 +318,43 @@ func NewCollectionWithOptions(spec *CollectionSpec, opts CollectionOptions) (col for _, p := range progs { p.Close() } - }() - - loadBTF := func(spec *btf.Spec) (*btf.Handle, error) { - if btfs[spec] != nil { - return btfs[spec], nil - } - - handle, err := btf.NewHandle(spec) - if err != nil { - return nil, err - } - - btfs[spec] = handle - return handle, nil } - for mapName, mapSpec := range spec.Maps { - 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 - } + 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 } - m, err := newMapWithBTF(mapSpec, handle, opts.Maps) + mapSpec := coll.Maps[mapName] + if mapSpec == nil { + return nil, fmt.Errorf("missing map %s", mapName) + } + + m, err := newMapWithOptions(mapSpec, opts.Maps, btfs) if err != nil { 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 } diff --git a/vendor/github.com/cilium/ebpf/elf_reader.go b/vendor/github.com/cilium/ebpf/elf_reader.go index 2b564dae0..943142c49 100644 --- a/vendor/github.com/cilium/ebpf/elf_reader.go +++ b/vendor/github.com/cilium/ebpf/elf_reader.go @@ -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 - license string - version uint32 + *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 { - return nil, fmt.Errorf("load BTF maps: %w", err) - } + 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 { - return nil, fmt.Errorf("load data sections: %w", err) - } + 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] + + switch target.kind { + case mapSection, btfMapSection: + if bind != elf.STB_GLOBAL { + return fmt.Errorf("possible erroneous static qualifier on map definition: found reference to %q", name) } - 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 + if typ != elf.STT_OBJECT && typ != elf.STT_NOTYPE { + // STT_NOTYPE is generated on clang < 8 which doesn't tag // relocations appropriately. - fallthrough - - case elf.STT_OBJECT: - if bind != elf.STB_GLOBAL { - return fmt.Errorf("load: %s: unsupported binding: %s", name, bind) - } - - ins.Src = asm.PseudoMapFD - - default: - return fmt.Errorf("load: %s: unsupported relocation: %s", name, typ) + return fmt.Errorf("map load: incorrect relocation type %v", typ) } + ins.Src = asm.PseudoMapFD + // Mark the instruction as needing an update when creating the // collection. if err := ins.RewriteMapPtr(-1); err != nil { return err } - case 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 { - return fmt.Errorf("missing BTF") - } +func (ec *elfCode) loadBTFMaps(maps map[string]*MapSpec) error { + for _, sec := range ec.sections { + if sec.kind != btfMapSection { + continue + } - for idx, sec := range mapSections { - syms := ec.symbolsPerSection[idx] - if len(syms) == 0 { + if ec.btf == nil { + return fmt.Errorf("missing BTF") + } + + 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 '.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 { - return errors.New("data sections require BTF, make sure all consts are marked as static") +// 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) } - for _, sec := range dataSections { - btfMap, err := spec.Datasec(sec.Name) + ptr, ok := arr.Type.(*btf.Pointer) + if !ok { + return nil, fmt.Errorf("not an array of pointers: %v", typ) + } + + return ptr.Target, nil +} + +func (ec *elfCode) loadDataSections(maps map[string]*MapSpec) error { + for _, sec := range ec.sections { + if sec.kind != dataSection { + continue + } + + if sec.references == 0 { + // Prune data sections which are not referenced by any + // instructions. + continue + } + + if ec.btf == nil { + return errors.New("data sections require BTF, make sure all consts are marked as static") + } + + btfMap, err := ec.btf.Datasec(sec.Name) if err != nil { return err } @@ -678,69 +901,30 @@ 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 { - rels := make(map[uint64]elf.Symbol) +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) - } - - r := bufio.NewReader(sec.Open()) - for off := uint64(0); off < sec.Size; off += sec.Entsize { - ent := io.LimitReader(r, int64(sec.Entsize)) - - var rel elf.Rel64 - if binary.Read(ent, ec.ByteOrder, &rel) != nil { - return nil, nil, fmt.Errorf("can't parse relocation at offset %v", off) - } - - symNo := int(elf.R_SYM64(rel.Info) - 1) - if symNo >= len(ec.symbols) { - return nil, nil, fmt.Errorf("relocation at offset %d: symbol %v doesnt exist", off, symNo) - } - - symbol := ec.symbols[symNo] - targets[symbol.Section] = true - rels[rel.Off] = ec.symbols[symNo] - } - - result[idx] = rels + if sec.Entsize < 16 { + return nil, fmt.Errorf("section %s: relocations are less than 16 bytes", sec.Name) } - 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 + r := bufio.NewReader(sec.Open()) + for off := uint64(0); off < sec.Size; off += sec.Entsize { + ent := io.LimitReader(r, int64(sec.Entsize)) + + var rel elf.Rel64 + if binary.Read(ent, ec.ByteOrder, &rel) != nil { + return nil, fmt.Errorf("can't parse relocation at offset %v", off) } - if sym.Section == elf.SHN_UNDEF || sym.Section >= elf.SHN_LORESERVE { - continue + symNo := int(elf.R_SYM64(rel.Info) - 1) + if symNo >= len(symbols) { + return nil, fmt.Errorf("offset %d: symbol %d doesn't exist", off, symNo) } - if sym.Name == "" { - continue - } - - idx := sym.Section - if _, ok := result[idx]; !ok { - result[idx] = make(map[uint64]elf.Symbol) - } - result[idx][sym.Value] = sym + symbol := symbols[symNo] + rels[rel.Off] = symbol } - return result + + return rels, nil } diff --git a/vendor/github.com/cilium/ebpf/elf_reader_fuzz.go b/vendor/github.com/cilium/ebpf/elf_reader_fuzz.go new file mode 100644 index 000000000..d46d135f2 --- /dev/null +++ b/vendor/github.com/cilium/ebpf/elf_reader_fuzz.go @@ -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 +} diff --git a/vendor/github.com/cilium/ebpf/go.mod b/vendor/github.com/cilium/ebpf/go.mod index 2d1004425..df8139621 100644 --- a/vendor/github.com/cilium/ebpf/go.mod +++ b/vendor/github.com/cilium/ebpf/go.mod @@ -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 ) diff --git a/vendor/github.com/cilium/ebpf/go.sum b/vendor/github.com/cilium/ebpf/go.sum index 47dd82f29..a5039262a 100644 --- a/vendor/github.com/cilium/ebpf/go.sum +++ b/vendor/github.com/cilium/ebpf/go.sum @@ -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= diff --git a/vendor/github.com/cilium/ebpf/info.go b/vendor/github.com/cilium/ebpf/info.go new file mode 100644 index 000000000..b95131ef5 --- /dev/null +++ b/vendor/github.com/cilium/ebpf/info.go @@ -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 +} diff --git a/vendor/github.com/cilium/ebpf/internal/btf/btf.go b/vendor/github.com/cilium/ebpf/internal/btf/btf.go index 7a904a02c..1e66d9476 100644 --- a/vendor/github.com/cilium/ebpf/internal/btf/btf.go +++ b/vendor/github.com/cilium/ebpf/internal/btf/btf.go @@ -29,12 +29,14 @@ var ( // Spec represents decoded BTF. type Spec struct { - rawTypes []rawType - strings stringTable - types map[string][]namedType - funcInfos map[string]extInfo - lineInfos map[string]extInfo - byteOrder binary.ByteOrder + rawTypes []rawType + strings stringTable + types []Type + namedTypes map[string][]namedType + funcInfos map[string]extInfo + lineInfos map[string]extInfo + coreRelos map[string]bpfCoreRelos + byteOrder binary.ByteOrder } type btfHeader struct { @@ -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,16 +171,17 @@ 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, - types: types, - strings: rawStrings, - byteOrder: bo, + rawTypes: rawTypes, + namedTypes: typesByName, + types: types, + strings: rawStrings, + byteOrder: bo, }, nil } @@ -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 }) diff --git a/vendor/github.com/cilium/ebpf/internal/btf/core.go b/vendor/github.com/cilium/ebpf/internal/btf/core.go new file mode 100644 index 000000000..52b59ed18 --- /dev/null +++ b/vendor/github.com/cilium/ebpf/internal/btf/core.go @@ -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 +} diff --git a/vendor/github.com/cilium/ebpf/internal/btf/ext_info.go b/vendor/github.com/cilium/ebpf/internal/btf/ext_info.go index c1c82ec7f..6a21b6bda 100644 --- a/vendor/github.com/cilium/ebpf/internal/btf/ext_info.go +++ b/vendor/github.com/cilium/ebpf/internal/btf/ext_info.go @@ -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 +} diff --git a/vendor/github.com/cilium/ebpf/internal/btf/types.go b/vendor/github.com/cilium/ebpf/internal/btf/types.go index a93039bd5..9e1fd8d0b 100644 --- a/vendor/github.com/cilium/ebpf/internal/btf/types.go +++ b/vendor/github.com/cilium/ebpf/internal/btf/types.go @@ -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) size() uint32 { return 8 } -func (p *Pointer) walk(cs *copyStack) { cs.push(&p.Target) } +func (p *Pointer) String() string { + return fmt.Sprintf("pointer#%d[target=#%d]", p.TypeID, p.Target.ID()) +} + +func (p *Pointer) size() uint32 { return 8 } +func (p *Pointer) walk(tdq *typeDeque) { tdq.push(&p.Target) } func (p *Pointer) 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) qualify() Type { return v.Type } -func (v *Volatile) walk(cs *copyStack) { cs.push(&v.Type) } +func (v *Volatile) String() string { + return fmt.Sprintf("volatile#%d[#%d]", v.TypeID, v.Type.ID()) +} + +func (v *Volatile) qualify() Type { return v.Type } +func (v *Volatile) walk(tdq *typeDeque) { tdq.push(&v.Type) } func (v *Volatile) copy() Type { cpy := *v return &cpy @@ -255,8 +340,12 @@ type Const struct { Type Type } -func (c *Const) qualify() Type { return c.Type } -func (c *Const) walk(cs *copyStack) { cs.push(&c.Type) } +func (c *Const) String() string { + return fmt.Sprintf("const#%d[#%d]", c.TypeID, c.Type.ID()) +} + +func (c *Const) qualify() Type { return c.Type } +func (c *Const) walk(tdq *typeDeque) { tdq.push(&c.Type) } func (c *Const) copy() Type { cpy := *c return &cpy @@ -268,8 +357,12 @@ type Restrict struct { Type Type } -func (r *Restrict) qualify() Type { return r.Type } -func (r *Restrict) walk(cs *copyStack) { cs.push(&r.Type) } +func (r *Restrict) String() string { + return fmt.Sprintf("restrict#%d[#%d]", r.TypeID, r.Type.ID()) +} + +func (r *Restrict) qualify() Type { return r.Type } +func (r *Restrict) walk(tdq *typeDeque) { tdq.push(&r.Type) } func (r *Restrict) 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. diff --git a/vendor/github.com/cilium/ebpf/internal/elf.go b/vendor/github.com/cilium/ebpf/internal/elf.go new file mode 100644 index 000000000..c3f9ea0f8 --- /dev/null +++ b/vendor/github.com/cilium/ebpf/internal/elf.go @@ -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 +} diff --git a/vendor/github.com/cilium/ebpf/internal/feature.go b/vendor/github.com/cilium/ebpf/internal/feature.go index 8f282db64..ec62ed39b 100644 --- a/vendor/github.com/cilium/ebpf/internal/feature.go +++ b/vendor/github.com/cilium/ebpf/internal/feature.go @@ -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 } } diff --git a/vendor/github.com/cilium/ebpf/internal/syscall.go b/vendor/github.com/cilium/ebpf/internal/syscall.go index 9c5e0b3ed..c80815131 100644 --- a/vendor/github.com/cilium/ebpf/internal/syscall.go +++ b/vendor/github.com/cilium/ebpf/internal/syscall.go @@ -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 diff --git a/vendor/github.com/cilium/ebpf/internal/unix/types_linux.go b/vendor/github.com/cilium/ebpf/internal/unix/types_linux.go index d8135c183..86d2a10f9 100644 --- a/vendor/github.com/cilium/ebpf/internal/unix/types_linux.go +++ b/vendor/github.com/cilium/ebpf/internal/unix/types_linux.go @@ -10,16 +10,21 @@ import ( ) const ( - ENOENT = linux.ENOENT - EEXIST = linux.EEXIST - EAGAIN = linux.EAGAIN - ENOSPC = linux.ENOSPC - EINVAL = linux.EINVAL - EPOLLIN = linux.EPOLLIN - EINTR = linux.EINTR - EPERM = linux.EPERM - ESRCH = linux.ESRCH - ENODEV = linux.ENODEV + ENOENT = linux.ENOENT + EEXIST = linux.EEXIST + EAGAIN = linux.EAGAIN + ENOSPC = linux.ENOSPC + EINVAL = linux.EINVAL + EPOLLIN = linux.EPOLLIN + EINTR = linux.EINTR + EPERM = linux.EPERM + ESRCH = linux.ESRCH + ENODEV = linux.ENODEV + // ENOTSUPP is not the same as ENOTSUP or EOPNOTSUP + ENOTSUPP = syscall.Errno(0x20c) + + EBADF = linux.EBADF + BPF_F_NO_PREALLOC = linux.BPF_F_NO_PREALLOC 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 diff --git a/vendor/github.com/cilium/ebpf/internal/unix/types_other.go b/vendor/github.com/cilium/ebpf/internal/unix/types_other.go index 416b8d2f5..8c291796a 100644 --- a/vendor/github.com/cilium/ebpf/internal/unix/types_other.go +++ b/vendor/github.com/cilium/ebpf/internal/unix/types_other.go @@ -11,15 +11,20 @@ import ( var errNonLinux = fmt.Errorf("unsupported platform %s/%s", runtime.GOOS, runtime.GOARCH) const ( - ENOENT = syscall.ENOENT - EEXIST = syscall.EEXIST - EAGAIN = syscall.EAGAIN - ENOSPC = syscall.ENOSPC - EINVAL = syscall.EINVAL - EINTR = syscall.EINTR - EPERM = syscall.EPERM - ESRCH = syscall.ESRCH - ENODEV = syscall.ENODEV + ENOENT = syscall.ENOENT + EEXIST = syscall.EEXIST + EAGAIN = syscall.EAGAIN + ENOSPC = syscall.ENOSPC + EINVAL = syscall.EINVAL + EINTR = syscall.EINTR + EPERM = syscall.EPERM + ESRCH = syscall.ESRCH + ENODEV = syscall.ENODEV + EBADF = syscall.Errno(0) + // ENOTSUPP is not the same as ENOTSUP or EOPNOTSUP + ENOTSUPP = syscall.Errno(0x20c) + + BPF_F_NO_PREALLOC = 0 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 diff --git a/vendor/github.com/cilium/ebpf/link/cgroup.go b/vendor/github.com/cilium/ebpf/link/cgroup.go new file mode 100644 index 000000000..16a943930 --- /dev/null +++ b/vendor/github.com/cilium/ebpf/link/cgroup.go @@ -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 +} diff --git a/vendor/github.com/cilium/ebpf/link/doc.go b/vendor/github.com/cilium/ebpf/link/doc.go new file mode 100644 index 000000000..2bde35ed7 --- /dev/null +++ b/vendor/github.com/cilium/ebpf/link/doc.go @@ -0,0 +1,2 @@ +// Package link allows attaching eBPF programs to various kernel hooks. +package link diff --git a/vendor/github.com/cilium/ebpf/link/iter.go b/vendor/github.com/cilium/ebpf/link/iter.go new file mode 100644 index 000000000..2b5f2846a --- /dev/null +++ b/vendor/github.com/cilium/ebpf/link/iter.go @@ -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 +} diff --git a/vendor/github.com/cilium/ebpf/link/link.go b/vendor/github.com/cilium/ebpf/link/link.go new file mode 100644 index 000000000..48f1a5529 --- /dev/null +++ b/vendor/github.com/cilium/ebpf/link/link.go @@ -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 +} diff --git a/vendor/github.com/cilium/ebpf/link/netns.go b/vendor/github.com/cilium/ebpf/link/netns.go new file mode 100644 index 000000000..3533ff0fa --- /dev/null +++ b/vendor/github.com/cilium/ebpf/link/netns.go @@ -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 +} diff --git a/vendor/github.com/cilium/ebpf/link/program.go b/vendor/github.com/cilium/ebpf/link/program.go new file mode 100644 index 000000000..0fe9d37c4 --- /dev/null +++ b/vendor/github.com/cilium/ebpf/link/program.go @@ -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 +} diff --git a/vendor/github.com/cilium/ebpf/link/raw_tracepoint.go b/vendor/github.com/cilium/ebpf/link/raw_tracepoint.go new file mode 100644 index 000000000..65652486f --- /dev/null +++ b/vendor/github.com/cilium/ebpf/link/raw_tracepoint.go @@ -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) +} diff --git a/vendor/github.com/cilium/ebpf/link/syscalls.go b/vendor/github.com/cilium/ebpf/link/syscalls.go new file mode 100644 index 000000000..19326c8af --- /dev/null +++ b/vendor/github.com/cilium/ebpf/link/syscalls.go @@ -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 +} diff --git a/vendor/github.com/cilium/ebpf/linker.go b/vendor/github.com/cilium/ebpf/linker.go index fc4ad9dff..f843bb25e 100644 --- a/vendor/github.com/cilium/ebpf/linker.go +++ b/vendor/github.com/cilium/ebpf/linker.go @@ -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) diff --git a/vendor/github.com/cilium/ebpf/map.go b/vendor/github.com/cilium/ebpf/map.go index 5c9028d9d..316fc37b1 100644 --- a/vendor/github.com/cilium/ebpf/map.go +++ b/vendor/github.com/cilium/ebpf/map.go @@ -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 } @@ -118,9 +119,14 @@ func (ms *MapSpec) checkCompatibility(m *Map) error { // Implement encoding.BinaryMarshaler or encoding.BinaryUnmarshaler // if you require custom encoding. type Map struct { - name string - fd *internal.FD - abi MapABI + name string + fd *internal.FD + 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) + return newMapFromFD(internal.NewFD(uint32(fd))) +} + +func newMapFromFD(fd *internal.FD) (*Map, error) { + info, err := newMapInfoFromFd(fd) if err != nil { - bpfFd.Forget() - return nil, err + fd.Close() + return nil, fmt.Errorf("get map info: %s", err) } - return newMap(bpfFd, name, abi) + + return newMap(fd, info.Name, info.Type, info.KeySize, info.ValueSize, info.MaxEntries, info.Flags) } // NewMap creates a new Map. @@ -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() - 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) + return newMapWithOptions(spec, opts, btfs) } -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 + + m, err := newMapFromFD(fd) + if err == nil { + m.pinnedPath = fileName } - return newMap(fd, name, abi) -} - -// LoadPinnedMapExplicit loads a map with explicit parameters. -func LoadPinnedMapExplicit(fileName string, abi *MapABI) (*Map, error) { - fd, err := internal.BPFObjGet(fileName) - if err != nil { - return nil, err - } - return newMap(fd, "", abi) + + 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 { diff --git a/vendor/github.com/cilium/ebpf/marshalers.go b/vendor/github.com/cilium/ebpf/marshalers.go index c0db2f6b0..3ea1021a8 100644 --- a/vendor/github.com/cilium/ebpf/marshalers.go +++ b/vendor/github.com/cilium/ebpf/marshalers.go @@ -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: diff --git a/vendor/github.com/cilium/ebpf/pinning.go b/vendor/github.com/cilium/ebpf/pinning.go new file mode 100644 index 000000000..78812364a --- /dev/null +++ b/vendor/github.com/cilium/ebpf/pinning.go @@ -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 +} diff --git a/vendor/github.com/cilium/ebpf/prog.go b/vendor/github.com/cilium/ebpf/prog.go index 67cfff67e..4b65f23b2 100644 --- a/vendor/github.com/cilium/ebpf/prog.go +++ b/vendor/github.com/cilium/ebpf/prog.go @@ -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() - 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) + return newProgramWithOptions(spec, opts, btfs) } -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,24 +169,39 @@ func convertProgramSpec(spec *ProgramSpec, handle *btf.Handle) (*bpfProgLoadAttr attr.progName = newBPFObjName(spec.Name) } - if handle != nil && spec.BTF != 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) + 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) } - attr.lineInfoRecSize = recSize - attr.lineInfoCnt = uint32(uint64(len(bytes)) / uint64(recSize)) - attr.lineInfo = internal.NewSlicePointer(bytes) - recSize, bytes, err = btf.ProgramFuncInfos(spec.BTF) - if err != nil { - return nil, fmt.Errorf("can't get BTF function infos: %w", err) + 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("get BTF line infos: %w", err) + } + attr.lineInfoRecSize = recSize + attr.lineInfoCnt = uint32(uint64(len(bytes)) / uint64(recSize)) + attr.lineInfo = internal.NewSlicePointer(bytes) + + recSize, bytes, err = btf.ProgramFuncInfos(spec.BTF) + if err != nil { + return nil, fmt.Errorf("get BTF function infos: %w", err) + } + attr.funcInfoRecSize = recSize + attr.funcInfoCnt = uint32(uint64(len(bytes)) / uint64(recSize)) + attr.funcInfo = internal.NewSlicePointer(bytes) } - attr.funcInfoRecSize = recSize - attr.funcInfoCnt = uint32(uint64(len(bytes)) / uint64(recSize)) - attr.funcInfo = internal.NewSlicePointer(bytes) } if spec.AttachTo != "" { @@ -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) - - // Check for EINVAL specifically, rather than err != nil since we - // otherwise misdetect due to insufficient permissions. - return !errors.Is(err, unix.EINVAL), nil + if errors.Is(err, unix.EINVAL) { + // Check for EINVAL specifically, rather than err != nil since we + // otherwise misdetect due to insufficient permissions. + 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 { diff --git a/vendor/github.com/cilium/ebpf/readme.md b/vendor/github.com/cilium/ebpf/readme.md deleted file mode 100644 index 298db57c3..000000000 --- a/vendor/github.com/cilium/ebpf/readme.md +++ /dev/null @@ -1,29 +0,0 @@ -eBPF -------- -[![PkgGoDev](https://pkg.go.dev/badge/github.com/cilium/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) diff --git a/vendor/github.com/cilium/ebpf/run-tests.sh b/vendor/github.com/cilium/ebpf/run-tests.sh index bd349f951..647a61aab 100644 --- a/vendor/github.com/cilium/ebpf/run-tests.sh +++ b/vendor/github.com/cilium/ebpf/run-tests.sh @@ -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}" diff --git a/vendor/github.com/cilium/ebpf/syscalls.go b/vendor/github.com/cilium/ebpf/syscalls.go index ff5c8e6c3..1cba1d747 100644 --- a/vendor/github.com/cilium/ebpf/syscalls.go +++ b/vendor/github.com/cilium/ebpf/syscalls.go @@ -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 - id uint32 - keySize uint32 - valueSize uint32 - maxEntries uint32 - flags uint32 - mapName bpfObjName // since 4.15 ad5b177bd73f + map_type uint32 // since 4.12 1e2709769086 + id uint32 + 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 - 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 + prog_type uint32 + id uint32 + tag [unix.BPF_TAG_SIZE]byte + 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) { diff --git a/vendor/github.com/cilium/ebpf/types.go b/vendor/github.com/cilium/ebpf/types.go index dd82dfd4d..3191ba1e0 100644 --- a/vendor/github.com/cilium/ebpf/types.go +++ b/vendor/github.com/cilium/ebpf/types.go @@ -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 false + return mt == PerCPUHash || mt == PerCPUArray || mt == LRUCPUHash +} + +// 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 +} diff --git a/vendor/github.com/containerd/cgroups/go.mod b/vendor/github.com/containerd/cgroups/go.mod index 9763944e2..fef297838 100644 --- a/vendor/github.com/containerd/cgroups/go.mod +++ b/vendor/github.com/containerd/cgroups/go.mod @@ -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 ) diff --git a/vendor/github.com/containerd/cgroups/go.sum b/vendor/github.com/containerd/cgroups/go.sum index 411bd4e6e..e3bdfb73a 100644 --- a/vendor/github.com/containerd/cgroups/go.sum +++ b/vendor/github.com/containerd/cgroups/go.sum @@ -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= diff --git a/vendor/github.com/containerd/cgroups/v2/ebpf.go b/vendor/github.com/containerd/cgroups/v2/ebpf.go index adda75508..bd384818c 100644 --- a/vendor/github.com/containerd/cgroups/v2/ebpf.go +++ b/vendor/github.com/containerd/cgroups/v2/ebpf.go @@ -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 } diff --git a/vendor/github.com/containerd/continuity/fs/copy.go b/vendor/github.com/containerd/continuity/fs/copy.go index 818bba2cd..2ee77d1ab 100644 --- a/vendor/github.com/containerd/continuity/fs/copy.go +++ b/vendor/github.com/containerd/continuity/fs/copy.go @@ -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") } } diff --git a/vendor/github.com/containerd/continuity/fs/copy_linux.go b/vendor/github.com/containerd/continuity/fs/copy_linux.go index 72bae7d4e..85beaee54 100644 --- a/vendor/github.com/containerd/continuity/fs/copy_linux.go +++ b/vendor/github.com/containerd/continuity/fs/copy_linux.go @@ -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 } } diff --git a/vendor/github.com/containerd/continuity/fs/copy_unix.go b/vendor/github.com/containerd/continuity/fs/copy_unix.go index dfd857aaa..923dd5a98 100644 --- a/vendor/github.com/containerd/continuity/fs/copy_unix.go +++ b/vendor/github.com/containerd/continuity/fs/copy_unix.go @@ -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 } } diff --git a/vendor/github.com/containerd/continuity/fs/copy_windows.go b/vendor/github.com/containerd/continuity/fs/copy_windows.go index 27c7d7dbb..0081583fd 100644 --- a/vendor/github.com/containerd/continuity/fs/copy_windows.go +++ b/vendor/github.com/containerd/continuity/fs/copy_windows.go @@ -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 } diff --git a/vendor/github.com/containerd/continuity/fs/fstest/file_unix.go b/vendor/github.com/containerd/continuity/fs/fstest/file_unix.go index c10e99ef2..9451198bb 100644 --- a/vendor/github.com/containerd/continuity/fs/fstest/file_unix.go +++ b/vendor/github.com/containerd/continuity/fs/fstest/file_unix.go @@ -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) }) } diff --git a/vendor/github.com/containerd/continuity/go.mod b/vendor/github.com/containerd/continuity/go.mod index 8587a8df8..35cea6ae8 100644 --- a/vendor/github.com/containerd/continuity/go.mod +++ b/vendor/github.com/containerd/continuity/go.mod @@ -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 ) diff --git a/vendor/github.com/containerd/continuity/go.sum b/vendor/github.com/containerd/continuity/go.sum index 71a34585c..a99faabda 100644 --- a/vendor/github.com/containerd/continuity/go.sum +++ b/vendor/github.com/containerd/continuity/go.sum @@ -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= diff --git a/vendor/github.com/containerd/continuity/proto/manifest.pb.go b/vendor/github.com/containerd/continuity/proto/manifest.pb.go index 243177662..c83a9e775 100644 --- a/vendor/github.com/containerd/continuity/proto/manifest.pb.go +++ b/vendor/github.com/containerd/continuity/proto/manifest.pb.go @@ -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, diff --git a/vendor/github.com/containerd/nri/README.md b/vendor/github.com/containerd/nri/README.md index 696262eb4..8329973f9 100644 --- a/vendor/github.com/containerd/nri/README.md +++ b/vendor/github.com/containerd/nri/README.md @@ -38,18 +38,18 @@ The config's default location will be `/etc/nri/resource.d/*.conf`. ```json { - "version": "0.1", - "plugins": [ - { - "type": "konfine", - "conf": { - "systemReserved": [0,1] - } - }, - { - "type": "clearcfs" - } - ] + "version": "0.1", + "plugins": [ + { + "type": "konfine", + "conf": { + "systemReserved": [0, 1] + } + }, + { + "type": "clearcfs" + } + ] } ``` @@ -59,23 +59,22 @@ Input to a plugin is provided via `STDIN` as a `json` payload. ```json { - "version": "0.1", - "state": "create", - "id": "redis", - "pid": 1234, - "spec": { - "resources": { - }, - "cgroupsPath": "default/redis", - "namespaces": { - "pid": "/proc/44/ns/pid", - "mount": "/proc/44/ns/mnt", - "net": "/proc/44/ns/net", - }, - "annotations": { - "qos.class: "ls" - } - } + "version": "0.1", + "state": "create", + "id": "redis", + "pid": 1234, + "spec": { + "resources": {}, + "cgroupsPath": "default/redis", + "namespaces": { + "pid": "/proc/44/ns/pid", + "mount": "/proc/44/ns/mnt", + "net": "/proc/44/ns/net" + }, + "annotations": { + "qos.class": "ls" + } + } } ``` @@ -83,11 +82,11 @@ Input to a plugin is provided via `STDIN` as a `json` payload. ```json { - "version": "0.1", - "state": "create", - "id": "redis", - "pid": 1234, - "cgroupsPath": "qos-ls/default/redis" + "version": "0.1", + "state": "create", + "id": "redis", + "pid": 1234, + "cgroupsPath": "qos-ls/default/redis" } ``` diff --git a/vendor/modules.txt b/vendor/modules.txt index 8e4495716..3d4c81483 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -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