api_create and do_bdev_create: a few more fixes

don't use lxcpath variable for rootfs_path, it's confusing.

if rootfs is passed in and tpath is passed in, return error
before we save a new config, and don't delete the container

make sure to check c->lxc_conf is not NULL before dereferencing it.

Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
This commit is contained in:
Serge Hallyn 2013-10-30 10:57:45 -05:00
parent cd219ae659
commit cf465fe41c

View File

@ -701,19 +701,18 @@ static struct bdev *do_bdev_create(struct lxc_container *c, const char *type,
struct bdev_specs *specs) struct bdev_specs *specs)
{ {
char *dest; char *dest;
const char *lxcpath;
size_t len; size_t len;
struct bdev *bdev; struct bdev *bdev;
int ret; int ret;
/* rootfs.path or lxcpath/lxcname/rootfs */ /* rootfs.path or lxcpath/lxcname/rootfs */
if (c->lxc_conf->rootfs.path && access(c->lxc_conf->rootfs.path, F_OK) == 0) { if (c->lxc_conf->rootfs.path && access(c->lxc_conf->rootfs.path, F_OK) == 0) {
lxcpath = c->lxc_conf->rootfs.path; const char *rpath = c->lxc_conf->rootfs.path;
len = strlen(lxcpath) + 1; len = strlen(rpath) + 1;
dest = alloca(len); dest = alloca(len);
ret = snprintf(dest, len, "%s", lxcpath); ret = snprintf(dest, len, "%s", rpath);
} else { } else {
lxcpath = lxcapi_get_config_path(c); const char *lxcpath = lxcapi_get_config_path(c);
len = strlen(c->name) + strlen(lxcpath) + 9; len = strlen(c->name) + strlen(lxcpath) + 9;
dest = alloca(len); dest = alloca(len);
ret = snprintf(dest, len, "%s/%s/rootfs", lxcpath, c->name); ret = snprintf(dest, len, "%s/%s/rootfs", lxcpath, c->name);
@ -1110,24 +1109,44 @@ static bool lxcapi_create(struct lxc_container *c, const char *t,
} }
} }
/*
* If a template is passed in, and the rootfs already is defined in
* the container config and exists, then * caller is trying to create
* an existing container. Return an error, but do NOT delete the
* container.
*/
if (lxcapi_is_defined(c) && c->lxc_conf && c->lxc_conf->rootfs.path &&
access(c->lxc_conf->rootfs.path, F_OK) == 0 && tpath) {
ERROR("Container %s:%s already exists", c->config_path, c->name);
free(tpath);
return false;
}
/* Save the loaded configuration to disk */
if (!c->save_config(c, NULL)) { if (!c->save_config(c, NULL)) {
ERROR("failed to save starting configuration for %s\n", c->name); ERROR("failed to save starting configuration for %s\n", c->name);
goto out; goto out;
} }
if (c->lxc_conf) {
/* /*
* either template or rootfs.path should be set. * either template or rootfs.path should be set.
* if both template and rootfs.path are set, template is setup as rootfs.path. * if both template and rootfs.path are set, template is setup as rootfs.path.
* container is already created if we have a config and rootfs.path is accessible * container is already created if we have a config and rootfs.path is accessible
*/ */
if (c->lxc_conf && !c->lxc_conf->rootfs.path && !tpath) if (!c->lxc_conf->rootfs.path && !tpath)
/* no template passed in and rootfs does not exist: error */
goto out; goto out;
if (c->lxc_conf->rootfs.path && access(c->lxc_conf->rootfs.path, F_OK) != 0) if (c->lxc_conf->rootfs.path && access(c->lxc_conf->rootfs.path, F_OK) != 0)
/* rootfs passed into configuration, but does not exist: error */
goto out; goto out;
if (lxcapi_is_defined(c) && c->lxc_conf->rootfs.path && !tpath) { if (lxcapi_is_defined(c) && c->lxc_conf->rootfs.path && !tpath) {
/* Rootfs already existed, user just wanted to save the
* loaded configuration */
ret = true; ret = true;
goto out; goto out;
} }
}
/* Mark that this container is being created */ /* Mark that this container is being created */
if ((partial_fd = create_partial(c)) < 0) if ((partial_fd = create_partial(c)) < 0)