out:
cap_free(caps);
- return 0;
+ return 0;
}
int lxc_caps_up(void)
out:
cap_free(caps);
- return 0;
+ return 0;
}
int lxc_caps_init(void)
extern int lxc_caps_last_cap(void);
#else
static inline int lxc_caps_down(void) {
- return 0;
+ return 0;
}
static inline int lxc_caps_up(void) {
- return 0;
+ return 0;
}
static inline int lxc_caps_init(void) {
- return 0;
+ return 0;
}
static inline int lxc_caps_last_cap(void) {
- return 0;
+ return 0;
}
#endif
static void cgm_dbus_disconnect(void)
{
- if (cgroup_manager) {
- dbus_connection_flush(cgroup_manager->connection);
- dbus_connection_close(cgroup_manager->connection);
- nih_free(cgroup_manager);
- }
- cgroup_manager = NULL;
- cgm_unlock();
+ if (cgroup_manager) {
+ dbus_connection_flush(cgroup_manager->connection);
+ dbus_connection_close(cgroup_manager->connection);
+ nih_free(cgroup_manager);
+ }
+ cgroup_manager = NULL;
+ cgm_unlock();
}
#define CGMANAGER_DBUS_SOCK "unix:path=/sys/fs/cgroup/cgmanager/sock"
/* in case several groups are specified in a single line
* split these groups in a single element for the list */
for (groupptr = groups;;groupptr = NULL) {
- token = strtok_r(groupptr, " \t", &sptr);
- if (!token) {
+ token = strtok_r(groupptr, " \t", &sptr);
+ if (!token) {
ret = 0;
- break;
+ break;
}
grouplist = malloc(sizeof(*grouplist));
}
lxc_list_add_tail(&lxc_conf->groups, grouplist);
- }
+ }
free(groups);
}
for (autoptr = autos; ; autoptr = NULL) {
- token = strtok_r(autoptr, " \t", &sptr);
- if (!token) {
+ token = strtok_r(autoptr, " \t", &sptr);
+ if (!token) {
ret = 0;
- break;
+ break;
}
for (i = 0; allowed_auto_mounts[i].token; i++) {
lxc_conf->auto_mounts &= ~allowed_auto_mounts[i].mask;
lxc_conf->auto_mounts |= allowed_auto_mounts[i].flag;
- }
+ }
free(autos);
/* in case several capability keep is specified in a single line
* split these caps in a single element for the list */
for (keepptr = keepcaps;;keepptr = NULL) {
- token = strtok_r(keepptr, " \t", &sptr);
- if (!token) {
+ token = strtok_r(keepptr, " \t", &sptr);
+ if (!token) {
ret = 0;
- break;
+ break;
}
if (!strcmp(token, "none"))
}
lxc_list_add_tail(&lxc_conf->keepcaps, keeplist);
- }
+ }
free(keepcaps);
/* in case several capability drop is specified in a single line
* split these caps in a single element for the list */
for (dropptr = dropcaps;;dropptr = NULL) {
- token = strtok_r(dropptr, " \t", &sptr);
- if (!token) {
+ token = strtok_r(dropptr, " \t", &sptr);
+ if (!token) {
ret = 0;
- break;
+ break;
}
droplist = malloc(sizeof(*droplist));
}
lxc_list_add_tail(&lxc_conf->caps, droplist);
- }
+ }
free(dropcaps);
/* for the sake of backward compatibility, drop all privileges
if none is specified */
for (i = 0; all_privs[i].token; i++) {
- *flags |= all_privs[i].flag;
+ *flags |= all_privs[i].flag;
}
return 0;
}
request->nlmsghdr.nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
request->nlmsghdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
- request->nlmsghdr.nlmsg_type = GENL_ID_CTRL;
+ request->nlmsghdr.nlmsg_type = GENL_ID_CTRL;
genlmsghdr = NLMSG_DATA(&request->nlmsghdr);
- genlmsghdr->cmd = CTRL_CMD_GETFAMILY;
+ genlmsghdr->cmd = CTRL_CMD_GETFAMILY;
ret = netlink_open(&handler, NETLINK_GENERIC);
if (ret)
static inline int genetlink_len(const struct genlmsg *genlmsg)
{
- return ((genlmsg->nlmsghdr.nlmsg_len) - GENL_HDRLEN - NLMSG_HDRLEN);
+ return ((genlmsg->nlmsghdr.nlmsg_len) - GENL_HDRLEN - NLMSG_HDRLEN);
}
/*
struct lxc_list *prev,
struct lxc_list *next)
{
- next->prev = new;
- new->next = next;
- new->prev = prev;
- prev->next = new;
+ next->prev = new;
+ new->next = next;
+ new->prev = prev;
+ prev->next = new;
}
static inline void lxc_list_add(struct lxc_list *head, struct lxc_list *list)
/* -s implies -e */
lxc_fill_elevated_privileges(NULL, &elevated_privileges);
break;
- case 500: /* clear-env */
- env_policy = LXC_ATTACH_CLEAR_ENV;
- break;
- case 501: /* keep-env */
- env_policy = LXC_ATTACH_KEEP_ENV;
- break;
+ case 500: /* clear-env */
+ env_policy = LXC_ATTACH_CLEAR_ENV;
+ break;
+ case 501: /* keep-env */
+ env_policy = LXC_ATTACH_KEEP_ENV;
+ break;
case 502: /* keep-var */
ret = add_to_simple_array(&extra_keep, &extra_keep_size, arg);
if (ret < 0) {
aargv = &argv[optind];
- /*
+ /*
* mask all the signals so we are safe to install a
* signal handler and to fork
*/
-L, --console-log=FILE Log container console output to FILE\n\
-C, --close-all-fds If any fds are inherited, close them\n\
If not specified, exit with failure instead\n\
- Note: --daemon implies --close-all-fds\n\
+ Note: --daemon implies --close-all-fds\n\
-s, --define KEY=VAL Assign VAL to configuration variable KEY\n\
--share-[net|ipc|uts]=NAME Share a namespace with another container or pid\n\
",
int *flags;
uid_t *uid;
bool setuid;
- int want_default_mounts;
- const char *want_hostname;
+ int want_default_mounts;
+ const char *want_hostname;
};
static int do_start(void *arg)
goto out;
}
} else if (!inc) {
- if ((fd = open(path, O_RDWR | O_CLOEXEC)) < 0)
- goto out;
-
- if (fstat(fd, &fbuf) < 0) {
- close(fd);
- goto out;
- }
-
- if (fbuf.st_size != 0) {
- /* write terminating \0-byte to file */
- if (pwrite(fd, "", 1, fbuf.st_size) <= 0) {
- close(fd);
- goto out;
- }
-
- buf = mmap(NULL, fbuf.st_size + 1, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
- if (buf == MAP_FAILED) {
- SYSERROR("Failed to create mapping %s", path);
- close(fd);
- goto out;
- }
-
- len = strlen(newpath);
- while ((del = strstr((char *)buf, newpath))) {
- memmove(del, del + len, strlen(del) - len + 1);
- bytes += len;
- }
-
- munmap(buf, fbuf.st_size + 1);
- if (ftruncate(fd, fbuf.st_size - bytes) < 0) {
- SYSERROR("Failed to truncate file %s", path);
- close(fd);
- goto out;
- }
- }
- close(fd);
- }
+ if ((fd = open(path, O_RDWR | O_CLOEXEC)) < 0)
+ goto out;
+
+ if (fstat(fd, &fbuf) < 0) {
+ close(fd);
+ goto out;
+ }
+
+ if (fbuf.st_size != 0) {
+ /* write terminating \0-byte to file */
+ if (pwrite(fd, "", 1, fbuf.st_size) <= 0) {
+ close(fd);
+ goto out;
+ }
+
+ buf = mmap(NULL, fbuf.st_size + 1, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (buf == MAP_FAILED) {
+ SYSERROR("Failed to create mapping %s", path);
+ close(fd);
+ goto out;
+ }
+
+ len = strlen(newpath);
+ while ((del = strstr((char *)buf, newpath))) {
+ memmove(del, del + len, strlen(del) - len + 1);
+ bytes += len;
+ }
+
+ munmap(buf, fbuf.st_size + 1);
+ if (ftruncate(fd, fbuf.st_size - bytes) < 0) {
+ SYSERROR("Failed to truncate file %s", path);
+ close(fd);
+ goto out;
+ }
+ }
+ close(fd);
+ }
/* If the lxc-snapshot file is empty, remove it. */
if (stat(path, &fbuf) < 0)
goto out;
- if (!fbuf.st_size) {
- remove(path);
+ if (!fbuf.st_size) {
+ remove(path);
}
}
}
static bool do_destroy_container(struct lxc_conf *conf) {
- if (am_unpriv()) {
- if (userns_exec_1(conf, bdev_destroy_wrapper, conf) < 0)
- return false;
- return true;
- }
- return bdev_destroy(conf);
+ if (am_unpriv()) {
+ if (userns_exec_1(conf, bdev_destroy_wrapper, conf) < 0)
+ return false;
+ return true;
+ }
+ return bdev_destroy(conf);
}
static int lxc_rmdir_onedev_wrapper(void *data)
}
}
- if (conf && conf->rootfs.path && conf->rootfs.mount) {
- if (!do_destroy_container(conf)) {
- ERROR("Error destroying rootfs for %s", c->name);
- goto out;
- }
- INFO("Destroyed rootfs for %s", c->name);
- }
+ if (conf && conf->rootfs.path && conf->rootfs.mount) {
+ if (!do_destroy_container(conf)) {
+ ERROR("Error destroying rootfs for %s", c->name);
+ goto out;
+ }
+ INFO("Destroyed rootfs for %s", c->name);
+ }
mod_all_rdeps(c, false);
ERROR("Error destroying container directory for %s", c->name);
goto out;
}
- INFO("Destroyed directory for %s", c->name);
+ INFO("Destroyed directory for %s", c->name);
bret = true;
if (!p)
return -1;
*p = '\0';
- ret = do_create_container_dir(path, conf);
+ ret = do_create_container_dir(path, conf);
*p = '/';
return ret;
}
* \brief Specifications for how to create a new backing store
*/
struct bdev_specs {
- char *fstype; /*!< Filesystem type */
- uint64_t fssize; /*!< Filesystem size in bytes */
- struct {
- char *zfsroot; /*!< ZFS root path */
- } zfs;
- struct {
- char *vg; /*!< LVM Volume Group name */
- char *lv; /*!< LVM Logical Volume name */
- char *thinpool; /*!< LVM thin pool to use, if any */
- } lvm;
- char *dir; /*!< Directory path */
+ char *fstype; /*!< Filesystem type */
+ uint64_t fssize; /*!< Filesystem size in bytes */
+ struct {
+ char *zfsroot; /*!< ZFS root path */
+ } zfs;
+ struct {
+ char *vg; /*!< LVM Volume Group name */
+ char *lv; /*!< LVM Logical Volume name */
+ char *thinpool; /*!< LVM thin pool to use, if any */
+ } lvm;
+ char *dir; /*!< Directory path */
};
/*!
extern int nla_put_string(struct nlmsg *nlmsg, int attr, const char *string)
{
- return nla_put(nlmsg, attr, string, strlen(string) + 1);
+ return nla_put(nlmsg, attr, string, strlen(string) + 1);
}
extern int nla_put_u32(struct nlmsg *nlmsg, int attr, int value)
extern int netlink_rcv(struct nl_handler *handler, struct nlmsg *answer)
{
int ret;
- struct sockaddr_nl nladdr;
- struct iovec iov = {
- .iov_base = answer->nlmsghdr,
- .iov_len = answer->nlmsghdr->nlmsg_len,
- };
+ struct sockaddr_nl nladdr;
+ struct iovec iov = {
+ .iov_base = answer->nlmsghdr,
+ .iov_len = answer->nlmsghdr->nlmsg_len,
+ };
struct msghdr msg = {
- .msg_name = &nladdr,
- .msg_namelen = sizeof(nladdr),
- .msg_iov = &iov,
- .msg_iovlen = 1,
- };
+ .msg_name = &nladdr,
+ .msg_namelen = sizeof(nladdr),
+ .msg_iov = &iov,
+ .msg_iovlen = 1,
+ };
- memset(&nladdr, 0, sizeof(nladdr));
- nladdr.nl_family = AF_NETLINK;
- nladdr.nl_pid = 0;
- nladdr.nl_groups = 0;
+ memset(&nladdr, 0, sizeof(nladdr));
+ nladdr.nl_family = AF_NETLINK;
+ nladdr.nl_pid = 0;
+ nladdr.nl_groups = 0;
again:
ret = recvmsg(handler->fd, &msg, 0);
extern int netlink_send(struct nl_handler *handler, struct nlmsg *nlmsg)
{
- struct sockaddr_nl nladdr;
- struct iovec iov = {
- .iov_base = nlmsg->nlmsghdr,
- .iov_len = nlmsg->nlmsghdr->nlmsg_len,
- };
+ struct sockaddr_nl nladdr;
+ struct iovec iov = {
+ .iov_base = nlmsg->nlmsghdr,
+ .iov_len = nlmsg->nlmsghdr->nlmsg_len,
+ };
struct msghdr msg = {
- .msg_name = &nladdr,
- .msg_namelen = sizeof(nladdr),
- .msg_iov = &iov,
- .msg_iovlen = 1,
- };
+ .msg_name = &nladdr,
+ .msg_namelen = sizeof(nladdr),
+ .msg_iov = &iov,
+ .msg_iovlen = 1,
+ };
int ret;
- memset(&nladdr, 0, sizeof(nladdr));
- nladdr.nl_family = AF_NETLINK;
- nladdr.nl_pid = 0;
- nladdr.nl_groups = 0;
+ memset(&nladdr, 0, sizeof(nladdr));
+ nladdr.nl_family = AF_NETLINK;
+ nladdr.nl_pid = 0;
+ nladdr.nl_groups = 0;
ret = sendmsg(handler->fd, &msg, 0);
if (ret < 0)
extern int netlink_open(struct nl_handler *handler, int protocol)
{
socklen_t socklen;
- int sndbuf = 32768;
- int rcvbuf = 32768;
+ int sndbuf = 32768;
+ int rcvbuf = 32768;
- memset(handler, 0, sizeof(*handler));
+ memset(handler, 0, sizeof(*handler));
- handler->fd = socket(AF_NETLINK, SOCK_RAW, protocol);
- if (handler->fd < 0)
- return -errno;
+ handler->fd = socket(AF_NETLINK, SOCK_RAW, protocol);
+ if (handler->fd < 0)
+ return -errno;
- if (setsockopt(handler->fd, SOL_SOCKET, SO_SNDBUF,
+ if (setsockopt(handler->fd, SOL_SOCKET, SO_SNDBUF,
&sndbuf, sizeof(sndbuf)) < 0)
- return -errno;
+ return -errno;
- if (setsockopt(handler->fd, SOL_SOCKET, SO_RCVBUF,
+ if (setsockopt(handler->fd, SOL_SOCKET, SO_RCVBUF,
&rcvbuf,sizeof(rcvbuf)) < 0)
- return -errno;
+ return -errno;
- memset(&handler->local, 0, sizeof(handler->local));
- handler->local.nl_family = AF_NETLINK;
- handler->local.nl_groups = 0;
+ memset(&handler->local, 0, sizeof(handler->local));
+ handler->local.nl_family = AF_NETLINK;
+ handler->local.nl_groups = 0;
- if (bind(handler->fd, (struct sockaddr*)&handler->local,
+ if (bind(handler->fd, (struct sockaddr*)&handler->local,
sizeof(handler->local)) < 0)
- return -errno;
+ return -errno;
- socklen = sizeof(handler->local);
- if (getsockname(handler->fd, (struct sockaddr*)&handler->local,
+ socklen = sizeof(handler->local);
+ if (getsockname(handler->fd, (struct sockaddr*)&handler->local,
&socklen) < 0)
- return -errno;
+ return -errno;
- if (socklen != sizeof(handler->local))
- return -EINVAL;
+ if (socklen != sizeof(handler->local))
+ return -EINVAL;
- if (handler->local.nl_family != AF_NETLINK)
- return -EINVAL;
+ if (handler->local.nl_family != AF_NETLINK)
+ return -EINVAL;
handler->seq = time(NULL);
- return 0;
+ return 0;
}
extern int netlink_close(struct nl_handler *handler)
* @peer: the peer address
*/
struct nl_handler {
- int fd;
+ int fd;
int seq;
- struct sockaddr_nl local;
- struct sockaddr_nl peer;
+ struct sockaddr_nl local;
+ struct sockaddr_nl peer;
};
/*
*/
static int container_reboot_supported(void *arg)
{
- int *cmd = arg;
+ int *cmd = arg;
int ret;
- ret = reboot(*cmd);
+ ret = reboot(*cmd);
if (ret == -1 && errno == EINVAL)
return 1;
return 0;
{
FILE *f;
int ret, cmd, v, flags;
- long stack_size = 4096;
- void *stack = alloca(stack_size);
- int status;
- pid_t pid;
+ long stack_size = 4096;
+ void *stack = alloca(stack_size);
+ int status;
+ pid_t pid;
f = fopen("/proc/sys/kernel/ctrl-alt-del", "r");
if (!f) {
return -1;
}
- /* This prctl must be before the synchro, so if the parent
+ /* This prctl must be before the synchro, so if the parent
* dies before we set the parent death signal, we will detect
* its death with the synchro right after, otherwise we have
* a window where the parent can exit before we set the pdeath
* lxc-execute which simply exited. In any case, treat
* it as a 'halt'
*/
- if (WIFSIGNALED(status)) {
+ if (WIFSIGNALED(status)) {
switch(WTERMSIG(status)) {
case SIGINT: /* halt */
DEBUG("Container halting");
DEBUG("unknown exit status for init: %d", WTERMSIG(status));
break;
}
- }
+ }
DEBUG("Pushing physical nics back to host namespace");
lxc_rename_phys_nics_on_shutdown(netnsfd, handler->conf);
}
static bool do_destroy_container(struct lxc_conf *conf) {
- if (am_unpriv()) {
- if (userns_exec_1(conf, bdev_destroy_wrapper, conf) < 0)
- return false;
- return true;
- }
- return bdev_destroy(conf);
+ if (am_unpriv()) {
+ if (userns_exec_1(conf, bdev_destroy_wrapper, conf) < 0)
+ return false;
+ return true;
+ }
+ return bdev_destroy(conf);
}
assert(dst_name != NULL);
}
- if (self->container->attach_interface(self->container, src_name,
- dst_name)) {
+ if (self->container->attach_interface(self->container, src_name, dst_name)) {
Py_XDECREF(py_src_name);
Py_XDECREF(py_dst_name);
Py_RETURN_TRUE;
}
if (debug) {
- c->set_config_item(c, "lxc.loglevel", "DEBUG");
- c->set_config_item(c, "lxc.logfile", name);
+ c->set_config_item(c, "lxc.loglevel", "DEBUG");
+ c->set_config_item(c, "lxc.logfile", name);
}
if (strcmp(args->mode, "create") == 0) {
out:
lxc_container_put(c);
if (debug)
- lxc_log_close();
+ lxc_log_close();
}
static void *concurrent(void *arguments)
case 'q':
quiet = 1;
break;
- case 'D':
- debug = 1;
- break;
+ case 'D':
+ debug = 1;
+ break;
case 'm': {
char *mode_tok, *tok, *saveptr = NULL;
exit(EXIT_FAILURE);
}
modes[i] = tok;
- }
+ }
modes[i] = NULL;
break;
- }
+ }
default: /* '?' */
usage();
exit(EXIT_FAILURE);
static int do_reboot(void *arg)
{
- int *cmd = arg;
+ int *cmd = arg;
- if (reboot(*cmd))
- printf("failed to reboot(%d): %m\n", *cmd);
+ if (reboot(*cmd))
+ printf("failed to reboot(%d): %m\n", *cmd);
return 0;
}
static int test_reboot(int cmd, int sig)
{
- long stack_size = 4096;
- void *stack = alloca(stack_size) + stack_size;
- int status;
- pid_t ret;
-
- ret = clone(do_reboot, stack, CLONE_NEWPID | SIGCHLD, &cmd);
- if (ret < 0) {
- printf("failed to clone: %m\n");
- return -1;
- }
-
- if (wait(&status) < 0) {
- printf("unexpected wait error: %m\n");
- return -1;
- }
-
- if (!WIFSIGNALED(status)) {
+ long stack_size = 4096;
+ void *stack = alloca(stack_size) + stack_size;
+ int status;
+ pid_t ret;
+
+ ret = clone(do_reboot, stack, CLONE_NEWPID | SIGCHLD, &cmd);
+ if (ret < 0) {
+ printf("failed to clone: %m\n");
+ return -1;
+ }
+
+ if (wait(&status) < 0) {
+ printf("unexpected wait error: %m\n");
+ return -1;
+ }
+
+ if (!WIFSIGNALED(status)) {
if (sig != -1)
printf("child process exited but was not signaled\n");
- return -1;
- }
+ return -1;
+ }
- if (WTERMSIG(status) != sig) {
- printf("signal termination is not the one expected\n");
- return -1;
- }
+ if (WTERMSIG(status) != sig) {
+ printf("signal termination is not the one expected\n");
+ return -1;
+ }
- return 0;
+ return 0;
}
static int have_reboot_patch(void)
int main(int argc, char *argv[])
{
- int status;
+ int status;
if (getuid() != 0) {
- printf("Must run as root.\n");
- return 1;
+ printf("Must run as root.\n");
+ return 1;
}
status = have_reboot_patch();
if (status != 0) {
- printf("Your kernel does not have the container reboot patch\n");
- return 1;
+ printf("Your kernel does not have the container reboot patch\n");
+ return 1;
}
- status = test_reboot(LINUX_REBOOT_CMD_CAD_ON, -1);
- if (status >= 0) {
- printf("reboot(LINUX_REBOOT_CMD_CAD_ON) should have failed\n");
- return 1;
- }
- printf("reboot(LINUX_REBOOT_CMD_CAD_ON) has failed as expected\n");
-
- status = test_reboot(LINUX_REBOOT_CMD_RESTART, SIGHUP);
- if (status < 0)
- return 1;
- printf("reboot(LINUX_REBOOT_CMD_RESTART) succeed\n");
-
- status = test_reboot(LINUX_REBOOT_CMD_RESTART2, SIGHUP);
- if (status < 0)
- return 1;
- printf("reboot(LINUX_REBOOT_CMD_RESTART2) succeed\n");
-
- status = test_reboot(LINUX_REBOOT_CMD_HALT, SIGINT);
- if (status < 0)
- return 1;
- printf("reboot(LINUX_REBOOT_CMD_HALT) succeed\n");
-
- status = test_reboot(LINUX_REBOOT_CMD_POWER_OFF, SIGINT);
- if (status < 0)
- return 1;
- printf("reboot(LINUX_REBOOT_CMD_POWERR_OFF) succeed\n");
-
- printf("All tests passed\n");
- return 0;
+ status = test_reboot(LINUX_REBOOT_CMD_CAD_ON, -1);
+ if (status >= 0) {
+ printf("reboot(LINUX_REBOOT_CMD_CAD_ON) should have failed\n");
+ return 1;
+ }
+ printf("reboot(LINUX_REBOOT_CMD_CAD_ON) has failed as expected\n");
+
+ status = test_reboot(LINUX_REBOOT_CMD_RESTART, SIGHUP);
+ if (status < 0)
+ return 1;
+ printf("reboot(LINUX_REBOOT_CMD_RESTART) succeed\n");
+
+ status = test_reboot(LINUX_REBOOT_CMD_RESTART2, SIGHUP);
+ if (status < 0)
+ return 1;
+ printf("reboot(LINUX_REBOOT_CMD_RESTART2) succeed\n");
+
+ status = test_reboot(LINUX_REBOOT_CMD_HALT, SIGINT);
+ if (status < 0)
+ return 1;
+ printf("reboot(LINUX_REBOOT_CMD_HALT) succeed\n");
+
+ status = test_reboot(LINUX_REBOOT_CMD_POWER_OFF, SIGINT);
+ if (status < 0)
+ return 1;
+ printf("reboot(LINUX_REBOOT_CMD_POWERR_OFF) succeed\n");
+
+ printf("All tests passed\n");
+ return 0;
}