Commit 534dfdeb by Christian Brauner

lxc-copy: cleanup

- make free_mnts() work directly on the globals mnt_table and mnt_table_size - have free_mnts() set mnt_table = NULL and mnt_table_size = 0 when its done to avoid double frees - simplify error-handling in do_clone_ephemeral() - do_clone_ephemeral(): when chmod() falls to set permissions on the temporary folder we created for mkdtemp() remove the folder - simplify error handling in main() Signed-off-by: 's avatarChristian Brauner <christian.brauner@mailbox.org>
parent ddf81220
...@@ -144,7 +144,7 @@ static int do_clone_ephemeral(struct lxc_container *c, ...@@ -144,7 +144,7 @@ static int do_clone_ephemeral(struct lxc_container *c,
static int do_clone_rename(struct lxc_container *c, char *newname); static int do_clone_rename(struct lxc_container *c, char *newname);
static int do_clone_task(struct lxc_container *c, enum task task, int flags, static int do_clone_task(struct lxc_container *c, enum task task, int flags,
char **args); char **args);
static void free_mnts(struct mnts *m, unsigned int num); static void free_mnts(void);
static uint64_t get_fssize(char *s); static uint64_t get_fssize(char *s);
static int parse_mntsubopts(char *subopts, char *const *keys, static int parse_mntsubopts(char *subopts, char *const *keys,
char *mntparameters); char *mntparameters);
...@@ -156,29 +156,29 @@ int main(int argc, char *argv[]) ...@@ -156,29 +156,29 @@ int main(int argc, char *argv[])
{ {
struct lxc_container *c; struct lxc_container *c;
int flags = 0; int flags = 0;
int ret; int ret = EXIT_FAILURE;
if (lxc_arguments_parse(&my_args, argc, argv)) if (lxc_arguments_parse(&my_args, argc, argv))
exit(EXIT_FAILURE); exit(ret);
if (!my_args.log_file) if (!my_args.log_file)
my_args.log_file = "none"; my_args.log_file = "none";
if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority, if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority,
my_args.progname, my_args.quiet, my_args.lxcpath[0])) my_args.progname, my_args.quiet, my_args.lxcpath[0]))
exit(EXIT_FAILURE); exit(ret);
lxc_log_options_no_override(); lxc_log_options_no_override();
if (geteuid()) { if (geteuid()) {
if (access(my_args.lxcpath[0], O_RDWR) < 0) { if (access(my_args.lxcpath[0], O_RDWR) < 0) {
fprintf(stderr, "You lack access to %s\n", my_args.lxcpath[0]); fprintf(stderr, "You lack access to %s\n", my_args.lxcpath[0]);
exit(EXIT_FAILURE); exit(ret);
} }
} }
if (!my_args.newname && !(my_args.task == DESTROY)) { if (!my_args.newname && !(my_args.task == DESTROY)) {
printf("Error: You must provide a NEWNAME for the clone.\n"); printf("Error: You must provide a NEWNAME for the clone.\n");
exit(EXIT_FAILURE); exit(ret);
} }
if (my_args.task == SNAP || my_args.task == DESTROY) if (my_args.task == SNAP || my_args.task == DESTROY)
...@@ -193,24 +193,21 @@ int main(int argc, char *argv[]) ...@@ -193,24 +193,21 @@ int main(int argc, char *argv[])
c = lxc_container_new(my_args.name, my_args.lxcpath[0]); c = lxc_container_new(my_args.name, my_args.lxcpath[0]);
if (!c) if (!c)
exit(EXIT_FAILURE); exit(ret);
if (!c->may_control(c)) { if (!c->may_control(c)) {
fprintf(stderr, "Insufficent privileges to control %s\n", fprintf(stderr, "Insufficent privileges to control %s\n", c->name);
c->name); goto out;
lxc_container_put(c);
exit(EXIT_FAILURE);
} }
if (!c->is_defined(c)) { if (!c->is_defined(c)) {
fprintf(stderr, "Error: container %s is not defined\n", fprintf(stderr, "Error: container %s is not defined\n", c->name);
c->name); goto out;
lxc_container_put(c);
exit(EXIT_FAILURE);
} }
ret = do_clone_task(c, my_args.task, flags, &argv[optind]); ret = do_clone_task(c, my_args.task, flags, &argv[optind]);
out:
lxc_container_put(c); lxc_container_put(c);
if (ret == 0) if (ret == 0)
...@@ -240,41 +237,36 @@ static int mk_rand_ovl_dirs(struct mnts *mnts, unsigned int num, struct lxc_argu ...@@ -240,41 +237,36 @@ static int mk_rand_ovl_dirs(struct mnts *mnts, unsigned int num, struct lxc_argu
char upperdir[MAXPATHLEN]; char upperdir[MAXPATHLEN];
char workdir[MAXPATHLEN]; char workdir[MAXPATHLEN];
unsigned int i; unsigned int i;
int ret = 0; int ret;
struct mnts *m; struct mnts *m = NULL;
for (i = 0; i < num; i++) { for (i = 0, m = mnts; i < num; i++, m++) {
m = mnts + i;
if ((m->mnt_type == LXC_MNT_OVL) || (m->mnt_type == LXC_MNT_AUFS)) { if ((m->mnt_type == LXC_MNT_OVL) || (m->mnt_type == LXC_MNT_AUFS)) {
ret = snprintf(upperdir, MAXPATHLEN, "%s/%s/delta#XXXXXX", ret = snprintf(upperdir, MAXPATHLEN, "%s/%s/delta#XXXXXX",
arg->newpath, arg->newname); arg->newpath, arg->newname);
if (ret < 0 || ret >= MAXPATHLEN) if (ret < 0 || ret >= MAXPATHLEN)
goto err; return -1;
if (!mkdtemp(upperdir)) if (!mkdtemp(upperdir))
goto err; return -1;
m->upper = strdup(upperdir); m->upper = strdup(upperdir);
if (!m->upper) if (!m->upper)
goto err; return -1;
} }
if (m->mnt_type == LXC_MNT_OVL) { if (m->mnt_type == LXC_MNT_OVL) {
ret = snprintf(workdir, MAXPATHLEN, "%s/%s/work#XXXXXX", ret = snprintf(workdir, MAXPATHLEN, "%s/%s/work#XXXXXX",
arg->newpath, arg->newname); arg->newpath, arg->newname);
if (ret < 0 || ret >= MAXPATHLEN) if (ret < 0 || ret >= MAXPATHLEN)
goto err; return -1;
if (!mkdtemp(workdir)) if (!mkdtemp(workdir))
goto err; return -1;
m->workdir = strdup(workdir); m->workdir = strdup(workdir);
if (!m->workdir) if (!m->workdir)
goto err; return -1;
} }
} }
return 0; return 0;
err:
free_mnts(mnt_table, mnt_table_size);
return -1;
} }
static char *construct_path(char *path, bool as_prefix) static char *construct_path(char *path, bool as_prefix)
...@@ -343,7 +335,6 @@ static char *set_mnt_entry(struct mnts *m) ...@@ -343,7 +335,6 @@ static char *set_mnt_entry(struct mnts *m)
return mntentry; return mntentry;
err: err:
free_mnts(mnt_table, mnt_table_size);
free(mntentry); free(mntentry);
return NULL; return NULL;
} }
...@@ -370,15 +361,13 @@ static int do_clone(struct lxc_container *c, char *newname, char *newpath, ...@@ -370,15 +361,13 @@ static int do_clone(struct lxc_container *c, char *newname, char *newpath,
} }
static int do_clone_ephemeral(struct lxc_container *c, static int do_clone_ephemeral(struct lxc_container *c,
struct lxc_arguments *arg, char **args, struct lxc_arguments *arg, char **args, int flags)
int flags)
{ {
char randname[MAXPATHLEN]; char randname[MAXPATHLEN];
unsigned int i; unsigned int i;
int ret = 0; int ret = 0;
bool bret = true; bool bret = true, started = false;
struct lxc_container *clone; struct lxc_container *clone;
struct mnts *n;
lxc_attach_options_t attach_options = LXC_ATTACH_OPTIONS_DEFAULT; lxc_attach_options_t attach_options = LXC_ATTACH_OPTIONS_DEFAULT;
attach_options.env_policy = LXC_ATTACH_CLEAR_ENV; attach_options.env_policy = LXC_ATTACH_CLEAR_ENV;
...@@ -389,8 +378,10 @@ static int do_clone_ephemeral(struct lxc_container *c, ...@@ -389,8 +378,10 @@ static int do_clone_ephemeral(struct lxc_container *c,
return -1; return -1;
if (!mkdtemp(randname)) if (!mkdtemp(randname))
return -1; return -1;
if (chmod(randname, 0770) < 0) if (chmod(randname, 0770) < 0) {
remove(randname);
return -1; return -1;
}
arg->newname = randname + strlen(arg->newpath) + 1; arg->newname = randname + strlen(arg->newpath) + 1;
} }
...@@ -401,26 +392,27 @@ static int do_clone_ephemeral(struct lxc_container *c, ...@@ -401,26 +392,27 @@ static int do_clone_ephemeral(struct lxc_container *c,
if (!arg->keepdata) if (!arg->keepdata)
if (!clone->set_config_item(clone, "lxc.ephemeral", "1")) if (!clone->set_config_item(clone, "lxc.ephemeral", "1"))
goto err; goto destroy_and_put;
/* allocate and create random upper- and workdirs for overlay mounts */ /* allocate and create random upper- and workdirs for overlay mounts */
if (mk_rand_ovl_dirs(mnt_table, mnt_table_size, arg) < 0) if (mk_rand_ovl_dirs(mnt_table, mnt_table_size, arg) < 0)
goto err; goto destroy_and_put;
/* allocate and set mount entries */ /* allocate and set mount entries */
for (i = 0; i < mnt_table_size; i++) { struct mnts *n = NULL;
for (i = 0, n = mnt_table; i < mnt_table_size; i++, n++) {
char *mntentry = NULL; char *mntentry = NULL;
n = mnt_table + i; mntentry = set_mnt_entry(n);
if ((mntentry = set_mnt_entry(n))) { if (!mntentry)
bret = clone->set_config_item(clone, "lxc.mount.entry", mntentry); goto destroy_and_put;
free(mntentry); bret = clone->set_config_item(clone, "lxc.mount.entry", mntentry);
} free(mntentry);
if (!mntentry || !bret) if (!bret)
goto err; goto destroy_and_put;
} }
if (!clone->save_config(clone, NULL)) if (!clone->save_config(clone, NULL))
goto err; goto destroy_and_put;
printf("Created %s as %s of %s\n", arg->name, "clone", arg->newname); printf("Created %s as %s of %s\n", arg->name, "clone", arg->newname);
...@@ -431,26 +423,27 @@ static int do_clone_ephemeral(struct lxc_container *c, ...@@ -431,26 +423,27 @@ static int do_clone_ephemeral(struct lxc_container *c,
clone->want_daemonize(clone, false); clone->want_daemonize(clone, false);
} }
if (!clone->start(clone, 0, NULL)) { started = clone->start(clone, 0, NULL);
if (!(clone->lxc_conf->ephemeral == 1)) if (!started)
goto err; goto destroy_and_put;
goto put;
}
if (arg->daemonize && arg->argc) { if (arg->daemonize && arg->argc) {
ret = clone->attach_run_wait(clone, &attach_options, arg->argv[0], (const char *const *)arg->argv); ret = clone->attach_run_wait(clone, &attach_options, arg->argv[0], (const char *const *)arg->argv);
if (ret < 0) if (ret < 0)
goto put; goto destroy_and_put;
clone->shutdown(clone, true); clone->shutdown(clone, -1);
} }
free_mnts();
lxc_container_put(clone); lxc_container_put(clone);
return 0; return 0;
err: destroy_and_put:
clone->destroy(clone); if (started)
put: clone->shutdown(clone, -1);
free_mnts(mnt_table, mnt_table_size); if (!started || clone->lxc_conf->ephemeral != 1)
clone->destroy(clone);
free_mnts();
lxc_container_put(clone); lxc_container_put(clone);
return -1; return -1;
} }
...@@ -489,20 +482,21 @@ static int do_clone_task(struct lxc_container *c, enum task task, int flags, ...@@ -489,20 +482,21 @@ static int do_clone_task(struct lxc_container *c, enum task task, int flags,
return ret; return ret;
} }
static void free_mnts(struct mnts *m, unsigned int num) static void free_mnts()
{ {
unsigned int i; unsigned int i;
struct mnts *n; struct mnts *n = NULL;
for (i = 0; i < num; i++) { for (i = 0, n = mnt_table; i < mnt_table_size; i++, n++) {
n = m + i;
free(n->src); free(n->src);
free(n->dest); free(n->dest);
free(n->options); free(n->options);
free(n->upper); free(n->upper);
free(n->workdir); free(n->workdir);
} }
free(m); free(mnt_table);
mnt_table = NULL;
mnt_table_size = 0;
} }
/* we pass fssize in bytes */ /* we pass fssize in bytes */
...@@ -627,7 +621,7 @@ static int parse_aufs_mnt(char *mntstring, enum mnttype type) ...@@ -627,7 +621,7 @@ static int parse_aufs_mnt(char *mntstring, enum mnttype type)
return 0; return 0;
err: err:
free_mnts(mnt_table, mnt_table_size); free_mnts();
lxc_free_array((void **)mntarray, free); lxc_free_array((void **)mntarray, free);
return -1; return -1;
} }
...@@ -685,7 +679,7 @@ static int parse_bind_mnt(char *mntstring, enum mnttype type) ...@@ -685,7 +679,7 @@ static int parse_bind_mnt(char *mntstring, enum mnttype type)
return 0; return 0;
err: err:
free_mnts(mnt_table, mnt_table_size); free_mnts();
lxc_free_array((void **)mntarray, free); lxc_free_array((void **)mntarray, free);
return -1; return -1;
} }
...@@ -746,8 +740,7 @@ static int parse_ovl_mnt(char *mntstring, enum mnttype type) ...@@ -746,8 +740,7 @@ static int parse_ovl_mnt(char *mntstring, enum mnttype type)
return 0; return 0;
err: err:
free_mnts(mnt_table, mnt_table_size); free_mnts();
lxc_free_array((void **)mntarray, free); lxc_free_array((void **)mntarray, free);
return -1; return -1;
} }
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