From 530a258376cebea6400348e4e343316199230357 Mon Sep 17 00:00:00 2001 From: Mrunal Patel Date: Fri, 26 Aug 2016 14:00:30 -0700 Subject: [PATCH] Add a container monitor process Signed-off-by: Mrunal Patel --- conmon/conmon.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 conmon/conmon.c diff --git a/conmon/conmon.c b/conmon/conmon.c new file mode 100644 index 00000000..1a5eacd6 --- /dev/null +++ b/conmon/conmon.c @@ -0,0 +1,98 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include + +#include + +#define pexit(fmt, ...) \ + do { \ + fprintf(stderr, "conmon: " fmt " %m\n", ##__VA_ARGS__); \ + exit(EXIT_FAILURE); \ + } while (0) + +#define nexit(fmt, ...) \ + do { \ + fprintf(stderr, "conmon: " fmt "\n", ##__VA_ARGS__); \ + exit(EXIT_FAILURE); \ + } while (0) + +#define nexit(fmt, ...) \ + do { \ + fprintf(stderr, "conmon: " fmt "\n", ##__VA_ARGS__); \ + exit(EXIT_FAILURE); \ + } while (0) + +#define _cleanup_(x) __attribute__((cleanup(x))) + +static inline void freep(void *p) { + free(*(void**) p); +} + +#define _cleanup_free_ _cleanup_(freep) + +int main(int argc, char *argv[]) +{ + int ret; + const char *cid; + char cmd[128]; + GError *err = NULL; + gchar *contents; + int cpid = -1; + int status; + pid_t pid; + + if (argc < 2) { + nexit("Run as: conmon "); + } + + // Get the container id + cid = argv[1]; + + // Set self as subreaper so we can wait for container process + // and return its exit code. + ret = prctl(PR_SET_CHILD_SUBREAPER, 1, 0, 0, 0); + if (ret != 0) { + pexit("Failed to set as subreaper"); + } + + snprintf(cmd, 128, "runc create %s --pid-file pidfile", cid); + ret = system(cmd); + if (ret != 0) { + nexit("Failed to create container"); + } + + // Read the pid so we can wait for the process to exit + g_file_get_contents("pidfile", &contents, NULL, &err); + if (err) { + fprintf(stderr, "Failed to read pidfile: %s\n", err->message); + g_error_free(err); + exit(1); + } + + cpid = atoi(contents); + printf("container PID: %d\n", cpid); + + while ((pid = waitpid(-1, &status, 0)) > 0) { + printf("PID %d exited\n", pid); + if (pid == cpid) { + _cleanup_free_ char *status_str = NULL; + ret = asprintf(&status_str, "%d", status); + if (ret < 0) { + pexit("Failed to allocate memory for status"); + } + g_file_set_contents("exit", status_str, strlen(status_str), &err); + if (err) { + fprintf(stderr, "Failed to write %s to exit file: %s\n", status_str, err->message); + g_error_free(err); + exit(1); + } + break; + } + } + + return EXIT_SUCCESS; +}