From 8c1663f34b38689371979e3ed44c07d65555243c Mon Sep 17 00:00:00 2001 From: Peter Hunt Date: Tue, 15 Jun 2021 13:55:38 -0400 Subject: [PATCH 1/2] oci: don't pre-create pid file or else we race with the runtime for creation Signed-off-by: Peter Hunt --- internal/oci/runtime_oci.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/internal/oci/runtime_oci.go b/internal/oci/runtime_oci.go index bbc7e9c8d65..5f45b0528d9 100644 --- a/internal/oci/runtime_oci.go +++ b/internal/oci/runtime_oci.go @@ -331,11 +331,13 @@ func (r *runtimeOCI) ExecSyncContainer(ctx context.Context, c *Container, comman } defer os.RemoveAll(processFile) - pidFile, err := createPidFile() + pidDir, err := ioutil.TempDir("", "pidfile") if err != nil { return nil, err } - defer os.RemoveAll(pidFile) + defer os.RemoveAll(pidDir) + + pidFile := filepath.Join(pidDir, c.id) cmd := r.constructExecCommand(ctx, c, processFile, pidFile) cmd.SysProcAttr = sysProcAttrPlatform() From 483c5782913a9364d54447e0fc845469c6572f28 Mon Sep 17 00:00:00 2001 From: Peter Hunt Date: Tue, 15 Jun 2021 14:03:58 -0400 Subject: [PATCH 2/2] oci: kill runtime process on exec if exec pid isn't written yet Signed-off-by: Peter Hunt --- internal/oci/runtime_oci.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/internal/oci/runtime_oci.go b/internal/oci/runtime_oci.go index 5f45b0528d9..0c233a9aa1b 100644 --- a/internal/oci/runtime_oci.go +++ b/internal/oci/runtime_oci.go @@ -361,7 +361,7 @@ func (r *runtimeOCI) ExecSyncContainer(ctx context.Context, c *Container, comman select { case <-time.After(time.Second * time.Duration(timeout)): // Ensure the process is not left behind - killContainerExecProcess(ctx, pidFile) + killContainerExecProcess(ctx, pidFile, cmd) // Make sure the runtime process has been cleaned up <-done @@ -419,13 +419,15 @@ func createPidFile() (string, error) { return pidFileName, nil } -func killContainerExecProcess(ctx context.Context, pidFile string) { +func killContainerExecProcess(ctx context.Context, pidFile string, cmd *exec.Cmd) { // Attempt to get the container PID and PGID from the file the runtime should have written. - // TODO(haircommander): There does exist a race that we could time out before the runtime actually creates the file. - // Should we do inotify on this file to ensure it exists? Is that overkill? ctrPid, ctrPgid, err := pidAndpgidFromFile(pidFile) - if err != nil { - log.Errorf(ctx, "Failed to get pid (%d) or pgid (%d) from file %s: %v", ctrPid, ctrPgid, pidFile, err) + if err != nil && ctrPid <= 0 { + // only kill the runtime process if we failed to find a ctrPid + // as this means the runtime exec hasn't successfully written the pid file + if killErr := cmd.Process.Kill(); killErr != nil { + log.Errorf(ctx, "Error killing runtime exec process(%v) after error finding runtime pid: (%v)", killErr, err) + } } if ctrPgid > 1 {