]> git.proxmox.com Git - mirror_lxc.git/commitdiff
lxcapi_create: split out the template execution
authorSerge Hallyn <serge.hallyn@ubuntu.com>
Thu, 11 Jul 2013 04:29:20 +0000 (23:29 -0500)
committerSerge Hallyn <serge.hallyn@ubuntu.com>
Thu, 11 Jul 2013 15:25:10 +0000 (10:25 -0500)
Make it its own function to make both more readable.

Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
src/lxc/lxccontainer.c

index 245d5eba58e804eec14a2abcaaf65086a7b60c83..596c189a2952c9cbb5b611b1f3e647a0bddf302c 100644 (file)
@@ -715,115 +715,34 @@ static struct bdev *do_bdev_create(struct lxc_container *c, const char *type,
        return bdev;
 }
 
-static bool lxcapi_destroy(struct lxc_container *c);
-/*
- * lxcapi_create:
- * create a container with the given parameters.
- * @c: container to be created.  It has the lxcpath, name, and a starting
- *     configuration already set
- * @t: the template to execute to instantiate the root filesystem and
- *     adjust the configuration.
- * @bdevtype: backing store type to use.  If NULL, dir will be used.
- * @specs: additional parameters for the backing store, i.e. LVM vg to
- *         use.
- *
- * @argv: the arguments to pass to the template, terminated by NULL.  If no
- * arguments, you can just pass NULL.
- */
-static bool lxcapi_create(struct lxc_container *c, const char *t,
-               const char *bdevtype, struct bdev_specs *specs,
-               char *const argv[])
+static char *lxcbasename(char *path)
 {
-       bool bret = false;
-       pid_t pid;
-       char *tpath = NULL, **newargv;
-       int partial_fd, ret, len, nargs = 0;
+       char *p = path + strlen(path) - 1;
+       while (*p != '/' && p > path)
+               p--;
+       return p;
+}
 
-       if (!c)
-               return false;
+static bool create_run_template(struct lxc_container *c, char *tpath,
+                               char *const argv[])
+{
+       pid_t pid;
 
-       len = strlen(LXCTEMPLATEDIR) + strlen(t) + strlen("/lxc-") + 1;
-       tpath = malloc(len);
        if (!tpath)
-               return false;
-       ret = snprintf(tpath, len, "%s/lxc-%s", LXCTEMPLATEDIR, t);
-       if (ret < 0 || ret >= len)
-               goto out;
-       if (!valid_template(tpath)) {
-               ERROR("bad template: %s\n", t);
-               goto out;
-       }
-
-       if (!c->save_config(c, NULL)) {
-               ERROR("failed to save starting configuration for %s\n", c->name);
-               goto out;
-       }
-
-       /* container is already created if we have a config and rootfs.path is accessible */
-       if (lxcapi_is_defined(c) && c->lxc_conf && c->lxc_conf->rootfs.path && access(c->lxc_conf->rootfs.path, F_OK) == 0)
-               goto out;
-
-       /* Mark that this container is being created */
-       if ((partial_fd = create_partial(c)) < 0)
-               goto out;
-
-       /* no need to get disk lock bc we have the partial locked */
-
-       /*
-        * Create the backing store
-        * Note we can't do this in the same task as we use to execute the
-        * template because of the way zfs works.
-        * After you 'zfs create', zfs mounts the fs only in the initial
-        * namespace.
-        */
-       pid = fork();
-       if (pid < 0) {
-               SYSERROR("failed to fork task for container creation template\n");
-               goto out_unlock;
-       }
-
-       if (pid == 0) { // child
-               struct bdev *bdev = NULL;
-
-               if (!(bdev = do_bdev_create(c, bdevtype, specs))) {
-                       ERROR("Error creating backing store type %s for %s",
-                               bdevtype ? bdevtype : "(none)", c->name);
-                       exit(1);
-               }
-
-               /* save config file again to store the new rootfs location */
-               if (!c->save_config(c, NULL)) {
-                       ERROR("failed to save starting configuration for %s\n", c->name);
-                       // parent task won't see bdev in config so we delete it
-                       bdev->ops->umount(bdev);
-                       bdev->ops->destroy(bdev);
-                       exit(1);
-               }
-               exit(0);
-       }
-       if (wait_for_pid(pid) != 0)
-               goto out;
-
-       /* reload config to get the rootfs */
-       if (c->lxc_conf)
-               lxc_conf_free(c->lxc_conf);
-       c->lxc_conf = NULL;
-       if (!load_config_locked(c, c->configfile))
-               goto out;
+               return true;
 
-       /*
-        * now execute the template
-        */
        pid = fork();
        if (pid < 0) {
                SYSERROR("failed to fork task for container creation template\n");
-               goto out_unlock;
+               return false;
        }
 
        if (pid == 0) { // child
                char *patharg, *namearg, *rootfsarg, *src;
                struct bdev *bdev = NULL;
                int i;
+               int ret, len, nargs = 0;
+               char **newargv;
 
                if (unshare(CLONE_NEWNS) < 0) {
                        ERROR("error unsharing mounts");
@@ -860,7 +779,7 @@ static bool lxcapi_create(struct lxc_container *c, const char *t,
                newargv = malloc(nargs * sizeof(*newargv));
                if (!newargv)
                        exit(1);
-               newargv[0] = (char *)t;
+               newargv[0] = lxcbasename(tpath);
 
                len = strlen(c->config_path) + strlen(c->name) + strlen("--path=") + 2;
                patharg = malloc(len);
@@ -908,9 +827,111 @@ static bool lxcapi_create(struct lxc_container *c, const char *t,
 
        if (wait_for_pid(pid) != 0) {
                ERROR("container creation template for %s failed\n", c->name);
+               return false;
+       }
+
+       return true;
+}
+
+static bool lxcapi_destroy(struct lxc_container *c);
+/*
+ * lxcapi_create:
+ * create a container with the given parameters.
+ * @c: container to be created.  It has the lxcpath, name, and a starting
+ *     configuration already set
+ * @t: the template to execute to instantiate the root filesystem and
+ *     adjust the configuration.
+ * @bdevtype: backing store type to use.  If NULL, dir will be used.
+ * @specs: additional parameters for the backing store, i.e. LVM vg to
+ *         use.
+ *
+ * @argv: the arguments to pass to the template, terminated by NULL.  If no
+ * arguments, you can just pass NULL.
+ */
+static bool lxcapi_create(struct lxc_container *c, const char *t,
+               const char *bdevtype, struct bdev_specs *specs,
+               char *const argv[])
+{
+       bool bret = false;
+       pid_t pid;
+       char *tpath = NULL;
+       int partial_fd, ret, len;
+
+       if (!c)
+               return false;
+
+       len = strlen(LXCTEMPLATEDIR) + strlen(t) + strlen("/lxc-") + 1;
+       tpath = malloc(len);
+       if (!tpath)
+               return false;
+       ret = snprintf(tpath, len, "%s/lxc-%s", LXCTEMPLATEDIR, t);
+       if (ret < 0 || ret >= len)
+               goto out;
+       if (!valid_template(tpath)) {
+               ERROR("bad template: %s\n", t);
+               goto out;
+       }
+
+       if (!c->save_config(c, NULL)) {
+               ERROR("failed to save starting configuration for %s\n", c->name);
+               goto out;
+       }
+
+       /* container is already created if we have a config and rootfs.path is accessible */
+       if (lxcapi_is_defined(c) && c->lxc_conf && c->lxc_conf->rootfs.path && access(c->lxc_conf->rootfs.path, F_OK) == 0)
+               goto out;
+
+       /* Mark that this container is being created */
+       if ((partial_fd = create_partial(c)) < 0)
+               goto out;
+
+       /* no need to get disk lock bc we have the partial locked */
+
+       /*
+        * Create the backing store
+        * Note we can't do this in the same task as we use to execute the
+        * template because of the way zfs works.
+        * After you 'zfs create', zfs mounts the fs only in the initial
+        * namespace.
+        */
+       pid = fork();
+       if (pid < 0) {
+               SYSERROR("failed to fork task for container creation template\n");
                goto out_unlock;
        }
 
+       if (pid == 0) { // child
+               struct bdev *bdev = NULL;
+
+               if (!(bdev = do_bdev_create(c, bdevtype, specs))) {
+                       ERROR("Error creating backing store type %s for %s",
+                               bdevtype ? bdevtype : "(none)", c->name);
+                       exit(1);
+               }
+
+               /* save config file again to store the new rootfs location */
+               if (!c->save_config(c, NULL)) {
+                       ERROR("failed to save starting configuration for %s\n", c->name);
+                       // parent task won't see bdev in config so we delete it
+                       bdev->ops->umount(bdev);
+                       bdev->ops->destroy(bdev);
+                       exit(1);
+               }
+               exit(0);
+       }
+       if (wait_for_pid(pid) != 0)
+               goto out;
+
+       /* reload config to get the rootfs */
+       if (c->lxc_conf)
+               lxc_conf_free(c->lxc_conf);
+       c->lxc_conf = NULL;
+       if (!load_config_locked(c, c->configfile))
+               goto out;
+
+       if (!create_run_template(c, tpath, argv))
+               goto out_unlock;
+
        // now clear out the lxc_conf we have, reload from the created
        // container
        if (c->lxc_conf)