From b9048edbe0d72aaa9f843d6e5f90ff97d48eab6b Mon Sep 17 00:00:00 2001 From: Mrunal Patel Date: Wed, 11 Nov 2015 19:04:15 -0500 Subject: [PATCH 1/3] Add code to parse mountinfo Signed-off-by: Mrunal Patel --- Makefile.am | 2 ++ configure.ac | 1 + src/systemdhook.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/Makefile.am b/Makefile.am index 7ed4047..7df9b07 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5,6 +5,8 @@ oci_systemd_hook_CFLAGS = $(YAJL_CFLAGS) oci_systemd_hook_LDADD = $(YAJL_LIBS) oci_systemd_hook_CFLAGS += $(SELINUX_CFLAGS) oci_systemd_hook_LDADD += $(SELINUX_LIBS) +oci_systemd_hook_CFLAGS += $(MOUNT_CFLAGS) +oci_systemd_hook_LDADD += $(MOUNT_LIBS) dist_man_MANS = doc/oci_systemd_hook.1 EXTRA_DIST = README.md LICENSE diff --git a/configure.ac b/configure.ac index c132100..882091d 100644 --- a/configure.ac +++ b/configure.ac @@ -6,6 +6,7 @@ AC_PROG_CC PKG_CHECK_MODULES([YAJL], [yajl >= 2.0.0]) PKG_CHECK_MODULES([SELINUX], [libselinux >= 2.0.0]) +PKG_CHECK_MODULES([MOUNT], [mount >= 2.1.0]) AC_MSG_CHECKING([whether to disable argument checking]) AC_ARG_ENABLE([args], AS_HELP_STRING([--disable-args], [disable checking that cmd args are either init/systemd])) diff --git a/src/systemdhook.c b/src/systemdhook.c index 5b2f9b4..87b068b 100644 --- a/src/systemdhook.c +++ b/src/systemdhook.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "config.h" @@ -69,6 +70,49 @@ static int makepath(char *dir, mode_t mode) return mkdir(dir, mode); } +DEFINE_CLEANUP_FUNC(struct libmnt_table*, mnt_free_table); +DEFINE_CLEANUP_FUNC(struct libmnt_iter*, mnt_free_iter); +static int mount_cgroups() +{ + _cleanup_(mnt_free_tablep) struct libmnt_table *t = NULL; + _cleanup_(mnt_free_iterp) struct libmnt_iter *i = NULL; + int ret = 0; + + t = mnt_new_table(); + if (!t) + return -1; + + i = mnt_new_iter(MNT_ITER_FORWARD); + if (!i) + return -1; + + ret = mnt_table_parse_mtab(t, NULL); + if (ret < 0) { + pr_perror("Failed to parse /proc/self/mountinfo"); + return -1; + } + + ret = 0; + for (;;) { + const char *path; + struct libmnt_fs *fs; + int rc; + + rc = mnt_table_next_fs(t, i, &fs); + if (rc == 1) + break; + if (rc < 0) { + + pr_perror("Failed to get next entry from /proc/self/mountinfo"); + return -1; + } + + path = mnt_fs_get_target(fs); + } + + return ret; +} + bool contains_mount(const char **config_mounts, unsigned len, const char *mount) { for (unsigned i = 0; i < len; i++) { if (!strcmp(mount, config_mounts[i])) { From df3b20b94d84da8f6f8d40a369bb18e77e2a6dd7 Mon Sep 17 00:00:00 2001 From: Mrunal Patel Date: Thu, 12 Nov 2015 16:26:52 -0500 Subject: [PATCH 2/3] WIP cgroups mounts Signed-off-by: Mrunal Patel --- src/systemdhook.c | 69 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 13 deletions(-) diff --git a/src/systemdhook.c b/src/systemdhook.c index 87b068b..66d72dd 100644 --- a/src/systemdhook.c +++ b/src/systemdhook.c @@ -54,6 +54,7 @@ DEFINE_CLEANUP_FUNC(yajl_val, yajl_tree_free) #define BUFLEN 1024 #define CONFIGSZ 65536 +#define CGROUP_ROOT "/sys/fs/cgroup" static int makepath(char *dir, mode_t mode) { @@ -70,9 +71,31 @@ static int makepath(char *dir, mode_t mode) return mkdir(dir, mode); } +static int mount_cgroup_path(const char *rootfs, const char* cgroup_path) +{ + char cont_cgroup_dir[PATH_MAX]; + snprintf(cont_cgroup_dir, PATH_MAX, "%s/%s", rootfs, cgroup_path); + + int ret = 0; + if (makepath(cont_cgroup_dir, 0755) == -1) { + if (errno != EEXIST) { + pr_perror("Failed to mkdir container cgroup dir %s", cgroup_path); + return -1; + } + } + + pr_pinfo("Mounting %s at %s\n", cgroup_path, cont_cgroup_dir); + if (mount(cgroup_path, cont_cgroup_dir, "bind", MS_BIND, NULL) == -1) { + pr_perror("Failed to mount %s at %s", cgroup_path, cont_cgroup_dir); + return -1; + } + + return ret; +} + DEFINE_CLEANUP_FUNC(struct libmnt_table*, mnt_free_table); DEFINE_CLEANUP_FUNC(struct libmnt_iter*, mnt_free_iter); -static int mount_cgroups() +static int mount_cgroups(const char *rootfs) { _cleanup_(mnt_free_tablep) struct libmnt_table *t = NULL; _cleanup_(mnt_free_iterp) struct libmnt_iter *i = NULL; @@ -108,6 +131,21 @@ static int mount_cgroups() } path = mnt_fs_get_target(fs); + + if (!strcmp(path, CGROUP_ROOT)) { + pr_pinfo("Skipping /sys/fs/cgroup"); + continue; + } + + + if (!strncmp(path, CGROUP_ROOT, strlen(CGROUP_ROOT))) { + pr_pinfo("Found path: %s\n", path); + rc = mount_cgroup_path(rootfs, path); + if (rc < 0) { + pr_perror("Failed to mount %s"); + return -1; + } + } } return ret; @@ -250,25 +288,30 @@ int prestart(const char *rootfs, } } -#if 0 - if (!contains_mount(config_mounts, config_mounts_len, "/sys/fs/cgroup")) { - char cont_cgroup_dir[PATH_MAX]; - snprintf(cont_cgroup_dir, PATH_MAX, "%s/sys/fs/cgroup", rootfs); + char cgroup_dir[PATH_MAX]; + snprintf(cgroup_dir, PATH_MAX, "%s/sys/fs/cgroup", rootfs); - if (makepath(cont_cgroup_dir, 0755) == -1) { + /* Create the /sys/fs/cgroup directory */ + if (!contains_mount(config_mounts, config_mounts_len, "/sys/fs/cgroup")) { + if (makepath(cgroup_dir, 0755) == -1) { if (errno != EEXIST) { - pr_perror("Failed to mkdir container cgroup dir"); - goto out; + pr_perror("Failed to mkdir"); + return -1; } } - /* Mount cgroup directory at /sys/fs/cgroup in the container */ - if (mount("/sys/fs/cgroup", cont_cgroup_dir, "bind", MS_BIND|MS_REC, "ro") == -1) { - pr_perror("Failed to mount /sys/fs/cgroup at %s", cont_cgroup_dir); - goto out; + /* Mount tmpfs at /sys/fs/cgroup for systemd */ + if (mount("tmpfs", cgroup_dir, "tmpfs", MS_NODEV|MS_NOSUID, "mode=755") == -1) { + pr_perror("Failed to mount tmpfs at /sys/fs/cgroup"); + return -1; + } + + if (mount_cgroups(rootfs) < 0) { + pr_perror("Failed to mount cgroups"); + return -1; } } -#endif + if (!contains_mount(config_mounts, config_mounts_len, "/etc/machine-id")) { char mid_path[PATH_MAX]; snprintf(mid_path, PATH_MAX, "%s/etc/machine-id", rootfs); From c7edcfbef154a3fa5c368ffdc0ab6f2436f048b2 Mon Sep 17 00:00:00 2001 From: Dan Walsh Date: Tue, 15 Dec 2015 09:14:14 -0500 Subject: [PATCH 3/3] Add missing BuildRequires --- oci-systemd-hook.spec | 1 + 1 file changed, 1 insertion(+) diff --git a/oci-systemd-hook.spec b/oci-systemd-hook.spec index f8e969c..d0d2057 100644 --- a/oci-systemd-hook.spec +++ b/oci-systemd-hook.spec @@ -11,6 +11,7 @@ BuildRequires: autoconf BuildRequires: automake BuildRequires: yajl-devel BuildRequires: libselinux-devel +BuildRequires: libmount-devel %description OCI systemd hooks enable running systemd in a OCI runc/docker container.