Commit 96b3cb40 by Serge Hallyn

lxcapi_create: split out the template execution

Make it its own function to make both more readable. Signed-off-by: 's avatarSerge Hallyn <serge.hallyn@ubuntu.com>
parent fb75356a
......@@ -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)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment