[lxc-devel] [PATCH 1/2] lxcapi_create: split out the template execution

Serge Hallyn serge.hallyn at ubuntu.com
Thu Jul 11 04:29:20 UTC 2013


Make it its own function to make both more readable.

Signed-off-by: Serge Hallyn <serge.hallyn at ubuntu.com>
---
 src/lxc/lxccontainer.c | 215 +++++++++++++++++++++++++++----------------------
 1 file changed, 118 insertions(+), 97 deletions(-)

diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index 245d5eb..caf8c72 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -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;
-
-	if (!c)
-		return false;
+	char *p = path + strlen(path) - 1;
+	while (*p != '/' && p > path)
+		p--;
+	return p;
+}
 
-	len = strlen(LXCTEMPLATEDIR) + strlen(t) + strlen("/lxc-") + 1;
-	tpath = malloc(len);
+static bool create_run_template(struct lxc_container *c, char *tpath,
+				char *const argv[])
+{
+	pid_t pid;
+	
 	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)
-- 
1.8.1.2





More information about the lxc-devel mailing list