[lxc-devel] [lxc/master] error handling cleanups #2471
2xsec on Github
lxc-bot at linuxcontainers.org
Fri Jul 20 17:45:10 UTC 2018
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 414 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20180720/29c83ab7/attachment.bin>
-------------- next part --------------
From 29c98ddd9b949357383665796331af35e38d8f09 Mon Sep 17 00:00:00 2001
From: 2xsec <dh48.jeong at samsung.com>
Date: Fri, 20 Jul 2018 22:05:15 +0900
Subject: [PATCH 1/3] confile_utils: fix return value & cleanups
Signed-off-by: 2xsec <dh48.jeong at samsung.com>
---
src/lxc/confile_utils.c | 54 +++++++++++++++++++++++++++++++++----------------
src/lxc/confile_utils.h | 2 +-
2 files changed, 38 insertions(+), 18 deletions(-)
diff --git a/src/lxc/confile_utils.c b/src/lxc/confile_utils.c
index ff563e0ac..4a7d934a2 100644
--- a/src/lxc/confile_utils.c
+++ b/src/lxc/confile_utils.c
@@ -149,6 +149,7 @@ int parse_idmaps(const char *idmap, char *type, unsigned long *nsid,
*/
if (*(slide + strspn(slide, " \t\r\n")) != '\0')
goto on_error;
+
/* Mark end of range. */
*slide = '\0';
@@ -211,6 +212,7 @@ struct lxc_netdev *lxc_network_add(struct lxc_list *networks, int idx, bool tail
lxc_list_add_tail(networks, newlist);
else
lxc_list_add(networks, newlist);
+
return netdev;
}
@@ -265,23 +267,29 @@ void lxc_log_configured_netdevs(const struct lxc_conf *conf)
TRACE("index: %zd", netdev->idx);
TRACE("ifindex: %d", netdev->ifindex);
+
switch (netdev->type) {
case LXC_NET_VETH:
TRACE("type: veth");
+
if (netdev->priv.veth_attr.pair[0] != '\0')
TRACE("veth pair: %s",
netdev->priv.veth_attr.pair);
+
if (netdev->priv.veth_attr.veth1[0] != '\0')
TRACE("veth1 : %s",
netdev->priv.veth_attr.veth1);
+
if (netdev->priv.veth_attr.ifindex > 0)
TRACE("host side ifindex for veth device: %d",
netdev->priv.veth_attr.ifindex);
break;
case LXC_NET_MACVLAN:
TRACE("type: macvlan");
+
if (netdev->priv.macvlan_attr.mode > 0) {
char *macvlan_mode;
+
macvlan_mode = lxc_macvlan_flag_to_mode(
netdev->priv.macvlan_attr.mode);
TRACE("macvlan mode: %s",
@@ -295,10 +303,10 @@ void lxc_log_configured_netdevs(const struct lxc_conf *conf)
break;
case LXC_NET_PHYS:
TRACE("type: phys");
- if (netdev->priv.phys_attr.ifindex > 0) {
+
+ if (netdev->priv.phys_attr.ifindex > 0)
TRACE("host side ifindex for phys device: %d",
netdev->priv.phys_attr.ifindex);
- }
break;
case LXC_NET_EMPTY:
TRACE("type: empty");
@@ -314,16 +322,22 @@ void lxc_log_configured_netdevs(const struct lxc_conf *conf)
if (netdev->type != LXC_NET_EMPTY) {
TRACE("flags: %s",
netdev->flags == IFF_UP ? "up" : "none");
+
if (netdev->link[0] != '\0')
TRACE("link: %s", netdev->link);
+
if (netdev->name[0] != '\0')
TRACE("name: %s", netdev->name);
+
if (netdev->hwaddr)
TRACE("hwaddr: %s", netdev->hwaddr);
+
if (netdev->mtu)
TRACE("mtu: %s", netdev->mtu);
+
if (netdev->upscript)
TRACE("upscript: %s", netdev->upscript);
+
if (netdev->downscript)
TRACE("downscript: %s", netdev->downscript);
@@ -345,11 +359,13 @@ void lxc_log_configured_netdevs(const struct lxc_conf *conf)
TRACE("ipv6 gateway auto: %s",
netdev->ipv6_gateway_auto ? "true" : "false");
+
if (netdev->ipv6_gateway) {
inet_ntop(AF_INET6, netdev->ipv6_gateway,
bufinet6, sizeof(bufinet6));
TRACE("ipv6 gateway: %s", bufinet6);
}
+
lxc_list_for_each_safe(cur, &netdev->ipv6, next) {
inet6dev = cur->elem;
inet_ntop(AF_INET6, &inet6dev->addr, bufinet6,
@@ -477,7 +493,7 @@ int set_config_string_item(char **conf_item, const char *value)
new_value = strdup(value);
if (!new_value) {
- SYSERROR("failed to duplicate string \"%s\"", value);
+ SYSERROR("Failed to duplicate string \"%s\"", value);
return -1;
}
@@ -505,8 +521,10 @@ int config_ip_prefix(struct in_addr *addr)
{
if (IN_CLASSA(addr->s_addr))
return 32 - IN_CLASSA_NSHIFT;
+
if (IN_CLASSB(addr->s_addr))
return 32 - IN_CLASSB_NSHIFT;
+
if (IN_CLASSC(addr->s_addr))
return 32 - IN_CLASSC_NSHIFT;
@@ -521,15 +539,14 @@ int network_ifname(char *valuep, const char *value, size_t size)
return -1;
retlen = strlcpy(valuep, value, size);
- if (retlen >= size) {
+ if (retlen >= size)
ERROR("Network devie name \"%s\" is too long (>= %zu)", value,
size);
- }
return 0;
}
-int rand_complete_hwaddr(char *hwaddr)
+void rand_complete_hwaddr(char *hwaddr)
{
const char hex[] = "0123456789abcdef";
char *curs = hwaddr;
@@ -558,7 +575,6 @@ int rand_complete_hwaddr(char *hwaddr)
}
curs++;
}
- return 0;
}
bool lxc_config_net_hwaddr(const char *line)
@@ -568,11 +584,15 @@ bool lxc_config_net_hwaddr(const char *line)
if (strncmp(line, "lxc.net", 7) != 0)
return false;
+
if (strncmp(line, "lxc.net.hwaddr", 14) == 0)
return true;
+
if (strncmp(line, "lxc.network.hwaddr", 18) == 0)
return true;
- if (sscanf(line, "lxc.net.%u.%6s", &index, tmp) == 2 || sscanf(line, "lxc.network.%u.%6s", &index, tmp) == 2)
+
+ if (sscanf(line, "lxc.net.%u.%6s", &index, tmp) == 2 ||
+ sscanf(line, "lxc.network.%u.%6s", &index, tmp) == 2)
return strncmp(tmp, "hwaddr", 6) == 0;
return false;
@@ -639,7 +659,7 @@ int lxc_get_conf_str(char *retv, int inlen, const char *value)
if (retv && inlen >= value_len + 1)
memcpy(retv, value, value_len + 1);
- return strlen(value);
+ return value_len;
}
int lxc_get_conf_int(struct lxc_conf *c, char *retv, int inlen, int v)
@@ -701,6 +721,7 @@ bool parse_limit_value(const char **value, rlim_t *res)
*res = strtoull(*value, &endptr, 10);
if (errno || !endptr)
return false;
+
*value = endptr;
return true;
@@ -744,7 +765,7 @@ static int lxc_container_name_to_pid(const char *lxcname_or_pid,
ret = kill(pid, 0);
if (ret < 0) {
SYSERROR("Failed to send signal to pid %d", (int)pid);
- return -EPERM;
+ return -1;
}
return pid;
@@ -760,7 +781,7 @@ int lxc_inherit_namespace(const char *lxcname_or_pid, const char *lxcpath,
if (lastslash) {
dup = strdup(lxcname_or_pid);
if (!dup)
- return -ENOMEM;
+ return -1;
dup[lastslash - lxcname_or_pid] = '\0';
pid = lxc_container_name_to_pid(lastslash + 1, dup);
@@ -770,11 +791,11 @@ int lxc_inherit_namespace(const char *lxcname_or_pid, const char *lxcpath,
}
if (pid < 0)
- return -EINVAL;
+ return -1;
fd = lxc_preserve_ns(pid, namespace);
if (fd < 0)
- return -EINVAL;
+ return -1;
return fd;
}
@@ -877,9 +898,8 @@ static int rt_sig_num(const char *signame)
{
int rtmax = 0, sig_n = 0;
- if (strncasecmp(signame, "max-", 4) == 0) {
+ if (strncasecmp(signame, "max-", 4) == 0)
rtmax = 1;
- }
signame += 4;
if (!isdigit(*signame))
@@ -903,10 +923,10 @@ int sig_parse(const char *signame)
signame += 3;
if (strncasecmp(signame, "rt", 2) == 0)
return rt_sig_num(signame + 2);
- for (n = 0; n < sizeof(signames) / sizeof((signames)[0]); n++) {
+
+ for (n = 0; n < sizeof(signames) / sizeof((signames)[0]); n++)
if (strcasecmp(signames[n].name, signame) == 0)
return signames[n].num;
- }
}
return -1;
diff --git a/src/lxc/confile_utils.h b/src/lxc/confile_utils.h
index ef11969fc..b58ce47b2 100644
--- a/src/lxc/confile_utils.h
+++ b/src/lxc/confile_utils.h
@@ -81,7 +81,7 @@ extern int set_config_string_item_max(char **conf_item, const char *value,
extern int set_config_path_item(char **conf_item, const char *value);
extern int config_ip_prefix(struct in_addr *addr);
extern int network_ifname(char *valuep, const char *value, size_t size);
-extern int rand_complete_hwaddr(char *hwaddr);
+extern void rand_complete_hwaddr(char *hwaddr);
extern bool lxc_config_net_hwaddr(const char *line);
extern void update_hwaddr(const char *line);
extern bool new_hwaddr(char *hwaddr);
From a73846d8935ca471939cc38f92f232806594608f Mon Sep 17 00:00:00 2001
From: 2xsec <dh48.jeong at samsung.com>
Date: Fri, 20 Jul 2018 23:41:10 +0900
Subject: [PATCH 2/3] lxccontainer: coding rules
Signed-off-by: 2xsec <dh48.jeong at samsung.com>
---
src/lxc/lxccontainer.c | 316 +++++++++++++++++++++++++++++++++++++------------
1 file changed, 242 insertions(+), 74 deletions(-)
diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index ce01f13e9..cd4891ab0 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -167,11 +167,12 @@ static int ongoing_create(struct lxc_container *c)
ret = fcntl(fd, F_OFD_GETLK, &lk);
if (ret < 0 && errno == EINVAL)
ret = flock(fd, LOCK_EX | LOCK_NB);
+
close(fd);
- if (ret == 0 && lk.l_pid != -1) {
+
+ if (ret == 0 && lk.l_pid != -1)
/* create is still ongoing */
return 1;
- }
/* Create completed but partial is still there. */
return 2;
@@ -221,6 +222,7 @@ static void remove_partial(struct lxc_container *c, int fd)
char *path;
close(fd);
+
/* $lxcpath + '/' + $name + '/partial' + \0 */
len = strlen(c->config_path) + strlen(c->name) + 10;
path = alloca(len);
@@ -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.
* Do not ever use a lxccontainer whose numthreads you did not bump.
*/
-
static void lxc_container_free(struct lxc_container *c)
{
if (!c)
@@ -358,7 +359,6 @@ int lxc_container_put(struct lxc_container *c)
}
container_mem_unlock(c);
-
return 0;
}
@@ -385,7 +385,6 @@ static bool do_lxcapi_is_defined(struct lxc_container *c)
on_error:
container_mem_unlock(c);
-
return ret;
}
@@ -596,7 +595,6 @@ static bool load_config_locked(struct lxc_container *c, const char *fname)
return false;
c->lxc_conf->name = c->name;
-
return true;
}
@@ -610,8 +608,10 @@ static bool do_lxcapi_load_config(struct lxc_container *c, const char *alt_file)
return false;
fname = c->configfile;
+
if (alt_file)
fname = alt_file;
+
if (!fname)
return false;
@@ -746,9 +746,8 @@ static char **split_init_cmd(const char *incmd)
len = strlen(incmd) + 1;
copy = alloca(len);
retlen = strlcpy(copy, incmd, len);
- if (retlen >= len) {
+ if (retlen >= len)
return NULL;
- }
do {
argv = malloc(sizeof(char *));
@@ -781,62 +780,62 @@ static void free_init_cmd(char **argv)
static int lxc_rcv_status(int state_socket)
{
- int ret;
- int state = -1;
+ int ret;
+ int state = -1;
again:
- /* Receive container state. */
- ret = lxc_abstract_unix_rcv_credential(state_socket, &state,
- sizeof(int));
- if (ret <= 0) {
+ /* Receive container state. */
+ ret = lxc_abstract_unix_rcv_credential(state_socket, &state, sizeof(int));
+ if (ret <= 0) {
if (errno != EINTR)
return -1;
+
TRACE("Caught EINTR; retrying");
goto again;
}
- return state;
+ return state;
}
static bool wait_on_daemonized_start(struct lxc_handler *handler, int pid)
{
- int ret, state;
+ int ret, state;
- /* Close write end of the socket pair. */
- close(handler->state_socket_pair[1]);
- handler->state_socket_pair[1] = -1;
+ /* Close write end of the socket pair. */
+ close(handler->state_socket_pair[1]);
+ handler->state_socket_pair[1] = -1;
- state = lxc_rcv_status(handler->state_socket_pair[0]);
+ state = lxc_rcv_status(handler->state_socket_pair[0]);
- /* Close read end of the socket pair. */
- close(handler->state_socket_pair[0]);
- handler->state_socket_pair[0] = -1;
+ /* Close read end of the socket pair. */
+ close(handler->state_socket_pair[0]);
+ handler->state_socket_pair[0] = -1;
- /* The first child is going to fork() again and then exits. So we reap
- * the first child here.
- */
+ /* The first child is going to fork() again and then exits. So we reap
+ * the first child here.
+ */
ret = wait_for_pid(pid);
if (ret < 0)
- DEBUG("Failed waiting on first child %d", pid);
+ DEBUG("Failed waiting on first child %d", pid);
else
- DEBUG("First child %d exited", pid);
+ DEBUG("First child %d exited", pid);
- if (state < 0) {
- SYSERROR("Failed to receive the container state");
- return false;
- }
+ if (state < 0) {
+ SYSERROR("Failed to receive the container state");
+ return false;
+ }
- /* If we receive anything else then running we know that the container
- * failed to start.
- */
- if (state != RUNNING) {
- ERROR("Received container state \"%s\" instead of \"RUNNING\"",
- lxc_state2str(state));
- return false;
- }
+ /* If we receive anything else then running we know that the container
+ * failed to start.
+ */
+ if (state != RUNNING) {
+ ERROR("Received container state \"%s\" instead of \"RUNNING\"",
+ lxc_state2str(state));
+ return false;
+ }
- TRACE("Container is in \"RUNNING\" state");
- return true;
+ TRACE("Container is in \"RUNNING\" state");
+ return true;
}
static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const argv[])
@@ -1147,6 +1146,7 @@ static bool lxcapi_startl(struct lxc_container *c, int useinit, ...)
on_error:
if (inargs) {
char **arg;
+
for (arg = inargs; *arg; arg++)
free(*arg);
free(inargs);
@@ -1405,9 +1405,9 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
* args.
*/
if (argv)
- for (nargs = 0; argv[nargs]; nargs++) {
+ for (nargs = 0; argv[nargs]; nargs++)
;
- }
+
/* template, path, rootfs and name args */
nargs += 4;
@@ -1421,6 +1421,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
patharg = malloc(len);
if (!patharg)
_exit(EXIT_FAILURE);
+
ret = snprintf(patharg, len, "--path=%s/%s", c->config_path, c->name);
if (ret < 0 || ret >= len)
_exit(EXIT_FAILURE);
@@ -1431,6 +1432,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
namearg = malloc(len);
if (!namearg)
_exit(EXIT_FAILURE);
+
ret = snprintf(namearg, len, "--name=%s", c->name);
if (ret < 0 || ret >= len)
_exit(EXIT_FAILURE);
@@ -1441,6 +1443,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
rootfsarg = malloc(len);
if (!rootfsarg)
_exit(EXIT_FAILURE);
+
ret = snprintf(rootfsarg, len, "--rootfs=%s", bdev->dest);
if (ret < 0 || ret >= len)
_exit(EXIT_FAILURE);
@@ -1478,6 +1481,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
newargv[0] = tpath;
tpath = "lxc-usernsexec";
n2[0] = "lxc-usernsexec";
+
lxc_list_for_each(it, &conf->id_map) {
map = it->elem;
n2args += 2;
@@ -1499,6 +1503,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
hostuid_mapped = mapped_hostid(geteuid(), conf, ID_TYPE_UID);
extraargs = hostuid_mapped >= 0 ? 1 : 3;
+
n2 = realloc(n2, (nargs + n2args + extraargs) * sizeof(char *));
if (!n2)
_exit(EXIT_FAILURE);
@@ -1516,6 +1521,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
SYSERROR("out of memory");
_exit(EXIT_FAILURE);
}
+
ret = snprintf(n2[n2args - 1], 200, "u:%d:%d:1",
hostuid_mapped, geteuid());
if (ret < 0 || ret >= 200)
@@ -1524,6 +1530,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
hostgid_mapped = mapped_hostid(getegid(), conf, ID_TYPE_GID);
extraargs = hostgid_mapped >= 0 ? 1 : 3;
+
n2 = realloc(n2, (nargs + n2args + extraargs) * sizeof(char *));
if (!n2)
_exit(EXIT_FAILURE);
@@ -1547,7 +1554,9 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
if (ret < 0 || ret >= 200)
_exit(EXIT_FAILURE);
}
+
n2[n2args++] = "--";
+
for (i = 0; i < nargs; i++)
n2[i + n2args] = newargv[i];
n2args += nargs;
@@ -1644,6 +1653,7 @@ static bool prepend_lxc_header(char *path, const char *t, char *const argv[])
goto out_free_contents;
contents[flen] = '\0';
+
ret = fclose(f);
f = NULL;
if (ret < 0)
@@ -1681,6 +1691,7 @@ static bool prepend_lxc_header(char *path, const char *t, char *const argv[])
}
fprintf(f, "\n");
}
+
#if HAVE_LIBGNUTLS
fprintf(f, "# Template script checksum (SHA-1): ");
for (i=0; i<SHA_DIGEST_LENGTH; i++)
@@ -1770,7 +1781,7 @@ static bool do_lxcapi_create(struct lxc_container *c, const char *t,
* existing container. Return an error, but do NOT delete the container.
*/
if (do_lxcapi_is_defined(c) && c->lxc_conf && c->lxc_conf->rootfs.path &&
- access(c->lxc_conf->rootfs.path, F_OK) == 0 && tpath) {
+ access(c->lxc_conf->rootfs.path, F_OK) == 0 && tpath) {
ERROR("Container \"%s\" already exists in \"%s\"", c->name,
c->config_path);
goto free_tpath;
@@ -1811,6 +1822,7 @@ static bool do_lxcapi_create(struct lxc_container *c, const char *t,
*/
if (!c->save_config(c, NULL))
ERROR("Failed to save initial config for \"%s\"", c->name);
+
ret = true;
goto out;
}
@@ -1856,14 +1868,17 @@ static bool do_lxcapi_create(struct lxc_container *c, const char *t,
bdev->ops->destroy(bdev);
_exit(EXIT_FAILURE);
}
+
_exit(EXIT_SUCCESS);
}
+
if (wait_for_pid(pid) != 0)
goto out_unlock;
/* Reload config to get the rootfs. */
lxc_conf_free(c->lxc_conf);
c->lxc_conf = NULL;
+
if (!load_config_locked(c, c->configfile))
goto out_unlock;
@@ -1881,15 +1896,18 @@ static bool do_lxcapi_create(struct lxc_container *c, const char *t,
goto out_unlock;
}
}
+
ret = load_config_locked(c, c->configfile);
out_unlock:
umask(mask);
if (partial_fd >= 0)
remove_partial(c, partial_fd);
+
out:
if (!ret)
container_destroy(c, NULL);
+
free_tpath:
free(tpath);
return ret;
@@ -1900,7 +1918,9 @@ static bool lxcapi_create(struct lxc_container *c, const char *t,
int flags, char *const argv[])
{
bool ret;
+
current_config = c ? c->lxc_conf : NULL;
+
ret = do_lxcapi_create(c, t, bdevtype, specs, flags, argv);
current_config = NULL;
return ret;
@@ -1981,6 +2001,7 @@ static bool do_lxcapi_reboot2(struct lxc_container *c, int timeout)
if (killret < 0) {
if (state_client_fd >= 0)
close(state_client_fd);
+
WARN("Failed to send signal %d to pid %d", rebootsignal, pid);
return false;
}
@@ -2051,6 +2072,7 @@ static bool do_lxcapi_shutdown(struct lxc_container *c, int timeout)
if (killret < 0) {
if (state_client_fd >= 0)
close(state_client_fd);
+
WARN("Failed to send signal %d to pid %d", haltsignal, pid);
return false;
}
@@ -2151,6 +2173,7 @@ static bool do_lxcapi_clear_config_item(struct lxc_container *c,
*/
if (config && config->clr)
ret = config->clr(key, c->lxc_conf, NULL);
+
if (!ret)
do_clear_unexp_config_line(c->lxc_conf, key);
@@ -2164,10 +2187,11 @@ static inline bool enter_net_ns(struct lxc_container *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"))
return false;
- }
+
return switch_to_ns(pid, "net");
}
@@ -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);
}
-
-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)
return true;
+
return false;
}
@@ -2243,6 +2268,7 @@ static bool remove_from_array(char ***names, char *cname, int size)
free(result);
return true;
}
+
return false;
}
@@ -2293,6 +2319,7 @@ static char ** do_lxcapi_get_interfaces(struct lxc_container *c)
}
count++;
}
+
ret = 0;
out:
@@ -2322,6 +2349,7 @@ static char ** do_lxcapi_get_interfaces(struct lxc_container *c)
if (wait_for_pid(pid) != 0) {
for(i=0;i<count;i++)
free(interfaces[i]);
+
free(interfaces);
interfaces = NULL;
}
@@ -2422,8 +2450,10 @@ static char **do_lxcapi_get_ips(struct lxc_container *c, const char *interface,
address);
goto out;
}
+
count++;
}
+
ret = 0;
out:
@@ -2497,8 +2527,10 @@ static char* do_lxcapi_get_running_config_item(struct lxc_container *c, const ch
if (!c || !c->lxc_conf)
return NULL;
+
if (container_mem_lock(c))
return NULL;
+
ret = lxc_cmd_get_config_item(c->name, key, do_lxcapi_get_config_path(c));
container_mem_unlock(c);
return ret;
@@ -2542,6 +2574,7 @@ static bool do_lxcapi_save_config(struct lxc_container *c, const char *alt_file)
if (!alt_file)
alt_file = c->configfile;
+
if (!alt_file)
return false;
@@ -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);
if (ret < 0 || ret > MAXPATHLEN)
goto out;
+
ret = snprintf(newpath, MAXPATHLEN, "%s\n%s\n", c->config_path, c->name);
if (ret < 0 || ret > MAXPATHLEN)
goto out;
@@ -2702,6 +2736,7 @@ static bool mod_rdep(struct lxc_container *c0, struct lxc_container *c, bool inc
goto out;
}
}
+
close(fd);
}
@@ -2737,9 +2772,11 @@ void mod_all_rdeps(struct lxc_container *c, bool inc)
ERROR("Path name too long");
return;
}
+
f = fopen(path, "r");
if (f == NULL)
return;
+
while (getline(&lxcpath, &pathlen, f) != -1) {
if (getline(&lxcname, &namelen, f) == -1) {
ERROR("badly formatted file %s", path);
@@ -2754,11 +2791,14 @@ void mod_all_rdeps(struct lxc_container *c, bool inc)
lxcpath, lxcname);
continue;
}
+
if (!mod_rdep(p, c, inc))
ERROR("Failed to update snapshots file for %s:%s",
lxcpath, lxcname);
+
lxc_container_put(p);
}
+
out:
free(lxcpath);
free(lxcname);
@@ -2777,20 +2817,24 @@ static bool has_fs_snapshots(struct lxc_container *c)
c->name);
if (ret < 0 || ret > MAXPATHLEN)
goto out;
+
/* If the file doesn't exist there are no snapshots. */
if (stat(path, &fbuf) < 0)
goto out;
+
v = fbuf.st_size;
if (v != 0) {
f = fopen(path, "r");
if (!f)
goto out;
+
ret = fscanf(f, "%d", &v);
fclose(f);
/* TODO: Figure out what to do with the return value of fscanf. */
if (ret != 1)
INFO("Container uses new lxc-snapshots format %s", path);
}
+
bret = v != 0;
out:
@@ -2806,9 +2850,11 @@ static bool has_snapshots(struct lxc_container *c)
if (!get_snappath_dir(c, path))
return false;
+
dir = opendir(path);
if (!dir)
return false;
+
while ((direntp = readdir(dir))) {
if (!strcmp(direntp->d_name, "."))
continue;
@@ -2818,6 +2864,7 @@ static bool has_snapshots(struct lxc_container *c)
count++;
break;
}
+
closedir(dir);
return count > 0;
}
@@ -2901,6 +2948,7 @@ static bool container_destroy(struct lxc_container *c,
if (current_config && conf == current_config) {
current_config = NULL;
+
if (conf->logfd != -1) {
close(conf->logfd);
conf->logfd = -1;
@@ -2966,6 +3014,7 @@ static bool container_destroy(struct lxc_container *c,
ret = snprintf(path, len, "%s/%s", p1, c->name);
if (ret < 0 || (size_t)ret >= len)
goto out;
+
if (am_guest_unpriv())
ret = userns_exec_full(conf, lxc_rmdir_onedev_wrapper, path,
"lxc_rmdir_onedev_wrapper");
@@ -2983,6 +3032,7 @@ static bool container_destroy(struct lxc_container *c,
out:
if (path)
free(path);
+
container_disk_unlock(c);
return bret;
}
@@ -3011,10 +3061,12 @@ static bool do_lxcapi_destroy_with_snapshots(struct lxc_container *c)
{
if (!c || !lxcapi_is_defined(c))
return false;
+
if (!lxcapi_snapshot_destroy_all(c)) {
ERROR("Error deleting all snapshots");
return false;
}
+
return lxcapi_destroy(c);
}
@@ -3085,6 +3137,7 @@ static char *lxcapi_config_file_name(struct lxc_container *c)
{
if (!c || !c->configfile)
return NULL;
+
return strdup(c->configfile);
}
@@ -3092,6 +3145,7 @@ static const char *lxcapi_get_config_path(struct lxc_container *c)
{
if (!c || !c->config_path)
return NULL;
+
return (const char *)(c->config_path);
}
@@ -3160,6 +3214,7 @@ static bool do_lxcapi_set_config_path(struct lxc_container *c, const char *path)
c->config_path = oldpath;
oldpath = NULL;
}
+
err:
free(oldpath);
container_mem_unlock(c);
@@ -3248,6 +3303,7 @@ static int copy_file(const char *old, const char *new)
ERROR("copy destination %s exists", new);
return -1;
}
+
ret = stat(old, &sbuf);
if (ret < 0) {
INFO("Error stat'ing %s", old);
@@ -3259,6 +3315,7 @@ static int copy_file(const char *old, const char *new)
SYSERROR("Error opening original file %s", old);
return -1;
}
+
out = open(new, O_CREAT | O_EXCL | O_WRONLY, 0644);
if (out < 0) {
SYSERROR("Error opening new file %s", new);
@@ -3272,14 +3329,17 @@ static int copy_file(const char *old, const char *new)
SYSERROR("Error reading old file %s", old);
goto err;
}
+
if (len == 0)
break;
+
ret = write(out, buf, len);
if (ret < len) { /* should we retry? */
SYSERROR("Error: write to new file %s was interrupted", new);
goto err;
}
}
+
close(in);
close(out);
@@ -3317,19 +3377,24 @@ static int copyhooks(struct lxc_container *oldc, struct lxc_container *c)
char tmppath[MAXPATHLEN];
if (!fname) /* relative path - we don't support, but maybe we should */
return 0;
+
if (strncmp(hookname, cpath, len - 1) != 0) {
/* this hook is public - ignore */
continue;
}
+
/* copy the script, and change the entry in confile */
ret = snprintf(tmppath, MAXPATHLEN, "%s/%s/%s",
c->config_path, c->name, fname+1);
if (ret < 0 || ret >= MAXPATHLEN)
return -1;
+
ret = copy_file(it->elem, tmppath);
if (ret < 0)
return -1;
+
free(it->elem);
+
it->elem = strdup(tmppath);
if (!it->elem) {
ERROR("out of memory copying hook path");
@@ -3343,6 +3408,7 @@ static int copyhooks(struct lxc_container *oldc, struct lxc_container *c)
ERROR("Error saving new hooks in clone");
return -1;
}
+
do_lxcapi_save_config(c, NULL);
return 0;
}
@@ -3362,12 +3428,14 @@ static int copy_fstab(struct lxc_container *oldc, struct lxc_container *c)
char *p = strrchr(oldpath, '/');
if (!p)
return -1;
+
ret = snprintf(newpath, MAXPATHLEN, "%s/%s%s",
c->config_path, c->name, p);
if (ret < 0 || ret >= MAXPATHLEN) {
ERROR("error printing new path for %s", oldpath);
return -1;
}
+
if (file_exists(newpath)) {
ERROR("error: fstab file %s exists", newpath);
return -1;
@@ -3377,12 +3445,15 @@ static int copy_fstab(struct lxc_container *oldc, struct lxc_container *c)
ERROR("error: copying %s to %s", oldpath, newpath);
return -1;
}
+
free(c->lxc_conf->fstab);
+
c->lxc_conf->fstab = strdup(newpath);
if (!c->lxc_conf->fstab) {
ERROR("error: allocating pathname");
return -1;
}
+
if (!do_append_unexp_config_line(c->lxc_conf, "lxc.mount.fstab", newpath)) {
ERROR("error saving new lxctab");
return -1;
@@ -3402,12 +3473,14 @@ static void copy_rdepends(struct lxc_container *c, struct lxc_container *c0)
WARN("Error copying reverse dependencies");
return;
}
+
ret = snprintf(path1, MAXPATHLEN, "%s/%s/lxc_rdepends", c->config_path,
c->name);
if (ret < 0 || ret >= MAXPATHLEN) {
WARN("Error copying reverse dependencies");
return;
}
+
if (copy_file(path0, path1) < 0) {
INFO("Error copying reverse dependencies");
return;
@@ -3425,15 +3498,20 @@ static bool add_rdepends(struct lxc_container *c, struct lxc_container *c0)
c->name);
if (ret < 0 || ret >= MAXPATHLEN)
return false;
+
f = fopen(path, "a");
if (!f)
return false;
+
bret = true;
+
/* If anything goes wrong, just return an error. */
if (fprintf(f, "%s\n%s\n", c0->config_path, c0->name) < 0)
bret = false;
+
if (fclose(f) != 0)
bret = false;
+
return bret;
}
@@ -3506,6 +3584,7 @@ static int copy_storage(struct lxc_container *c0, struct lxc_container *c,
if (flags & LXC_CLONE_SNAPSHOT)
copy_rdepends(c, c0);
+
if (need_rdep) {
if (!add_rdepends(c, c0))
WARN("Error adding reverse dependency from %s to %s",
@@ -3543,30 +3622,36 @@ static int clone_update_rootfs(struct clone_update_data *data)
ERROR("Failed to setgid to 0");
return -1;
}
+
if (setuid(0) < 0) {
ERROR("Failed to setuid to 0");
return -1;
}
+
if (setgroups(0, NULL) < 0)
WARN("Failed to clear groups");
if (unshare(CLONE_NEWNS) < 0)
return -1;
+
bdev = storage_init(c->lxc_conf);
if (!bdev)
return -1;
+
if (strcmp(bdev->type, "dir") != 0) {
if (unshare(CLONE_NEWNS) < 0) {
ERROR("error unsharing mounts");
storage_put(bdev);
return -1;
}
+
if (detect_shared_rootfs()) {
if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL)) {
SYSERROR("Failed to make / rslave");
ERROR("Continuing...");
}
}
+
if (bdev->ops->mount(bdev) < 0) {
storage_put(bdev);
return -1;
@@ -3578,21 +3663,20 @@ static int clone_update_rootfs(struct clone_update_data *data)
if (!lxc_list_empty(&conf->hooks[LXCHOOK_CLONE])) {
/* 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");
- }
- if (setenv("LXC_NAME", c->name, 1)) {
+
+ if (setenv("LXC_NAME", c->name, 1))
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");
- }
- 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");
- }
- 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");
- }
if (run_lxc_hooks(c->name, "clone", conf, hookargs)) {
ERROR("Error executing clone hook for %s", c->name);
@@ -3607,16 +3691,20 @@ static int clone_update_rootfs(struct clone_update_data *data)
if (ret < 0 || ret >= MAXPATHLEN)
return -1;
+
if (!file_exists(path))
return 0;
+
if (!(fout = fopen(path, "w"))) {
SYSERROR("unable to open %s: ignoring", path);
return 0;
}
+
if (fprintf(fout, "%s", c->name) < 0) {
fclose(fout);
return -1;
}
+
if (fclose(fout) < 0)
return -1;
} else {
@@ -3650,9 +3738,11 @@ static int create_file_dirname(char *path, struct lxc_conf *conf)
if (!p)
return -1;
+
*p = '\0';
ret = do_create_container_dir(path, conf);
*p = '/';
+
return ret;
}
@@ -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. */
if (!newname)
newname = c->name;
+
if (!lxcpath)
lxcpath = do_lxcapi_get_config_path(c);
+
ret = snprintf(newpath, MAXPATHLEN, "%s/%s/config", lxcpath, newname);
if (ret < 0 || ret >= MAXPATHLEN) {
SYSERROR("clone: failed making config pathname");
@@ -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);
write_config(fd, c->lxc_conf);
close(fd);
+
c->lxc_conf->rootfs.path = origroot;
+
free(c->lxc_conf->unexpanded_config);
c->lxc_conf->unexpanded_config = saved_unexp_conf;
saved_unexp_conf = NULL;
@@ -3771,7 +3865,6 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char
if (ret < 0)
goto out;
-
/* update utsname */
if (!(flags & LXC_CLONE_KEEPNAME)) {
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
SYSERROR("fork");
goto out;
}
+
if (pid > 0) {
ret = wait_for_pid(pid);
if (ret)
goto out;
+
container_mem_unlock(c);
return c2;
}
+
data.c0 = c;
data.c1 = c2;
data.flags = flags;
data.hookargs = hookargs;
+
if (am_guest_unpriv())
ret = userns_exec_full(c->lxc_conf, clone_update_rootfs_wrapper,
&data, "clone_update_rootfs_wrapper");
@@ -3846,6 +3943,7 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char
if (c2) {
if (!storage_copied)
c2->lxc_conf->rootfs.path = NULL;
+
c2->destroy(c2);
lxc_container_put(c2);
}
@@ -3859,9 +3957,11 @@ static struct lxc_container *lxcapi_clone(struct lxc_container *c, const char *n
char **hookargs)
{
struct lxc_container * ret;
+
current_config = c ? c->lxc_conf : NULL;
ret = do_lxcapi_clone(c, newname, lxcpath, flags, bdevtype, bdevdata, newsize, hookargs);
current_config = NULL;
+
return ret;
}
@@ -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");
return false;
}
+
bdev = storage_init(c->lxc_conf);
if (!bdev) {
ERROR("Failed to find original backing store type");
@@ -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);
return false;
}
+
return true;
}
@@ -3927,20 +4029,24 @@ static int do_lxcapi_attach_run_wait(struct lxc_container *c, lxc_attach_options
command.program = (char*)program;
command.argv = (char**)argv;
+
r = lxc_attach(c->name, c->config_path, lxc_attach_run_command, &command, options, &pid);
if (r < 0) {
ERROR("ups");
return r;
}
+
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[])
{
int ret;
+
current_config = c ? c->lxc_conf : NULL;
ret = do_lxcapi_attach_run_wait(c, options, program, argv);
current_config = NULL;
+
return ret;
}
@@ -3951,11 +4057,14 @@ static int get_next_index(const char *lxcpath, char *cname)
int i = 0, ret;
fname = alloca(strlen(lxcpath) + 20);
+
while (1) {
sprintf(fname, "%s/snap%d", lxcpath, i);
+
ret = stat(fname, &sb);
if (ret != 0)
return i;
+
i++;
}
}
@@ -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)
{
int ret;
+
/*
* If the old style snapshot path exists, use it
* /var/lib/lxc -> /var/lib/lxcsnaps
@@ -3970,10 +4080,12 @@ static bool get_snappath_dir(struct lxc_container *c, char *snappath)
ret = snprintf(snappath, MAXPATHLEN, "%ssnaps", c->config_path);
if (ret < 0 || ret >= MAXPATHLEN)
return false;
+
if (dir_exists(snappath)) {
ret = snprintf(snappath, MAXPATHLEN, "%ssnaps/%s", c->config_path, c->name);
if (ret < 0 || ret >= MAXPATHLEN)
return false;
+
return true;
}
@@ -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);
if (ret < 0 || ret >= MAXPATHLEN)
return false;
+
return true;
}
@@ -4029,6 +4142,7 @@ static int do_lxcapi_snapshot(struct lxc_container *c, const char *commentfile)
ERROR("and keep the original container pristine.");
flags &= ~LXC_CLONE_SNAPSHOT | LXC_CLONE_MAYBE_SNAPSHOT;
}
+
c2 = do_lxcapi_clone(c, newname, snappath, flags, NULL, NULL, 0, NULL);
if (!c2) {
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)
ERROR("Failed to open %s", dfnam);
return -1;
}
+
if (fprintf(f, "%s", buffer) < 0) {
SYSERROR("Writing timestamp");
fclose(f);
return -1;
}
+
ret = fclose(f);
if (ret != 0) {
SYSERROR("Writing timestamp");
@@ -4070,6 +4186,7 @@ static int do_lxcapi_snapshot(struct lxc_container *c, const char *commentfile)
/* $p / $name / comment \0 */
int len = strlen(snappath) + strlen(newname) + 10;
char *path = alloca(len);
+
sprintf(path, "%s/%s/comment", snappath, newname);
return copy_file(commentfile, path) < 0 ? -1 : i;
}
@@ -4100,6 +4217,7 @@ static char *get_snapcomment_path(char* snappath, char *name)
s = NULL;
}
}
+
return s;
}
@@ -4112,9 +4230,11 @@ static char *get_timestamp(char* snappath, char *name)
ret = snprintf(path, MAXPATHLEN, "%s/%s/ts", snappath, name);
if (ret < 0 || ret >= MAXPATHLEN)
return NULL;
+
fin = fopen(path, "r");
if (!fin)
return NULL;
+
(void) fseek(fin, 0, SEEK_END);
len = ftell(fin);
(void) fseek(fin, 0, SEEK_SET);
@@ -4129,6 +4249,7 @@ static char *get_timestamp(char* snappath, char *name)
}
}
}
+
fclose(fin);
return s;
}
@@ -4148,9 +4269,10 @@ static int do_lxcapi_snapshot_list(struct lxc_container *c, struct lxc_snapshot
ERROR("path name too long");
return -1;
}
+
dir = opendir(snappath);
if (!dir) {
- INFO("failed to open %s - assuming no snapshots", snappath);
+ INFO("Failed to open %s - assuming no snapshots", snappath);
return 0;
}
@@ -4166,30 +4288,35 @@ static int do_lxcapi_snapshot_list(struct lxc_container *c, struct lxc_snapshot
ERROR("pathname too long");
goto out_free;
}
+
if (!file_exists(path2))
continue;
+
nsnaps = realloc(snaps, (count + 1)*sizeof(*snaps));
if (!nsnaps) {
SYSERROR("Out of memory");
goto out_free;
}
+
snaps = nsnaps;
snaps[count].free = lxcsnap_free;
snaps[count].name = strdup(direntp->d_name);
if (!snaps[count].name)
goto out_free;
+
snaps[count].lxcpath = strdup(snappath);
if (!snaps[count].lxcpath) {
free(snaps[count].name);
goto out_free;
}
+
snaps[count].comment_pathname = get_snapcomment_path(snappath, direntp->d_name);
snaps[count].timestamp = get_timestamp(snappath, direntp->d_name);
count++;
}
if (closedir(dir))
- WARN("failed to close directory");
+ WARN("Failed to close directory");
*ret_snaps = snaps;
return count;
@@ -4197,12 +4324,16 @@ static int do_lxcapi_snapshot_list(struct lxc_container *c, struct lxc_snapshot
out_free:
if (snaps) {
int i;
+
for (i=0; i<count; i++)
lxcsnap_free(&snaps[i]);
+
free(snaps);
}
+
if (closedir(dir))
- WARN("failed to close directory");
+ WARN("Failed to close directory");
+
return -1;
}
@@ -4250,8 +4381,10 @@ static bool do_lxcapi_snapshot_restore(struct lxc_container *c, const char *snap
snap = lxc_container_new(snapname, clonelxcpath);
if (!snap || !lxcapi_is_defined(snap)) {
ERROR("Could not open snapshot %s", snapname);
+
if (snap)
lxc_container_put(snap);
+
storage_put(bdev);
return false;
}
@@ -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"))
flags |= LXC_STORAGE_INTERNAL_OVERLAY_RESTORE;
+
rest = lxcapi_clone(snap, newname, c->config_path, flags, bdev->type,
NULL, 0, NULL);
storage_put(bdev);
if (rest && lxcapi_is_defined(rest))
b = true;
+
if (rest)
lxc_container_put(rest);
@@ -4299,11 +4434,13 @@ static bool do_snapshot_destroy(const char *snapname, const char *clonelxcpath)
ERROR("Could not destroy snapshot %s", snapname);
goto err;
}
+
bret = true;
err:
if (snap)
lxc_container_put(snap);
+
return bret;
}
@@ -4318,11 +4455,14 @@ static bool remove_all_snapshots(const char *path)
SYSERROR("opendir on snapshot path %s", path);
return false;
}
+
while ((direntp = readdir(dir))) {
if (!strcmp(direntp->d_name, "."))
continue;
+
if (!strcmp(direntp->d_name, ".."))
continue;
+
if (!do_snapshot_destroy(direntp->d_name, path)) {
bret = false;
continue;
@@ -4507,6 +4647,7 @@ static bool do_lxcapi_add_device_node(struct lxc_container *c, const char *src_p
ERROR(LXC_UNPRIV_EOPNOTSUPP, __FUNCTION__);
return false;
}
+
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
ERROR(LXC_UNPRIV_EOPNOTSUPP, __FUNCTION__);
return 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,
ERROR("Network device \"%s\" not found", ifname);
else
ERROR("Failed to remove network device \"%s\"", ifname);
+
_exit(EXIT_FAILURE);
}
@@ -4654,11 +4797,10 @@ static int do_lxcapi_migrate(struct lxc_container *c, unsigned int cmd,
addr = (void *)opts + sizeof(*opts);
end = (void *)opts + size;
- for (; addr < end; addr++) {
- if (*addr) {
+
+ for (; addr < end; addr++)
+ if (*addr)
return -E2BIG;
- }
- }
}
/* If the caller has a smaller struct, let's zero out the end for them
@@ -4680,6 +4822,7 @@ static int do_lxcapi_migrate(struct lxc_container *c, unsigned int cmd,
ERROR("container is not running");
goto on_error;
}
+
ret = !__criu_pre_dump(c, valid_opts);
break;
case MIGRATE_DUMP:
@@ -4687,6 +4830,7 @@ static int do_lxcapi_migrate(struct lxc_container *c, unsigned int cmd,
ERROR("container is not running");
goto on_error;
}
+
ret = !__criu_dump(c, valid_opts);
break;
case MIGRATE_RESTORE:
@@ -4694,6 +4838,7 @@ static int do_lxcapi_migrate(struct lxc_container *c, unsigned int cmd,
ERROR("container is already running");
goto on_error;
}
+
ret = !__criu_restore(c, valid_opts);
break;
case MIGRATE_FEATURE_CHECK:
@@ -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);
free((void*)argv);
+
out:
current_config = NULL;
return ret;
@@ -4796,7 +4942,6 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath
c->config_path = strdup(configpath);
else
c->config_path = strdup(lxc_global_config_value("lxc.lxcpath"));
-
if (!c->config_path) {
fprintf(stderr, "Failed to allocate memory for %s\n", name);
goto err;
@@ -4840,6 +4985,7 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath
container_destroy(c, NULL);
lxcapi_clear_config(c);
}
+
c->daemonize = true;
c->pidfile = NULL;
@@ -4914,6 +5060,7 @@ int lxc_get_wait_states(const char **states)
if (states)
for (i=0; i<MAX_STATE; i++)
states[i] = lxc_state2str(i);
+
return MAX_STATE;
}
@@ -4939,6 +5086,7 @@ int list_defined_containers(const char *lxcpath, char ***names, struct lxc_conta
if (cret)
*cret = NULL;
+
if (names)
*names = NULL;
@@ -4950,10 +5098,10 @@ int list_defined_containers(const char *lxcpath, char ***names, struct lxc_conta
if (!config_file_exists(lxcpath, direntp->d_name))
continue;
- if (names) {
+ if (names)
if (!add_to_array(names, direntp->d_name, cfound))
goto free_bad;
- }
+
cfound++;
if (!cret) {
@@ -4965,17 +5113,22 @@ int list_defined_containers(const char *lxcpath, char ***names, struct lxc_conta
if (!c) {
INFO("Container %s:%s has a config but could not be loaded",
lxcpath, direntp->d_name);
+
if (names)
if(!remove_from_array(names, direntp->d_name, cfound--))
goto free_bad;
+
continue;
}
+
if (!do_lxcapi_is_defined(c)) {
INFO("Container %s:%s has a config but is not defined",
lxcpath, direntp->d_name);
+
if (names)
if(!remove_from_array(names, direntp->d_name, cfound--))
goto free_bad;
+
lxc_container_put(c);
continue;
}
@@ -4984,6 +5137,7 @@ int list_defined_containers(const char *lxcpath, char ***names, struct lxc_conta
lxc_container_put(c);
goto free_bad;
}
+
nfound++;
}
@@ -4996,11 +5150,13 @@ int list_defined_containers(const char *lxcpath, char ***names, struct lxc_conta
free((*names)[i]);
free(*names);
}
+
if (cret && *cret) {
for (i=0; i<nfound; i++)
lxc_container_put((*cret)[i]);
free(*cret);
}
+
closedir(dir);
return -1;
}
@@ -5022,6 +5178,7 @@ int list_active_containers(const char *lxcpath, char ***nret,
if (cret)
*cret = NULL;
+
if (nret)
*nret = NULL;
@@ -5030,16 +5187,17 @@ int list_active_containers(const char *lxcpath, char ***nret,
return -1;
while (getline(&line, &len, f) != -1) {
-
char *p = strrchr(line, ' '), *p2;
if (!p)
continue;
p++;
+
if (*p != 0x40)
continue;
p++;
is_hashed = false;
+
if (strncmp(p, lxcpath, lxcpath_len) == 0) {
p += lxcpath_len;
} else if (strncmp(p, "lxc/", 4) == 0) {
@@ -5062,11 +5220,13 @@ int list_active_containers(const char *lxcpath, char ***nret,
char *recvpath = lxc_cmd_get_lxcpath(p);
if (!recvpath)
continue;
+
if (strncmp(lxcpath, recvpath, lxcpath_len) != 0) {
free(recvpath);
continue;
}
free(recvpath);
+
p = lxc_cmd_get_name(p);
if (!p)
continue;
@@ -5096,9 +5256,11 @@ int list_active_containers(const char *lxcpath, char ***nret,
if (!c) {
INFO("Container %s:%s is running but could not be loaded",
lxcpath, p);
+
remove_from_array(&ct_name, p, ct_name_cnt--);
if (is_hashed)
free(p);
+
continue;
}
@@ -5115,6 +5277,7 @@ int list_active_containers(const char *lxcpath, char ***nret,
lxc_container_put(c);
goto free_cret_list;
}
+
cret_cnt++;
}
@@ -5129,6 +5292,7 @@ int list_active_containers(const char *lxcpath, char ***nret,
*nret = ct_name;
else
goto free_ct_name;
+
goto out;
free_cret_list:
@@ -5147,7 +5311,6 @@ int list_active_containers(const char *lxcpath, char ***nret,
out:
free(line);
-
fclose(f);
return ret;
}
@@ -5176,11 +5339,14 @@ int list_all_containers(const char *lxcpath, char ***nret,
ret = -1;
goto free_active_name;
}
+
ct_cnt++;
}
+
free(active_name[i]);
active_name[i] = NULL;
}
+
free(active_name);
active_name = NULL;
active_cnt = 0;
@@ -5200,18 +5366,20 @@ int list_all_containers(const char *lxcpath, char ***nret,
ret = -1;
goto free_ct_list;
}
+
ct_list_cnt++;
}
if (cret)
*cret = ct_list;
- if (nret)
+ if (nret) {
*nret = ct_name;
- else {
+ } else {
ret = ct_cnt;
goto free_ct_name;
}
+
return ct_cnt;
free_ct_list:
From 9044b79e191a09f9a6a41138e54a5fbf579a0a1a Mon Sep 17 00:00:00 2001
From: 2xsec <dh48.jeong at samsung.com>
Date: Sat, 21 Jul 2018 02:41:53 +0900
Subject: [PATCH 3/3] af_unix: fix return value & cleanups
Signed-off-by: 2xsec <dh48.jeong at samsung.com>
---
src/lxc/af_unix.c | 31 +++++++++++--------
src/lxc/af_unix.h | 2 +-
src/lxc/attach.c | 15 +++++++--
src/lxc/cmd/lxc_monitord.c | 76 +++++++++++++++++++++++++++-------------------
src/lxc/commands.c | 37 +++++++++++-----------
src/lxc/start.c | 21 +++++++++----
6 files changed, 111 insertions(+), 71 deletions(-)
diff --git a/src/lxc/af_unix.c b/src/lxc/af_unix.c
index 86f1fe9fd..0afc6590c 100644
--- a/src/lxc/af_unix.c
+++ b/src/lxc/af_unix.c
@@ -74,30 +74,28 @@ int lxc_abstract_unix_open(const char *path, int type, int flags)
ret = bind(fd, (struct sockaddr *)&addr,
offsetof(struct sockaddr_un, sun_path) + len + 1);
if (ret < 0) {
- int tmp = errno;
+ int saved_erron = errno;
close(fd);
- errno = tmp;
+ errno = saved_erron;
return -1;
}
if (type == SOCK_STREAM) {
ret = listen(fd, 100);
if (ret < 0) {
- int tmp = errno;
+ int saved_erron = errno;
close(fd);
- errno = tmp;
+ errno = saved_erron;
return -1;
}
-
}
return fd;
}
-int lxc_abstract_unix_close(int fd)
+void lxc_abstract_unix_close(int fd)
{
close(fd);
- return 0;
}
int lxc_abstract_unix_connect(const char *path)
@@ -128,7 +126,9 @@ int lxc_abstract_unix_connect(const char *path)
ret = connect(fd, (struct sockaddr *)&addr,
offsetof(struct sockaddr_un, sun_path) + len + 1);
if (ret < 0) {
+ int saved_errno = errno;
close(fd);
+ errno = saved_errno;
return -1;
}
@@ -150,8 +150,10 @@ int lxc_abstract_unix_send_fds(int fd, int *sendfds, int num_sendfds,
memset(&iov, 0, sizeof(iov));
cmsgbuf = malloc(cmsgbufsize);
- if (!cmsgbuf)
+ if (!cmsgbuf) {
+ errno = ENOMEM;
return -1;
+ }
msg.msg_control = cmsgbuf;
msg.msg_controllen = cmsgbufsize;
@@ -190,8 +192,10 @@ int lxc_abstract_unix_recv_fds(int fd, int *recvfds, int num_recvfds,
memset(&iov, 0, sizeof(iov));
cmsgbuf = malloc(cmsgbufsize);
- if (!cmsgbuf)
+ if (!cmsgbuf) {
+ errno = ENOMEM;
return -1;
+ }
msg.msg_control = cmsgbuf;
msg.msg_controllen = cmsgbufsize;
@@ -209,9 +213,8 @@ int lxc_abstract_unix_recv_fds(int fd, int *recvfds, int num_recvfds,
memset(recvfds, -1, num_recvfds * sizeof(int));
if (cmsg && cmsg->cmsg_len == CMSG_LEN(num_recvfds * sizeof(int)) &&
- cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
+ cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS)
memcpy(recvfds, CMSG_DATA(cmsg), num_recvfds * sizeof(int));
- }
out:
free(cmsgbuf);
@@ -281,10 +284,12 @@ int lxc_abstract_unix_rcv_credential(int fd, void *data, size_t size)
memcpy(&cred, CMSG_DATA(cmsg), sizeof(cred));
if (cred.uid &&
(cred.uid != getuid() || cred.gid != getgid())) {
- INFO("message denied for '%d/%d'", cred.uid, cred.gid);
- return -EACCES;
+ INFO("Message denied for '%d/%d'", cred.uid, cred.gid);
+ errno = EACCES;
+ return -1;
}
}
+
out:
return ret;
}
diff --git a/src/lxc/af_unix.h b/src/lxc/af_unix.h
index 9dfccd16e..f2c2fdcc6 100644
--- a/src/lxc/af_unix.h
+++ b/src/lxc/af_unix.h
@@ -28,7 +28,7 @@
/* does not enforce \0-termination */
extern int lxc_abstract_unix_open(const char *path, int type, int flags);
-extern int lxc_abstract_unix_close(int fd);
+extern void lxc_abstract_unix_close(int fd);
/* does not enforce \0-termination */
extern int lxc_abstract_unix_connect(const char *path);
extern int lxc_abstract_unix_send_fds(int fd, int *sendfds, int num_sendfds,
diff --git a/src/lxc/attach.c b/src/lxc/attach.c
index 8ac83a6c9..9bc3e23d1 100644
--- a/src/lxc/attach.c
+++ b/src/lxc/attach.c
@@ -828,8 +828,13 @@ static int attach_child_main(struct attach_clone_payload *payload)
*/
if (needs_lsm) {
ret = lxc_abstract_unix_recv_fds(payload->ipc_socket, &lsm_fd, 1, NULL, 0);
- if (ret <= 0)
+ if (ret <= 0) {
+ if (ret < 0)
+ SYSERROR("Failed to receive lsm label fd");
+
goto on_error;
+ }
+
TRACE("Received LSM label file descriptor %d from parent", lsm_fd);
}
@@ -1330,11 +1335,15 @@ int lxc_attach(const char *name, const char *lxcpath,
/* Send child fd of the LSM security module to write to. */
ret = lxc_abstract_unix_send_fds(ipc_sockets[0], &labelfd, 1, NULL, 0);
- close(labelfd);
if (ret <= 0) {
- SYSERROR("%d", (int)ret);
+ if (ret < 0)
+ SYSERROR("Failed to send lsm label fd");
+
+ close(labelfd);
goto close_mainloop;
}
+
+ close(labelfd);
TRACE("Sent LSM label file descriptor %d to child", labelfd);
}
diff --git a/src/lxc/cmd/lxc_monitord.c b/src/lxc/cmd/lxc_monitord.c
index 298f431ef..38eee0a9b 100644
--- a/src/lxc/cmd/lxc_monitord.c
+++ b/src/lxc/cmd/lxc_monitord.c
@@ -97,8 +97,8 @@ static int lxc_monitord_fifo_create(struct lxc_monitor *mon)
mon->fifofd = open(fifo_path, O_RDWR);
if (mon->fifofd < 0) {
+ SYSERROR("Failed to open monitor fifo %s", fifo_path);
unlink(fifo_path);
- ERROR("Failed to open monitor fifo.");
return -1;
}
@@ -106,12 +106,14 @@ static int lxc_monitord_fifo_create(struct lxc_monitor *mon)
lk.l_whence = SEEK_SET;
lk.l_start = 0;
lk.l_len = 0;
+
if (fcntl(mon->fifofd, F_SETLK, &lk) != 0) {
/* another lxc-monitord is already running, don't start up */
- DEBUG("lxc-monitord already running on lxcpath %s.", mon->lxcpath);
+ SYSDEBUG("lxc-monitord already running on lxcpath %s", mon->lxcpath);
close(mon->fifofd);
return -1;
}
+
return 0;
}
@@ -132,15 +134,15 @@ static void lxc_monitord_sockfd_remove(struct lxc_monitor *mon, int fd) {
int i;
if (lxc_mainloop_del_handler(&mon->descr, fd))
- CRIT("File descriptor %d not found in mainloop.", fd);
+ CRIT("File descriptor %d not found in mainloop", fd);
close(fd);
- for (i = 0; i < mon->clientfds_cnt; i++) {
+ for (i = 0; i < mon->clientfds_cnt; i++)
if (mon->clientfds[i] == fd)
break;
- }
+
if (i >= mon->clientfds_cnt) {
- CRIT("File descriptor %d not found in clients array.", fd);
+ CRIT("File descriptor %d not found in clients array", fd);
lxc_monitord_cleanup();
exit(EXIT_FAILURE);
}
@@ -166,6 +168,7 @@ static int lxc_monitord_sock_handler(int fd, uint32_t events, void *data,
if (events & EPOLLHUP)
lxc_monitord_sockfd_remove(mon, fd);
+
return quit;
}
@@ -180,53 +183,55 @@ static int lxc_monitord_sock_accept(int fd, uint32_t events, void *data,
ret = LXC_MAINLOOP_ERROR;
clientfd = accept(fd, NULL, 0);
if (clientfd < 0) {
- SYSERROR("Failed to accept connection for client file descriptor %d.", fd);
+ SYSERROR("Failed to accept connection for client file descriptor %d", fd);
goto out;
}
if (fcntl(clientfd, F_SETFD, FD_CLOEXEC)) {
- SYSERROR("Failed to set FD_CLOEXEC on client socket connection %d.", clientfd);
+ SYSERROR("Failed to set FD_CLOEXEC on client socket connection %d", clientfd);
goto err1;
}
- if (getsockopt(clientfd, SOL_SOCKET, SO_PEERCRED, &cred, &credsz))
- {
- ERROR("Failed to get credentials on client socket connection %d.", clientfd);
+ if (getsockopt(clientfd, SOL_SOCKET, SO_PEERCRED, &cred, &credsz)) {
+ SYSERROR("Failed to get credentials on client socket connection %d", clientfd);
goto err1;
}
+
if (cred.uid && cred.uid != geteuid()) {
- WARN("Monitor denied for uid %d on client socket connection %d.", cred.uid, clientfd);
- ret = -EACCES;
+ WARN("Monitor denied for uid %d on client socket connection %d", cred.uid, clientfd);
goto err1;
}
if (mon->clientfds_cnt + 1 > mon->clientfds_size) {
int *clientfds;
+
clientfds = realloc(mon->clientfds,
(mon->clientfds_size + CLIENTFDS_CHUNK) * sizeof(mon->clientfds[0]));
if (clientfds == NULL) {
- ERROR("Failed to realloc memory for %d client file "
- "descriptors.",
+ ERROR("Failed to realloc memory for %d client file descriptors",
mon->clientfds_size + CLIENTFDS_CHUNK);
goto err1;
}
+
mon->clientfds = clientfds;
mon->clientfds_size += CLIENTFDS_CHUNK;
}
ret = lxc_mainloop_add_handler(&mon->descr, clientfd,
lxc_monitord_sock_handler, mon);
- if (ret) {
- ERROR("Failed to add socket handler.");
+ if (ret < 0) {
+ ERROR("Failed to add socket handler");
goto err1;
}
mon->clientfds[mon->clientfds_cnt++] = clientfd;
- INFO("Accepted client file descriptor %d. Number of accepted file descriptors is now %d.", clientfd, mon->clientfds_cnt);
+ INFO("Accepted client file descriptor %d. Number of accepted file descriptors is now %d",
+ clientfd, mon->clientfds_cnt);
goto out;
err1:
close(clientfd);
+
out:
return ret;
}
@@ -255,8 +260,10 @@ static int lxc_monitord_sock_delete(struct lxc_monitor *mon)
if (lxc_monitor_sock_name(mon->lxcpath, &addr) < 0)
return -1;
+
if (addr.sun_path[0])
unlink(addr.sun_path);
+
return 0;
}
@@ -268,8 +275,7 @@ static int lxc_monitord_create(struct lxc_monitor *mon)
if (ret < 0)
return ret;
- ret = lxc_monitord_sock_create(mon);
- return ret;
+ return lxc_monitord_sock_create(mon);
}
static void lxc_monitord_delete(struct lxc_monitor *mon)
@@ -277,7 +283,7 @@ static void lxc_monitord_delete(struct lxc_monitor *mon)
int i;
lxc_mainloop_del_handler(&mon->descr, mon->listenfd);
- close(mon->listenfd);
+ lxc_abstract_unix_close(mon->listenfd);
lxc_monitord_sock_delete(mon);
lxc_mainloop_del_handler(&mon->descr, mon->fifofd);
@@ -288,6 +294,7 @@ static void lxc_monitord_delete(struct lxc_monitor *mon)
lxc_mainloop_del_handler(&mon->descr, mon->clientfds[i]);
close(mon->clientfds[i]);
}
+
mon->clientfds_cnt = 0;
}
@@ -321,14 +328,14 @@ static int lxc_monitord_mainloop_add(struct lxc_monitor *mon)
ret = lxc_mainloop_add_handler(&mon->descr, mon->fifofd,
lxc_monitord_fifo_handler, mon);
if (ret < 0) {
- ERROR("Failed to add to mainloop monitor handler for fifo.");
+ ERROR("Failed to add to mainloop monitor handler for fifo");
return -1;
}
ret = lxc_mainloop_add_handler(&mon->descr, mon->listenfd,
lxc_monitord_sock_accept, mon);
if (ret < 0) {
- ERROR("Failed to add to mainloop monitor handler for listen socket.");
+ ERROR("Failed to add to mainloop monitor handler for listen socket");
return -1;
}
@@ -374,9 +381,10 @@ int main(int argc, char *argv[])
log.prefix = "lxc-monitord";
log.quiet = 0;
log.lxcpath = lxcpath;
+
ret = lxc_log_init(&log);
if (ret)
- INFO("Failed to open log file %s, log will be lost.", lxcpath);
+ INFO("Failed to open log file %s, log will be lost", lxcpath);
lxc_log_options_no_override();
if (lxc_safe_int(argv[2], &pipefd) < 0)
@@ -388,7 +396,7 @@ int main(int argc, char *argv[])
sigdelset(&mask, SIGBUS) ||
sigdelset(&mask, SIGTERM) ||
pthread_sigmask(SIG_BLOCK, &mask, NULL)) {
- SYSERROR("Failed to set signal mask.");
+ SYSERROR("Failed to set signal mask");
exit(EXIT_FAILURE);
}
@@ -401,10 +409,11 @@ int main(int argc, char *argv[])
goto on_signal;
ret = EXIT_FAILURE;
+
memset(&mon, 0, sizeof(mon));
mon.lxcpath = lxcpath;
if (lxc_mainloop_open(&mon.descr)) {
- ERROR("Failed to create mainloop.");
+ ERROR("Failed to create mainloop");
goto on_error;
}
mainloop_opened = true;
@@ -424,33 +433,38 @@ int main(int argc, char *argv[])
close(pipefd);
if (lxc_monitord_mainloop_add(&mon)) {
- ERROR("Failed to add mainloop handlers.");
+ ERROR("Failed to add mainloop handlers");
goto on_error;
}
- NOTICE("lxc-monitord with pid %d is now monitoring lxcpath %s.",
+ NOTICE("lxc-monitord with pid %d is now monitoring lxcpath %s",
lxc_raw_getpid(), mon.lxcpath);
+
for (;;) {
ret = lxc_mainloop(&mon.descr, 1000 * 30);
if (ret) {
ERROR("mainloop returned an error");
break;
}
+
if (mon.clientfds_cnt <= 0) {
- NOTICE("No remaining clients. lxc-monitord is exiting.");
+ NOTICE("No remaining clients. lxc-monitord is exiting");
break;
}
- if (quit == 1) {
- NOTICE("got quit command. lxc-monitord is exitting.");
+
+ if (quit == LXC_MAINLOOP_CLOSE) {
+ NOTICE("Got quit command. lxc-monitord is exitting");
break;
}
}
on_signal:
ret = EXIT_SUCCESS;
+
on_error:
if (monitord_created)
lxc_monitord_cleanup();
+
if (mainloop_opened)
lxc_mainloop_close(&mon.descr);
diff --git a/src/lxc/commands.c b/src/lxc/commands.c
index 9bf96fa8d..30d6b6047 100644
--- a/src/lxc/commands.c
+++ b/src/lxc/commands.c
@@ -240,18 +240,21 @@ static int lxc_cmd_send(const char *name, struct lxc_cmd_rr *cmd,
ret = lxc_abstract_unix_send_credential(client_fd, &cmd->req,
sizeof(cmd->req));
- if (ret < 0 || (size_t)ret != sizeof(cmd->req)) {
- close(client_fd);
-
- if (errno == EPIPE)
+ if (ret < 0 ) {
+ if (errno == EPIPE) {
+ close(client_fd);
return -EPIPE;
-
- if (ret >= 0)
- return -EMSGSIZE;
+ }
+ close(client_fd);
return -1;
}
+ if ((size_t)ret != sizeof(cmd->req)) {
+ close(client_fd);
+ return -EMSGSIZE;
+ }
+
if (cmd->req.datalen <= 0)
return client_fd;
@@ -754,7 +757,7 @@ static int lxc_cmd_console_callback(int fd, struct lxc_cmd_req *req,
rsp.data = INT_TO_PTR(ttynum);
ret = lxc_abstract_unix_send_fds(fd, &masterfd, 1, &rsp, sizeof(rsp));
if (ret < 0) {
- ERROR("Failed to send tty to client");
+ SYSERROR("Failed to send tty to client");
lxc_terminal_free(handler->conf, fd);
goto out_close;
}
@@ -1112,17 +1115,17 @@ static int lxc_cmd_handler(int fd, uint32_t events, void *data,
struct lxc_handler *handler = data;
ret = lxc_abstract_unix_rcv_credential(fd, &req, sizeof(req));
- if (ret == -EACCES) {
- /* We don't care for the peer, just send and close. */
- struct lxc_cmd_rsp rsp = {.ret = ret};
-
- lxc_cmd_rsp_send(fd, &rsp);
- goto out_close;
- }
-
if (ret < 0) {
SYSERROR("Failed to receive data on command socket for command "
- "\"%s\"", lxc_cmd_str(req.cmd));
+ "\"%s\"", lxc_cmd_str(req.cmd));
+
+ if (errno == EACCES) {
+ /* We don't care for the peer, just send and close. */
+ struct lxc_cmd_rsp rsp = {.ret = ret};
+
+ lxc_cmd_rsp_send(fd, &rsp);
+ }
+
goto out_close;
}
diff --git a/src/lxc/start.c b/src/lxc/start.c
index 180a37ab4..a970d3c15 100644
--- a/src/lxc/start.c
+++ b/src/lxc/start.c
@@ -490,11 +490,17 @@ static int lxc_serve_state_socket_pair(const char *name,
again:
ret = lxc_abstract_unix_send_credential(handler->state_socket_pair[1],
&(int){state}, sizeof(int));
- if (ret != sizeof(int)) {
+ if (ret < 0) {
+ SYSERROR("Failed to send state to %d", handler->state_socket_pair[1]);
+
if (errno == EINTR)
goto again;
- SYSERROR("Failed to send state to %d",
- handler->state_socket_pair[1]);
+
+ return -1;
+ }
+
+ if (ret != sizeof(int)) {
+ ERROR("Message too long : %d", handler->state_socket_pair[1]);
return -1;
}
@@ -649,7 +655,7 @@ void lxc_free_handler(struct lxc_handler *handler)
if (handler->conf && handler->conf->reboot == REBOOT_NONE)
if (handler->conf->maincmd_fd >= 0)
- close(handler->conf->maincmd_fd);
+ lxc_abstract_unix_close(handler->conf->maincmd_fd);
if (handler->state_socket_pair[0] >= 0)
close(handler->state_socket_pair[0]);
@@ -671,6 +677,7 @@ struct lxc_handler *lxc_init_handler(const char *name, struct lxc_conf *conf,
handler = malloc(sizeof(*handler));
if (!handler)
return NULL;
+
memset(handler, 0, sizeof(*handler));
/* Note that am_guest_unpriv() checks the effective uid. We
@@ -704,6 +711,7 @@ struct lxc_handler *lxc_init_handler(const char *name, struct lxc_conf *conf,
ERROR("Failed to create anonymous pair of unix sockets");
goto on_error;
}
+
TRACE("Created anonymous pair {%d,%d} of unix sockets",
handler->state_socket_pair[0],
handler->state_socket_pair[1]);
@@ -716,6 +724,7 @@ struct lxc_handler *lxc_init_handler(const char *name, struct lxc_conf *conf,
goto on_error;
}
}
+
TRACE("Unix domain socket %d for command server is ready",
handler->conf->maincmd_fd);
@@ -866,7 +875,7 @@ int lxc_init(const char *name, struct lxc_handler *handler)
out_aborting:
(void)lxc_set_state(name, handler, ABORTING);
out_close_maincmd_fd:
- close(conf->maincmd_fd);
+ lxc_abstract_unix_close(conf->maincmd_fd);
conf->maincmd_fd = -1;
return -1;
}
@@ -953,7 +962,7 @@ void lxc_fini(const char *name, struct lxc_handler *handler)
* the command socket causing a new process to get ECONNREFUSED
* because we haven't yet closed the command socket.
*/
- close(handler->conf->maincmd_fd);
+ lxc_abstract_unix_close(handler->conf->maincmd_fd);
handler->conf->maincmd_fd = -1;
TRACE("Closed command socket");
More information about the lxc-devel
mailing list