From 2bac4d8a47f0db4a684fbe2df837523126d9ac3b Mon Sep 17 00:00:00 2001 From: Daniel J Walsh Date: Tue, 6 Mar 2018 05:23:43 -0500 Subject: [PATCH] Setup LISTEN_PID to point to new child process In order to get systemd socket passing to work properly the listen PID needs to match the process ID of the OCI runtime. This match modifies the LISTEN_PID if it is set to the new runtime. conmon will check that the LISTEN_PID the pid that conmon is running as and will ignore it if they are different. But, if the caller specifies the --replace-listen-pid flag, then the LISTEN_PID/LISTEN_FDS will always be used. Signed-off-by: Daniel J Walsh --- conmon/conmon.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/conmon/conmon.c b/conmon/conmon.c index 0f82dd12..4fa81c45 100644 --- a/conmon/conmon.c +++ b/conmon/conmon.c @@ -146,6 +146,7 @@ static char *opt_socket_path = DEFAULT_SOCKET_PATH; static bool opt_no_new_keyring = false; static char *opt_exit_command = NULL; static gchar **opt_exit_args = NULL; +static bool opt_replace_listen_pid = false; static GOptionEntry opt_entries[] = { { "terminal", 't', 0, G_OPTION_ARG_NONE, &opt_terminal, "Terminal", NULL }, @@ -156,6 +157,7 @@ static GOptionEntry opt_entries[] = { "runtime", 'r', 0, G_OPTION_ARG_STRING, &opt_runtime_path, "Runtime path", NULL }, { "no-new-keyring", 0, 0, G_OPTION_ARG_NONE, &opt_no_new_keyring, "Do not create a new session keyring for the container", NULL }, { "no-pivot", 0, 0, G_OPTION_ARG_NONE, &opt_no_pivot, "Do not use pivot_root", NULL }, + { "replace-listen-pid", 0, 0, G_OPTION_ARG_NONE, &opt_replace_listen_pid, "Replace listen pid if set for oci-runtime pid", NULL }, { "bundle", 'b', 0, G_OPTION_ARG_STRING, &opt_bundle_path, "Bundle path", NULL }, { "pidfile", 'p', 0, G_OPTION_ARG_STRING, &opt_pid_file, "PID file", NULL }, { "systemd-cgroup", 's', 0, G_OPTION_ARG_NONE, &opt_systemd_cgroup, "Enable systemd cgroup manager", NULL }, @@ -1422,6 +1424,24 @@ int main(int argc, char *argv[]) if (dup2(slavefd_stderr, STDERR_FILENO) < 0) pexit("Failed to dup over stderr"); + /* If LISTEN_PID env is set, we need to set the LISTEN_PID + it to the new child process */ + char *listenpid = getenv("LISTEN_PID"); + if (listenpid != NULL) { + errno=0; + int lpid = strtol(listenpid, NULL, 10); + if (errno != 0 || lpid <=0) + pexitf("Invalid LISTEN_PID %s", listenpid); + if (opt_replace_listen_pid || lpid == getppid()) { + gchar *pidstr = g_strdup_printf("%d", getpid()); + if (!pidstr) + pexit("Failed to g_strdup_sprintf pid"); + if (setenv("LISTEN_PID",pidstr,true) < 0) + pexit("Failed to setenv LISTEN_PID"); + free(pidstr); + } + } + execv(g_ptr_array_index(runtime_argv,0), (char **)runtime_argv->pdata); exit(127); }