From 975bdb2c96323bfc2392d9e3aabd0f79c5eb047f Mon Sep 17 00:00:00 2001 From: Cory Snider Date: Tue, 31 Jan 2023 11:36:19 -0500 Subject: [PATCH] daemon: identify container exits by ProcessID The Pid field of an exit event cannot be relied upon to differentiate exits of the container's task from exits of other container processes, i.e. execs. The Pid is reported by the runtime and is implementation- defined so there is no guarantee that a task's pid is distinct from the pids of any other process in the same container. In particular, kata-containers reports the pid of the hypervisor for all exit events. Update the daemon to differentiate container exits from exec exits by inspecting the event's ProcessID. The local_windows libcontainerd implementation already sets the ProcessID to InitProcessName on container exit events. Update the remote libcontainerd implementation to match. ContainerD guarantees that the process ID of a task (container init process) is set to the corresponding container ID, so use that invariant to distinguish task exits from other process exits. Signed-off-by: Cory Snider --- daemon/monitor.go | 2 +- libcontainerd/remote/client.go | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/daemon/monitor.go b/daemon/monitor.go index 9a087283c8a15..d0df021e28238 100644 --- a/daemon/monitor.go +++ b/daemon/monitor.go @@ -148,7 +148,7 @@ func (daemon *Daemon) ProcessEvent(id string, e libcontainerdtypes.EventType, ei daemon.LogContainerEvent(c, "oom") case libcontainerdtypes.EventExit: - if int(ei.Pid) == c.Pid { + if ei.ProcessID == libcontainerdtypes.InitProcessName { return daemon.handleContainerExit(c, &ei) } diff --git a/libcontainerd/remote/client.go b/libcontainerd/remote/client.go index 5278d4a974111..d88629affe60e 100644 --- a/libcontainerd/remote/client.go +++ b/libcontainerd/remote/client.go @@ -674,7 +674,7 @@ func (c *client) processEvent(ctx context.Context, et libcontainerdtypes.EventTy }).Error("failed to process event") } - if et == libcontainerdtypes.EventExit && ei.ProcessID != ei.ContainerID { + if et == libcontainerdtypes.EventExit && ei.ProcessID != libcontainerdtypes.InitProcessName { p, err := c.getProcess(ctx, ei.ContainerID, ei.ProcessID) if err != nil { @@ -823,6 +823,9 @@ func (c *client) processEventStream(ctx context.Context, ns string) { ExitCode: t.ExitStatus, ExitedAt: t.ExitedAt, } + if t.ID == t.ContainerID { + ei.ProcessID = libcontainerdtypes.InitProcessName + } case *apievents.TaskOOM: et = libcontainerdtypes.EventOOM ei = libcontainerdtypes.EventInfo{