Commit a73846d8 by 2xsec

lxccontainer: coding rules

Signed-off-by: 's avatar2xsec <dh48.jeong@samsung.com>
parent 29c98ddd
...@@ -167,11 +167,12 @@ static int ongoing_create(struct lxc_container *c) ...@@ -167,11 +167,12 @@ static int ongoing_create(struct lxc_container *c)
ret = fcntl(fd, F_OFD_GETLK, &lk); ret = fcntl(fd, F_OFD_GETLK, &lk);
if (ret < 0 && errno == EINVAL) if (ret < 0 && errno == EINVAL)
ret = flock(fd, LOCK_EX | LOCK_NB); ret = flock(fd, LOCK_EX | LOCK_NB);
close(fd); close(fd);
if (ret == 0 && lk.l_pid != -1) {
if (ret == 0 && lk.l_pid != -1)
/* create is still ongoing */ /* create is still ongoing */
return 1; return 1;
}
/* Create completed but partial is still there. */ /* Create completed but partial is still there. */
return 2; return 2;
...@@ -221,6 +222,7 @@ static void remove_partial(struct lxc_container *c, int fd) ...@@ -221,6 +222,7 @@ static void remove_partial(struct lxc_container *c, int fd)
char *path; char *path;
close(fd); close(fd);
/* $lxcpath + '/' + $name + '/partial' + \0 */ /* $lxcpath + '/' + $name + '/partial' + \0 */
len = strlen(c->config_path) + strlen(c->name) + 10; len = strlen(c->config_path) + strlen(c->name) + 10;
path = alloca(len); path = alloca(len);
...@@ -254,7 +256,6 @@ static void remove_partial(struct lxc_container *c, int fd) ...@@ -254,7 +256,6 @@ static void remove_partial(struct lxc_container *c, int fd)
* decrement numthreads under privlock, then if it hits 0 you can delete. * decrement numthreads under privlock, then if it hits 0 you can delete.
* Do not ever use a lxccontainer whose numthreads you did not bump. * Do not ever use a lxccontainer whose numthreads you did not bump.
*/ */
static void lxc_container_free(struct lxc_container *c) static void lxc_container_free(struct lxc_container *c)
{ {
if (!c) if (!c)
...@@ -358,7 +359,6 @@ int lxc_container_put(struct lxc_container *c) ...@@ -358,7 +359,6 @@ int lxc_container_put(struct lxc_container *c)
} }
container_mem_unlock(c); container_mem_unlock(c);
return 0; return 0;
} }
...@@ -385,7 +385,6 @@ static bool do_lxcapi_is_defined(struct lxc_container *c) ...@@ -385,7 +385,6 @@ static bool do_lxcapi_is_defined(struct lxc_container *c)
on_error: on_error:
container_mem_unlock(c); container_mem_unlock(c);
return ret; return ret;
} }
...@@ -596,7 +595,6 @@ static bool load_config_locked(struct lxc_container *c, const char *fname) ...@@ -596,7 +595,6 @@ static bool load_config_locked(struct lxc_container *c, const char *fname)
return false; return false;
c->lxc_conf->name = c->name; c->lxc_conf->name = c->name;
return true; return true;
} }
...@@ -610,8 +608,10 @@ static bool do_lxcapi_load_config(struct lxc_container *c, const char *alt_file) ...@@ -610,8 +608,10 @@ static bool do_lxcapi_load_config(struct lxc_container *c, const char *alt_file)
return false; return false;
fname = c->configfile; fname = c->configfile;
if (alt_file) if (alt_file)
fname = alt_file; fname = alt_file;
if (!fname) if (!fname)
return false; return false;
...@@ -746,9 +746,8 @@ static char **split_init_cmd(const char *incmd) ...@@ -746,9 +746,8 @@ static char **split_init_cmd(const char *incmd)
len = strlen(incmd) + 1; len = strlen(incmd) + 1;
copy = alloca(len); copy = alloca(len);
retlen = strlcpy(copy, incmd, len); retlen = strlcpy(copy, incmd, len);
if (retlen >= len) { if (retlen >= len)
return NULL; return NULL;
}
do { do {
argv = malloc(sizeof(char *)); argv = malloc(sizeof(char *));
...@@ -786,11 +785,11 @@ static int lxc_rcv_status(int state_socket) ...@@ -786,11 +785,11 @@ static int lxc_rcv_status(int state_socket)
again: again:
/* Receive container state. */ /* Receive container state. */
ret = lxc_abstract_unix_rcv_credential(state_socket, &state, ret = lxc_abstract_unix_rcv_credential(state_socket, &state, sizeof(int));
sizeof(int));
if (ret <= 0) { if (ret <= 0) {
if (errno != EINTR) if (errno != EINTR)
return -1; return -1;
TRACE("Caught EINTR; retrying"); TRACE("Caught EINTR; retrying");
goto again; goto again;
} }
...@@ -1147,6 +1146,7 @@ static bool lxcapi_startl(struct lxc_container *c, int useinit, ...) ...@@ -1147,6 +1146,7 @@ static bool lxcapi_startl(struct lxc_container *c, int useinit, ...)
on_error: on_error:
if (inargs) { if (inargs) {
char **arg; char **arg;
for (arg = inargs; *arg; arg++) for (arg = inargs; *arg; arg++)
free(*arg); free(*arg);
free(inargs); free(inargs);
...@@ -1405,9 +1405,9 @@ static bool create_run_template(struct lxc_container *c, char *tpath, ...@@ -1405,9 +1405,9 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
* args. * args.
*/ */
if (argv) if (argv)
for (nargs = 0; argv[nargs]; nargs++) { for (nargs = 0; argv[nargs]; nargs++)
; ;
}
/* template, path, rootfs and name args */ /* template, path, rootfs and name args */
nargs += 4; nargs += 4;
...@@ -1421,6 +1421,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath, ...@@ -1421,6 +1421,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
patharg = malloc(len); patharg = malloc(len);
if (!patharg) if (!patharg)
_exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
ret = snprintf(patharg, len, "--path=%s/%s", c->config_path, c->name); ret = snprintf(patharg, len, "--path=%s/%s", c->config_path, c->name);
if (ret < 0 || ret >= len) if (ret < 0 || ret >= len)
_exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
...@@ -1431,6 +1432,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath, ...@@ -1431,6 +1432,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
namearg = malloc(len); namearg = malloc(len);
if (!namearg) if (!namearg)
_exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
ret = snprintf(namearg, len, "--name=%s", c->name); ret = snprintf(namearg, len, "--name=%s", c->name);
if (ret < 0 || ret >= len) if (ret < 0 || ret >= len)
_exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
...@@ -1441,6 +1443,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath, ...@@ -1441,6 +1443,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
rootfsarg = malloc(len); rootfsarg = malloc(len);
if (!rootfsarg) if (!rootfsarg)
_exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
ret = snprintf(rootfsarg, len, "--rootfs=%s", bdev->dest); ret = snprintf(rootfsarg, len, "--rootfs=%s", bdev->dest);
if (ret < 0 || ret >= len) if (ret < 0 || ret >= len)
_exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
...@@ -1478,6 +1481,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath, ...@@ -1478,6 +1481,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
newargv[0] = tpath; newargv[0] = tpath;
tpath = "lxc-usernsexec"; tpath = "lxc-usernsexec";
n2[0] = "lxc-usernsexec"; n2[0] = "lxc-usernsexec";
lxc_list_for_each(it, &conf->id_map) { lxc_list_for_each(it, &conf->id_map) {
map = it->elem; map = it->elem;
n2args += 2; n2args += 2;
...@@ -1499,6 +1503,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath, ...@@ -1499,6 +1503,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
hostuid_mapped = mapped_hostid(geteuid(), conf, ID_TYPE_UID); hostuid_mapped = mapped_hostid(geteuid(), conf, ID_TYPE_UID);
extraargs = hostuid_mapped >= 0 ? 1 : 3; extraargs = hostuid_mapped >= 0 ? 1 : 3;
n2 = realloc(n2, (nargs + n2args + extraargs) * sizeof(char *)); n2 = realloc(n2, (nargs + n2args + extraargs) * sizeof(char *));
if (!n2) if (!n2)
_exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
...@@ -1516,6 +1521,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath, ...@@ -1516,6 +1521,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
SYSERROR("out of memory"); SYSERROR("out of memory");
_exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
} }
ret = snprintf(n2[n2args - 1], 200, "u:%d:%d:1", ret = snprintf(n2[n2args - 1], 200, "u:%d:%d:1",
hostuid_mapped, geteuid()); hostuid_mapped, geteuid());
if (ret < 0 || ret >= 200) if (ret < 0 || ret >= 200)
...@@ -1524,6 +1530,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath, ...@@ -1524,6 +1530,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
hostgid_mapped = mapped_hostid(getegid(), conf, ID_TYPE_GID); hostgid_mapped = mapped_hostid(getegid(), conf, ID_TYPE_GID);
extraargs = hostgid_mapped >= 0 ? 1 : 3; extraargs = hostgid_mapped >= 0 ? 1 : 3;
n2 = realloc(n2, (nargs + n2args + extraargs) * sizeof(char *)); n2 = realloc(n2, (nargs + n2args + extraargs) * sizeof(char *));
if (!n2) if (!n2)
_exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
...@@ -1547,7 +1554,9 @@ static bool create_run_template(struct lxc_container *c, char *tpath, ...@@ -1547,7 +1554,9 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
if (ret < 0 || ret >= 200) if (ret < 0 || ret >= 200)
_exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
} }
n2[n2args++] = "--"; n2[n2args++] = "--";
for (i = 0; i < nargs; i++) for (i = 0; i < nargs; i++)
n2[i + n2args] = newargv[i]; n2[i + n2args] = newargv[i];
n2args += nargs; n2args += nargs;
...@@ -1644,6 +1653,7 @@ static bool prepend_lxc_header(char *path, const char *t, char *const argv[]) ...@@ -1644,6 +1653,7 @@ static bool prepend_lxc_header(char *path, const char *t, char *const argv[])
goto out_free_contents; goto out_free_contents;
contents[flen] = '\0'; contents[flen] = '\0';
ret = fclose(f); ret = fclose(f);
f = NULL; f = NULL;
if (ret < 0) if (ret < 0)
...@@ -1681,6 +1691,7 @@ static bool prepend_lxc_header(char *path, const char *t, char *const argv[]) ...@@ -1681,6 +1691,7 @@ static bool prepend_lxc_header(char *path, const char *t, char *const argv[])
} }
fprintf(f, "\n"); fprintf(f, "\n");
} }
#if HAVE_LIBGNUTLS #if HAVE_LIBGNUTLS
fprintf(f, "# Template script checksum (SHA-1): "); fprintf(f, "# Template script checksum (SHA-1): ");
for (i=0; i<SHA_DIGEST_LENGTH; i++) for (i=0; i<SHA_DIGEST_LENGTH; i++)
...@@ -1811,6 +1822,7 @@ static bool do_lxcapi_create(struct lxc_container *c, const char *t, ...@@ -1811,6 +1822,7 @@ static bool do_lxcapi_create(struct lxc_container *c, const char *t,
*/ */
if (!c->save_config(c, NULL)) if (!c->save_config(c, NULL))
ERROR("Failed to save initial config for \"%s\"", c->name); ERROR("Failed to save initial config for \"%s\"", c->name);
ret = true; ret = true;
goto out; goto out;
} }
...@@ -1856,14 +1868,17 @@ static bool do_lxcapi_create(struct lxc_container *c, const char *t, ...@@ -1856,14 +1868,17 @@ static bool do_lxcapi_create(struct lxc_container *c, const char *t,
bdev->ops->destroy(bdev); bdev->ops->destroy(bdev);
_exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
} }
_exit(EXIT_SUCCESS); _exit(EXIT_SUCCESS);
} }
if (wait_for_pid(pid) != 0) if (wait_for_pid(pid) != 0)
goto out_unlock; goto out_unlock;
/* Reload config to get the rootfs. */ /* Reload config to get the rootfs. */
lxc_conf_free(c->lxc_conf); lxc_conf_free(c->lxc_conf);
c->lxc_conf = NULL; c->lxc_conf = NULL;
if (!load_config_locked(c, c->configfile)) if (!load_config_locked(c, c->configfile))
goto out_unlock; goto out_unlock;
...@@ -1881,15 +1896,18 @@ static bool do_lxcapi_create(struct lxc_container *c, const char *t, ...@@ -1881,15 +1896,18 @@ static bool do_lxcapi_create(struct lxc_container *c, const char *t,
goto out_unlock; goto out_unlock;
} }
} }
ret = load_config_locked(c, c->configfile); ret = load_config_locked(c, c->configfile);
out_unlock: out_unlock:
umask(mask); umask(mask);
if (partial_fd >= 0) if (partial_fd >= 0)
remove_partial(c, partial_fd); remove_partial(c, partial_fd);
out: out:
if (!ret) if (!ret)
container_destroy(c, NULL); container_destroy(c, NULL);
free_tpath: free_tpath:
free(tpath); free(tpath);
return ret; return ret;
...@@ -1900,7 +1918,9 @@ static bool lxcapi_create(struct lxc_container *c, const char *t, ...@@ -1900,7 +1918,9 @@ static bool lxcapi_create(struct lxc_container *c, const char *t,
int flags, char *const argv[]) int flags, char *const argv[])
{ {
bool ret; bool ret;
current_config = c ? c->lxc_conf : NULL; current_config = c ? c->lxc_conf : NULL;
ret = do_lxcapi_create(c, t, bdevtype, specs, flags, argv); ret = do_lxcapi_create(c, t, bdevtype, specs, flags, argv);
current_config = NULL; current_config = NULL;
return ret; return ret;
...@@ -1981,6 +2001,7 @@ static bool do_lxcapi_reboot2(struct lxc_container *c, int timeout) ...@@ -1981,6 +2001,7 @@ static bool do_lxcapi_reboot2(struct lxc_container *c, int timeout)
if (killret < 0) { if (killret < 0) {
if (state_client_fd >= 0) if (state_client_fd >= 0)
close(state_client_fd); close(state_client_fd);
WARN("Failed to send signal %d to pid %d", rebootsignal, pid); WARN("Failed to send signal %d to pid %d", rebootsignal, pid);
return false; return false;
} }
...@@ -2051,6 +2072,7 @@ static bool do_lxcapi_shutdown(struct lxc_container *c, int timeout) ...@@ -2051,6 +2072,7 @@ static bool do_lxcapi_shutdown(struct lxc_container *c, int timeout)
if (killret < 0) { if (killret < 0) {
if (state_client_fd >= 0) if (state_client_fd >= 0)
close(state_client_fd); close(state_client_fd);
WARN("Failed to send signal %d to pid %d", haltsignal, pid); WARN("Failed to send signal %d to pid %d", haltsignal, pid);
return false; return false;
} }
...@@ -2151,6 +2173,7 @@ static bool do_lxcapi_clear_config_item(struct lxc_container *c, ...@@ -2151,6 +2173,7 @@ static bool do_lxcapi_clear_config_item(struct lxc_container *c,
*/ */
if (config && config->clr) if (config && config->clr)
ret = config->clr(key, c->lxc_conf, NULL); ret = config->clr(key, c->lxc_conf, NULL);
if (!ret) if (!ret)
do_clear_unexp_config_line(c->lxc_conf, key); do_clear_unexp_config_line(c->lxc_conf, key);
...@@ -2164,10 +2187,11 @@ static inline bool enter_net_ns(struct lxc_container *c) ...@@ -2164,10 +2187,11 @@ static inline bool enter_net_ns(struct lxc_container *c)
{ {
pid_t pid = do_lxcapi_init_pid(c); pid_t pid = do_lxcapi_init_pid(c);
if ((geteuid() != 0 || (c->lxc_conf && !lxc_list_empty(&c->lxc_conf->id_map))) && access("/proc/self/ns/user", F_OK) == 0) { if ((geteuid() != 0 || (c->lxc_conf && !lxc_list_empty(&c->lxc_conf->id_map))) &&
(access("/proc/self/ns/user", F_OK) == 0))
if (!switch_to_ns(pid, "user")) if (!switch_to_ns(pid, "user"))
return false; return false;
}
return switch_to_ns(pid, "net"); return switch_to_ns(pid, "net");
} }
...@@ -2229,10 +2253,11 @@ static char** get_from_array(char ***names, char *cname, int size) ...@@ -2229,10 +2253,11 @@ static char** get_from_array(char ***names, char *cname, int size)
return (char **)bsearch(&cname, *names, size, sizeof(char *), (int (*)(const void *, const void *))string_cmp); return (char **)bsearch(&cname, *names, size, sizeof(char *), (int (*)(const void *, const void *))string_cmp);
} }
static bool array_contains(char ***names, char *cname, int size)
static bool array_contains(char ***names, char *cname, int size) { {
if(get_from_array(names, cname, size) != NULL) if(get_from_array(names, cname, size) != NULL)
return true; return true;
return false; return false;
} }
...@@ -2243,6 +2268,7 @@ static bool remove_from_array(char ***names, char *cname, int size) ...@@ -2243,6 +2268,7 @@ static bool remove_from_array(char ***names, char *cname, int size)
free(result); free(result);
return true; return true;
} }
return false; return false;
} }
...@@ -2293,6 +2319,7 @@ static char ** do_lxcapi_get_interfaces(struct lxc_container *c) ...@@ -2293,6 +2319,7 @@ static char ** do_lxcapi_get_interfaces(struct lxc_container *c)
} }
count++; count++;
} }
ret = 0; ret = 0;
out: out:
...@@ -2322,6 +2349,7 @@ static char ** do_lxcapi_get_interfaces(struct lxc_container *c) ...@@ -2322,6 +2349,7 @@ static char ** do_lxcapi_get_interfaces(struct lxc_container *c)
if (wait_for_pid(pid) != 0) { if (wait_for_pid(pid) != 0) {
for(i=0;i<count;i++) for(i=0;i<count;i++)
free(interfaces[i]); free(interfaces[i]);
free(interfaces); free(interfaces);
interfaces = NULL; interfaces = NULL;
} }
...@@ -2422,8 +2450,10 @@ static char **do_lxcapi_get_ips(struct lxc_container *c, const char *interface, ...@@ -2422,8 +2450,10 @@ static char **do_lxcapi_get_ips(struct lxc_container *c, const char *interface,
address); address);
goto out; goto out;
} }
count++; count++;
} }
ret = 0; ret = 0;
out: out:
...@@ -2497,8 +2527,10 @@ static char* do_lxcapi_get_running_config_item(struct lxc_container *c, const ch ...@@ -2497,8 +2527,10 @@ static char* do_lxcapi_get_running_config_item(struct lxc_container *c, const ch
if (!c || !c->lxc_conf) if (!c || !c->lxc_conf)
return NULL; return NULL;
if (container_mem_lock(c)) if (container_mem_lock(c))
return NULL; return NULL;
ret = lxc_cmd_get_config_item(c->name, key, do_lxcapi_get_config_path(c)); ret = lxc_cmd_get_config_item(c->name, key, do_lxcapi_get_config_path(c));
container_mem_unlock(c); container_mem_unlock(c);
return ret; return ret;
...@@ -2542,6 +2574,7 @@ static bool do_lxcapi_save_config(struct lxc_container *c, const char *alt_file) ...@@ -2542,6 +2574,7 @@ static bool do_lxcapi_save_config(struct lxc_container *c, const char *alt_file)
if (!alt_file) if (!alt_file)
alt_file = c->configfile; alt_file = c->configfile;
if (!alt_file) if (!alt_file)
return false; return false;
...@@ -2615,6 +2648,7 @@ static bool mod_rdep(struct lxc_container *c0, struct lxc_container *c, bool inc ...@@ -2615,6 +2648,7 @@ static bool mod_rdep(struct lxc_container *c0, struct lxc_container *c, bool inc
ret = snprintf(path, MAXPATHLEN, "%s/%s/lxc_snapshots", c0->config_path, c0->name); ret = snprintf(path, MAXPATHLEN, "%s/%s/lxc_snapshots", c0->config_path, c0->name);
if (ret < 0 || ret > MAXPATHLEN) if (ret < 0 || ret > MAXPATHLEN)
goto out; goto out;
ret = snprintf(newpath, MAXPATHLEN, "%s\n%s\n", c->config_path, c->name); ret = snprintf(newpath, MAXPATHLEN, "%s\n%s\n", c->config_path, c->name);
if (ret < 0 || ret > MAXPATHLEN) if (ret < 0 || ret > MAXPATHLEN)
goto out; goto out;
...@@ -2702,6 +2736,7 @@ static bool mod_rdep(struct lxc_container *c0, struct lxc_container *c, bool inc ...@@ -2702,6 +2736,7 @@ static bool mod_rdep(struct lxc_container *c0, struct lxc_container *c, bool inc
goto out; goto out;
} }
} }
close(fd); close(fd);
} }
...@@ -2737,9 +2772,11 @@ void mod_all_rdeps(struct lxc_container *c, bool inc) ...@@ -2737,9 +2772,11 @@ void mod_all_rdeps(struct lxc_container *c, bool inc)
ERROR("Path name too long"); ERROR("Path name too long");
return; return;
} }
f = fopen(path, "r"); f = fopen(path, "r");
if (f == NULL) if (f == NULL)
return; return;
while (getline(&lxcpath, &pathlen, f) != -1) { while (getline(&lxcpath, &pathlen, f) != -1) {
if (getline(&lxcname, &namelen, f) == -1) { if (getline(&lxcname, &namelen, f) == -1) {
ERROR("badly formatted file %s", path); ERROR("badly formatted file %s", path);
...@@ -2754,11 +2791,14 @@ void mod_all_rdeps(struct lxc_container *c, bool inc) ...@@ -2754,11 +2791,14 @@ void mod_all_rdeps(struct lxc_container *c, bool inc)
lxcpath, lxcname); lxcpath, lxcname);
continue; continue;
} }
if (!mod_rdep(p, c, inc)) if (!mod_rdep(p, c, inc))
ERROR("Failed to update snapshots file for %s:%s", ERROR("Failed to update snapshots file for %s:%s",
lxcpath, lxcname); lxcpath, lxcname);
lxc_container_put(p); lxc_container_put(p);
} }
out: out:
free(lxcpath); free(lxcpath);
free(lxcname); free(lxcname);
...@@ -2777,20 +2817,24 @@ static bool has_fs_snapshots(struct lxc_container *c) ...@@ -2777,20 +2817,24 @@ static bool has_fs_snapshots(struct lxc_container *c)
c->name); c->name);
if (ret < 0 || ret > MAXPATHLEN) if (ret < 0 || ret > MAXPATHLEN)
goto out; goto out;
/* If the file doesn't exist there are no snapshots. */ /* If the file doesn't exist there are no snapshots. */
if (stat(path, &fbuf) < 0) if (stat(path, &fbuf) < 0)
goto out; goto out;
v = fbuf.st_size; v = fbuf.st_size;
if (v != 0) { if (v != 0) {
f = fopen(path, "r"); f = fopen(path, "r");
if (!f) if (!f)
goto out; goto out;
ret = fscanf(f, "%d", &v); ret = fscanf(f, "%d", &v);
fclose(f); fclose(f);
/* TODO: Figure out what to do with the return value of fscanf. */ /* TODO: Figure out what to do with the return value of fscanf. */
if (ret != 1) if (ret != 1)
INFO("Container uses new lxc-snapshots format %s", path); INFO("Container uses new lxc-snapshots format %s", path);
} }
bret = v != 0; bret = v != 0;
out: out:
...@@ -2806,9 +2850,11 @@ static bool has_snapshots(struct lxc_container *c) ...@@ -2806,9 +2850,11 @@ static bool has_snapshots(struct lxc_container *c)
if (!get_snappath_dir(c, path)) if (!get_snappath_dir(c, path))
return false; return false;
dir = opendir(path); dir = opendir(path);
if (!dir) if (!dir)
return false; return false;
while ((direntp = readdir(dir))) { while ((direntp = readdir(dir))) {
if (!strcmp(direntp->d_name, ".")) if (!strcmp(direntp->d_name, "."))
continue; continue;
...@@ -2818,6 +2864,7 @@ static bool has_snapshots(struct lxc_container *c) ...@@ -2818,6 +2864,7 @@ static bool has_snapshots(struct lxc_container *c)
count++; count++;
break; break;
} }
closedir(dir); closedir(dir);
return count > 0; return count > 0;
} }
...@@ -2901,6 +2948,7 @@ static bool container_destroy(struct lxc_container *c, ...@@ -2901,6 +2948,7 @@ static bool container_destroy(struct lxc_container *c,
if (current_config && conf == current_config) { if (current_config && conf == current_config) {
current_config = NULL; current_config = NULL;
if (conf->logfd != -1) { if (conf->logfd != -1) {
close(conf->logfd); close(conf->logfd);
conf->logfd = -1; conf->logfd = -1;
...@@ -2966,6 +3014,7 @@ static bool container_destroy(struct lxc_container *c, ...@@ -2966,6 +3014,7 @@ static bool container_destroy(struct lxc_container *c,
ret = snprintf(path, len, "%s/%s", p1, c->name); ret = snprintf(path, len, "%s/%s", p1, c->name);
if (ret < 0 || (size_t)ret >= len) if (ret < 0 || (size_t)ret >= len)
goto out; goto out;
if (am_guest_unpriv()) if (am_guest_unpriv())
ret = userns_exec_full(conf, lxc_rmdir_onedev_wrapper, path, ret = userns_exec_full(conf, lxc_rmdir_onedev_wrapper, path,
"lxc_rmdir_onedev_wrapper"); "lxc_rmdir_onedev_wrapper");
...@@ -2983,6 +3032,7 @@ static bool container_destroy(struct lxc_container *c, ...@@ -2983,6 +3032,7 @@ static bool container_destroy(struct lxc_container *c,
out: out:
if (path) if (path)
free(path); free(path);
container_disk_unlock(c); container_disk_unlock(c);
return bret; return bret;
} }
...@@ -3011,10 +3061,12 @@ static bool do_lxcapi_destroy_with_snapshots(struct lxc_container *c) ...@@ -3011,10 +3061,12 @@ static bool do_lxcapi_destroy_with_snapshots(struct lxc_container *c)
{ {
if (!c || !lxcapi_is_defined(c)) if (!c || !lxcapi_is_defined(c))
return false; return false;
if (!lxcapi_snapshot_destroy_all(c)) { if (!lxcapi_snapshot_destroy_all(c)) {
ERROR("Error deleting all snapshots"); ERROR("Error deleting all snapshots");
return false; return false;
} }
return lxcapi_destroy(c); return lxcapi_destroy(c);
} }
...@@ -3085,6 +3137,7 @@ static char *lxcapi_config_file_name(struct lxc_container *c) ...@@ -3085,6 +3137,7 @@ static char *lxcapi_config_file_name(struct lxc_container *c)
{ {
if (!c || !c->configfile) if (!c || !c->configfile)
return NULL; return NULL;
return strdup(c->configfile); return strdup(c->configfile);
} }
...@@ -3092,6 +3145,7 @@ static const char *lxcapi_get_config_path(struct lxc_container *c) ...@@ -3092,6 +3145,7 @@ static const char *lxcapi_get_config_path(struct lxc_container *c)
{ {
if (!c || !c->config_path) if (!c || !c->config_path)
return NULL; return NULL;
return (const char *)(c->config_path); return (const char *)(c->config_path);
} }
...@@ -3160,6 +3214,7 @@ static bool do_lxcapi_set_config_path(struct lxc_container *c, const char *path) ...@@ -3160,6 +3214,7 @@ static bool do_lxcapi_set_config_path(struct lxc_container *c, const char *path)
c->config_path = oldpath; c->config_path = oldpath;
oldpath = NULL; oldpath = NULL;
} }
err: err:
free(oldpath); free(oldpath);
container_mem_unlock(c); container_mem_unlock(c);
...@@ -3248,6 +3303,7 @@ static int copy_file(const char *old, const char *new) ...@@ -3248,6 +3303,7 @@ static int copy_file(const char *old, const char *new)
ERROR("copy destination %s exists", new); ERROR("copy destination %s exists", new);
return -1; return -1;
} }
ret = stat(old, &sbuf); ret = stat(old, &sbuf);
if (ret < 0) { if (ret < 0) {
INFO("Error stat'ing %s", old); INFO("Error stat'ing %s", old);
...@@ -3259,6 +3315,7 @@ static int copy_file(const char *old, const char *new) ...@@ -3259,6 +3315,7 @@ static int copy_file(const char *old, const char *new)
SYSERROR("Error opening original file %s", old); SYSERROR("Error opening original file %s", old);
return -1; return -1;
} }
out = open(new, O_CREAT | O_EXCL | O_WRONLY, 0644); out = open(new, O_CREAT | O_EXCL | O_WRONLY, 0644);
if (out < 0) { if (out < 0) {
SYSERROR("Error opening new file %s", new); SYSERROR("Error opening new file %s", new);
...@@ -3272,14 +3329,17 @@ static int copy_file(const char *old, const char *new) ...@@ -3272,14 +3329,17 @@ static int copy_file(const char *old, const char *new)
SYSERROR("Error reading old file %s", old); SYSERROR("Error reading old file %s", old);
goto err; goto err;
} }
if (len == 0) if (len == 0)
break; break;
ret = write(out, buf, len); ret = write(out, buf, len);
if (ret < len) { /* should we retry? */ if (ret < len) { /* should we retry? */
SYSERROR("Error: write to new file %s was interrupted", new); SYSERROR("Error: write to new file %s was interrupted", new);
goto err; goto err;
} }
} }
close(in); close(in);
close(out); close(out);
...@@ -3317,19 +3377,24 @@ static int copyhooks(struct lxc_container *oldc, struct lxc_container *c) ...@@ -3317,19 +3377,24 @@ static int copyhooks(struct lxc_container *oldc, struct lxc_container *c)
char tmppath[MAXPATHLEN]; char tmppath[MAXPATHLEN];
if (!fname) /* relative path - we don't support, but maybe we should */ if (!fname) /* relative path - we don't support, but maybe we should */
return 0; return 0;
if (strncmp(hookname, cpath, len - 1) != 0) { if (strncmp(hookname, cpath, len - 1) != 0) {
/* this hook is public - ignore */ /* this hook is public - ignore */
continue; continue;
} }
/* copy the script, and change the entry in confile */ /* copy the script, and change the entry in confile */
ret = snprintf(tmppath, MAXPATHLEN, "%s/%s/%s", ret = snprintf(tmppath, MAXPATHLEN, "%s/%s/%s",
c->config_path, c->name, fname+1); c->config_path, c->name, fname+1);
if (ret < 0 || ret >= MAXPATHLEN) if (ret < 0 || ret >= MAXPATHLEN)
return -1; return -1;
ret = copy_file(it->elem, tmppath); ret = copy_file(it->elem, tmppath);
if (ret < 0) if (ret < 0)
return -1; return -1;
free(it->elem); free(it->elem);
it->elem = strdup(tmppath); it->elem = strdup(tmppath);
if (!it->elem) { if (!it->elem) {
ERROR("out of memory copying hook path"); ERROR("out of memory copying hook path");
...@@ -3343,6 +3408,7 @@ static int copyhooks(struct lxc_container *oldc, struct lxc_container *c) ...@@ -3343,6 +3408,7 @@ static int copyhooks(struct lxc_container *oldc, struct lxc_container *c)
ERROR("Error saving new hooks in clone"); ERROR("Error saving new hooks in clone");
return -1; return -1;
} }
do_lxcapi_save_config(c, NULL); do_lxcapi_save_config(c, NULL);
return 0; return 0;
} }
...@@ -3362,12 +3428,14 @@ static int copy_fstab(struct lxc_container *oldc, struct lxc_container *c) ...@@ -3362,12 +3428,14 @@ static int copy_fstab(struct lxc_container *oldc, struct lxc_container *c)
char *p = strrchr(oldpath, '/'); char *p = strrchr(oldpath, '/');
if (!p) if (!p)
return -1; return -1;
ret = snprintf(newpath, MAXPATHLEN, "%s/%s%s", ret = snprintf(newpath, MAXPATHLEN, "%s/%s%s",
c->config_path, c->name, p); c->config_path, c->name, p);
if (ret < 0 || ret >= MAXPATHLEN) { if (ret < 0 || ret >= MAXPATHLEN) {
ERROR("error printing new path for %s", oldpath); ERROR("error printing new path for %s", oldpath);
return -1; return -1;
} }
if (file_exists(newpath)) { if (file_exists(newpath)) {
ERROR("error: fstab file %s exists", newpath); ERROR("error: fstab file %s exists", newpath);
return -1; return -1;
...@@ -3377,12 +3445,15 @@ static int copy_fstab(struct lxc_container *oldc, struct lxc_container *c) ...@@ -3377,12 +3445,15 @@ static int copy_fstab(struct lxc_container *oldc, struct lxc_container *c)
ERROR("error: copying %s to %s", oldpath, newpath); ERROR("error: copying %s to %s", oldpath, newpath);
return -1; return -1;
} }
free(c->lxc_conf->fstab); free(c->lxc_conf->fstab);
c->lxc_conf->fstab = strdup(newpath); c->lxc_conf->fstab = strdup(newpath);
if (!c->lxc_conf->fstab) { if (!c->lxc_conf->fstab) {
ERROR("error: allocating pathname"); ERROR("error: allocating pathname");
return -1; return -1;
} }
if (!do_append_unexp_config_line(c->lxc_conf, "lxc.mount.fstab", newpath)) { if (!do_append_unexp_config_line(c->lxc_conf, "lxc.mount.fstab", newpath)) {
ERROR("error saving new lxctab"); ERROR("error saving new lxctab");
return -1; return -1;
...@@ -3402,12 +3473,14 @@ static void copy_rdepends(struct lxc_container *c, struct lxc_container *c0) ...@@ -3402,12 +3473,14 @@ static void copy_rdepends(struct lxc_container *c, struct lxc_container *c0)
WARN("Error copying reverse dependencies"); WARN("Error copying reverse dependencies");
return; return;
} }
ret = snprintf(path1, MAXPATHLEN, "%s/%s/lxc_rdepends", c->config_path, ret = snprintf(path1, MAXPATHLEN, "%s/%s/lxc_rdepends", c->config_path,
c->name); c->name);
if (ret < 0 || ret >= MAXPATHLEN) { if (ret < 0 || ret >= MAXPATHLEN) {
WARN("Error copying reverse dependencies"); WARN("Error copying reverse dependencies");
return; return;
} }
if (copy_file(path0, path1) < 0) { if (copy_file(path0, path1) < 0) {
INFO("Error copying reverse dependencies"); INFO("Error copying reverse dependencies");
return; return;
...@@ -3425,15 +3498,20 @@ static bool add_rdepends(struct lxc_container *c, struct lxc_container *c0) ...@@ -3425,15 +3498,20 @@ static bool add_rdepends(struct lxc_container *c, struct lxc_container *c0)
c->name); c->name);
if (ret < 0 || ret >= MAXPATHLEN) if (ret < 0 || ret >= MAXPATHLEN)
return false; return false;
f = fopen(path, "a"); f = fopen(path, "a");
if (!f) if (!f)
return false; return false;
bret = true; bret = true;
/* If anything goes wrong, just return an error. */ /* If anything goes wrong, just return an error. */
if (fprintf(f, "%s\n%s\n", c0->config_path, c0->name) < 0) if (fprintf(f, "%s\n%s\n", c0->config_path, c0->name) < 0)
bret = false; bret = false;
if (fclose(f) != 0) if (fclose(f) != 0)
bret = false; bret = false;
return bret; return bret;
} }
...@@ -3506,6 +3584,7 @@ static int copy_storage(struct lxc_container *c0, struct lxc_container *c, ...@@ -3506,6 +3584,7 @@ static int copy_storage(struct lxc_container *c0, struct lxc_container *c,
if (flags & LXC_CLONE_SNAPSHOT) if (flags & LXC_CLONE_SNAPSHOT)
copy_rdepends(c, c0); copy_rdepends(c, c0);
if (need_rdep) { if (need_rdep) {
if (!add_rdepends(c, c0)) if (!add_rdepends(c, c0))
WARN("Error adding reverse dependency from %s to %s", WARN("Error adding reverse dependency from %s to %s",
...@@ -3543,30 +3622,36 @@ static int clone_update_rootfs(struct clone_update_data *data) ...@@ -3543,30 +3622,36 @@ static int clone_update_rootfs(struct clone_update_data *data)
ERROR("Failed to setgid to 0"); ERROR("Failed to setgid to 0");
return -1; return -1;
} }
if (setuid(0) < 0) { if (setuid(0) < 0) {
ERROR("Failed to setuid to 0"); ERROR("Failed to setuid to 0");
return -1; return -1;
} }
if (setgroups(0, NULL) < 0) if (setgroups(0, NULL) < 0)
WARN("Failed to clear groups"); WARN("Failed to clear groups");
if (unshare(CLONE_NEWNS) < 0) if (unshare(CLONE_NEWNS) < 0)
return -1; return -1;
bdev = storage_init(c->lxc_conf); bdev = storage_init(c->lxc_conf);
if (!bdev) if (!bdev)
return -1; return -1;
if (strcmp(bdev->type, "dir") != 0) { if (strcmp(bdev->type, "dir") != 0) {
if (unshare(CLONE_NEWNS) < 0) { if (unshare(CLONE_NEWNS) < 0) {
ERROR("error unsharing mounts"); ERROR("error unsharing mounts");
storage_put(bdev); storage_put(bdev);
return -1; return -1;
} }
if (detect_shared_rootfs()) { if (detect_shared_rootfs()) {
if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL)) { if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL)) {
SYSERROR("Failed to make / rslave"); SYSERROR("Failed to make / rslave");
ERROR("Continuing..."); ERROR("Continuing...");
} }
} }
if (bdev->ops->mount(bdev) < 0) { if (bdev->ops->mount(bdev) < 0) {
storage_put(bdev); storage_put(bdev);
return -1; return -1;
...@@ -3578,21 +3663,20 @@ static int clone_update_rootfs(struct clone_update_data *data) ...@@ -3578,21 +3663,20 @@ static int clone_update_rootfs(struct clone_update_data *data)
if (!lxc_list_empty(&conf->hooks[LXCHOOK_CLONE])) { if (!lxc_list_empty(&conf->hooks[LXCHOOK_CLONE])) {
/* Start of environment variable setup for hooks */ /* Start of environment variable setup for hooks */
if (c0->name && setenv("LXC_SRC_NAME", c0->name, 1)) { if (c0->name && setenv("LXC_SRC_NAME", c0->name, 1))
SYSERROR("failed to set environment variable for source container name"); SYSERROR("failed to set environment variable for source container name");
}
if (setenv("LXC_NAME", c->name, 1)) { if (setenv("LXC_NAME", c->name, 1))
SYSERROR("failed to set environment variable for container name"); SYSERROR("failed to set environment variable for container name");
}
if (conf->rcfile && setenv("LXC_CONFIG_FILE", conf->rcfile, 1)) { if (conf->rcfile && setenv("LXC_CONFIG_FILE", conf->rcfile, 1))
SYSERROR("failed to set environment variable for config path"); SYSERROR("failed to set environment variable for config path");
}
if (bdev->dest && setenv("LXC_ROOTFS_MOUNT", bdev->dest, 1)) { if (bdev->dest && setenv("LXC_ROOTFS_MOUNT", bdev->dest, 1))
SYSERROR("failed to set environment variable for rootfs mount"); SYSERROR("failed to set environment variable for rootfs mount");
}
if (conf->rootfs.path && setenv("LXC_ROOTFS_PATH", conf->rootfs.path, 1)) { if (conf->rootfs.path && setenv("LXC_ROOTFS_PATH", conf->rootfs.path, 1))
SYSERROR("failed to set environment variable for rootfs mount"); SYSERROR("failed to set environment variable for rootfs mount");
}
if (run_lxc_hooks(c->name, "clone", conf, hookargs)) { if (run_lxc_hooks(c->name, "clone", conf, hookargs)) {
ERROR("Error executing clone hook for %s", c->name); ERROR("Error executing clone hook for %s", c->name);
...@@ -3607,16 +3691,20 @@ static int clone_update_rootfs(struct clone_update_data *data) ...@@ -3607,16 +3691,20 @@ static int clone_update_rootfs(struct clone_update_data *data)
if (ret < 0 || ret >= MAXPATHLEN) if (ret < 0 || ret >= MAXPATHLEN)
return -1; return -1;
if (!file_exists(path)) if (!file_exists(path))
return 0; return 0;
if (!(fout = fopen(path, "w"))) { if (!(fout = fopen(path, "w"))) {
SYSERROR("unable to open %s: ignoring", path); SYSERROR("unable to open %s: ignoring", path);
return 0; return 0;
} }
if (fprintf(fout, "%s", c->name) < 0) { if (fprintf(fout, "%s", c->name) < 0) {
fclose(fout); fclose(fout);
return -1; return -1;
} }
if (fclose(fout) < 0) if (fclose(fout) < 0)
return -1; return -1;
} else { } else {
...@@ -3650,9 +3738,11 @@ static int create_file_dirname(char *path, struct lxc_conf *conf) ...@@ -3650,9 +3738,11 @@ static int create_file_dirname(char *path, struct lxc_conf *conf)
if (!p) if (!p)
return -1; return -1;
*p = '\0'; *p = '\0';
ret = do_create_container_dir(path, conf); ret = do_create_container_dir(path, conf);
*p = '/'; *p = '/';
return ret; return ret;
} }
...@@ -3684,8 +3774,10 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char ...@@ -3684,8 +3774,10 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char
/* Make sure the container doesn't yet exist. */ /* Make sure the container doesn't yet exist. */
if (!newname) if (!newname)
newname = c->name; newname = c->name;
if (!lxcpath) if (!lxcpath)
lxcpath = do_lxcapi_get_config_path(c); lxcpath = do_lxcapi_get_config_path(c);
ret = snprintf(newpath, MAXPATHLEN, "%s/%s/config", lxcpath, newname); ret = snprintf(newpath, MAXPATHLEN, "%s/%s/config", lxcpath, newname);
if (ret < 0 || ret >= MAXPATHLEN) { if (ret < 0 || ret >= MAXPATHLEN) {
SYSERROR("clone: failed making config pathname"); SYSERROR("clone: failed making config pathname");
...@@ -3727,7 +3819,9 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char ...@@ -3727,7 +3819,9 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char
clear_unexp_config_line(c->lxc_conf, "lxc.rootfs.path", false); clear_unexp_config_line(c->lxc_conf, "lxc.rootfs.path", false);
write_config(fd, c->lxc_conf); write_config(fd, c->lxc_conf);
close(fd); close(fd);
c->lxc_conf->rootfs.path = origroot; c->lxc_conf->rootfs.path = origroot;
free(c->lxc_conf->unexpanded_config); free(c->lxc_conf->unexpanded_config);
c->lxc_conf->unexpanded_config = saved_unexp_conf; c->lxc_conf->unexpanded_config = saved_unexp_conf;
saved_unexp_conf = NULL; saved_unexp_conf = NULL;
...@@ -3771,7 +3865,6 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char ...@@ -3771,7 +3865,6 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char
if (ret < 0) if (ret < 0)
goto out; goto out;
/* update utsname */ /* update utsname */
if (!(flags & LXC_CLONE_KEEPNAME)) { if (!(flags & LXC_CLONE_KEEPNAME)) {
clear_unexp_config_line(c2->lxc_conf, "lxc.utsname", false); clear_unexp_config_line(c2->lxc_conf, "lxc.utsname", false);
...@@ -3819,17 +3912,21 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char ...@@ -3819,17 +3912,21 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char
SYSERROR("fork"); SYSERROR("fork");
goto out; goto out;
} }
if (pid > 0) { if (pid > 0) {
ret = wait_for_pid(pid); ret = wait_for_pid(pid);
if (ret) if (ret)
goto out; goto out;
container_mem_unlock(c); container_mem_unlock(c);
return c2; return c2;
} }
data.c0 = c; data.c0 = c;
data.c1 = c2; data.c1 = c2;
data.flags = flags; data.flags = flags;
data.hookargs = hookargs; data.hookargs = hookargs;
if (am_guest_unpriv()) if (am_guest_unpriv())
ret = userns_exec_full(c->lxc_conf, clone_update_rootfs_wrapper, ret = userns_exec_full(c->lxc_conf, clone_update_rootfs_wrapper,
&data, "clone_update_rootfs_wrapper"); &data, "clone_update_rootfs_wrapper");
...@@ -3846,6 +3943,7 @@ out: ...@@ -3846,6 +3943,7 @@ out:
if (c2) { if (c2) {
if (!storage_copied) if (!storage_copied)
c2->lxc_conf->rootfs.path = NULL; c2->lxc_conf->rootfs.path = NULL;
c2->destroy(c2); c2->destroy(c2);
lxc_container_put(c2); lxc_container_put(c2);
} }
...@@ -3859,9 +3957,11 @@ static struct lxc_container *lxcapi_clone(struct lxc_container *c, const char *n ...@@ -3859,9 +3957,11 @@ static struct lxc_container *lxcapi_clone(struct lxc_container *c, const char *n
char **hookargs) char **hookargs)
{ {
struct lxc_container * ret; struct lxc_container * ret;
current_config = c ? c->lxc_conf : NULL; current_config = c ? c->lxc_conf : NULL;
ret = do_lxcapi_clone(c, newname, lxcpath, flags, bdevtype, bdevdata, newsize, hookargs); ret = do_lxcapi_clone(c, newname, lxcpath, flags, bdevtype, bdevdata, newsize, hookargs);
current_config = NULL; current_config = NULL;
return ret; return ret;
} }
...@@ -3877,6 +3977,7 @@ static bool do_lxcapi_rename(struct lxc_container *c, const char *newname) ...@@ -3877,6 +3977,7 @@ static bool do_lxcapi_rename(struct lxc_container *c, const char *newname)
ERROR("Renaming a container with snapshots is not supported"); ERROR("Renaming a container with snapshots is not supported");
return false; return false;
} }
bdev = storage_init(c->lxc_conf); bdev = storage_init(c->lxc_conf);
if (!bdev) { if (!bdev) {
ERROR("Failed to find original backing store type"); ERROR("Failed to find original backing store type");
...@@ -3897,6 +3998,7 @@ static bool do_lxcapi_rename(struct lxc_container *c, const char *newname) ...@@ -3897,6 +3998,7 @@ static bool do_lxcapi_rename(struct lxc_container *c, const char *newname)
ERROR("Could not destroy existing container %s", c->name); ERROR("Could not destroy existing container %s", c->name);
return false; return false;
} }
return true; return true;
} }
...@@ -3927,20 +4029,24 @@ static int do_lxcapi_attach_run_wait(struct lxc_container *c, lxc_attach_options ...@@ -3927,20 +4029,24 @@ static int do_lxcapi_attach_run_wait(struct lxc_container *c, lxc_attach_options
command.program = (char*)program; command.program = (char*)program;
command.argv = (char**)argv; command.argv = (char**)argv;
r = lxc_attach(c->name, c->config_path, lxc_attach_run_command, &command, options, &pid); r = lxc_attach(c->name, c->config_path, lxc_attach_run_command, &command, options, &pid);
if (r < 0) { if (r < 0) {
ERROR("ups"); ERROR("ups");
return r; return r;
} }
return lxc_wait_for_pid_status(pid); return lxc_wait_for_pid_status(pid);
} }
static int lxcapi_attach_run_wait(struct lxc_container *c, lxc_attach_options_t *options, const char *program, const char * const argv[]) static int lxcapi_attach_run_wait(struct lxc_container *c, lxc_attach_options_t *options, const char *program, const char * const argv[])
{ {
int ret; int ret;
current_config = c ? c->lxc_conf : NULL; current_config = c ? c->lxc_conf : NULL;
ret = do_lxcapi_attach_run_wait(c, options, program, argv); ret = do_lxcapi_attach_run_wait(c, options, program, argv);
current_config = NULL; current_config = NULL;
return ret; return ret;
} }
...@@ -3951,11 +4057,14 @@ static int get_next_index(const char *lxcpath, char *cname) ...@@ -3951,11 +4057,14 @@ static int get_next_index(const char *lxcpath, char *cname)
int i = 0, ret; int i = 0, ret;
fname = alloca(strlen(lxcpath) + 20); fname = alloca(strlen(lxcpath) + 20);
while (1) { while (1) {
sprintf(fname, "%s/snap%d", lxcpath, i); sprintf(fname, "%s/snap%d", lxcpath, i);
ret = stat(fname, &sb); ret = stat(fname, &sb);
if (ret != 0) if (ret != 0)
return i; return i;
i++; i++;
} }
} }
...@@ -3963,6 +4072,7 @@ static int get_next_index(const char *lxcpath, char *cname) ...@@ -3963,6 +4072,7 @@ static int get_next_index(const char *lxcpath, char *cname)
static bool get_snappath_dir(struct lxc_container *c, char *snappath) static bool get_snappath_dir(struct lxc_container *c, char *snappath)
{ {
int ret; int ret;
/* /*
* If the old style snapshot path exists, use it * If the old style snapshot path exists, use it
* /var/lib/lxc -> /var/lib/lxcsnaps * /var/lib/lxc -> /var/lib/lxcsnaps
...@@ -3970,10 +4080,12 @@ static bool get_snappath_dir(struct lxc_container *c, char *snappath) ...@@ -3970,10 +4080,12 @@ static bool get_snappath_dir(struct lxc_container *c, char *snappath)
ret = snprintf(snappath, MAXPATHLEN, "%ssnaps", c->config_path); ret = snprintf(snappath, MAXPATHLEN, "%ssnaps", c->config_path);
if (ret < 0 || ret >= MAXPATHLEN) if (ret < 0 || ret >= MAXPATHLEN)
return false; return false;
if (dir_exists(snappath)) { if (dir_exists(snappath)) {
ret = snprintf(snappath, MAXPATHLEN, "%ssnaps/%s", c->config_path, c->name); ret = snprintf(snappath, MAXPATHLEN, "%ssnaps/%s", c->config_path, c->name);
if (ret < 0 || ret >= MAXPATHLEN) if (ret < 0 || ret >= MAXPATHLEN)
return false; return false;
return true; return true;
} }
...@@ -3984,6 +4096,7 @@ static bool get_snappath_dir(struct lxc_container *c, char *snappath) ...@@ -3984,6 +4096,7 @@ static bool get_snappath_dir(struct lxc_container *c, char *snappath)
ret = snprintf(snappath, MAXPATHLEN, "%s/%s/snaps", c->config_path, c->name); ret = snprintf(snappath, MAXPATHLEN, "%s/%s/snaps", c->config_path, c->name);
if (ret < 0 || ret >= MAXPATHLEN) if (ret < 0 || ret >= MAXPATHLEN)
return false; return false;
return true; return true;
} }
...@@ -4029,6 +4142,7 @@ static int do_lxcapi_snapshot(struct lxc_container *c, const char *commentfile) ...@@ -4029,6 +4142,7 @@ static int do_lxcapi_snapshot(struct lxc_container *c, const char *commentfile)
ERROR("and keep the original container pristine."); ERROR("and keep the original container pristine.");
flags &= ~LXC_CLONE_SNAPSHOT | LXC_CLONE_MAYBE_SNAPSHOT; flags &= ~LXC_CLONE_SNAPSHOT | LXC_CLONE_MAYBE_SNAPSHOT;
} }
c2 = do_lxcapi_clone(c, newname, snappath, flags, NULL, NULL, 0, NULL); c2 = do_lxcapi_clone(c, newname, snappath, flags, NULL, NULL, 0, NULL);
if (!c2) { if (!c2) {
ERROR("clone of %s:%s failed", c->config_path, c->name); ERROR("clone of %s:%s failed", c->config_path, c->name);
...@@ -4055,11 +4169,13 @@ static int do_lxcapi_snapshot(struct lxc_container *c, const char *commentfile) ...@@ -4055,11 +4169,13 @@ static int do_lxcapi_snapshot(struct lxc_container *c, const char *commentfile)
ERROR("Failed to open %s", dfnam); ERROR("Failed to open %s", dfnam);
return -1; return -1;
} }
if (fprintf(f, "%s", buffer) < 0) { if (fprintf(f, "%s", buffer) < 0) {
SYSERROR("Writing timestamp"); SYSERROR("Writing timestamp");
fclose(f); fclose(f);
return -1; return -1;
} }
ret = fclose(f); ret = fclose(f);
if (ret != 0) { if (ret != 0) {
SYSERROR("Writing timestamp"); SYSERROR("Writing timestamp");
...@@ -4070,6 +4186,7 @@ static int do_lxcapi_snapshot(struct lxc_container *c, const char *commentfile) ...@@ -4070,6 +4186,7 @@ static int do_lxcapi_snapshot(struct lxc_container *c, const char *commentfile)
/* $p / $name / comment \0 */ /* $p / $name / comment \0 */
int len = strlen(snappath) + strlen(newname) + 10; int len = strlen(snappath) + strlen(newname) + 10;
char *path = alloca(len); char *path = alloca(len);
sprintf(path, "%s/%s/comment", snappath, newname); sprintf(path, "%s/%s/comment", snappath, newname);
return copy_file(commentfile, path) < 0 ? -1 : i; return copy_file(commentfile, path) < 0 ? -1 : i;
} }
...@@ -4100,6 +4217,7 @@ static char *get_snapcomment_path(char* snappath, char *name) ...@@ -4100,6 +4217,7 @@ static char *get_snapcomment_path(char* snappath, char *name)
s = NULL; s = NULL;
} }
} }
return s; return s;
} }
...@@ -4112,9 +4230,11 @@ static char *get_timestamp(char* snappath, char *name) ...@@ -4112,9 +4230,11 @@ static char *get_timestamp(char* snappath, char *name)
ret = snprintf(path, MAXPATHLEN, "%s/%s/ts", snappath, name); ret = snprintf(path, MAXPATHLEN, "%s/%s/ts", snappath, name);
if (ret < 0 || ret >= MAXPATHLEN) if (ret < 0 || ret >= MAXPATHLEN)
return NULL; return NULL;
fin = fopen(path, "r"); fin = fopen(path, "r");
if (!fin) if (!fin)
return NULL; return NULL;
(void) fseek(fin, 0, SEEK_END); (void) fseek(fin, 0, SEEK_END);
len = ftell(fin); len = ftell(fin);
(void) fseek(fin, 0, SEEK_SET); (void) fseek(fin, 0, SEEK_SET);
...@@ -4129,6 +4249,7 @@ static char *get_timestamp(char* snappath, char *name) ...@@ -4129,6 +4249,7 @@ static char *get_timestamp(char* snappath, char *name)
} }
} }
} }
fclose(fin); fclose(fin);
return s; return s;
} }
...@@ -4148,9 +4269,10 @@ static int do_lxcapi_snapshot_list(struct lxc_container *c, struct lxc_snapshot ...@@ -4148,9 +4269,10 @@ static int do_lxcapi_snapshot_list(struct lxc_container *c, struct lxc_snapshot
ERROR("path name too long"); ERROR("path name too long");
return -1; return -1;
} }
dir = opendir(snappath); dir = opendir(snappath);
if (!dir) { if (!dir) {
INFO("failed to open %s - assuming no snapshots", snappath); INFO("Failed to open %s - assuming no snapshots", snappath);
return 0; return 0;
} }
...@@ -4166,30 +4288,35 @@ static int do_lxcapi_snapshot_list(struct lxc_container *c, struct lxc_snapshot ...@@ -4166,30 +4288,35 @@ static int do_lxcapi_snapshot_list(struct lxc_container *c, struct lxc_snapshot
ERROR("pathname too long"); ERROR("pathname too long");
goto out_free; goto out_free;
} }
if (!file_exists(path2)) if (!file_exists(path2))
continue; continue;
nsnaps = realloc(snaps, (count + 1)*sizeof(*snaps)); nsnaps = realloc(snaps, (count + 1)*sizeof(*snaps));
if (!nsnaps) { if (!nsnaps) {
SYSERROR("Out of memory"); SYSERROR("Out of memory");
goto out_free; goto out_free;
} }
snaps = nsnaps; snaps = nsnaps;
snaps[count].free = lxcsnap_free; snaps[count].free = lxcsnap_free;
snaps[count].name = strdup(direntp->d_name); snaps[count].name = strdup(direntp->d_name);
if (!snaps[count].name) if (!snaps[count].name)
goto out_free; goto out_free;
snaps[count].lxcpath = strdup(snappath); snaps[count].lxcpath = strdup(snappath);
if (!snaps[count].lxcpath) { if (!snaps[count].lxcpath) {
free(snaps[count].name); free(snaps[count].name);
goto out_free; goto out_free;
} }
snaps[count].comment_pathname = get_snapcomment_path(snappath, direntp->d_name); snaps[count].comment_pathname = get_snapcomment_path(snappath, direntp->d_name);
snaps[count].timestamp = get_timestamp(snappath, direntp->d_name); snaps[count].timestamp = get_timestamp(snappath, direntp->d_name);
count++; count++;
} }
if (closedir(dir)) if (closedir(dir))
WARN("failed to close directory"); WARN("Failed to close directory");
*ret_snaps = snaps; *ret_snaps = snaps;
return count; return count;
...@@ -4197,12 +4324,16 @@ static int do_lxcapi_snapshot_list(struct lxc_container *c, struct lxc_snapshot ...@@ -4197,12 +4324,16 @@ static int do_lxcapi_snapshot_list(struct lxc_container *c, struct lxc_snapshot
out_free: out_free:
if (snaps) { if (snaps) {
int i; int i;
for (i=0; i<count; i++) for (i=0; i<count; i++)
lxcsnap_free(&snaps[i]); lxcsnap_free(&snaps[i]);
free(snaps); free(snaps);
} }
if (closedir(dir)) if (closedir(dir))
WARN("failed to close directory"); WARN("Failed to close directory");
return -1; return -1;
} }
...@@ -4250,8 +4381,10 @@ static bool do_lxcapi_snapshot_restore(struct lxc_container *c, const char *snap ...@@ -4250,8 +4381,10 @@ static bool do_lxcapi_snapshot_restore(struct lxc_container *c, const char *snap
snap = lxc_container_new(snapname, clonelxcpath); snap = lxc_container_new(snapname, clonelxcpath);
if (!snap || !lxcapi_is_defined(snap)) { if (!snap || !lxcapi_is_defined(snap)) {
ERROR("Could not open snapshot %s", snapname); ERROR("Could not open snapshot %s", snapname);
if (snap) if (snap)
lxc_container_put(snap); lxc_container_put(snap);
storage_put(bdev); storage_put(bdev);
return false; return false;
} }
...@@ -4270,11 +4403,13 @@ static bool do_lxcapi_snapshot_restore(struct lxc_container *c, const char *snap ...@@ -4270,11 +4403,13 @@ static bool do_lxcapi_snapshot_restore(struct lxc_container *c, const char *snap
if (!strcmp(bdev->type, "overlay") || !strcmp(bdev->type, "overlayfs")) if (!strcmp(bdev->type, "overlay") || !strcmp(bdev->type, "overlayfs"))
flags |= LXC_STORAGE_INTERNAL_OVERLAY_RESTORE; flags |= LXC_STORAGE_INTERNAL_OVERLAY_RESTORE;
rest = lxcapi_clone(snap, newname, c->config_path, flags, bdev->type, rest = lxcapi_clone(snap, newname, c->config_path, flags, bdev->type,
NULL, 0, NULL); NULL, 0, NULL);
storage_put(bdev); storage_put(bdev);
if (rest && lxcapi_is_defined(rest)) if (rest && lxcapi_is_defined(rest))
b = true; b = true;
if (rest) if (rest)
lxc_container_put(rest); lxc_container_put(rest);
...@@ -4299,11 +4434,13 @@ static bool do_snapshot_destroy(const char *snapname, const char *clonelxcpath) ...@@ -4299,11 +4434,13 @@ static bool do_snapshot_destroy(const char *snapname, const char *clonelxcpath)
ERROR("Could not destroy snapshot %s", snapname); ERROR("Could not destroy snapshot %s", snapname);
goto err; goto err;
} }
bret = true; bret = true;
err: err:
if (snap) if (snap)
lxc_container_put(snap); lxc_container_put(snap);
return bret; return bret;
} }
...@@ -4318,11 +4455,14 @@ static bool remove_all_snapshots(const char *path) ...@@ -4318,11 +4455,14 @@ static bool remove_all_snapshots(const char *path)
SYSERROR("opendir on snapshot path %s", path); SYSERROR("opendir on snapshot path %s", path);
return false; return false;
} }
while ((direntp = readdir(dir))) { while ((direntp = readdir(dir))) {
if (!strcmp(direntp->d_name, ".")) if (!strcmp(direntp->d_name, "."))
continue; continue;
if (!strcmp(direntp->d_name, "..")) if (!strcmp(direntp->d_name, ".."))
continue; continue;
if (!do_snapshot_destroy(direntp->d_name, path)) { if (!do_snapshot_destroy(direntp->d_name, path)) {
bret = false; bret = false;
continue; continue;
...@@ -4507,6 +4647,7 @@ static bool do_lxcapi_add_device_node(struct lxc_container *c, const char *src_p ...@@ -4507,6 +4647,7 @@ static bool do_lxcapi_add_device_node(struct lxc_container *c, const char *src_p
ERROR(LXC_UNPRIV_EOPNOTSUPP, __FUNCTION__); ERROR(LXC_UNPRIV_EOPNOTSUPP, __FUNCTION__);
return false; return false;
} }
return add_remove_device_node(c, src_path, dest_path, true); return add_remove_device_node(c, src_path, dest_path, true);
} }
...@@ -4518,6 +4659,7 @@ static bool do_lxcapi_remove_device_node(struct lxc_container *c, const char *sr ...@@ -4518,6 +4659,7 @@ static bool do_lxcapi_remove_device_node(struct lxc_container *c, const char *sr
ERROR(LXC_UNPRIV_EOPNOTSUPP, __FUNCTION__); ERROR(LXC_UNPRIV_EOPNOTSUPP, __FUNCTION__);
return false; return false;
} }
return add_remove_device_node(c, src_path, dest_path, false); return add_remove_device_node(c, src_path, dest_path, false);
} }
...@@ -4621,6 +4763,7 @@ static bool do_lxcapi_detach_interface(struct lxc_container *c, ...@@ -4621,6 +4763,7 @@ static bool do_lxcapi_detach_interface(struct lxc_container *c,
ERROR("Network device \"%s\" not found", ifname); ERROR("Network device \"%s\" not found", ifname);
else else
ERROR("Failed to remove network device \"%s\"", ifname); ERROR("Failed to remove network device \"%s\"", ifname);
_exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
} }
...@@ -4654,12 +4797,11 @@ static int do_lxcapi_migrate(struct lxc_container *c, unsigned int cmd, ...@@ -4654,12 +4797,11 @@ static int do_lxcapi_migrate(struct lxc_container *c, unsigned int cmd,
addr = (void *)opts + sizeof(*opts); addr = (void *)opts + sizeof(*opts);
end = (void *)opts + size; end = (void *)opts + size;
for (; addr < end; addr++) {
if (*addr) { for (; addr < end; addr++)
if (*addr)
return -E2BIG; return -E2BIG;
} }
}
}
/* If the caller has a smaller struct, let's zero out the end for them /* If the caller has a smaller struct, let's zero out the end for them
* so we don't accidentally use bits of it that they didn't know about * so we don't accidentally use bits of it that they didn't know about
...@@ -4680,6 +4822,7 @@ static int do_lxcapi_migrate(struct lxc_container *c, unsigned int cmd, ...@@ -4680,6 +4822,7 @@ static int do_lxcapi_migrate(struct lxc_container *c, unsigned int cmd,
ERROR("container is not running"); ERROR("container is not running");
goto on_error; goto on_error;
} }
ret = !__criu_pre_dump(c, valid_opts); ret = !__criu_pre_dump(c, valid_opts);
break; break;
case MIGRATE_DUMP: case MIGRATE_DUMP:
...@@ -4687,6 +4830,7 @@ static int do_lxcapi_migrate(struct lxc_container *c, unsigned int cmd, ...@@ -4687,6 +4830,7 @@ static int do_lxcapi_migrate(struct lxc_container *c, unsigned int cmd,
ERROR("container is not running"); ERROR("container is not running");
goto on_error; goto on_error;
} }
ret = !__criu_dump(c, valid_opts); ret = !__criu_dump(c, valid_opts);
break; break;
case MIGRATE_RESTORE: case MIGRATE_RESTORE:
...@@ -4694,6 +4838,7 @@ static int do_lxcapi_migrate(struct lxc_container *c, unsigned int cmd, ...@@ -4694,6 +4838,7 @@ static int do_lxcapi_migrate(struct lxc_container *c, unsigned int cmd,
ERROR("container is already running"); ERROR("container is already running");
goto on_error; goto on_error;
} }
ret = !__criu_restore(c, valid_opts); ret = !__criu_restore(c, valid_opts);
break; break;
case MIGRATE_FEATURE_CHECK: case MIGRATE_FEATURE_CHECK:
...@@ -4772,6 +4917,7 @@ static int lxcapi_attach_run_waitl(struct lxc_container *c, lxc_attach_options_t ...@@ -4772,6 +4917,7 @@ static int lxcapi_attach_run_waitl(struct lxc_container *c, lxc_attach_options_t
ret = do_lxcapi_attach_run_wait(c, options, program, (const char * const *)argv); ret = do_lxcapi_attach_run_wait(c, options, program, (const char * const *)argv);
free((void*)argv); free((void*)argv);
out: out:
current_config = NULL; current_config = NULL;
return ret; return ret;
...@@ -4796,7 +4942,6 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath ...@@ -4796,7 +4942,6 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath
c->config_path = strdup(configpath); c->config_path = strdup(configpath);
else else
c->config_path = strdup(lxc_global_config_value("lxc.lxcpath")); c->config_path = strdup(lxc_global_config_value("lxc.lxcpath"));
if (!c->config_path) { if (!c->config_path) {
fprintf(stderr, "Failed to allocate memory for %s\n", name); fprintf(stderr, "Failed to allocate memory for %s\n", name);
goto err; goto err;
...@@ -4840,6 +4985,7 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath ...@@ -4840,6 +4985,7 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath
container_destroy(c, NULL); container_destroy(c, NULL);
lxcapi_clear_config(c); lxcapi_clear_config(c);
} }
c->daemonize = true; c->daemonize = true;
c->pidfile = NULL; c->pidfile = NULL;
...@@ -4914,6 +5060,7 @@ int lxc_get_wait_states(const char **states) ...@@ -4914,6 +5060,7 @@ int lxc_get_wait_states(const char **states)
if (states) if (states)
for (i=0; i<MAX_STATE; i++) for (i=0; i<MAX_STATE; i++)
states[i] = lxc_state2str(i); states[i] = lxc_state2str(i);
return MAX_STATE; return MAX_STATE;
} }
...@@ -4939,6 +5086,7 @@ int list_defined_containers(const char *lxcpath, char ***names, struct lxc_conta ...@@ -4939,6 +5086,7 @@ int list_defined_containers(const char *lxcpath, char ***names, struct lxc_conta
if (cret) if (cret)
*cret = NULL; *cret = NULL;
if (names) if (names)
*names = NULL; *names = NULL;
...@@ -4950,10 +5098,10 @@ int list_defined_containers(const char *lxcpath, char ***names, struct lxc_conta ...@@ -4950,10 +5098,10 @@ int list_defined_containers(const char *lxcpath, char ***names, struct lxc_conta
if (!config_file_exists(lxcpath, direntp->d_name)) if (!config_file_exists(lxcpath, direntp->d_name))
continue; continue;
if (names) { if (names)
if (!add_to_array(names, direntp->d_name, cfound)) if (!add_to_array(names, direntp->d_name, cfound))
goto free_bad; goto free_bad;
}
cfound++; cfound++;
if (!cret) { if (!cret) {
...@@ -4965,17 +5113,22 @@ int list_defined_containers(const char *lxcpath, char ***names, struct lxc_conta ...@@ -4965,17 +5113,22 @@ int list_defined_containers(const char *lxcpath, char ***names, struct lxc_conta
if (!c) { if (!c) {
INFO("Container %s:%s has a config but could not be loaded", INFO("Container %s:%s has a config but could not be loaded",
lxcpath, direntp->d_name); lxcpath, direntp->d_name);
if (names) if (names)
if(!remove_from_array(names, direntp->d_name, cfound--)) if(!remove_from_array(names, direntp->d_name, cfound--))
goto free_bad; goto free_bad;
continue; continue;
} }
if (!do_lxcapi_is_defined(c)) { if (!do_lxcapi_is_defined(c)) {
INFO("Container %s:%s has a config but is not defined", INFO("Container %s:%s has a config but is not defined",
lxcpath, direntp->d_name); lxcpath, direntp->d_name);
if (names) if (names)
if(!remove_from_array(names, direntp->d_name, cfound--)) if(!remove_from_array(names, direntp->d_name, cfound--))
goto free_bad; goto free_bad;
lxc_container_put(c); lxc_container_put(c);
continue; continue;
} }
...@@ -4984,6 +5137,7 @@ int list_defined_containers(const char *lxcpath, char ***names, struct lxc_conta ...@@ -4984,6 +5137,7 @@ int list_defined_containers(const char *lxcpath, char ***names, struct lxc_conta
lxc_container_put(c); lxc_container_put(c);
goto free_bad; goto free_bad;
} }
nfound++; nfound++;
} }
...@@ -4996,11 +5150,13 @@ free_bad: ...@@ -4996,11 +5150,13 @@ free_bad:
free((*names)[i]); free((*names)[i]);
free(*names); free(*names);
} }
if (cret && *cret) { if (cret && *cret) {
for (i=0; i<nfound; i++) for (i=0; i<nfound; i++)
lxc_container_put((*cret)[i]); lxc_container_put((*cret)[i]);
free(*cret); free(*cret);
} }
closedir(dir); closedir(dir);
return -1; return -1;
} }
...@@ -5022,6 +5178,7 @@ int list_active_containers(const char *lxcpath, char ***nret, ...@@ -5022,6 +5178,7 @@ int list_active_containers(const char *lxcpath, char ***nret,
if (cret) if (cret)
*cret = NULL; *cret = NULL;
if (nret) if (nret)
*nret = NULL; *nret = NULL;
...@@ -5030,16 +5187,17 @@ int list_active_containers(const char *lxcpath, char ***nret, ...@@ -5030,16 +5187,17 @@ int list_active_containers(const char *lxcpath, char ***nret,
return -1; return -1;
while (getline(&line, &len, f) != -1) { while (getline(&line, &len, f) != -1) {
char *p = strrchr(line, ' '), *p2; char *p = strrchr(line, ' '), *p2;
if (!p) if (!p)
continue; continue;
p++; p++;
if (*p != 0x40) if (*p != 0x40)
continue; continue;
p++; p++;
is_hashed = false; is_hashed = false;
if (strncmp(p, lxcpath, lxcpath_len) == 0) { if (strncmp(p, lxcpath, lxcpath_len) == 0) {
p += lxcpath_len; p += lxcpath_len;
} else if (strncmp(p, "lxc/", 4) == 0) { } else if (strncmp(p, "lxc/", 4) == 0) {
...@@ -5062,11 +5220,13 @@ int list_active_containers(const char *lxcpath, char ***nret, ...@@ -5062,11 +5220,13 @@ int list_active_containers(const char *lxcpath, char ***nret,
char *recvpath = lxc_cmd_get_lxcpath(p); char *recvpath = lxc_cmd_get_lxcpath(p);
if (!recvpath) if (!recvpath)
continue; continue;
if (strncmp(lxcpath, recvpath, lxcpath_len) != 0) { if (strncmp(lxcpath, recvpath, lxcpath_len) != 0) {
free(recvpath); free(recvpath);
continue; continue;
} }
free(recvpath); free(recvpath);
p = lxc_cmd_get_name(p); p = lxc_cmd_get_name(p);
if (!p) if (!p)
continue; continue;
...@@ -5096,9 +5256,11 @@ int list_active_containers(const char *lxcpath, char ***nret, ...@@ -5096,9 +5256,11 @@ int list_active_containers(const char *lxcpath, char ***nret,
if (!c) { if (!c) {
INFO("Container %s:%s is running but could not be loaded", INFO("Container %s:%s is running but could not be loaded",
lxcpath, p); lxcpath, p);
remove_from_array(&ct_name, p, ct_name_cnt--); remove_from_array(&ct_name, p, ct_name_cnt--);
if (is_hashed) if (is_hashed)
free(p); free(p);
continue; continue;
} }
...@@ -5115,6 +5277,7 @@ int list_active_containers(const char *lxcpath, char ***nret, ...@@ -5115,6 +5277,7 @@ int list_active_containers(const char *lxcpath, char ***nret,
lxc_container_put(c); lxc_container_put(c);
goto free_cret_list; goto free_cret_list;
} }
cret_cnt++; cret_cnt++;
} }
...@@ -5129,6 +5292,7 @@ int list_active_containers(const char *lxcpath, char ***nret, ...@@ -5129,6 +5292,7 @@ int list_active_containers(const char *lxcpath, char ***nret,
*nret = ct_name; *nret = ct_name;
else else
goto free_ct_name; goto free_ct_name;
goto out; goto out;
free_cret_list: free_cret_list:
...@@ -5147,7 +5311,6 @@ free_ct_name: ...@@ -5147,7 +5311,6 @@ free_ct_name:
out: out:
free(line); free(line);
fclose(f); fclose(f);
return ret; return ret;
} }
...@@ -5176,11 +5339,14 @@ int list_all_containers(const char *lxcpath, char ***nret, ...@@ -5176,11 +5339,14 @@ int list_all_containers(const char *lxcpath, char ***nret,
ret = -1; ret = -1;
goto free_active_name; goto free_active_name;
} }
ct_cnt++; ct_cnt++;
} }
free(active_name[i]); free(active_name[i]);
active_name[i] = NULL; active_name[i] = NULL;
} }
free(active_name); free(active_name);
active_name = NULL; active_name = NULL;
active_cnt = 0; active_cnt = 0;
...@@ -5200,18 +5366,20 @@ int list_all_containers(const char *lxcpath, char ***nret, ...@@ -5200,18 +5366,20 @@ int list_all_containers(const char *lxcpath, char ***nret,
ret = -1; ret = -1;
goto free_ct_list; goto free_ct_list;
} }
ct_list_cnt++; ct_list_cnt++;
} }
if (cret) if (cret)
*cret = ct_list; *cret = ct_list;
if (nret) if (nret) {
*nret = ct_name; *nret = ct_name;
else { } else {
ret = ct_cnt; ret = ct_cnt;
goto free_ct_name; goto free_ct_name;
} }
return ct_cnt; return ct_cnt;
free_ct_list: free_ct_list:
......
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