diff options
author | gVisor bot <gvisor-bot@google.com> | 2021-01-13 04:47:27 +0000 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2021-01-13 04:47:27 +0000 |
commit | 43ca8a82cb55b2e82f479869a6eee019e91a3eff (patch) | |
tree | 4cb0aa42960543b8b41917617a9d821a7b1d2463 | |
parent | aec44e37bc7cec5e23479822a69726a4091613cd (diff) | |
parent | e74aa25e2289878fdbfc7affdd2e031be3a99b31 (diff) |
Merge release-20201216.0-94-ge74aa25e2 (automated)
-rw-r--r-- | go.mod | 1 | ||||
-rw-r--r-- | go.sum | 3 | ||||
-rw-r--r-- | pkg/sentry/loader/vdso_bin.go | 5 | ||||
-rw-r--r-- | pkg/sentry/platform/ring0/pagetables/walker_empty.go | 255 | ||||
-rw-r--r-- | pkg/sentry/platform/ring0/pagetables/walker_lookup.go | 255 | ||||
-rw-r--r-- | pkg/sentry/platform/ring0/pagetables/walker_map.go | 255 | ||||
-rw-r--r-- | pkg/sentry/platform/ring0/pagetables/walker_unmap.go | 255 | ||||
-rw-r--r-- | pkg/sentry/socket/netstack/netstack.go | 223 | ||||
-rw-r--r-- | pkg/sentry/socket/netstack/netstack_state_autogen.go | 25 | ||||
-rw-r--r-- | pkg/shim/api.go (renamed from pkg/shim/v2/api.go) | 2 | ||||
-rw-r--r-- | pkg/shim/epoll.go (renamed from pkg/shim/v2/epoll.go) | 2 | ||||
-rw-r--r-- | pkg/shim/options.go (renamed from pkg/shim/v2/options.go) | 2 | ||||
-rw-r--r-- | pkg/shim/proc/deleted_state.go (renamed from pkg/shim/v1/proc/deleted_state.go) | 0 | ||||
-rw-r--r-- | pkg/shim/proc/exec.go (renamed from pkg/shim/v1/proc/exec.go) | 0 | ||||
-rw-r--r-- | pkg/shim/proc/exec_state.go (renamed from pkg/shim/v1/proc/exec_state.go) | 0 | ||||
-rw-r--r-- | pkg/shim/proc/init.go (renamed from pkg/shim/v1/proc/init.go) | 6 | ||||
-rw-r--r-- | pkg/shim/proc/init_state.go (renamed from pkg/shim/v1/proc/init_state.go) | 0 | ||||
-rw-r--r-- | pkg/shim/proc/io.go (renamed from pkg/shim/v1/proc/io.go) | 0 | ||||
-rw-r--r-- | pkg/shim/proc/proc.go (renamed from pkg/shim/v1/proc/process.go) | 3 | ||||
-rw-r--r-- | pkg/shim/proc/proc_state_autogen.go (renamed from pkg/shim/v1/proc/proc_state_autogen.go) | 0 | ||||
-rw-r--r-- | pkg/shim/proc/types.go (renamed from pkg/shim/v1/proc/types.go) | 0 | ||||
-rw-r--r-- | pkg/shim/proc/utils.go (renamed from pkg/shim/v1/proc/utils.go) | 0 | ||||
-rw-r--r-- | pkg/shim/runtimeoptions/runtimeoptions.go (renamed from pkg/shim/v2/runtimeoptions/runtimeoptions.go) | 0 | ||||
-rw-r--r-- | pkg/shim/runtimeoptions/runtimeoptions_cri.go (renamed from pkg/shim/v2/runtimeoptions/runtimeoptions_cri.go) | 0 | ||||
-rw-r--r-- | pkg/shim/runtimeoptions/runtimeoptions_state_autogen.go (renamed from pkg/shim/v2/runtimeoptions/runtimeoptions_state_autogen.go) | 0 | ||||
-rw-r--r-- | pkg/shim/service.go (renamed from pkg/shim/v2/service.go) | 10 | ||||
-rw-r--r-- | pkg/shim/service_linux.go (renamed from pkg/shim/v2/service_linux.go) | 2 | ||||
-rw-r--r-- | pkg/shim/shim_linux_state_autogen.go (renamed from pkg/shim/v2/v2_linux_state_autogen.go) | 2 | ||||
-rw-r--r-- | pkg/shim/shim_state_autogen.go (renamed from pkg/shim/v1/shim/shim_state_autogen.go) | 2 | ||||
-rw-r--r-- | pkg/shim/state.go (renamed from pkg/shim/v2/state.go) | 2 | ||||
-rw-r--r-- | pkg/shim/utils/annotations.go (renamed from pkg/shim/v1/utils/annotations.go) | 0 | ||||
-rw-r--r-- | pkg/shim/utils/utils.go (renamed from pkg/shim/v1/utils/utils.go) | 2 | ||||
-rw-r--r-- | pkg/shim/utils/utils_state_autogen.go (renamed from pkg/shim/v1/utils/utils_state_autogen.go) | 0 | ||||
-rw-r--r-- | pkg/shim/utils/volumes.go (renamed from pkg/shim/v1/utils/volumes.go) | 0 | ||||
-rw-r--r-- | pkg/shim/v1/shim/api.go | 41 | ||||
-rw-r--r-- | pkg/shim/v1/shim/platform.go | 106 | ||||
-rw-r--r-- | pkg/shim/v1/shim/service.go | 572 | ||||
-rw-r--r-- | pkg/shim/v1/shim/shim.go | 17 | ||||
-rw-r--r-- | pkg/shim/v2/v2_state_autogen.go | 5 | ||||
-rw-r--r-- | pkg/tcpip/stack/registration.go | 2 | ||||
-rw-r--r-- | pkg/tcpip/stack/transport_demuxer.go | 5 | ||||
-rw-r--r-- | pkg/tcpip/transport/icmp/endpoint.go | 2 | ||||
-rw-r--r-- | pkg/tcpip/transport/tcp/endpoint.go | 80 | ||||
-rw-r--r-- | pkg/tcpip/transport/udp/endpoint.go | 14 | ||||
-rw-r--r-- | shim/cli/cli.go (renamed from shim/v2/cli/cli.go) | 6 | ||||
-rw-r--r-- | shim/cli/cli_state_autogen.go (renamed from shim/v1/cli/cli_state_autogen.go) | 0 | ||||
-rw-r--r-- | shim/main.go (renamed from shim/v2/main.go) | 2 | ||||
-rw-r--r-- | shim/v1/cli/api.go | 24 | ||||
-rw-r--r-- | shim/v1/cli/cli.go | 266 | ||||
-rw-r--r-- | shim/v1/cli/config.go | 40 | ||||
-rw-r--r-- | shim/v1/main.go | 24 | ||||
-rw-r--r-- | shim/v2/cli/cli_state_autogen.go | 3 |
52 files changed, 155 insertions, 2366 deletions
@@ -15,7 +15,6 @@ require ( github.com/containerd/continuity v0.0.0-20200928162600-f2cc35102c2a // indirect github.com/containerd/fifo v0.0.0-20191213151349-ff969a566b00 // indirect github.com/containerd/go-runc v0.0.0-20200220073739-7016d3ce2328 // indirect - github.com/containerd/ttrpc v0.0.0-20200121165050-0be804eadb15 // indirect github.com/containerd/typeurl v0.0.0-20200205145503-b45ef1f1f737 // indirect github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf // indirect github.com/coreos/go-systemd/v22 v22.0.0 // indirect @@ -66,9 +66,6 @@ github.com/containerd/fifo v0.0.0-20191213151349-ff969a566b00/go.mod h1:jPQ2IAeZ github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0= github.com/containerd/go-runc v0.0.0-20200220073739-7016d3ce2328 h1:PRTagVMbJcCezLcHXe8UJvR1oBzp2lG3CEumeFOLOds= github.com/containerd/go-runc v0.0.0-20200220073739-7016d3ce2328/go.mod h1:PpyHrqVs8FTi9vpyHwPwiNEGaACDxT/N/pLcvMSRA9g= -github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= -github.com/containerd/ttrpc v0.0.0-20200121165050-0be804eadb15 h1:+jgiLE5QylzgADj0Yldb4id1NQNRrDOROj7KDvY9PEc= -github.com/containerd/ttrpc v0.0.0-20200121165050-0be804eadb15/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y= github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc= github.com/containerd/typeurl v0.0.0-20200205145503-b45ef1f1f737 h1:HovfQDS/K3Mr7eyS0QJLxE1CbVUhjZCl6g3OhFJgP1o= github.com/containerd/typeurl v0.0.0-20200205145503-b45ef1f1f737/go.mod h1:TB1hUtrpaiO88KEK56ijojHS1+NeF0izUACaJW2mdXg= diff --git a/pkg/sentry/loader/vdso_bin.go b/pkg/sentry/loader/vdso_bin.go deleted file mode 100644 index 6d1afb179..000000000 --- a/pkg/sentry/loader/vdso_bin.go +++ /dev/null @@ -1,5 +0,0 @@ -// Generated by go_embed_data for //pkg/sentry/loader:vdso_bin. DO NOT EDIT. - -package loader - -var vdsoBin = []byte("ELF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\x00X\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x008\x00\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00p\xff\xff\xff\xff\xff\x00\x00p\xff\xff\xff\xff\xff\xae\x00\x00\x00\x00\x00\x00\xae\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x00\x00\x00\x00\x00\x00\xe0p\xff\xff\xff\xff\xff\xe0p\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00T\x00\x00\x00\x00\x00\x00Tp\xff\xff\xff\xff\xffTp\xff\xff\xff\xff\xff`\x00\x00\x00\x00\x00\x00\x00`\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xe5td\x00\x00\x00\xb4\x00\x00\x00\x00\x00\x00\xb4p\xff\xff\xff\xff\xff\xb4p\xff\xff\xff\xff\xffD\x00\x00\x00\x00\x00\x00\x00D\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\"\x00\x00 p\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\"\x00\x00\x00\x00\x00 p\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x000\x00\x00\x00\"\x00\x00\xf0p\xff\xff\xff\xff\xff&\x00\x00\x00\x00\x00\x00\x005\x00\x00\x00\x00\x00\xf0p\xff\xff\xff\xff\xff&\x00\x00\x00\x00\x00\x00\x00A\x00\x00\x00\"\x00\x00\x80p\xff\xff\xff\xff\xffb\x00\x00\x00\x00\x00\x00\x00N\x00\x00\x00\x00\x00\x80p\xff\xff\xff\xff\xffb\x00\x00\x00\x00\x00\x00\x00b\x00\x00\x00\"\x00\x00@p\xff\xff\xff\xff\xff8\x00\x00\x00\x00\x00\x00\x00p\x00\x00\x00\x00\x00@p\xff\xff\xff\xff\xff8\x00\x00\x00\x00\x00\x00\x00\x85\x00\x00\x00\x00\x000p\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00linux-vdso.so.1\x00LINUX_2.6\x00getcpu\x00__vdso_getcpu\x00time\x00__vdso_time\x00gettimeofday\x00__vdso_gettimeofday\x00clock_gettime\x00__vdso_clock_gettime\x00__kernel_rt_sigreturn\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa1\xbf\xee
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6u\xae\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00GNU\x00\x00\x00\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x00\x00\x00GNU\x00gold 1.16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00GNU\x00g\xf3E\xee\xe6C\n\x9a<\x8b\xa5L\xddU\x9fN;@\x00\x00\x00\x00\x00\x00|\x00\x00\\\x00\x00\x00\x8c\x00\x00t\x00\x00\x00\xcc\x00\x00\x8c\x00\x00\x00<
\x00\x00\xb4\x00\x00\x00l
\x00\x00\xd4\x00\x00\x00|
\x00\x00\xec\x00\x00\x00<\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00zR\x00x\x90\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x004\x00\x00\x00\x00\x008\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$\x00\x00\x00L\x00\x00\x008\x00\x00b\x00\x00\x00\x00E\x86D\x83D0RAA\x00\x00\x00t\x00\x00\x00\x80\x00\x00&\x00\x00\x00\x00E\x83G XA\x00\x00\x00\x00\x94\x00\x00\x00\x90\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x00\x00\x00\x88\x00\x00\xbb\x00\x00\x00\x00E\x83~\nmJ\x00\x00\x00\xcc\x00\x00\x00(
\x00\x00\xbe\x00\x00\x00\x00E\x83~\nmM\x00\x00\x00\x00\x00\x00\x00`p\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00hp\xff\xff\xff\xff\xff\n\x00\x00\x00\x00\x00\x00\x00\x9b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 p\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\xff\xffo\x00\x00\x00\x00p\xff\xff\xff\xff\xff\xfc\xff\xffo\x00\x00\x00\x00p\xff\xff\xff\xff\xff\xfd\xff\xffo\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf3\xfa\xb8\x00\x00\x00\xc3@\x00\xf3\xfa\x83\xfft\x83\xfft\x85\xfft\xb8\xe4\x00\x00\x00\xc3fD\x00\x00H\x89\xf7\xe9\x88\x00\x00\x84\x00\x00\x00\x00\x00H\x89\xf7\xe9\xb8\x00\x00\x00\x84\x00\x00\x00\x00\x00\xf3\xfaUH\x89\xf5SH\x83\xecH\x85\xfft:H\x89\xfbH\x89\xe7\xe8\x93\x00\x00\x00\x85\xc0u:H\x8b$H\x8bL$H\xba\xcf\xf7S㥛\xc4 H\x89H\x89\xc8H\xc1\xf9?H\xf7\xeaH\xc1\xfaH)\xcaH\x89S1\xc0H\x85\xedtH\xc7E\x00\x00\x00\x00\x00H\x83\xc4[]\xc3ff.\x84\x00\x00\x00\x00\x00\x00\xf3\xfaSH\x89\xfbH\x83\xecH\x89\xe7\xe8,\x00\x00\x00H\x8b$H\x85\xdbtH\x89H\x83\xc4[\xc3f.\x84\x00\x00\x00\x00\x00\xf3\xfa\xb85\x00\x00H\x98Ð\x90\xf3\xfaSH\x89\xfeH\x8d
\xc1\xde\xff\xffH\x8b9\x83\xe7\xfeL\x8bQ(L\x8bA8H\x8bY0L\x8bY@Lc\xcf\xae\xe81H\x8b9L9\xcfu\xddM\x85\xd2tv\x89\xc0H\xc1\xe2 H \xc21\xc0H9\xd3+H\xb8\x00\x00\x00\x00\x00ʚ;H\x89\xd11\xd2I\xf7\xf3H)\xd9H\x89\xcfH\xc1\xff?H\xaf\xf8H\xf7\xe1H\xfaH\xac\xd0 H\xb9SZ\x9b\xa0/\xb8D\x00I\xc0[L\x89\xc2H\xc1\xea H\x89\xd0H\xf7\xe11\xc0H\xc1\xeaH\x89Hi\xd2\x00ʚ;I)\xd0L\x89F\xc3\x84\x00\x00\x00\x00\x00\xb8\xe4\x00\x00\x001\xff[\xc3D\x00\x00\xf3\xfaSH\x89\xfeH\x8d
\xde\xff\xffH\x8b9\x83\xe7\xfeL\x8bQL\x8bAH\x8bYL\x8bY Lc\xcf\xae\xe81H\x8b9L9\xcfu\xddM\x85\xd2tv\x89\xc0H\xc1\xe2 H \xc21\xc0H9\xd3+H\xb8\x00\x00\x00\x00\x00ʚ;H\x89\xd11\xd2I\xf7\xf3H)\xd9H\x89\xcfH\xc1\xff?H\xaf\xf8H\xf7\xe1H\xfaH\xac\xd0 H\xb9SZ\x9b\xa0/\xb8D\x00I\xc0[L\x89\xc2H\xc1\xea H\x89\xd0H\xf7\xe11\xc0H\xc1\xeaH\x89Hi\xd2\x00ʚ;I)\xd0L\x89F\xc3\x84\x00\x00\x00\x00\x00\xb8\xe4\x00\x00\x00\xbf\x00\x00\x00[\xc3\x00GCC: (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x00\xf1\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000p\xff\xff\xff\xff\xff\xbb\x00\x00\x00\x00\x00\x00\x009\x00\x00\x00\x00\x00\xf0p\xff\xff\xff\xff\xff\xbe\x00\x00\x00\x00\x00\x00\x00]\x00\x00\x00 \x00\xe0p\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00f\x00\x00\x00\x00\x00\xf1\xff\x00\x00p\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00s\x00\x00\x00\x00\x00\xf1\xff\x00\xf0o\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00{\x00\x00\x00\x00\xf1\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x85\x00\x00\x00\"\x00\x00 p\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x8c\x00\x00\x00\x00\x00 p\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x9a\x00\x00\x00\"\x00\x00\xf0p\xff\xff\xff\xff\xff&\x00\x00\x00\x00\x00\x00\x00\x9f\x00\x00\x00\x00\x00\xf0p\xff\xff\xff\xff\xff&\x00\x00\x00\x00\x00\x00\x00\xab\x00\x00\x00\"\x00\x00\x80p\xff\xff\xff\xff\xffb\x00\x00\x00\x00\x00\x00\x00\xb8\x00\x00\x00\x00\x00\x80p\xff\xff\xff\xff\xffb\x00\x00\x00\x00\x00\x00\x00\xcc\x00\x00\x00\"\x00\x00@p\xff\xff\xff\xff\xff8\x00\x00\x00\x00\x00\x00\x00\xda\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\x00\x00\x00\x00\x00@p\xff\xff\xff\xff\xff8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000p\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00vdso.cc\x00vdso_time.cc\x00_ZN4vdso13ClockRealtimeEP8timespec\x00_ZN4vdso14ClockMonotonicEP8timespec\x00_DYNAMIC\x00VDSO_PRELINK\x00_params\x00LINUX_2.6\x00getcpu\x00__vdso_getcpu\x00time\x00__vdso_time\x00gettimeofday\x00__vdso_gettimeofday\x00clock_gettime\x00_GLOBAL_OFFSET_TABLE_\x00__vdso_clock_gettime\x00__kernel_rt_sigreturn\x00\x00.text\x00.comment\x00.bss\x00.dynstr\x00.eh_frame_hdr\x00.gnu.version\x00.dynsym\x00.hash\x00.note\x00.eh_frame\x00.gnu.version_d\x00.dynamic\x00.shstrtab\x00.strtab\x00.symtab\x00.data\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 p\xff\xff\xff\xff\xff \x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x008\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00`p\xff\xff\xff\xff\xff`\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00hp\xff\xff\xff\xff\xffh\x00\x00\x00\x00\x00\x00\x9b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00\xff\xff\xffo\x00\x00\x00\x00\x00\x00\x00p\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\x00\x00\x00\xfd\xff\xffo\x00\x00\x00\x00\x00\x00\x00p\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x008\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Tp\xff\xff\xff\xff\xffT\x00\x00\x00\x00\x00\x00`\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00p\x00\x00\x00\x00\x00\x00\x00\xb4p\xff\xff\xff\xff\xff\xb4\x00\x00\x00\x00\x00\x00D\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00L\x00\x00\x00\x00\x00p\x00\x00\x00\x00\x00\x00\x00\xf8p\xff\xff\xff\xff\xff\xf8\x00\x00\x00\x00\x00\x00\xe8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0p\xff\xff\xff\xff\xff\xe0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x88\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0p\xff\xff\xff\xff\xff\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000p\xff\xff\xff\xff\xff0\x00\x00\x00\x00\x00\x00~\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaep\xff\xff\xff\xff\xff\xae\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xae\x00\x00\x00\x00\x00\x00+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x00\x00\x00\x00\x00\x00\xc8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00x\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc3\x00\x00\x00\x00\x00\x00\x8e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00") diff --git a/pkg/sentry/platform/ring0/pagetables/walker_empty.go b/pkg/sentry/platform/ring0/pagetables/walker_empty.go deleted file mode 100644 index 417784e17..000000000 --- a/pkg/sentry/platform/ring0/pagetables/walker_empty.go +++ /dev/null @@ -1,255 +0,0 @@ -package pagetables - -// Walker walks page tables. -type emptyWalker struct { - // pageTables are the tables to walk. - pageTables *PageTables - - // Visitor is the set of arguments. - visitor emptyVisitor -} - -// iterateRange iterates over all appropriate levels of page tables for the given range. -// -// If requiresAlloc is true, then Set _must_ be called on all given PTEs. The -// exception is super pages. If a valid super page (huge or jumbo) cannot be -// installed, then the walk will continue to individual entries. -// -// This algorithm will attempt to maximize the use of super pages whenever -// possible. Whether a super page is provided will be clear through the range -// provided in the callback. -// -// Note that if requiresAlloc is true, then no gaps will be present. However, -// if alloc is not set, then the iteration will likely be full of gaps. -// -// Note that this function should generally be avoided in favor of Map, Unmap, -// etc. when not necessary. -// -// Precondition: start must be page-aligned. -// -// Precondition: start must be less than end. -// -// Precondition: If requiresAlloc is true, then start and end should not span -// non-canonical ranges. If they do, a panic will result. -// -//go:nosplit -func (w *emptyWalker) iterateRange(start, end uintptr) { - if start%pteSize != 0 { - panic("unaligned start") - } - if end < start { - panic("start > end") - } - if start < lowerTop { - if end <= lowerTop { - w.iterateRangeCanonical(start, end) - } else if end > lowerTop && end <= upperBottom { - if w.visitor.requiresAlloc() { - panic("alloc spans non-canonical range") - } - w.iterateRangeCanonical(start, lowerTop) - } else { - if w.visitor.requiresAlloc() { - panic("alloc spans non-canonical range") - } - w.iterateRangeCanonical(start, lowerTop) - w.iterateRangeCanonical(upperBottom, end) - } - } else if start < upperBottom { - if end <= upperBottom { - if w.visitor.requiresAlloc() { - panic("alloc spans non-canonical range") - } - } else { - if w.visitor.requiresAlloc() { - panic("alloc spans non-canonical range") - } - w.iterateRangeCanonical(upperBottom, end) - } - } else { - w.iterateRangeCanonical(start, end) - } -} - -// next returns the next address quantized by the given size. -// -//go:nosplit -func emptynext(start uintptr, size uintptr) uintptr { - start &= ^(size - 1) - start += size - return start -} - -// iterateRangeCanonical walks a canonical range. -// -//go:nosplit -func (w *emptyWalker) iterateRangeCanonical(start, end uintptr) { - for pgdIndex := uint16((start & pgdMask) >> pgdShift); start < end && pgdIndex < entriesPerPage; pgdIndex++ { - var ( - pgdEntry = &w.pageTables.root[pgdIndex] - pudEntries *PTEs - ) - if !pgdEntry.Valid() { - if !w.visitor.requiresAlloc() { - - start = emptynext(start, pgdSize) - continue - } - - pudEntries = w.pageTables.Allocator.NewPTEs() - pgdEntry.setPageTable(w.pageTables, pudEntries) - } else { - pudEntries = w.pageTables.Allocator.LookupPTEs(pgdEntry.Address()) - } - - clearPUDEntries := uint16(0) - - for pudIndex := uint16((start & pudMask) >> pudShift); start < end && pudIndex < entriesPerPage; pudIndex++ { - var ( - pudEntry = &pudEntries[pudIndex] - pmdEntries *PTEs - ) - if !pudEntry.Valid() { - if !w.visitor.requiresAlloc() { - - clearPUDEntries++ - start = emptynext(start, pudSize) - continue - } - - if start&(pudSize-1) == 0 && end-start >= pudSize { - pudEntry.SetSuper() - w.visitor.visit(uintptr(start), pudEntry, pudSize-1) - if pudEntry.Valid() { - start = emptynext(start, pudSize) - continue - } - } - - pmdEntries = w.pageTables.Allocator.NewPTEs() - pudEntry.setPageTable(w.pageTables, pmdEntries) - - } else if pudEntry.IsSuper() { - - if w.visitor.requiresSplit() && (start&(pudSize-1) != 0 || end < emptynext(start, pudSize)) { - - pmdEntries = w.pageTables.Allocator.NewPTEs() - for index := uint16(0); index < entriesPerPage; index++ { - pmdEntries[index].SetSuper() - pmdEntries[index].Set( - pudEntry.Address()+(pmdSize*uintptr(index)), - pudEntry.Opts()) - } - pudEntry.setPageTable(w.pageTables, pmdEntries) - } else { - - w.visitor.visit(uintptr(start), pudEntry, pudSize-1) - - if !pudEntry.Valid() { - clearPUDEntries++ - } - - start = emptynext(start, pudSize) - continue - } - } else { - pmdEntries = w.pageTables.Allocator.LookupPTEs(pudEntry.Address()) - } - - clearPMDEntries := uint16(0) - - for pmdIndex := uint16((start & pmdMask) >> pmdShift); start < end && pmdIndex < entriesPerPage; pmdIndex++ { - var ( - pmdEntry = &pmdEntries[pmdIndex] - pteEntries *PTEs - ) - if !pmdEntry.Valid() { - if !w.visitor.requiresAlloc() { - - clearPMDEntries++ - start = emptynext(start, pmdSize) - continue - } - - if start&(pmdSize-1) == 0 && end-start >= pmdSize { - pmdEntry.SetSuper() - w.visitor.visit(uintptr(start), pmdEntry, pmdSize-1) - if pmdEntry.Valid() { - start = emptynext(start, pmdSize) - continue - } - } - - pteEntries = w.pageTables.Allocator.NewPTEs() - pmdEntry.setPageTable(w.pageTables, pteEntries) - - } else if pmdEntry.IsSuper() { - - if w.visitor.requiresSplit() && (start&(pmdSize-1) != 0 || end < emptynext(start, pmdSize)) { - - pteEntries = w.pageTables.Allocator.NewPTEs() - for index := uint16(0); index < entriesPerPage; index++ { - pteEntries[index].Set( - pmdEntry.Address()+(pteSize*uintptr(index)), - pmdEntry.Opts()) - } - pmdEntry.setPageTable(w.pageTables, pteEntries) - } else { - - w.visitor.visit(uintptr(start), pmdEntry, pmdSize-1) - - if !pmdEntry.Valid() { - clearPMDEntries++ - } - - start = emptynext(start, pmdSize) - continue - } - } else { - pteEntries = w.pageTables.Allocator.LookupPTEs(pmdEntry.Address()) - } - - clearPTEEntries := uint16(0) - - for pteIndex := uint16((start & pteMask) >> pteShift); start < end && pteIndex < entriesPerPage; pteIndex++ { - var ( - pteEntry = &pteEntries[pteIndex] - ) - if !pteEntry.Valid() && !w.visitor.requiresAlloc() { - clearPTEEntries++ - start += pteSize - continue - } - - w.visitor.visit(uintptr(start), pteEntry, pteSize-1) - if !pteEntry.Valid() { - if w.visitor.requiresAlloc() { - panic("PTE not set after iteration with requiresAlloc!") - } - clearPTEEntries++ - } - - start += pteSize - continue - } - - if clearPTEEntries == entriesPerPage { - pmdEntry.Clear() - w.pageTables.Allocator.FreePTEs(pteEntries) - clearPMDEntries++ - } - } - - if clearPMDEntries == entriesPerPage { - pudEntry.Clear() - w.pageTables.Allocator.FreePTEs(pmdEntries) - clearPUDEntries++ - } - } - - if clearPUDEntries == entriesPerPage { - pgdEntry.Clear() - w.pageTables.Allocator.FreePTEs(pudEntries) - } - } -} diff --git a/pkg/sentry/platform/ring0/pagetables/walker_lookup.go b/pkg/sentry/platform/ring0/pagetables/walker_lookup.go deleted file mode 100644 index 906c9c50f..000000000 --- a/pkg/sentry/platform/ring0/pagetables/walker_lookup.go +++ /dev/null @@ -1,255 +0,0 @@ -package pagetables - -// Walker walks page tables. -type lookupWalker struct { - // pageTables are the tables to walk. - pageTables *PageTables - - // Visitor is the set of arguments. - visitor lookupVisitor -} - -// iterateRange iterates over all appropriate levels of page tables for the given range. -// -// If requiresAlloc is true, then Set _must_ be called on all given PTEs. The -// exception is super pages. If a valid super page (huge or jumbo) cannot be -// installed, then the walk will continue to individual entries. -// -// This algorithm will attempt to maximize the use of super pages whenever -// possible. Whether a super page is provided will be clear through the range -// provided in the callback. -// -// Note that if requiresAlloc is true, then no gaps will be present. However, -// if alloc is not set, then the iteration will likely be full of gaps. -// -// Note that this function should generally be avoided in favor of Map, Unmap, -// etc. when not necessary. -// -// Precondition: start must be page-aligned. -// -// Precondition: start must be less than end. -// -// Precondition: If requiresAlloc is true, then start and end should not span -// non-canonical ranges. If they do, a panic will result. -// -//go:nosplit -func (w *lookupWalker) iterateRange(start, end uintptr) { - if start%pteSize != 0 { - panic("unaligned start") - } - if end < start { - panic("start > end") - } - if start < lowerTop { - if end <= lowerTop { - w.iterateRangeCanonical(start, end) - } else if end > lowerTop && end <= upperBottom { - if w.visitor.requiresAlloc() { - panic("alloc spans non-canonical range") - } - w.iterateRangeCanonical(start, lowerTop) - } else { - if w.visitor.requiresAlloc() { - panic("alloc spans non-canonical range") - } - w.iterateRangeCanonical(start, lowerTop) - w.iterateRangeCanonical(upperBottom, end) - } - } else if start < upperBottom { - if end <= upperBottom { - if w.visitor.requiresAlloc() { - panic("alloc spans non-canonical range") - } - } else { - if w.visitor.requiresAlloc() { - panic("alloc spans non-canonical range") - } - w.iterateRangeCanonical(upperBottom, end) - } - } else { - w.iterateRangeCanonical(start, end) - } -} - -// next returns the next address quantized by the given size. -// -//go:nosplit -func lookupnext(start uintptr, size uintptr) uintptr { - start &= ^(size - 1) - start += size - return start -} - -// iterateRangeCanonical walks a canonical range. -// -//go:nosplit -func (w *lookupWalker) iterateRangeCanonical(start, end uintptr) { - for pgdIndex := uint16((start & pgdMask) >> pgdShift); start < end && pgdIndex < entriesPerPage; pgdIndex++ { - var ( - pgdEntry = &w.pageTables.root[pgdIndex] - pudEntries *PTEs - ) - if !pgdEntry.Valid() { - if !w.visitor.requiresAlloc() { - - start = lookupnext(start, pgdSize) - continue - } - - pudEntries = w.pageTables.Allocator.NewPTEs() - pgdEntry.setPageTable(w.pageTables, pudEntries) - } else { - pudEntries = w.pageTables.Allocator.LookupPTEs(pgdEntry.Address()) - } - - clearPUDEntries := uint16(0) - - for pudIndex := uint16((start & pudMask) >> pudShift); start < end && pudIndex < entriesPerPage; pudIndex++ { - var ( - pudEntry = &pudEntries[pudIndex] - pmdEntries *PTEs - ) - if !pudEntry.Valid() { - if !w.visitor.requiresAlloc() { - - clearPUDEntries++ - start = lookupnext(start, pudSize) - continue - } - - if start&(pudSize-1) == 0 && end-start >= pudSize { - pudEntry.SetSuper() - w.visitor.visit(uintptr(start), pudEntry, pudSize-1) - if pudEntry.Valid() { - start = lookupnext(start, pudSize) - continue - } - } - - pmdEntries = w.pageTables.Allocator.NewPTEs() - pudEntry.setPageTable(w.pageTables, pmdEntries) - - } else if pudEntry.IsSuper() { - - if w.visitor.requiresSplit() && (start&(pudSize-1) != 0 || end < lookupnext(start, pudSize)) { - - pmdEntries = w.pageTables.Allocator.NewPTEs() - for index := uint16(0); index < entriesPerPage; index++ { - pmdEntries[index].SetSuper() - pmdEntries[index].Set( - pudEntry.Address()+(pmdSize*uintptr(index)), - pudEntry.Opts()) - } - pudEntry.setPageTable(w.pageTables, pmdEntries) - } else { - - w.visitor.visit(uintptr(start), pudEntry, pudSize-1) - - if !pudEntry.Valid() { - clearPUDEntries++ - } - - start = lookupnext(start, pudSize) - continue - } - } else { - pmdEntries = w.pageTables.Allocator.LookupPTEs(pudEntry.Address()) - } - - clearPMDEntries := uint16(0) - - for pmdIndex := uint16((start & pmdMask) >> pmdShift); start < end && pmdIndex < entriesPerPage; pmdIndex++ { - var ( - pmdEntry = &pmdEntries[pmdIndex] - pteEntries *PTEs - ) - if !pmdEntry.Valid() { - if !w.visitor.requiresAlloc() { - - clearPMDEntries++ - start = lookupnext(start, pmdSize) - continue - } - - if start&(pmdSize-1) == 0 && end-start >= pmdSize { - pmdEntry.SetSuper() - w.visitor.visit(uintptr(start), pmdEntry, pmdSize-1) - if pmdEntry.Valid() { - start = lookupnext(start, pmdSize) - continue - } - } - - pteEntries = w.pageTables.Allocator.NewPTEs() - pmdEntry.setPageTable(w.pageTables, pteEntries) - - } else if pmdEntry.IsSuper() { - - if w.visitor.requiresSplit() && (start&(pmdSize-1) != 0 || end < lookupnext(start, pmdSize)) { - - pteEntries = w.pageTables.Allocator.NewPTEs() - for index := uint16(0); index < entriesPerPage; index++ { - pteEntries[index].Set( - pmdEntry.Address()+(pteSize*uintptr(index)), - pmdEntry.Opts()) - } - pmdEntry.setPageTable(w.pageTables, pteEntries) - } else { - - w.visitor.visit(uintptr(start), pmdEntry, pmdSize-1) - - if !pmdEntry.Valid() { - clearPMDEntries++ - } - - start = lookupnext(start, pmdSize) - continue - } - } else { - pteEntries = w.pageTables.Allocator.LookupPTEs(pmdEntry.Address()) - } - - clearPTEEntries := uint16(0) - - for pteIndex := uint16((start & pteMask) >> pteShift); start < end && pteIndex < entriesPerPage; pteIndex++ { - var ( - pteEntry = &pteEntries[pteIndex] - ) - if !pteEntry.Valid() && !w.visitor.requiresAlloc() { - clearPTEEntries++ - start += pteSize - continue - } - - w.visitor.visit(uintptr(start), pteEntry, pteSize-1) - if !pteEntry.Valid() { - if w.visitor.requiresAlloc() { - panic("PTE not set after iteration with requiresAlloc!") - } - clearPTEEntries++ - } - - start += pteSize - continue - } - - if clearPTEEntries == entriesPerPage { - pmdEntry.Clear() - w.pageTables.Allocator.FreePTEs(pteEntries) - clearPMDEntries++ - } - } - - if clearPMDEntries == entriesPerPage { - pudEntry.Clear() - w.pageTables.Allocator.FreePTEs(pmdEntries) - clearPUDEntries++ - } - } - - if clearPUDEntries == entriesPerPage { - pgdEntry.Clear() - w.pageTables.Allocator.FreePTEs(pudEntries) - } - } -} diff --git a/pkg/sentry/platform/ring0/pagetables/walker_map.go b/pkg/sentry/platform/ring0/pagetables/walker_map.go deleted file mode 100644 index 61ee3c825..000000000 --- a/pkg/sentry/platform/ring0/pagetables/walker_map.go +++ /dev/null @@ -1,255 +0,0 @@ -package pagetables - -// Walker walks page tables. -type mapWalker struct { - // pageTables are the tables to walk. - pageTables *PageTables - - // Visitor is the set of arguments. - visitor mapVisitor -} - -// iterateRange iterates over all appropriate levels of page tables for the given range. -// -// If requiresAlloc is true, then Set _must_ be called on all given PTEs. The -// exception is super pages. If a valid super page (huge or jumbo) cannot be -// installed, then the walk will continue to individual entries. -// -// This algorithm will attempt to maximize the use of super pages whenever -// possible. Whether a super page is provided will be clear through the range -// provided in the callback. -// -// Note that if requiresAlloc is true, then no gaps will be present. However, -// if alloc is not set, then the iteration will likely be full of gaps. -// -// Note that this function should generally be avoided in favor of Map, Unmap, -// etc. when not necessary. -// -// Precondition: start must be page-aligned. -// -// Precondition: start must be less than end. -// -// Precondition: If requiresAlloc is true, then start and end should not span -// non-canonical ranges. If they do, a panic will result. -// -//go:nosplit -func (w *mapWalker) iterateRange(start, end uintptr) { - if start%pteSize != 0 { - panic("unaligned start") - } - if end < start { - panic("start > end") - } - if start < lowerTop { - if end <= lowerTop { - w.iterateRangeCanonical(start, end) - } else if end > lowerTop && end <= upperBottom { - if w.visitor.requiresAlloc() { - panic("alloc spans non-canonical range") - } - w.iterateRangeCanonical(start, lowerTop) - } else { - if w.visitor.requiresAlloc() { - panic("alloc spans non-canonical range") - } - w.iterateRangeCanonical(start, lowerTop) - w.iterateRangeCanonical(upperBottom, end) - } - } else if start < upperBottom { - if end <= upperBottom { - if w.visitor.requiresAlloc() { - panic("alloc spans non-canonical range") - } - } else { - if w.visitor.requiresAlloc() { - panic("alloc spans non-canonical range") - } - w.iterateRangeCanonical(upperBottom, end) - } - } else { - w.iterateRangeCanonical(start, end) - } -} - -// next returns the next address quantized by the given size. -// -//go:nosplit -func mapnext(start uintptr, size uintptr) uintptr { - start &= ^(size - 1) - start += size - return start -} - -// iterateRangeCanonical walks a canonical range. -// -//go:nosplit -func (w *mapWalker) iterateRangeCanonical(start, end uintptr) { - for pgdIndex := uint16((start & pgdMask) >> pgdShift); start < end && pgdIndex < entriesPerPage; pgdIndex++ { - var ( - pgdEntry = &w.pageTables.root[pgdIndex] - pudEntries *PTEs - ) - if !pgdEntry.Valid() { - if !w.visitor.requiresAlloc() { - - start = mapnext(start, pgdSize) - continue - } - - pudEntries = w.pageTables.Allocator.NewPTEs() - pgdEntry.setPageTable(w.pageTables, pudEntries) - } else { - pudEntries = w.pageTables.Allocator.LookupPTEs(pgdEntry.Address()) - } - - clearPUDEntries := uint16(0) - - for pudIndex := uint16((start & pudMask) >> pudShift); start < end && pudIndex < entriesPerPage; pudIndex++ { - var ( - pudEntry = &pudEntries[pudIndex] - pmdEntries *PTEs - ) - if !pudEntry.Valid() { - if !w.visitor.requiresAlloc() { - - clearPUDEntries++ - start = mapnext(start, pudSize) - continue - } - - if start&(pudSize-1) == 0 && end-start >= pudSize { - pudEntry.SetSuper() - w.visitor.visit(uintptr(start), pudEntry, pudSize-1) - if pudEntry.Valid() { - start = mapnext(start, pudSize) - continue - } - } - - pmdEntries = w.pageTables.Allocator.NewPTEs() - pudEntry.setPageTable(w.pageTables, pmdEntries) - - } else if pudEntry.IsSuper() { - - if w.visitor.requiresSplit() && (start&(pudSize-1) != 0 || end < mapnext(start, pudSize)) { - - pmdEntries = w.pageTables.Allocator.NewPTEs() - for index := uint16(0); index < entriesPerPage; index++ { - pmdEntries[index].SetSuper() - pmdEntries[index].Set( - pudEntry.Address()+(pmdSize*uintptr(index)), - pudEntry.Opts()) - } - pudEntry.setPageTable(w.pageTables, pmdEntries) - } else { - - w.visitor.visit(uintptr(start), pudEntry, pudSize-1) - - if !pudEntry.Valid() { - clearPUDEntries++ - } - - start = mapnext(start, pudSize) - continue - } - } else { - pmdEntries = w.pageTables.Allocator.LookupPTEs(pudEntry.Address()) - } - - clearPMDEntries := uint16(0) - - for pmdIndex := uint16((start & pmdMask) >> pmdShift); start < end && pmdIndex < entriesPerPage; pmdIndex++ { - var ( - pmdEntry = &pmdEntries[pmdIndex] - pteEntries *PTEs - ) - if !pmdEntry.Valid() { - if !w.visitor.requiresAlloc() { - - clearPMDEntries++ - start = mapnext(start, pmdSize) - continue - } - - if start&(pmdSize-1) == 0 && end-start >= pmdSize { - pmdEntry.SetSuper() - w.visitor.visit(uintptr(start), pmdEntry, pmdSize-1) - if pmdEntry.Valid() { - start = mapnext(start, pmdSize) - continue - } - } - - pteEntries = w.pageTables.Allocator.NewPTEs() - pmdEntry.setPageTable(w.pageTables, pteEntries) - - } else if pmdEntry.IsSuper() { - - if w.visitor.requiresSplit() && (start&(pmdSize-1) != 0 || end < mapnext(start, pmdSize)) { - - pteEntries = w.pageTables.Allocator.NewPTEs() - for index := uint16(0); index < entriesPerPage; index++ { - pteEntries[index].Set( - pmdEntry.Address()+(pteSize*uintptr(index)), - pmdEntry.Opts()) - } - pmdEntry.setPageTable(w.pageTables, pteEntries) - } else { - - w.visitor.visit(uintptr(start), pmdEntry, pmdSize-1) - - if !pmdEntry.Valid() { - clearPMDEntries++ - } - - start = mapnext(start, pmdSize) - continue - } - } else { - pteEntries = w.pageTables.Allocator.LookupPTEs(pmdEntry.Address()) - } - - clearPTEEntries := uint16(0) - - for pteIndex := uint16((start & pteMask) >> pteShift); start < end && pteIndex < entriesPerPage; pteIndex++ { - var ( - pteEntry = &pteEntries[pteIndex] - ) - if !pteEntry.Valid() && !w.visitor.requiresAlloc() { - clearPTEEntries++ - start += pteSize - continue - } - - w.visitor.visit(uintptr(start), pteEntry, pteSize-1) - if !pteEntry.Valid() { - if w.visitor.requiresAlloc() { - panic("PTE not set after iteration with requiresAlloc!") - } - clearPTEEntries++ - } - - start += pteSize - continue - } - - if clearPTEEntries == entriesPerPage { - pmdEntry.Clear() - w.pageTables.Allocator.FreePTEs(pteEntries) - clearPMDEntries++ - } - } - - if clearPMDEntries == entriesPerPage { - pudEntry.Clear() - w.pageTables.Allocator.FreePTEs(pmdEntries) - clearPUDEntries++ - } - } - - if clearPUDEntries == entriesPerPage { - pgdEntry.Clear() - w.pageTables.Allocator.FreePTEs(pudEntries) - } - } -} diff --git a/pkg/sentry/platform/ring0/pagetables/walker_unmap.go b/pkg/sentry/platform/ring0/pagetables/walker_unmap.go deleted file mode 100644 index be2aa0ce4..000000000 --- a/pkg/sentry/platform/ring0/pagetables/walker_unmap.go +++ /dev/null @@ -1,255 +0,0 @@ -package pagetables - -// Walker walks page tables. -type unmapWalker struct { - // pageTables are the tables to walk. - pageTables *PageTables - - // Visitor is the set of arguments. - visitor unmapVisitor -} - -// iterateRange iterates over all appropriate levels of page tables for the given range. -// -// If requiresAlloc is true, then Set _must_ be called on all given PTEs. The -// exception is super pages. If a valid super page (huge or jumbo) cannot be -// installed, then the walk will continue to individual entries. -// -// This algorithm will attempt to maximize the use of super pages whenever -// possible. Whether a super page is provided will be clear through the range -// provided in the callback. -// -// Note that if requiresAlloc is true, then no gaps will be present. However, -// if alloc is not set, then the iteration will likely be full of gaps. -// -// Note that this function should generally be avoided in favor of Map, Unmap, -// etc. when not necessary. -// -// Precondition: start must be page-aligned. -// -// Precondition: start must be less than end. -// -// Precondition: If requiresAlloc is true, then start and end should not span -// non-canonical ranges. If they do, a panic will result. -// -//go:nosplit -func (w *unmapWalker) iterateRange(start, end uintptr) { - if start%pteSize != 0 { - panic("unaligned start") - } - if end < start { - panic("start > end") - } - if start < lowerTop { - if end <= lowerTop { - w.iterateRangeCanonical(start, end) - } else if end > lowerTop && end <= upperBottom { - if w.visitor.requiresAlloc() { - panic("alloc spans non-canonical range") - } - w.iterateRangeCanonical(start, lowerTop) - } else { - if w.visitor.requiresAlloc() { - panic("alloc spans non-canonical range") - } - w.iterateRangeCanonical(start, lowerTop) - w.iterateRangeCanonical(upperBottom, end) - } - } else if start < upperBottom { - if end <= upperBottom { - if w.visitor.requiresAlloc() { - panic("alloc spans non-canonical range") - } - } else { - if w.visitor.requiresAlloc() { - panic("alloc spans non-canonical range") - } - w.iterateRangeCanonical(upperBottom, end) - } - } else { - w.iterateRangeCanonical(start, end) - } -} - -// next returns the next address quantized by the given size. -// -//go:nosplit -func unmapnext(start uintptr, size uintptr) uintptr { - start &= ^(size - 1) - start += size - return start -} - -// iterateRangeCanonical walks a canonical range. -// -//go:nosplit -func (w *unmapWalker) iterateRangeCanonical(start, end uintptr) { - for pgdIndex := uint16((start & pgdMask) >> pgdShift); start < end && pgdIndex < entriesPerPage; pgdIndex++ { - var ( - pgdEntry = &w.pageTables.root[pgdIndex] - pudEntries *PTEs - ) - if !pgdEntry.Valid() { - if !w.visitor.requiresAlloc() { - - start = unmapnext(start, pgdSize) - continue - } - - pudEntries = w.pageTables.Allocator.NewPTEs() - pgdEntry.setPageTable(w.pageTables, pudEntries) - } else { - pudEntries = w.pageTables.Allocator.LookupPTEs(pgdEntry.Address()) - } - - clearPUDEntries := uint16(0) - - for pudIndex := uint16((start & pudMask) >> pudShift); start < end && pudIndex < entriesPerPage; pudIndex++ { - var ( - pudEntry = &pudEntries[pudIndex] - pmdEntries *PTEs - ) - if !pudEntry.Valid() { - if !w.visitor.requiresAlloc() { - - clearPUDEntries++ - start = unmapnext(start, pudSize) - continue - } - - if start&(pudSize-1) == 0 && end-start >= pudSize { - pudEntry.SetSuper() - w.visitor.visit(uintptr(start), pudEntry, pudSize-1) - if pudEntry.Valid() { - start = unmapnext(start, pudSize) - continue - } - } - - pmdEntries = w.pageTables.Allocator.NewPTEs() - pudEntry.setPageTable(w.pageTables, pmdEntries) - - } else if pudEntry.IsSuper() { - - if w.visitor.requiresSplit() && (start&(pudSize-1) != 0 || end < unmapnext(start, pudSize)) { - - pmdEntries = w.pageTables.Allocator.NewPTEs() - for index := uint16(0); index < entriesPerPage; index++ { - pmdEntries[index].SetSuper() - pmdEntries[index].Set( - pudEntry.Address()+(pmdSize*uintptr(index)), - pudEntry.Opts()) - } - pudEntry.setPageTable(w.pageTables, pmdEntries) - } else { - - w.visitor.visit(uintptr(start), pudEntry, pudSize-1) - - if !pudEntry.Valid() { - clearPUDEntries++ - } - - start = unmapnext(start, pudSize) - continue - } - } else { - pmdEntries = w.pageTables.Allocator.LookupPTEs(pudEntry.Address()) - } - - clearPMDEntries := uint16(0) - - for pmdIndex := uint16((start & pmdMask) >> pmdShift); start < end && pmdIndex < entriesPerPage; pmdIndex++ { - var ( - pmdEntry = &pmdEntries[pmdIndex] - pteEntries *PTEs - ) - if !pmdEntry.Valid() { - if !w.visitor.requiresAlloc() { - - clearPMDEntries++ - start = unmapnext(start, pmdSize) - continue - } - - if start&(pmdSize-1) == 0 && end-start >= pmdSize { - pmdEntry.SetSuper() - w.visitor.visit(uintptr(start), pmdEntry, pmdSize-1) - if pmdEntry.Valid() { - start = unmapnext(start, pmdSize) - continue - } - } - - pteEntries = w.pageTables.Allocator.NewPTEs() - pmdEntry.setPageTable(w.pageTables, pteEntries) - - } else if pmdEntry.IsSuper() { - - if w.visitor.requiresSplit() && (start&(pmdSize-1) != 0 || end < unmapnext(start, pmdSize)) { - - pteEntries = w.pageTables.Allocator.NewPTEs() - for index := uint16(0); index < entriesPerPage; index++ { - pteEntries[index].Set( - pmdEntry.Address()+(pteSize*uintptr(index)), - pmdEntry.Opts()) - } - pmdEntry.setPageTable(w.pageTables, pteEntries) - } else { - - w.visitor.visit(uintptr(start), pmdEntry, pmdSize-1) - - if !pmdEntry.Valid() { - clearPMDEntries++ - } - - start = unmapnext(start, pmdSize) - continue - } - } else { - pteEntries = w.pageTables.Allocator.LookupPTEs(pmdEntry.Address()) - } - - clearPTEEntries := uint16(0) - - for pteIndex := uint16((start & pteMask) >> pteShift); start < end && pteIndex < entriesPerPage; pteIndex++ { - var ( - pteEntry = &pteEntries[pteIndex] - ) - if !pteEntry.Valid() && !w.visitor.requiresAlloc() { - clearPTEEntries++ - start += pteSize - continue - } - - w.visitor.visit(uintptr(start), pteEntry, pteSize-1) - if !pteEntry.Valid() { - if w.visitor.requiresAlloc() { - panic("PTE not set after iteration with requiresAlloc!") - } - clearPTEEntries++ - } - - start += pteSize - continue - } - - if clearPTEEntries == entriesPerPage { - pmdEntry.Clear() - w.pageTables.Allocator.FreePTEs(pteEntries) - clearPMDEntries++ - } - } - - if clearPMDEntries == entriesPerPage { - pudEntry.Clear() - w.pageTables.Allocator.FreePTEs(pmdEntries) - clearPUDEntries++ - } - } - - if clearPUDEntries == entriesPerPage { - pgdEntry.Clear() - w.pageTables.Allocator.FreePTEs(pudEntries) - } - } -} diff --git a/pkg/sentry/socket/netstack/netstack.go b/pkg/sentry/socket/netstack/netstack.go index dcf898c0a..57f224120 100644 --- a/pkg/sentry/socket/netstack/netstack.go +++ b/pkg/sentry/socket/netstack/netstack.go @@ -309,11 +309,6 @@ type socketOpsCommon struct { // readMu protects access to the below fields. readMu sync.Mutex `state:"nosave"` - // readCM holds control message information for the last packet read - // from Endpoint. - readCM socket.IPControlMessages - sender tcpip.FullAddress - linkPacketInfo tcpip.LinkPacketInfo // sockOptTimestamp corresponds to SO_TIMESTAMP. When true, timestamps // of returned messages can be returned via control messages. When @@ -368,25 +363,6 @@ func (s *socketOpsCommon) isPacketBased() bool { return s.skType == linux.SOCK_DGRAM || s.skType == linux.SOCK_SEQPACKET || s.skType == linux.SOCK_RDM || s.skType == linux.SOCK_RAW } -// Precondition: s.readMu must be held. -func (s *socketOpsCommon) readLocked(dst io.Writer, count int, peek bool) (numRead, numTotal int, serr *syserr.Error) { - res, err := s.Endpoint.Read(dst, count, tcpip.ReadOptions{ - Peek: peek, - NeedRemoteAddr: true, - NeedLinkPacketInfo: true, - }) - - // Assign these anyways. - s.readCM = socket.NewIPControlMessages(s.family, res.ControlMessages) - s.sender = res.RemoteAddr - s.linkPacketInfo = res.LinkPacketInfo - - if err != nil { - return 0, 0, syserr.TranslateNetstackError(err) - } - return res.Count, res.Total, nil -} - // Release implements fs.FileOperations.Release. func (s *socketOpsCommon) Release(ctx context.Context) { e, ch := waiter.NewChannelEntry(nil) @@ -436,11 +412,13 @@ func (s *SocketOperations) WriteTo(ctx context.Context, _ *fs.File, dst io.Write defer s.readMu.Unlock() // This may return a blocking error. - n, _, err := s.readLocked(dst, int(count), dup /* peek */) + res, err := s.Endpoint.Read(dst, int(count), tcpip.ReadOptions{ + Peek: dup, + }) if err != nil { - return 0, err.ToError() + return 0, syserr.TranslateNetstackError(err).ToError() } - return int64(n), nil + return int64(res.Count), nil } // ioSequencePayload implements tcpip.Payload. @@ -2557,22 +2535,6 @@ func (s *socketOpsCommon) GetPeerName(t *kernel.Task) (linux.SockAddr, uint32, * return a, l, nil } -// streamRead is the fast path for non-blocking, non-peek, stream-based socket. -// -// Precondition: s.readMu must be locked. -func (s *socketOpsCommon) streamRead(ctx context.Context, dst io.Writer, count int) (int, *syserr.Error) { - // Always do at least one read, even if the number of bytes to read is 0. - var n int - n, _, err := s.readLocked(dst, count, false /* peek */) - if err != nil { - return 0, err - } - if n > 0 { - s.Endpoint.ModerateRecvBuf(n) - } - return n, nil -} - func (s *socketOpsCommon) fillCmsgInq(cmsg *socket.ControlMessages) { if !s.sockOptInq { return @@ -2608,133 +2570,102 @@ func toLinuxPacketType(pktType tcpip.PacketType) uint8 { func (s *socketOpsCommon) nonBlockingRead(ctx context.Context, dst usermem.IOSequence, peek, trunc, senderRequested bool) (int, int, linux.SockAddr, uint32, socket.ControlMessages, *syserr.Error) { isPacket := s.isPacketBased() - // Fast path for regular reads from stream (e.g., TCP) endpoints. Note - // that senderRequested is ignored for stream sockets. - if !peek && !isPacket { - // TCP sockets discard the data if MSG_TRUNC is set. - // - // This behavior is documented in man 7 tcp: - // Since version 2.4, Linux supports the use of MSG_TRUNC in the flags - // argument of recv(2) (and recvmsg(2)). This flag causes the received - // bytes of data to be discarded, rather than passed back in a - // caller-supplied buffer. - s.readMu.Lock() - - var w io.Writer - if trunc { - w = ioutil.Discard - } else { - w = dst.Writer(ctx) - } - - n, err := s.streamRead(ctx, w, int(dst.NumBytes())) - - if err == nil && !trunc { - // Set the control message, even if 0 bytes were read. - s.updateTimestamp() - } - - cmsg := s.controlMessages() - s.fillCmsgInq(&cmsg) - s.readMu.Unlock() - return n, 0, nil, 0, cmsg, err + readOptions := tcpip.ReadOptions{ + Peek: peek, + NeedRemoteAddr: senderRequested, + NeedLinkPacketInfo: isPacket, } - s.readMu.Lock() - defer s.readMu.Unlock() - - // MSG_TRUNC with MSG_PEEK on a TCP socket returns the - // amount that could be read, and does not write to buffer. - isTCPPeekTrunc := !isPacket && peek && trunc - + // TCP sockets discard the data if MSG_TRUNC is set. + // + // This behavior is documented in man 7 tcp: + // Since version 2.4, Linux supports the use of MSG_TRUNC in the flags + // argument of recv(2) (and recvmsg(2)). This flag causes the received + // bytes of data to be discarded, rather than passed back in a + // caller-supplied buffer. var w io.Writer - if isTCPPeekTrunc { + if !isPacket && trunc { w = ioutil.Discard } else { w = dst.Writer(ctx) } - var numRead, numTotal int - var err *syserr.Error - numRead, numTotal, err = s.readLocked(w, int(dst.NumBytes()), peek) - if err != nil { - return 0, 0, nil, 0, socket.ControlMessages{}, err - } + s.readMu.Lock() + defer s.readMu.Unlock() - if isTCPPeekTrunc { - // TCP endpoint does not return the total bytes in buffer as numTotal. - // We need to query it from socket option. - rql, err := s.Endpoint.GetSockOptInt(tcpip.ReceiveQueueSizeOption) - if err != nil { - return 0, 0, nil, 0, socket.ControlMessages{}, syserr.TranslateNetstackError(err) - } - available := int(rql) - bufLen := int(dst.NumBytes()) - if available < bufLen { - return available, 0, nil, 0, socket.ControlMessages{}, nil - } - return bufLen, 0, nil, 0, socket.ControlMessages{}, nil + res, err := s.Endpoint.Read(w, int(dst.NumBytes()), readOptions) + if err != nil { + return 0, 0, nil, 0, socket.ControlMessages{}, syserr.TranslateNetstackError(err) } - // Set the control message, even if 0 bytes were read. - s.updateTimestamp() + s.updateTimestamp(res.ControlMessages) - var addr linux.SockAddr - var addrLen uint32 - if isPacket && senderRequested { - addr, addrLen = socket.ConvertAddress(s.family, s.sender) - switch v := addr.(type) { - case *linux.SockAddrLink: - v.Protocol = socket.Htons(uint16(s.linkPacketInfo.Protocol)) - v.PacketType = toLinuxPacketType(s.linkPacketInfo.PktType) + if isPacket { + var addr linux.SockAddr + var addrLen uint32 + if senderRequested { + addr, addrLen = socket.ConvertAddress(s.family, res.RemoteAddr) + switch v := addr.(type) { + case *linux.SockAddrLink: + v.Protocol = socket.Htons(uint16(res.LinkPacketInfo.Protocol)) + v.PacketType = toLinuxPacketType(res.LinkPacketInfo.PktType) + } } - } - if peek { - if trunc && numTotal > numRead { - // isPacket must be true. - return numTotal, linux.MSG_TRUNC, addr, addrLen, s.controlMessages(), nil + msgLen := res.Count + if trunc { + msgLen = res.Total } - return numRead, 0, nil, 0, s.controlMessages(), nil - } - var msgLen int - if isPacket { - msgLen = numTotal - } else { - msgLen = numRead - } + var flags int + if res.Total > res.Count { + flags |= linux.MSG_TRUNC + } - var flags int - if msgLen > numRead { - flags |= linux.MSG_TRUNC + return msgLen, flags, addr, addrLen, s.controlMessages(res.ControlMessages), nil } - n := numRead - if trunc { - n = msgLen + if peek { + // MSG_TRUNC with MSG_PEEK on a TCP socket returns the + // amount that could be read, and does not write to buffer. + if trunc { + // TCP endpoint does not return the total bytes in buffer as numTotal. + // We need to query it from socket option. + rql, err := s.Endpoint.GetSockOptInt(tcpip.ReceiveQueueSizeOption) + if err != nil { + return 0, 0, nil, 0, socket.ControlMessages{}, syserr.TranslateNetstackError(err) + } + msgLen := int(dst.NumBytes()) + if msgLen > rql { + msgLen = rql + } + return msgLen, 0, nil, 0, socket.ControlMessages{}, nil + } + } else if n := res.Count; n != 0 { + s.Endpoint.ModerateRecvBuf(n) } - cmsg := s.controlMessages() + cmsg := s.controlMessages(res.ControlMessages) s.fillCmsgInq(&cmsg) - return n, flags, addr, addrLen, cmsg, nil + return res.Count, 0, nil, 0, cmsg, syserr.TranslateNetstackError(err) } -func (s *socketOpsCommon) controlMessages() socket.ControlMessages { +func (s *socketOpsCommon) controlMessages(cm tcpip.ControlMessages) socket.ControlMessages { + readCM := socket.NewIPControlMessages(s.family, cm) return socket.ControlMessages{ IP: socket.IPControlMessages{ - HasTimestamp: s.readCM.HasTimestamp && s.sockOptTimestamp, - Timestamp: s.readCM.Timestamp, - HasInq: s.readCM.HasInq, - Inq: s.readCM.Inq, - HasTOS: s.readCM.HasTOS, - TOS: s.readCM.TOS, - HasTClass: s.readCM.HasTClass, - TClass: s.readCM.TClass, - HasIPPacketInfo: s.readCM.HasIPPacketInfo, - PacketInfo: s.readCM.PacketInfo, - OriginalDstAddress: s.readCM.OriginalDstAddress, - SockErr: s.readCM.SockErr, + HasTimestamp: readCM.HasTimestamp && s.sockOptTimestamp, + Timestamp: readCM.Timestamp, + HasInq: readCM.HasInq, + Inq: readCM.Inq, + HasTOS: readCM.HasTOS, + TOS: readCM.TOS, + HasTClass: readCM.HasTClass, + TClass: readCM.TClass, + HasIPPacketInfo: readCM.HasIPPacketInfo, + PacketInfo: readCM.PacketInfo, + OriginalDstAddress: readCM.OriginalDstAddress, + SockErr: readCM.SockErr, }, } } @@ -2743,11 +2674,11 @@ func (s *socketOpsCommon) controlMessages() socket.ControlMessages { // successfully writing packet data out to userspace. // // Precondition: s.readMu must be locked. -func (s *socketOpsCommon) updateTimestamp() { +func (s *socketOpsCommon) updateTimestamp(cm tcpip.ControlMessages) { // Save the SIOCGSTAMP timestamp only if SO_TIMESTAMP is disabled. if !s.sockOptTimestamp { s.timestampValid = true - s.timestampNS = s.readCM.Timestamp + s.timestampNS = cm.Timestamp } } diff --git a/pkg/sentry/socket/netstack/netstack_state_autogen.go b/pkg/sentry/socket/netstack/netstack_state_autogen.go index 9925e2e9e..ec15d5643 100644 --- a/pkg/sentry/socket/netstack/netstack_state_autogen.go +++ b/pkg/sentry/socket/netstack/netstack_state_autogen.go @@ -41,9 +41,6 @@ func (s *socketOpsCommon) StateFields() []string { "Endpoint", "skType", "protocol", - "readCM", - "sender", - "linkPacketInfo", "sockOptTimestamp", "timestampValid", "timestampNS", @@ -61,13 +58,10 @@ func (s *socketOpsCommon) StateSave(stateSinkObject state.Sink) { stateSinkObject.Save(3, &s.Endpoint) stateSinkObject.Save(4, &s.skType) stateSinkObject.Save(5, &s.protocol) - stateSinkObject.Save(6, &s.readCM) - stateSinkObject.Save(7, &s.sender) - stateSinkObject.Save(8, &s.linkPacketInfo) - stateSinkObject.Save(9, &s.sockOptTimestamp) - stateSinkObject.Save(10, &s.timestampValid) - stateSinkObject.Save(11, &s.timestampNS) - stateSinkObject.Save(12, &s.sockOptInq) + stateSinkObject.Save(6, &s.sockOptTimestamp) + stateSinkObject.Save(7, &s.timestampValid) + stateSinkObject.Save(8, &s.timestampNS) + stateSinkObject.Save(9, &s.sockOptInq) } func (s *socketOpsCommon) afterLoad() {} @@ -79,13 +73,10 @@ func (s *socketOpsCommon) StateLoad(stateSourceObject state.Source) { stateSourceObject.Load(3, &s.Endpoint) stateSourceObject.Load(4, &s.skType) stateSourceObject.Load(5, &s.protocol) - stateSourceObject.Load(6, &s.readCM) - stateSourceObject.Load(7, &s.sender) - stateSourceObject.Load(8, &s.linkPacketInfo) - stateSourceObject.Load(9, &s.sockOptTimestamp) - stateSourceObject.Load(10, &s.timestampValid) - stateSourceObject.Load(11, &s.timestampNS) - stateSourceObject.Load(12, &s.sockOptInq) + stateSourceObject.Load(6, &s.sockOptTimestamp) + stateSourceObject.Load(7, &s.timestampValid) + stateSourceObject.Load(8, &s.timestampNS) + stateSourceObject.Load(9, &s.sockOptInq) } func (s *SocketVFS2) StateTypeName() string { diff --git a/pkg/shim/v2/api.go b/pkg/shim/api.go index 5a60a04db..6d1741f0c 100644 --- a/pkg/shim/v2/api.go +++ b/pkg/shim/api.go @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package v2 +package shim import ( "github.com/containerd/containerd/api/events" diff --git a/pkg/shim/v2/epoll.go b/pkg/shim/epoll.go index 41232cca8..737d2b781 100644 --- a/pkg/shim/v2/epoll.go +++ b/pkg/shim/epoll.go @@ -15,7 +15,7 @@ // +build linux -package v2 +package shim import ( "context" diff --git a/pkg/shim/v2/options.go b/pkg/shim/options.go index 9db33fd1f..e40a1a07d 100644 --- a/pkg/shim/v2/options.go +++ b/pkg/shim/options.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package v2 +package shim const optionsType = "io.containerd.runsc.v1.options" diff --git a/pkg/shim/v1/proc/deleted_state.go b/pkg/shim/proc/deleted_state.go index d9b970c4d..d9b970c4d 100644 --- a/pkg/shim/v1/proc/deleted_state.go +++ b/pkg/shim/proc/deleted_state.go diff --git a/pkg/shim/v1/proc/exec.go b/pkg/shim/proc/exec.go index 1d1d90488..1d1d90488 100644 --- a/pkg/shim/v1/proc/exec.go +++ b/pkg/shim/proc/exec.go diff --git a/pkg/shim/v1/proc/exec_state.go b/pkg/shim/proc/exec_state.go index 4dcda8b44..4dcda8b44 100644 --- a/pkg/shim/v1/proc/exec_state.go +++ b/pkg/shim/proc/exec_state.go diff --git a/pkg/shim/v1/proc/init.go b/pkg/shim/proc/init.go index 9fd7d978c..cacaade88 100644 --- a/pkg/shim/v1/proc/init.go +++ b/pkg/shim/proc/init.go @@ -39,9 +39,6 @@ import ( "gvisor.dev/gvisor/pkg/shim/runsc" ) -// InitPidFile name of the file that contains the init pid. -const InitPidFile = "init.pid" - // Init represents an initial process for a container. type Init struct { wg sync.WaitGroup @@ -122,7 +119,8 @@ func (p *Init) Create(ctx context.Context, r *CreateConfig) (err error) { return fmt.Errorf("failed to create OCI runtime io pipes: %w", err) } } - pidFile := filepath.Join(p.Bundle, InitPidFile) + // pidFile is the file that will contain the sandbox pid. + pidFile := filepath.Join(p.Bundle, "init.pid") opts := &runsc.CreateOpts{ PidFile: pidFile, } diff --git a/pkg/shim/v1/proc/init_state.go b/pkg/shim/proc/init_state.go index 0065fc385..0065fc385 100644 --- a/pkg/shim/v1/proc/init_state.go +++ b/pkg/shim/proc/init_state.go diff --git a/pkg/shim/v1/proc/io.go b/pkg/shim/proc/io.go index 34d825fb7..34d825fb7 100644 --- a/pkg/shim/v1/proc/io.go +++ b/pkg/shim/proc/io.go diff --git a/pkg/shim/v1/proc/process.go b/pkg/shim/proc/proc.go index e8315326d..edba3fca5 100644 --- a/pkg/shim/v1/proc/process.go +++ b/pkg/shim/proc/proc.go @@ -13,7 +13,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -// Package proc contains process-related utilities. +// Package proc is responsible to manage the communication between the shim and +// the sandbox process running the container. package proc import ( diff --git a/pkg/shim/v1/proc/proc_state_autogen.go b/pkg/shim/proc/proc_state_autogen.go index 210252d9d..210252d9d 100644 --- a/pkg/shim/v1/proc/proc_state_autogen.go +++ b/pkg/shim/proc/proc_state_autogen.go diff --git a/pkg/shim/v1/proc/types.go b/pkg/shim/proc/types.go index fc182cf5e..fc182cf5e 100644 --- a/pkg/shim/v1/proc/types.go +++ b/pkg/shim/proc/types.go diff --git a/pkg/shim/v1/proc/utils.go b/pkg/shim/proc/utils.go index 7c2c409af..7c2c409af 100644 --- a/pkg/shim/v1/proc/utils.go +++ b/pkg/shim/proc/utils.go diff --git a/pkg/shim/v2/runtimeoptions/runtimeoptions.go b/pkg/shim/runtimeoptions/runtimeoptions.go index 072dd87f0..072dd87f0 100644 --- a/pkg/shim/v2/runtimeoptions/runtimeoptions.go +++ b/pkg/shim/runtimeoptions/runtimeoptions.go diff --git a/pkg/shim/v2/runtimeoptions/runtimeoptions_cri.go b/pkg/shim/runtimeoptions/runtimeoptions_cri.go index e6102b4cf..e6102b4cf 100644 --- a/pkg/shim/v2/runtimeoptions/runtimeoptions_cri.go +++ b/pkg/shim/runtimeoptions/runtimeoptions_cri.go diff --git a/pkg/shim/v2/runtimeoptions/runtimeoptions_state_autogen.go b/pkg/shim/runtimeoptions/runtimeoptions_state_autogen.go index f5c883045..f5c883045 100644 --- a/pkg/shim/v2/runtimeoptions/runtimeoptions_state_autogen.go +++ b/pkg/shim/runtimeoptions/runtimeoptions_state_autogen.go diff --git a/pkg/shim/v2/service.go b/pkg/shim/service.go index 6aaf5fab8..9aba26ac7 100644 --- a/pkg/shim/v2/service.go +++ b/pkg/shim/service.go @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -// Package v2 implements Containerd Shim v2 interface. -package v2 +// Package shim implements Containerd Shim v2 interface. +package shim import ( "context" @@ -49,10 +49,10 @@ import ( "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/cleanup" + "gvisor.dev/gvisor/pkg/shim/proc" "gvisor.dev/gvisor/pkg/shim/runsc" - "gvisor.dev/gvisor/pkg/shim/v1/proc" - "gvisor.dev/gvisor/pkg/shim/v1/utils" - "gvisor.dev/gvisor/pkg/shim/v2/runtimeoptions" + "gvisor.dev/gvisor/pkg/shim/runtimeoptions" + "gvisor.dev/gvisor/pkg/shim/utils" "gvisor.dev/gvisor/runsc/specutils" ) diff --git a/pkg/shim/v2/service_linux.go b/pkg/shim/service_linux.go index 1800ab90b..11622ed60 100644 --- a/pkg/shim/v2/service_linux.go +++ b/pkg/shim/service_linux.go @@ -15,7 +15,7 @@ // +build linux -package v2 +package shim import ( "context" diff --git a/pkg/shim/v2/v2_linux_state_autogen.go b/pkg/shim/shim_linux_state_autogen.go index 1023f4d8f..191a9e496 100644 --- a/pkg/shim/v2/v2_linux_state_autogen.go +++ b/pkg/shim/shim_linux_state_autogen.go @@ -2,4 +2,4 @@ // +build linux -package v2 +package shim diff --git a/pkg/shim/v1/shim/shim_state_autogen.go b/pkg/shim/shim_state_autogen.go index ce6579b97..191a9e496 100644 --- a/pkg/shim/v1/shim/shim_state_autogen.go +++ b/pkg/shim/shim_state_autogen.go @@ -1,3 +1,5 @@ // automatically generated by stateify. +// +build linux + package shim diff --git a/pkg/shim/v2/state.go b/pkg/shim/state.go index 1f4be33d3..5e9e92ec3 100644 --- a/pkg/shim/v2/state.go +++ b/pkg/shim/state.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package v2 +package shim import ( "encoding/json" diff --git a/pkg/shim/v1/utils/annotations.go b/pkg/shim/utils/annotations.go index 1e9d3f365..1e9d3f365 100644 --- a/pkg/shim/v1/utils/annotations.go +++ b/pkg/shim/utils/annotations.go diff --git a/pkg/shim/v1/utils/utils.go b/pkg/shim/utils/utils.go index 21e75d16d..7b1cd983e 100644 --- a/pkg/shim/v1/utils/utils.go +++ b/pkg/shim/utils/utils.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// Package utils contains utility functions. +// Package utils container miscellaneous utility function used by the shim. package utils import ( diff --git a/pkg/shim/v1/utils/utils_state_autogen.go b/pkg/shim/utils/utils_state_autogen.go index dba8bfb1a..dba8bfb1a 100644 --- a/pkg/shim/v1/utils/utils_state_autogen.go +++ b/pkg/shim/utils/utils_state_autogen.go diff --git a/pkg/shim/v1/utils/volumes.go b/pkg/shim/utils/volumes.go index 52a428179..52a428179 100644 --- a/pkg/shim/v1/utils/volumes.go +++ b/pkg/shim/utils/volumes.go diff --git a/pkg/shim/v1/shim/api.go b/pkg/shim/v1/shim/api.go deleted file mode 100644 index 8200eb012..000000000 --- a/pkg/shim/v1/shim/api.go +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2018 The containerd Authors. -// Copyright 2019 The gVisor Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package shim - -import ( - "github.com/containerd/containerd/api/events" -) - -// TaskCreate is an alias for events.TaskCreate. -type TaskCreate = events.TaskCreate - -// TaskStart is an alias for events.TaskStart. -type TaskStart = events.TaskStart - -// TaskOOM is an alias for events.TaskOOM. -type TaskOOM = events.TaskOOM - -// TaskExit is an alias for events.TaskExit. -type TaskExit = events.TaskExit - -// TaskDelete is an alias for events.TaskDelete. -type TaskDelete = events.TaskDelete - -// TaskExecAdded is an alias for events.TaskExecAdded. -type TaskExecAdded = events.TaskExecAdded - -// TaskExecStarted is an alias for events.TaskExecStarted. -type TaskExecStarted = events.TaskExecStarted diff --git a/pkg/shim/v1/shim/platform.go b/pkg/shim/v1/shim/platform.go deleted file mode 100644 index f590f80ef..000000000 --- a/pkg/shim/v1/shim/platform.go +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright 2018 The containerd Authors. -// Copyright 2019 The gVisor Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package shim - -import ( - "context" - "fmt" - "io" - "sync" - "syscall" - - "github.com/containerd/console" - "github.com/containerd/fifo" -) - -type linuxPlatform struct { - epoller *console.Epoller -} - -func (p *linuxPlatform) CopyConsole(ctx context.Context, console console.Console, stdin, stdout, stderr string, wg *sync.WaitGroup) (console.Console, error) { - if p.epoller == nil { - return nil, fmt.Errorf("uninitialized epoller") - } - - epollConsole, err := p.epoller.Add(console) - if err != nil { - return nil, err - } - - if stdin != "" { - in, err := fifo.OpenFifo(ctx, stdin, syscall.O_RDONLY, 0) - if err != nil { - return nil, err - } - go func() { - p := bufPool.Get().(*[]byte) - defer bufPool.Put(p) - io.CopyBuffer(epollConsole, in, *p) - }() - } - - outw, err := fifo.OpenFifo(ctx, stdout, syscall.O_WRONLY, 0) - if err != nil { - return nil, err - } - outr, err := fifo.OpenFifo(ctx, stdout, syscall.O_RDONLY, 0) - if err != nil { - return nil, err - } - wg.Add(1) - go func() { - p := bufPool.Get().(*[]byte) - defer bufPool.Put(p) - io.CopyBuffer(outw, epollConsole, *p) - epollConsole.Close() - outr.Close() - outw.Close() - wg.Done() - }() - return epollConsole, nil -} - -func (p *linuxPlatform) ShutdownConsole(ctx context.Context, cons console.Console) error { - if p.epoller == nil { - return fmt.Errorf("uninitialized epoller") - } - epollConsole, ok := cons.(*console.EpollConsole) - if !ok { - return fmt.Errorf("expected EpollConsole, got %#v", cons) - } - return epollConsole.Shutdown(p.epoller.CloseConsole) -} - -func (p *linuxPlatform) Close() error { - return p.epoller.Close() -} - -// initialize a single epoll fd to manage our consoles. `initPlatform` should -// only be called once. -func (s *Service) initPlatform() error { - if s.platform != nil { - return nil - } - epoller, err := console.NewEpoller() - if err != nil { - return fmt.Errorf("failed to initialize epoller: %w", err) - } - s.platform = &linuxPlatform{ - epoller: epoller, - } - go epoller.Wait() - return nil -} diff --git a/pkg/shim/v1/shim/service.go b/pkg/shim/v1/shim/service.go deleted file mode 100644 index 80aa59b33..000000000 --- a/pkg/shim/v1/shim/service.go +++ /dev/null @@ -1,572 +0,0 @@ -// Copyright 2018 The containerd Authors. -// Copyright 2019 The gVisor Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package shim - -import ( - "context" - "fmt" - "os" - "path/filepath" - "sync" - - "github.com/containerd/console" - "github.com/containerd/containerd/api/types/task" - "github.com/containerd/containerd/errdefs" - "github.com/containerd/containerd/events" - "github.com/containerd/containerd/log" - "github.com/containerd/containerd/mount" - "github.com/containerd/containerd/namespaces" - "github.com/containerd/containerd/pkg/process" - "github.com/containerd/containerd/pkg/stdio" - "github.com/containerd/containerd/runtime" - "github.com/containerd/containerd/runtime/linux/runctypes" - shim "github.com/containerd/containerd/runtime/v1/shim/v1" - "github.com/containerd/containerd/sys/reaper" - "github.com/containerd/typeurl" - "github.com/gogo/protobuf/types" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - - "gvisor.dev/gvisor/pkg/shim/runsc" - "gvisor.dev/gvisor/pkg/shim/v1/proc" - "gvisor.dev/gvisor/pkg/shim/v1/utils" -) - -var ( - empty = &types.Empty{} - bufPool = sync.Pool{ - New: func() interface{} { - buffer := make([]byte, 32<<10) - return &buffer - }, - } -) - -// Config contains shim specific configuration. -type Config struct { - Path string - Namespace string - WorkDir string - RuntimeRoot string - RunscConfig map[string]string -} - -// NewService returns a new shim service that can be used via GRPC. -func NewService(config Config, publisher events.Publisher) (*Service, error) { - if config.Namespace == "" { - return nil, fmt.Errorf("shim namespace cannot be empty") - } - ctx := namespaces.WithNamespace(context.Background(), config.Namespace) - s := &Service{ - config: config, - context: ctx, - processes: make(map[string]process.Process), - events: make(chan interface{}, 128), - ec: proc.ExitCh, - } - go s.processExits() - if err := s.initPlatform(); err != nil { - return nil, fmt.Errorf("failed to initialized platform behavior: %w", err) - } - go s.forward(publisher) - return s, nil -} - -// Service is the shim implementation of a remote shim over GRPC. -type Service struct { - mu sync.Mutex - - config Config - context context.Context - processes map[string]process.Process - events chan interface{} - platform stdio.Platform - ec chan proc.Exit - - // Filled by Create() - id string - bundle string -} - -// Create creates a new initial process and container with the underlying OCI runtime. -func (s *Service) Create(ctx context.Context, r *shim.CreateTaskRequest) (_ *shim.CreateTaskResponse, err error) { - s.mu.Lock() - defer s.mu.Unlock() - - var mounts []proc.Mount - for _, m := range r.Rootfs { - mounts = append(mounts, proc.Mount{ - Type: m.Type, - Source: m.Source, - Target: m.Target, - Options: m.Options, - }) - } - - rootfs := filepath.Join(r.Bundle, "rootfs") - if err := os.Mkdir(rootfs, 0711); err != nil && !os.IsExist(err) { - return nil, err - } - - config := &proc.CreateConfig{ - ID: r.ID, - Bundle: r.Bundle, - Runtime: r.Runtime, - Rootfs: mounts, - Terminal: r.Terminal, - Stdin: r.Stdin, - Stdout: r.Stdout, - Stderr: r.Stderr, - } - defer func() { - if err != nil { - if err2 := mount.UnmountAll(rootfs, 0); err2 != nil { - log.G(ctx).WithError(err2).Warn("Failed to cleanup rootfs mount") - } - } - }() - for _, rm := range mounts { - m := &mount.Mount{ - Type: rm.Type, - Source: rm.Source, - Options: rm.Options, - } - if err := m.Mount(rootfs); err != nil { - return nil, fmt.Errorf("failed to mount rootfs component %v: %w", m, err) - } - } - process, err := newInit( - s.config.Path, - s.config.WorkDir, - s.config.RuntimeRoot, - s.config.Namespace, - s.config.RunscConfig, - s.platform, - config, - r.Options, - ) - if err := process.Create(ctx, config); err != nil { - return nil, errdefs.ToGRPC(err) - } - // Save the main task id and bundle to the shim for additional - // requests. - s.id = r.ID - s.bundle = r.Bundle - pid := process.Pid() - s.processes[r.ID] = process - return &shim.CreateTaskResponse{ - Pid: uint32(pid), - }, nil -} - -// Start starts a process. -func (s *Service) Start(ctx context.Context, r *shim.StartRequest) (*shim.StartResponse, error) { - p, err := s.getExecProcess(r.ID) - if err != nil { - return nil, err - } - if err := p.Start(ctx); err != nil { - return nil, err - } - return &shim.StartResponse{ - ID: p.ID(), - Pid: uint32(p.Pid()), - }, nil -} - -// Delete deletes the initial process and container. -func (s *Service) Delete(ctx context.Context, r *types.Empty) (*shim.DeleteResponse, error) { - p, err := s.getInitProcess() - if err != nil { - return nil, err - } - if err := p.Delete(ctx); err != nil { - return nil, err - } - s.mu.Lock() - delete(s.processes, s.id) - s.mu.Unlock() - s.platform.Close() - return &shim.DeleteResponse{ - ExitStatus: uint32(p.ExitStatus()), - ExitedAt: p.ExitedAt(), - Pid: uint32(p.Pid()), - }, nil -} - -// DeleteProcess deletes an exec'd process. -func (s *Service) DeleteProcess(ctx context.Context, r *shim.DeleteProcessRequest) (*shim.DeleteResponse, error) { - if r.ID == s.id { - return nil, status.Errorf(codes.InvalidArgument, "cannot delete init process with DeleteProcess") - } - p, err := s.getExecProcess(r.ID) - if err != nil { - return nil, err - } - if err := p.Delete(ctx); err != nil { - return nil, err - } - s.mu.Lock() - delete(s.processes, r.ID) - s.mu.Unlock() - return &shim.DeleteResponse{ - ExitStatus: uint32(p.ExitStatus()), - ExitedAt: p.ExitedAt(), - Pid: uint32(p.Pid()), - }, nil -} - -// Exec spawns an additional process inside the container. -func (s *Service) Exec(ctx context.Context, r *shim.ExecProcessRequest) (*types.Empty, error) { - s.mu.Lock() - - if p := s.processes[r.ID]; p != nil { - s.mu.Unlock() - return nil, errdefs.ToGRPCf(errdefs.ErrAlreadyExists, "id %s", r.ID) - } - - p := s.processes[s.id] - s.mu.Unlock() - if p == nil { - return nil, errdefs.ToGRPCf(errdefs.ErrFailedPrecondition, "container must be created") - } - - process, err := p.(*proc.Init).Exec(ctx, s.config.Path, &proc.ExecConfig{ - ID: r.ID, - Terminal: r.Terminal, - Stdin: r.Stdin, - Stdout: r.Stdout, - Stderr: r.Stderr, - Spec: r.Spec, - }) - if err != nil { - return nil, errdefs.ToGRPC(err) - } - s.mu.Lock() - s.processes[r.ID] = process - s.mu.Unlock() - return empty, nil -} - -// ResizePty resises the terminal of a process. -func (s *Service) ResizePty(ctx context.Context, r *shim.ResizePtyRequest) (*types.Empty, error) { - if r.ID == "" { - return nil, errdefs.ToGRPCf(errdefs.ErrInvalidArgument, "id not provided") - } - ws := console.WinSize{ - Width: uint16(r.Width), - Height: uint16(r.Height), - } - p, err := s.getExecProcess(r.ID) - if err != nil { - return nil, err - } - if err := p.Resize(ws); err != nil { - return nil, errdefs.ToGRPC(err) - } - return empty, nil -} - -// State returns runtime state information for a process. -func (s *Service) State(ctx context.Context, r *shim.StateRequest) (*shim.StateResponse, error) { - p, err := s.getExecProcess(r.ID) - if err != nil { - return nil, err - } - st, err := p.Status(ctx) - if err != nil { - return nil, err - } - status := task.StatusUnknown - switch st { - case "created": - status = task.StatusCreated - case "running": - status = task.StatusRunning - case "stopped": - status = task.StatusStopped - } - sio := p.Stdio() - return &shim.StateResponse{ - ID: p.ID(), - Bundle: s.bundle, - Pid: uint32(p.Pid()), - Status: status, - Stdin: sio.Stdin, - Stdout: sio.Stdout, - Stderr: sio.Stderr, - Terminal: sio.Terminal, - ExitStatus: uint32(p.ExitStatus()), - ExitedAt: p.ExitedAt(), - }, nil -} - -// Pause pauses the container. -func (s *Service) Pause(ctx context.Context, r *types.Empty) (*types.Empty, error) { - return empty, errdefs.ToGRPC(errdefs.ErrNotImplemented) -} - -// Resume resumes the container. -func (s *Service) Resume(ctx context.Context, r *types.Empty) (*types.Empty, error) { - return empty, errdefs.ToGRPC(errdefs.ErrNotImplemented) -} - -// Kill kills a process with the provided signal. -func (s *Service) Kill(ctx context.Context, r *shim.KillRequest) (*types.Empty, error) { - if r.ID == "" { - p, err := s.getInitProcess() - if err != nil { - return nil, err - } - if err := p.Kill(ctx, r.Signal, r.All); err != nil { - return nil, errdefs.ToGRPC(err) - } - return empty, nil - } - - p, err := s.getExecProcess(r.ID) - if err != nil { - return nil, err - } - if err := p.Kill(ctx, r.Signal, r.All); err != nil { - return nil, errdefs.ToGRPC(err) - } - return empty, nil -} - -// ListPids returns all pids inside the container. -func (s *Service) ListPids(ctx context.Context, r *shim.ListPidsRequest) (*shim.ListPidsResponse, error) { - pids, err := s.getContainerPids(ctx, r.ID) - if err != nil { - return nil, errdefs.ToGRPC(err) - } - var processes []*task.ProcessInfo - for _, pid := range pids { - pInfo := task.ProcessInfo{ - Pid: pid, - } - for _, p := range s.processes { - if p.Pid() == int(pid) { - d := &runctypes.ProcessDetails{ - ExecID: p.ID(), - } - a, err := typeurl.MarshalAny(d) - if err != nil { - return nil, fmt.Errorf("failed to marshal process %d info: %w", pid, err) - } - pInfo.Info = a - break - } - } - processes = append(processes, &pInfo) - } - return &shim.ListPidsResponse{ - Processes: processes, - }, nil -} - -// CloseIO closes the I/O context of a process. -func (s *Service) CloseIO(ctx context.Context, r *shim.CloseIORequest) (*types.Empty, error) { - p, err := s.getExecProcess(r.ID) - if err != nil { - return nil, err - } - if stdin := p.Stdin(); stdin != nil { - if err := stdin.Close(); err != nil { - return nil, fmt.Errorf("close stdin: %w", err) - } - } - return empty, nil -} - -// Checkpoint checkpoints the container. -func (s *Service) Checkpoint(ctx context.Context, r *shim.CheckpointTaskRequest) (*types.Empty, error) { - return empty, errdefs.ToGRPC(errdefs.ErrNotImplemented) -} - -// ShimInfo returns shim information such as the shim's pid. -func (s *Service) ShimInfo(ctx context.Context, r *types.Empty) (*shim.ShimInfoResponse, error) { - return &shim.ShimInfoResponse{ - ShimPid: uint32(os.Getpid()), - }, nil -} - -// Update updates a running container. -func (s *Service) Update(ctx context.Context, r *shim.UpdateTaskRequest) (*types.Empty, error) { - return empty, errdefs.ToGRPC(errdefs.ErrNotImplemented) -} - -// Wait waits for a process to exit. -func (s *Service) Wait(ctx context.Context, r *shim.WaitRequest) (*shim.WaitResponse, error) { - p, err := s.getExecProcess(r.ID) - if err != nil { - return nil, err - } - p.Wait() - - return &shim.WaitResponse{ - ExitStatus: uint32(p.ExitStatus()), - ExitedAt: p.ExitedAt(), - }, nil -} - -func (s *Service) processExits() { - for e := range s.ec { - s.checkProcesses(e) - } -} - -func (s *Service) allProcesses() []process.Process { - s.mu.Lock() - defer s.mu.Unlock() - - res := make([]process.Process, 0, len(s.processes)) - for _, p := range s.processes { - res = append(res, p) - } - return res -} - -func (s *Service) checkProcesses(e proc.Exit) { - for _, p := range s.allProcesses() { - if p.ID() == e.ID { - if ip, ok := p.(*proc.Init); ok { - // Ensure all children are killed. - if err := ip.KillAll(s.context); err != nil { - log.G(s.context).WithError(err).WithField("id", ip.ID()). - Error("failed to kill init's children") - } - } - p.SetExited(e.Status) - s.events <- &TaskExit{ - ContainerID: s.id, - ID: p.ID(), - Pid: uint32(p.Pid()), - ExitStatus: uint32(e.Status), - ExitedAt: p.ExitedAt(), - } - return - } - } -} - -func (s *Service) getContainerPids(ctx context.Context, id string) ([]uint32, error) { - p, err := s.getInitProcess() - if err != nil { - return nil, err - } - - ps, err := p.(*proc.Init).Runtime().Ps(ctx, id) - if err != nil { - return nil, err - } - pids := make([]uint32, 0, len(ps)) - for _, pid := range ps { - pids = append(pids, uint32(pid)) - } - return pids, nil -} - -func (s *Service) forward(publisher events.Publisher) { - for e := range s.events { - if err := publisher.Publish(s.context, getTopic(s.context, e), e); err != nil { - log.G(s.context).WithError(err).Error("post event") - } - } -} - -// getInitProcess returns the init process. -func (s *Service) getInitProcess() (process.Process, error) { - s.mu.Lock() - defer s.mu.Unlock() - p := s.processes[s.id] - if p == nil { - return nil, errdefs.ToGRPCf(errdefs.ErrFailedPrecondition, "container must be created") - } - return p, nil -} - -// getExecProcess returns the given exec process. -func (s *Service) getExecProcess(id string) (process.Process, error) { - s.mu.Lock() - defer s.mu.Unlock() - p := s.processes[id] - if p == nil { - return nil, errdefs.ToGRPCf(errdefs.ErrNotFound, "process %s does not exist", id) - } - return p, nil -} - -func getTopic(ctx context.Context, e interface{}) string { - switch e.(type) { - case *TaskCreate: - return runtime.TaskCreateEventTopic - case *TaskStart: - return runtime.TaskStartEventTopic - case *TaskOOM: - return runtime.TaskOOMEventTopic - case *TaskExit: - return runtime.TaskExitEventTopic - case *TaskDelete: - return runtime.TaskDeleteEventTopic - case *TaskExecAdded: - return runtime.TaskExecAddedEventTopic - case *TaskExecStarted: - return runtime.TaskExecStartedEventTopic - default: - log.L.Printf("no topic for type %#v", e) - } - return runtime.TaskUnknownTopic -} - -func newInit(path, workDir, runtimeRoot, namespace string, config map[string]string, platform stdio.Platform, r *proc.CreateConfig, options *types.Any) (*proc.Init, error) { - var opts runctypes.CreateOptions - if options != nil { - v, err := typeurl.UnmarshalAny(options) - if err != nil { - return nil, err - } - opts = *v.(*runctypes.CreateOptions) - } - - spec, err := utils.ReadSpec(r.Bundle) - if err != nil { - return nil, fmt.Errorf("read oci spec: %w", err) - } - if err := utils.UpdateVolumeAnnotations(r.Bundle, spec); err != nil { - return nil, fmt.Errorf("update volume annotations: %w", err) - } - - runsc.FormatRunscLogPath(r.ID, config) - rootfs := filepath.Join(path, "rootfs") - runtime := proc.NewRunsc(runtimeRoot, path, namespace, r.Runtime, config) - p := proc.New(r.ID, runtime, stdio.Stdio{ - Stdin: r.Stdin, - Stdout: r.Stdout, - Stderr: r.Stderr, - Terminal: r.Terminal, - }) - p.Bundle = r.Bundle - p.Platform = platform - p.Rootfs = rootfs - p.WorkDir = workDir - p.IoUID = int(opts.IoUid) - p.IoGID = int(opts.IoGid) - p.Sandbox = utils.IsSandbox(spec) - p.UserLog = utils.UserLogPath(spec) - p.Monitor = reaper.Default - return p, nil -} diff --git a/pkg/shim/v1/shim/shim.go b/pkg/shim/v1/shim/shim.go deleted file mode 100644 index 1855a8769..000000000 --- a/pkg/shim/v1/shim/shim.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2018 The containerd Authors. -// Copyright 2019 The gVisor Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package shim contains the core containerd shim implementation. -package shim diff --git a/pkg/shim/v2/v2_state_autogen.go b/pkg/shim/v2/v2_state_autogen.go deleted file mode 100644 index 1023f4d8f..000000000 --- a/pkg/shim/v2/v2_state_autogen.go +++ /dev/null @@ -1,5 +0,0 @@ -// automatically generated by stateify. - -// +build linux - -package v2 diff --git a/pkg/tcpip/stack/registration.go b/pkg/tcpip/stack/registration.go index 7e83b7fbb..4795208b4 100644 --- a/pkg/tcpip/stack/registration.go +++ b/pkg/tcpip/stack/registration.go @@ -84,7 +84,7 @@ type TransportEndpoint interface { // HandleControlPacket is called by the stack when new control (e.g. // ICMP) packets arrive to this transport endpoint. // HandleControlPacket takes ownership of pkt. - HandleControlPacket(id TransportEndpointID, typ ControlType, extra uint32, pkt *PacketBuffer) + HandleControlPacket(typ ControlType, extra uint32, pkt *PacketBuffer) // Abort initiates an expedited endpoint teardown. It puts the endpoint // in a closed state and frees all resources associated with it. This diff --git a/pkg/tcpip/stack/transport_demuxer.go b/pkg/tcpip/stack/transport_demuxer.go index f183ec6e4..07b2818d2 100644 --- a/pkg/tcpip/stack/transport_demuxer.go +++ b/pkg/tcpip/stack/transport_demuxer.go @@ -182,7 +182,8 @@ func (epsByNIC *endpointsByNIC) handlePacket(id TransportEndpointID, pkt *Packet epsByNIC.mu.RUnlock() // Don't use defer for performance reasons. } -// HandleControlPacket implements stack.TransportEndpoint.HandleControlPacket. +// handleControlPacket delivers a control packet to the transport endpoint +// identified by id. func (epsByNIC *endpointsByNIC) handleControlPacket(n *NIC, id TransportEndpointID, typ ControlType, extra uint32, pkt *PacketBuffer) { epsByNIC.mu.RLock() defer epsByNIC.mu.RUnlock() @@ -199,7 +200,7 @@ func (epsByNIC *endpointsByNIC) handleControlPacket(n *NIC, id TransportEndpoint // broadcast like we are doing with handlePacket above? // multiPortEndpoints are guaranteed to have at least one element. - selectEndpoint(id, mpep, epsByNIC.seed).HandleControlPacket(id, typ, extra, pkt) + selectEndpoint(id, mpep, epsByNIC.seed).HandleControlPacket(typ, extra, pkt) } // registerEndpoint returns true if it succeeds. It fails and returns diff --git a/pkg/tcpip/transport/icmp/endpoint.go b/pkg/tcpip/transport/icmp/endpoint.go index 2eb4457df..c32fe5c4f 100644 --- a/pkg/tcpip/transport/icmp/endpoint.go +++ b/pkg/tcpip/transport/icmp/endpoint.go @@ -789,7 +789,7 @@ func (e *endpoint) HandlePacket(id stack.TransportEndpointID, pkt *stack.PacketB } // HandleControlPacket implements stack.TransportEndpoint.HandleControlPacket. -func (e *endpoint) HandleControlPacket(id stack.TransportEndpointID, typ stack.ControlType, extra uint32, pkt *stack.PacketBuffer) { +func (e *endpoint) HandleControlPacket(typ stack.ControlType, extra uint32, pkt *stack.PacketBuffer) { } // State implements tcpip.Endpoint.State. The ICMP endpoint currently doesn't diff --git a/pkg/tcpip/transport/tcp/endpoint.go b/pkg/tcpip/transport/tcp/endpoint.go index 281f4cd58..25b180fa5 100644 --- a/pkg/tcpip/transport/tcp/endpoint.go +++ b/pkg/tcpip/transport/tcp/endpoint.go @@ -1544,46 +1544,38 @@ func (e *endpoint) Write(p tcpip.Payloader, opts tcpip.WriteOptions) (int64, <-c return 0, nil, perr } - queueAndSend := func() (int64, <-chan struct{}, *tcpip.Error) { - // Add data to the send queue. - s := newOutgoingSegment(e.ID, v) - e.sndBufUsed += len(v) - e.sndBufInQueue += seqnum.Size(len(v)) - e.sndQueue.PushBack(s) - e.sndBufMu.Unlock() - - // Do the work inline. - e.handleWrite() - e.UnlockUser() - return int64(len(v)), nil, nil - } - - if opts.Atomic { - // Locks released in queueAndSend() - return queueAndSend() - } + if !opts.Atomic { + // Since we released locks in between it's possible that the + // endpoint transitioned to a CLOSED/ERROR states so make + // sure endpoint is still writable before trying to write. + e.LockUser() + e.sndBufMu.Lock() + avail, err := e.isEndpointWritableLocked() + if err != nil { + e.sndBufMu.Unlock() + e.UnlockUser() + e.stats.WriteErrors.WriteClosed.Increment() + return 0, nil, err + } - // Since we released locks in between it's possible that the - // endpoint transitioned to a CLOSED/ERROR states so make - // sure endpoint is still writable before trying to write. - e.LockUser() - e.sndBufMu.Lock() - avail, err = e.isEndpointWritableLocked() - if err != nil { - e.sndBufMu.Unlock() - e.UnlockUser() - e.stats.WriteErrors.WriteClosed.Increment() - return 0, nil, err + // Discard any excess data copied in due to avail being reduced due + // to a simultaneous write call to the socket. + if avail < len(v) { + v = v[:avail] + } } - // Discard any excess data copied in due to avail being reduced due - // to a simultaneous write call to the socket. - if avail < len(v) { - v = v[:avail] - } + // Add data to the send queue. + s := newOutgoingSegment(e.ID, v) + e.sndBufUsed += len(v) + e.sndBufInQueue += seqnum.Size(len(v)) + e.sndQueue.PushBack(s) + e.sndBufMu.Unlock() - // Locks released in queueAndSend() - return queueAndSend() + // Do the work inline. + e.handleWrite() + e.UnlockUser() + return int64(len(v)), nil, nil } // selectWindowLocked returns the new window without checking for shrinking or scaling @@ -2736,7 +2728,7 @@ func (e *endpoint) enqueueSegment(s *segment) bool { return true } -func (e *endpoint) onICMPError(err *tcpip.Error, id stack.TransportEndpointID, errType byte, errCode byte, extra uint32, pkt *stack.PacketBuffer) { +func (e *endpoint) onICMPError(err *tcpip.Error, errType byte, errCode byte, extra uint32, pkt *stack.PacketBuffer) { // Update last error first. e.lastErrorMu.Lock() e.lastError = err @@ -2755,13 +2747,13 @@ func (e *endpoint) onICMPError(err *tcpip.Error, id stack.TransportEndpointID, e Payload: pkt.Data.ToView(), Dst: tcpip.FullAddress{ NIC: pkt.NICID, - Addr: id.RemoteAddress, - Port: id.RemotePort, + Addr: e.ID.RemoteAddress, + Port: e.ID.RemotePort, }, Offender: tcpip.FullAddress{ NIC: pkt.NICID, - Addr: id.LocalAddress, - Port: id.LocalPort, + Addr: e.ID.LocalAddress, + Port: e.ID.LocalPort, }, NetProto: pkt.NetworkProtocolNumber, }) @@ -2772,7 +2764,7 @@ func (e *endpoint) onICMPError(err *tcpip.Error, id stack.TransportEndpointID, e } // HandleControlPacket implements stack.TransportEndpoint.HandleControlPacket. -func (e *endpoint) HandleControlPacket(id stack.TransportEndpointID, typ stack.ControlType, extra uint32, pkt *stack.PacketBuffer) { +func (e *endpoint) HandleControlPacket(typ stack.ControlType, extra uint32, pkt *stack.PacketBuffer) { switch typ { case stack.ControlPacketTooBig: e.sndBufMu.Lock() @@ -2785,10 +2777,10 @@ func (e *endpoint) HandleControlPacket(id stack.TransportEndpointID, typ stack.C e.notifyProtocolGoroutine(notifyMTUChanged) case stack.ControlNoRoute: - e.onICMPError(tcpip.ErrNoRoute, id, byte(header.ICMPv4DstUnreachable), byte(header.ICMPv4HostUnreachable), extra, pkt) + e.onICMPError(tcpip.ErrNoRoute, byte(header.ICMPv4DstUnreachable), byte(header.ICMPv4HostUnreachable), extra, pkt) case stack.ControlNetworkUnreachable: - e.onICMPError(tcpip.ErrNetworkUnreachable, id, byte(header.ICMPv6DstUnreachable), byte(header.ICMPv6NetworkUnreachable), extra, pkt) + e.onICMPError(tcpip.ErrNetworkUnreachable, byte(header.ICMPv6DstUnreachable), byte(header.ICMPv6NetworkUnreachable), extra, pkt) } } diff --git a/pkg/tcpip/transport/udp/endpoint.go b/pkg/tcpip/transport/udp/endpoint.go index 075de1db0..5d87f3a7e 100644 --- a/pkg/tcpip/transport/udp/endpoint.go +++ b/pkg/tcpip/transport/udp/endpoint.go @@ -1352,7 +1352,7 @@ func (e *endpoint) HandlePacket(id stack.TransportEndpointID, pkt *stack.PacketB } } -func (e *endpoint) onICMPError(err *tcpip.Error, id stack.TransportEndpointID, errType byte, errCode byte, extra uint32, pkt *stack.PacketBuffer) { +func (e *endpoint) onICMPError(err *tcpip.Error, errType byte, errCode byte, extra uint32, pkt *stack.PacketBuffer) { // Update last error first. e.lastErrorMu.Lock() e.lastError = err @@ -1376,13 +1376,13 @@ func (e *endpoint) onICMPError(err *tcpip.Error, id stack.TransportEndpointID, e Payload: payload, Dst: tcpip.FullAddress{ NIC: pkt.NICID, - Addr: id.RemoteAddress, - Port: id.RemotePort, + Addr: e.ID.RemoteAddress, + Port: e.ID.RemotePort, }, Offender: tcpip.FullAddress{ NIC: pkt.NICID, - Addr: id.LocalAddress, - Port: id.LocalPort, + Addr: e.ID.LocalAddress, + Port: e.ID.LocalPort, }, NetProto: pkt.NetworkProtocolNumber, }) @@ -1393,7 +1393,7 @@ func (e *endpoint) onICMPError(err *tcpip.Error, id stack.TransportEndpointID, e } // HandleControlPacket implements stack.TransportEndpoint.HandleControlPacket. -func (e *endpoint) HandleControlPacket(id stack.TransportEndpointID, typ stack.ControlType, extra uint32, pkt *stack.PacketBuffer) { +func (e *endpoint) HandleControlPacket(typ stack.ControlType, extra uint32, pkt *stack.PacketBuffer) { if typ == stack.ControlPortUnreachable { if e.EndpointState() == StateConnected { var errType byte @@ -1408,7 +1408,7 @@ func (e *endpoint) HandleControlPacket(id stack.TransportEndpointID, typ stack.C default: panic(fmt.Sprintf("unsupported net proto for infering ICMP type and code: %d", pkt.NetworkProtocolNumber)) } - e.onICMPError(tcpip.ErrConnectionRefused, id, errType, errCode, extra, pkt) + e.onICMPError(tcpip.ErrConnectionRefused, errType, errCode, extra, pkt) return } } diff --git a/shim/v2/cli/cli.go b/shim/cli/cli.go index 3d6644feb..068976c79 100644 --- a/shim/v2/cli/cli.go +++ b/shim/cli/cli.go @@ -17,12 +17,12 @@ package cli import ( - "github.com/containerd/containerd/runtime/v2/shim" + containerdshim "github.com/containerd/containerd/runtime/v2/shim" - "gvisor.dev/gvisor/pkg/shim/v2" + "gvisor.dev/gvisor/pkg/shim" ) // Main is the main entrypoint. func Main() { - shim.Run("io.containerd.runsc.v1", v2.New) + containerdshim.Run("io.containerd.runsc.v1", shim.New) } diff --git a/shim/v1/cli/cli_state_autogen.go b/shim/cli/cli_state_autogen.go index e81991e0b..e81991e0b 100644 --- a/shim/v1/cli/cli_state_autogen.go +++ b/shim/cli/cli_state_autogen.go diff --git a/shim/v2/main.go b/shim/main.go index 3680cdf9c..b87a20d08 100644 --- a/shim/v2/main.go +++ b/shim/main.go @@ -16,7 +16,7 @@ package main import ( - "gvisor.dev/gvisor/shim/v2/cli" + "gvisor.dev/gvisor/shim/cli" ) func main() { diff --git a/shim/v1/cli/api.go b/shim/v1/cli/api.go deleted file mode 100644 index 050793094..000000000 --- a/shim/v1/cli/api.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2018 The containerd Authors. -// Copyright 2019 The gVisor Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package cli - -import ( - shim "github.com/containerd/containerd/runtime/v1/shim/v1" -) - -type KillRequest = shim.KillRequest - -var registerShimService = shim.RegisterShimService diff --git a/shim/v1/cli/cli.go b/shim/v1/cli/cli.go deleted file mode 100644 index cdf60cc2e..000000000 --- a/shim/v1/cli/cli.go +++ /dev/null @@ -1,266 +0,0 @@ -// Copyright 2018 The containerd Authors. -// Copyright 2019 The gVisor Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package cli defines the command line interface for the V1 shim. -package cli - -import ( - "bytes" - "context" - "flag" - "fmt" - "log" - "net" - "os" - "os/exec" - "os/signal" - "path/filepath" - "strings" - "sync" - "syscall" - - "github.com/containerd/containerd/events" - "github.com/containerd/containerd/namespaces" - "github.com/containerd/containerd/sys" - "github.com/containerd/containerd/sys/reaper" - "github.com/containerd/ttrpc" - "github.com/containerd/typeurl" - "github.com/gogo/protobuf/types" - "golang.org/x/sys/unix" - - "gvisor.dev/gvisor/pkg/shim/runsc" - "gvisor.dev/gvisor/pkg/shim/v1/shim" -) - -var ( - debugFlag bool - namespaceFlag string - socketFlag string - addressFlag string - workdirFlag string - runtimeRootFlag string - containerdBinaryFlag string - shimConfigFlag string -) - -// Containerd defaults to runc, unless another runtime is explicitly specified. -// We keep the same default to make the default behavior consistent. -const defaultRoot = "/run/containerd/runc" - -func init() { - flag.BoolVar(&debugFlag, "debug", false, "enable debug output in logs") - flag.StringVar(&namespaceFlag, "namespace", "", "namespace that owns the shim") - flag.StringVar(&socketFlag, "socket", "", "abstract socket path to serve") - flag.StringVar(&addressFlag, "address", "", "grpc address back to main containerd") - flag.StringVar(&workdirFlag, "workdir", "", "path used to storge large temporary data") - flag.StringVar(&runtimeRootFlag, "runtime-root", defaultRoot, "root directory for the runtime") - - // Currently, the `containerd publish` utility is embedded in the - // daemon binary. The daemon invokes `containerd-shim - // -containerd-binary ...` with its own os.Executable() path. - flag.StringVar(&containerdBinaryFlag, "containerd-binary", "containerd", "path to containerd binary (used for `containerd publish`)") - flag.StringVar(&shimConfigFlag, "config", "/etc/containerd/runsc.toml", "path to the shim configuration file") -} - -// Main is the main entrypoint. -func Main() { - flag.Parse() - - // This is a hack. Exec current process to run standard containerd-shim - // if runtime root is not `runsc`. We don't need this for shim v2 api. - if filepath.Base(runtimeRootFlag) != "runsc" { - if err := executeRuncShim(); err != nil { - fmt.Fprintf(os.Stderr, "gvisor-containerd-shim: %s\n", err) - os.Exit(1) - } - } - - // Run regular shim if needed. - if err := executeShim(); err != nil { - fmt.Fprintf(os.Stderr, "gvisor-containerd-shim: %s\n", err) - os.Exit(1) - } -} - -// executeRuncShim execs current process to a containerd-shim process and -// retains all flags and envs. -func executeRuncShim() error { - c, err := loadConfig(shimConfigFlag) - if err != nil && !os.IsNotExist(err) { - return fmt.Errorf("failed to load shim config: %w", err) - } - shimPath := c.RuncShim - if shimPath == "" { - shimPath, err = exec.LookPath("containerd-shim") - if err != nil { - return fmt.Errorf("lookup containerd-shim failed: %w", err) - } - } - - args := append([]string{shimPath}, os.Args[1:]...) - if err := syscall.Exec(shimPath, args, os.Environ()); err != nil { - return fmt.Errorf("exec containerd-shim @ %q failed: %w", shimPath, err) - } - return nil -} - -func executeShim() error { - // start handling signals as soon as possible so that things are - // properly reaped or if runtime exits before we hit the handler. - signals, err := setupSignals() - if err != nil { - return err - } - path, err := os.Getwd() - if err != nil { - return err - } - server, err := ttrpc.NewServer(ttrpc.WithServerHandshaker(ttrpc.UnixSocketRequireSameUser())) - if err != nil { - return fmt.Errorf("failed creating server: %w", err) - } - c, err := loadConfig(shimConfigFlag) - if err != nil && !os.IsNotExist(err) { - return fmt.Errorf("failed to load shim config: %w", err) - } - sv, err := shim.NewService( - shim.Config{ - Path: path, - Namespace: namespaceFlag, - WorkDir: workdirFlag, - RuntimeRoot: runtimeRootFlag, - RunscConfig: c.RunscConfig, - }, - &remoteEventsPublisher{address: addressFlag}, - ) - if err != nil { - return err - } - registerShimService(server, sv) - if err := serve(server, socketFlag); err != nil { - return err - } - return handleSignals(signals, server, sv) -} - -// serve serves the ttrpc API over a unix socket at the provided path this -// function does not block. -func serve(server *ttrpc.Server, path string) error { - var ( - l net.Listener - err error - ) - if path == "" { - l, err = net.FileListener(os.NewFile(3, "socket")) - } else { - if len(path) > 106 { - return fmt.Errorf("%q: unix socket path too long (> 106)", path) - } - l, err = net.Listen("unix", "\x00"+path) - } - if err != nil { - return err - } - go func() { - defer l.Close() - err := server.Serve(context.Background(), l) - if err != nil && !strings.Contains(err.Error(), "use of closed network connection") { - log.Fatalf("ttrpc server failure: %v", err) - } - }() - return nil -} - -// setupSignals creates a new signal handler for all signals and sets the shim -// as a sub-reaper so that the container processes are reparented. -func setupSignals() (chan os.Signal, error) { - signals := make(chan os.Signal, 32) - signal.Notify(signals, unix.SIGTERM, unix.SIGINT, unix.SIGCHLD, unix.SIGPIPE) - // make sure runc is setup to use the monitor for waiting on processes. - // TODO(random-liu): Move shim/reaper.go to a separate package. - runsc.Monitor = reaper.Default - // Set the shim as the subreaper for all orphaned processes created by - // the container. - if err := unix.Prctl(unix.PR_SET_CHILD_SUBREAPER, 1, 0, 0, 0); err != nil { - return nil, err - } - return signals, nil -} - -func handleSignals(signals chan os.Signal, server *ttrpc.Server, sv *shim.Service) error { - var ( - termOnce sync.Once - done = make(chan struct{}) - ) - - for { - select { - case <-done: - return nil - case s := <-signals: - switch s { - case unix.SIGCHLD: - if _, err := sys.Reap(false); err != nil { - log.Printf("reap error: %v", err) - } - case unix.SIGTERM, unix.SIGINT: - go termOnce.Do(func() { - ctx := context.TODO() - if err := server.Shutdown(ctx); err != nil { - log.Printf("failed to shutdown server: %v", err) - } - // Ensure our child is dead if any. - sv.Kill(ctx, &KillRequest{ - Signal: uint32(syscall.SIGKILL), - All: true, - }) - sv.Delete(context.Background(), &types.Empty{}) - close(done) - }) - case unix.SIGPIPE: - } - } - } -} - -type remoteEventsPublisher struct { - address string -} - -func (l *remoteEventsPublisher) Publish(ctx context.Context, topic string, event events.Event) error { - ns, _ := namespaces.Namespace(ctx) - encoded, err := typeurl.MarshalAny(event) - if err != nil { - return err - } - data, err := encoded.Marshal() - if err != nil { - return err - } - cmd := exec.CommandContext(ctx, containerdBinaryFlag, "--address", l.address, "publish", "--topic", topic, "--namespace", ns) - cmd.Stdin = bytes.NewReader(data) - c, err := reaper.Default.Start(cmd) - if err != nil { - return err - } - status, err := reaper.Default.Wait(cmd, c) - if err != nil { - return fmt.Errorf("failed to publish event: %w", err) - } - if status != 0 { - return fmt.Errorf("failed to publish event: status %d", status) - } - return nil -} diff --git a/shim/v1/cli/config.go b/shim/v1/cli/config.go deleted file mode 100644 index 1be9597ed..000000000 --- a/shim/v1/cli/config.go +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2018 The gVisor Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package cli - -import "github.com/BurntSushi/toml" - -// config is the configuration for gvisor containerd shim. -type config struct { - // RuncShim is the shim binary path for standard containerd-shim for runc. - // When the runtime is `runc`, gvisor containerd shim will exec current - // process to standard containerd-shim. This is a work around for containerd - // 1.1. In containerd 1.2, containerd will choose different containerd-shims - // based on runtime. - RuncShim string `toml:"runc_shim"` - // RunscConfig is configuration for runsc. The key value will be converted - // to runsc flags --key=value directly. - RunscConfig map[string]string `toml:"runsc_config"` -} - -// loadConfig load gvisor containerd shim config from config file. -func loadConfig(path string) (*config, error) { - var c config - _, err := toml.DecodeFile(path, &c) - if err != nil { - return &c, err - } - return &c, nil -} diff --git a/shim/v1/main.go b/shim/v1/main.go deleted file mode 100644 index 11ff4add1..000000000 --- a/shim/v1/main.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2020 The gVisor Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Binary gvisor-containerd-shim is the v1 containerd shim. -package main - -import ( - "gvisor.dev/gvisor/shim/v1/cli" -) - -func main() { - cli.Main() -} diff --git a/shim/v2/cli/cli_state_autogen.go b/shim/v2/cli/cli_state_autogen.go deleted file mode 100644 index e81991e0b..000000000 --- a/shim/v2/cli/cli_state_autogen.go +++ /dev/null @@ -1,3 +0,0 @@ -// automatically generated by stateify. - -package cli |