]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
start: add shmount setup on container start
authorLiza Tretyakova <elizabet.tretyakova@gmail.com>
Wed, 2 May 2018 07:58:54 +0000 (10:58 +0300)
committerChristian Brauner <christian.brauner@ubuntu.com>
Sun, 22 Jul 2018 13:25:16 +0000 (15:25 +0200)
Signed-off-by: Liza Tretyakova <elizabet.tretyakova@gmail.com>
src/lxc/start.c

index 1d22a6a5988be0b8723390125244ddd33816cc71..552c7759919245a5d19e619fb9708e5368e391a9 100644 (file)
@@ -1529,6 +1529,70 @@ static inline int do_share_ns(void *arg)
        return 0;
 }
 
+static int lxc_setup_shmount(struct lxc_conf *conf) {
+       size_t len_cont;
+       char *full_cont_path;
+       int ret = -1;
+
+       /* Construct the shmount path under the container root */
+       /* +1 for slash */
+       len_cont = strlen(conf->rootfs.mount) + 1 + strlen(conf->lxc_shmount.path_cont);
+       /* +1 for the terminating '\0' */
+       full_cont_path = malloc(len_cont + 1);
+       if(!full_cont_path) {
+               SYSERROR("Not enough memory");
+               return -ENOMEM;
+       }
+       ret = snprintf(full_cont_path, len_cont + 1, "%s/%s", conf->rootfs.mount, conf->lxc_shmount.path_cont);
+       if (ret < 0 || ret >= len_cont + 1) {
+               SYSERROR("Failed to create filename");
+               free(full_cont_path);
+               return -1;
+       }
+
+       /* Check if shmount point is already set up */
+       if (is_shared_mountpoint(conf->lxc_shmount.path_host)) {
+               INFO("Path \"%s\" is already MS_SHARED. Reusing", conf->lxc_shmount.path_host);
+               free(full_cont_path);
+               return 0;
+       }
+
+       /* Create host and cont mount paths */
+       ret = mkdir_p(conf->lxc_shmount.path_host, 0711);
+       if (ret < 0 && errno != EEXIST) {
+               SYSERROR("Failed to create directory \"%s\"", conf->lxc_shmount.path_host);
+               free(full_cont_path);
+               return ret;
+       }
+
+       ret = mkdir_p(full_cont_path, 0711);
+       if (ret < 0 && errno != EEXIST) {
+               SYSERROR("Failed to create directory \"%s\"", full_cont_path);
+               free(full_cont_path);
+               return ret;
+       }
+
+       /* Prepare host mountpoint */
+       ret = mount("tmpfs", conf->lxc_shmount.path_host, "tmpfs",
+                               0, "size=100k,mode=0711");
+       if (ret < 0) {
+               SYSERROR("Failed to mount \"%s\"", conf->lxc_shmount.path_host);
+               free(full_cont_path);
+               return ret;
+       }
+       ret = mount(conf->lxc_shmount.path_host, conf->lxc_shmount.path_host, "none",
+                               MS_REC | MS_SHARED, "");
+       if (ret < 0) {
+               SYSERROR("Failed to make shared \"%s\"", conf->lxc_shmount.path_host);
+               free(full_cont_path);
+               return ret;
+       }
+
+       INFO("Made shared mount point \"%s\"", conf->lxc_shmount.path_host);
+       free(full_cont_path);
+       return 0;
+}
+
 /* lxc_spawn() performs crucial setup tasks and clone()s the new process which
  * exec()s the requested container binary.
  * Note that lxc_spawn() runs in the parent namespaces. Any operations performed
@@ -1606,6 +1670,25 @@ static int lxc_spawn(struct lxc_handler *handler)
                }
        }
 
+       if (conf->lxc_shmount.path_host && !conf->lxc_shmount.path_cont) {
+                       ERROR("Missing the container side path to the shared mount point");
+                       lxc_sync_fini(handler);
+                       return -1;
+       }
+       if (conf->lxc_shmount.path_host) {
+               ret = lxc_setup_shmount(conf);
+               if (ret < 0) {
+                       ERROR("Failed to setup shared mount point");
+                       lxc_sync_fini(handler);
+                       return -1;
+               }
+       }
+
+       if (!cgroup_init(handler)) {
+               ERROR("Failed initializing cgroup support");
+               goto out_delete_net;
+       }
+
        if (!cgroup_ops->create(cgroup_ops, handler)) {
                ERROR("Failed creating cgroups");
                goto out_delete_net;