diff --git a/src/lxc/Makefile.am b/src/lxc/Makefile.am index c91057313..227e14477 100644 --- a/src/lxc/Makefile.am +++ b/src/lxc/Makefile.am @@ -2,6 +2,7 @@ INCLUDES= -I$(top_srcdir)/src lib_LTLIBRARIES = liblxc.la pkginclude_HEADERS = \ + monitor.h \ lxc.h \ lxc_cgroup.h \ lxc_conf.h \ diff --git a/src/lxc/destroy.c b/src/lxc/destroy.c index 4823c06eb..83d7d6bde 100644 --- a/src/lxc/destroy.c +++ b/src/lxc/destroy.c @@ -30,7 +30,6 @@ #include #include -#include "monitor.h" static int dir_filter(const struct dirent *dirent) { diff --git a/src/lxc/lxc.h b/src/lxc/lxc.h index b83741347..4df9c4a09 100644 --- a/src/lxc/lxc.h +++ b/src/lxc/lxc.h @@ -41,6 +41,7 @@ extern "C" { #include #include #include +#include #define LXCPATH "/var/lxc" #define MAXPIDLEN 20 @@ -130,7 +131,7 @@ extern int lxc_monitor_open(const char *name); * Returns 0 if the monitored container has exited, > 0 if * data was readen, < 0 otherwise */ -extern int lxc_monitor_read(int fd, lxc_state_t *state); +extern int lxc_monitor_read(int fd, struct lxc_msg *msg); /* * Close the fd associated with the monitoring diff --git a/src/lxc/lxc_cgroup.c b/src/lxc/lxc_cgroup.c index 9dfd34c50..85f48b905 100644 --- a/src/lxc/lxc_cgroup.c +++ b/src/lxc/lxc_cgroup.c @@ -104,17 +104,21 @@ int lxc_unlink_nsgroup(const char *name) int lxc_cgroup_set_priority(const char *name, int priority) { int fd; - char *path = NULL, *prio = NULL; + char path[MAXPATHLEN], *prio = NULL; - asprintf(&path, LXCPATH "/%s/nsgroup/cpu.shares", name); + snprintf(path, MAXPATHLEN, + LXCPATH "/%s/nsgroup/cpu.shares", name); fd = open(path, O_WRONLY); if (fd < 0) { lxc_log_syserror("failed to open '%s'", path); - goto out; + return -1; } - asprintf(&prio, "%d", priority); + if (!asprintf(&prio, "%d", priority)) { + lxc_log_syserror("not enough memory"); + goto out; + } if (write(fd, prio, strlen(prio) + 1) < 0) { lxc_log_syserror("failed to write to '%s'", path); @@ -122,9 +126,10 @@ int lxc_cgroup_set_priority(const char *name, int priority) goto out; } + lxc_monitor_send_priority(name, priority); + close(fd); out: - free(path); free(prio); return 0; } diff --git a/src/lxc/lxc_conf.c b/src/lxc/lxc_conf.c index f7c37d7c2..9ba58a8d9 100644 --- a/src/lxc/lxc_conf.c +++ b/src/lxc/lxc_conf.c @@ -404,13 +404,13 @@ static int configure_cgroup(const char *name, struct lxc_cgroup *cgroup) return 0; } -static int configure_chroot(const char *name, const char *chroot) +static int configure_rootfs(const char *name, const char *rootfs) { char path[MAXPATHLEN]; - snprintf(path, MAXPATHLEN, LXCPATH "/%s/chroot", name); + snprintf(path, MAXPATHLEN, LXCPATH "/%s/rootfs", name); - return symlink(chroot, path); + return symlink(rootfs, path); } @@ -524,12 +524,12 @@ static int unconfigure_cgroup(const char *name) return 0; } -static int unconfigure_chroot(const char *name) +static int unconfigure_rootfs(const char *name) { char path[MAXPATHLEN]; snprintf(path, MAXPATHLEN, LXCPATH "/%s", name); - delete_info(path, "chroot"); + delete_info(path, "rootfs"); return 0; } @@ -578,11 +578,11 @@ static int setup_utsname(const char *name) return 0; } -static int setup_chroot(const char *name) +static int setup_rootfs(const char *name) { char path[MAXPATHLEN], chrt[MAXPATHLEN]; - snprintf(path, MAXPATHLEN, LXCPATH "/%s/chroot", name); + snprintf(path, MAXPATHLEN, LXCPATH "/%s/rootfs", name); if (readlink(path, chrt, MAXPATHLEN) > 0) { @@ -889,8 +889,8 @@ int lxc_configure(const char *name, struct lxc_conf *conf) return -1; } - if (conf->chroot && configure_chroot(name, conf->chroot)) { - lxc_log_error("failed to configure the chroot"); + if (conf->rootfs && configure_rootfs(name, conf->rootfs)) { + lxc_log_error("failed to configure the rootfs"); return -1; } @@ -913,8 +913,8 @@ int lxc_unconfigure(const char *name) if (unconfigure_cgroup(name)) lxc_log_error("failed to cleanup cgroup"); - if (conf_has_chroot(name) && unconfigure_chroot(name)) - lxc_log_error("failed to cleanup chroot"); + if (conf_has_rootfs(name) && unconfigure_rootfs(name)) + lxc_log_error("failed to cleanup rootfs"); if (conf_has_fstab(name) && unconfigure_mount(name)) lxc_log_error("failed to cleanup mount"); @@ -1225,8 +1225,8 @@ int lxc_setup(const char *name) return -1; } - if (conf_has_chroot(name) && setup_chroot(name)) { - lxc_log_error("failed to set chroot for '%s'", name); + if (conf_has_rootfs(name) && setup_rootfs(name)) { + lxc_log_error("failed to set rootfs for '%s'", name); return -1; } diff --git a/src/lxc/lxc_conf.h b/src/lxc/lxc_conf.h index a00a4a7b8..84feaf50b 100644 --- a/src/lxc/lxc_conf.h +++ b/src/lxc/lxc_conf.h @@ -105,13 +105,13 @@ struct lxc_cgroup { /* * Defines the global container configuration - * @chroot : the root directory to run the container + * @rootfs : the root directory to run the container * @mount : the list of mount points * @network : the network configuration * @utsname : the container utsname */ struct lxc_conf { - char *chroot; + char *rootfs; char *fstab; struct utsname *utsname; struct lxc_cgroup *cgroup; @@ -140,7 +140,7 @@ extern int lxc_setup(const char *name); extern int conf_has(const char *name, const char *info); #define conf_has_fstab(__name) conf_has(__name, "fstab") -#define conf_has_chroot(__name) conf_has(__name, "chroot") +#define conf_has_rootfs(__name) conf_has(__name, "rootfs") #define conf_has_utsname(__name) conf_has(__name, "utsname") #define conf_has_network(__name) conf_has(__name, "network") diff --git a/src/lxc/lxc_config.c b/src/lxc/lxc_config.c index 8a71b5590..00851912b 100644 --- a/src/lxc/lxc_config.c +++ b/src/lxc/lxc_config.c @@ -38,7 +38,7 @@ typedef int (*file_cb)(char* buffer, void *data); typedef int (*config_cb)(char *value, struct lxc_conf *lxc_conf); static int config_mount(char *, struct lxc_conf *); -static int config_chroot(char *, struct lxc_conf *); +static int config_rootfs(char *, struct lxc_conf *); static int config_utsname(char *, struct lxc_conf *); static int config_network_type(char *, struct lxc_conf *); static int config_network_flags(char *, struct lxc_conf *); @@ -54,12 +54,12 @@ struct config { config_cb cb; }; -enum { MOUNT, CHROOT, UTSNAME, NETTYPE, NETFLAGS, NETLINK, +enum { MOUNT, ROOTFS, UTSNAME, NETTYPE, NETFLAGS, NETLINK, NETNAME, NETHWADDR, NETIPV4, NETIPV6 }; struct config config[] = { { "lxc.mount", MOUNT, config_mount }, - { "lxc.chroot", CHROOT, config_chroot }, + { "lxc.rootfs", ROOTFS, config_rootfs }, { "lxc.utsname", UTSNAME, config_utsname }, { "lxc.network.type", NETTYPE, config_network_type }, { "lxc.network.flags", NETFLAGS, config_network_flags }, @@ -434,15 +434,15 @@ static int config_mount(char *value, struct lxc_conf *lxc_conf) return 0; } -static int config_chroot(char *value, struct lxc_conf *lxc_conf) +static int config_rootfs(char *value, struct lxc_conf *lxc_conf) { if (strlen(value) >= MAXPATHLEN) { lxc_log_error("%s path is too long", value); return -1; } - lxc_conf->chroot = strdup(value); - if (!lxc_conf->chroot) { + lxc_conf->rootfs = strdup(value); + if (!lxc_conf->rootfs) { lxc_log_syserror("failed to duplicate string %s", value); return -1; } @@ -539,7 +539,7 @@ int lxc_config_read(const char *file, struct lxc_conf *conf) int lxc_config_init(struct lxc_conf *conf) { - conf->chroot = NULL; + conf->rootfs = NULL; conf->fstab = NULL; conf->utsname = NULL; conf->cgroup = NULL; diff --git a/src/lxc/lxc_monitor.c b/src/lxc/lxc_monitor.c index 631579c16..85ad25f80 100644 --- a/src/lxc/lxc_monitor.c +++ b/src/lxc/lxc_monitor.c @@ -36,10 +36,9 @@ void usage(char *cmd) int main(int argc, char *argv[]) { - char opt; - char *name = NULL; - int fds[2]; - pid_t pid; + char opt, *name = NULL; + struct lxc_msg msg; + int fd; while ((opt = getopt(argc, argv, "n:")) != -1) { switch (opt) { @@ -52,46 +51,35 @@ int main(int argc, char *argv[]) if (!name) usage(argv[0]); - if (pipe(fds)) { - perror("pipe"); - return 1; + fd = lxc_monitor_open(name); + if (fd < 0) { + fprintf(stderr, "failed to open monitor for '%s'\n", name); + return -1; } - pid = fork(); - if (pid < 0) { - perror("fork"); - return 1; - } - - if (!pid) { - close(fds[0]); - if (lxc_monitor(name, fds[1])) { - fprintf(stderr, "failed to monitor %s\n", name); - return 1; - } - - return 0; - } - - close(fds[1]); - for (;;) { - int err, state; - - err = read(fds[0], &state, sizeof(state)); - if (err < 0) { - perror("read"); - return 1; + if (lxc_monitor_read(fd, &msg) < 0) { + fprintf(stderr, + "failed to read monitor's message for '%s'\n", + name); + return -1; } - if (!err) { - printf("container has been destroyed\n"); - return 0; + switch (msg.type) { + case lxc_msg_state: + printf("'%s' changed state to [%s]\n", + name, lxc_state2str(msg.value)); + break; + case lxc_msg_priority: + printf("'%s' changed priority to [%d]\n", + name, msg.value); + break; + default: + printf("invalid msg format\n"); + break; } - - printf("container has changed the state to %d - %s\n", - state, lxc_state2str(state)); } + return 0; } diff --git a/src/lxc/lxc_state.c b/src/lxc/lxc_state.c index 740c3f1e4..f4df4ebfe 100644 --- a/src/lxc/lxc_state.c +++ b/src/lxc/lxc_state.c @@ -32,7 +32,6 @@ #include #include -#include "monitor.h" static char *strstate[] = { "STOPPED", "STARTING", "RUNNING", "STOPPING", diff --git a/src/lxc/monitor.c b/src/lxc/monitor.c index afc5b182c..2cd4d3514 100644 --- a/src/lxc/monitor.c +++ b/src/lxc/monitor.c @@ -101,25 +101,42 @@ out: return err; } -void lxc_monitor_send_state(const char *name, lxc_state_t state) +static void lxc_monitor_send(const char *name, struct lxc_msg *msg) { int fd; struct sockaddr_un addr; fd = socket(PF_UNIX, SOCK_DGRAM, 0); - if (fd < 0) + if (fd < 0) { lxc_log_syserror("failed to create notification socket"); + return; + } memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; - snprintf(addr.sun_path, UNIX_PATH_MAX, LXCPATH "/%s/notification", name); + snprintf(addr.sun_path, UNIX_PATH_MAX, + LXCPATH "/%s/notification", name); - sendto(fd, &state, sizeof(state), 0, + sendto(fd, msg, sizeof(*msg), 0, (const struct sockaddr *)&addr, sizeof(addr)); close(fd); } +void lxc_monitor_send_priority(const char *name, int priority) +{ + struct lxc_msg msg = { .type = lxc_msg_priority, + .value = priority }; + lxc_monitor_send(name, &msg); +} + +void lxc_monitor_send_state(const char *name, lxc_state_t state) +{ + struct lxc_msg msg = { .type = lxc_msg_state, + .value = state }; + lxc_monitor_send(name, &msg); +} + void lxc_monitor_cleanup(const char *name) { char path[UNIX_PATH_MAX]; @@ -153,11 +170,11 @@ int lxc_monitor_open(const char *name) return fd; } -int lxc_monitor_read(int fd, lxc_state_t *state) +int lxc_monitor_read(int fd, struct lxc_msg *msg) { int ret; - ret = recv(fd, state, sizeof(*state), 0); + ret = recv(fd, msg, sizeof(*msg), 0); if (ret < 0) { lxc_log_syserror("failed to received state"); return -1; diff --git a/src/lxc/monitor.h b/src/lxc/monitor.h index a282986c1..304450e5a 100644 --- a/src/lxc/monitor.h +++ b/src/lxc/monitor.h @@ -23,7 +23,18 @@ #ifndef __monitor_h #define __monitor_h +typedef enum { + lxc_msg_state, + lxc_msg_priority, +} lxc_msg_type_t; + +struct lxc_msg { + lxc_msg_type_t type; + int value; +}; + void lxc_monitor_send_state(const char *name, lxc_state_t state); +void lxc_monitor_send_priority(const char *name, int priority); void lxc_monitor_cleanup(const char *name); #endif diff --git a/test/lxc_create.c b/test/lxc_create.c index 6d156dd61..bac0bf99d 100644 --- a/test/lxc_create.c +++ b/test/lxc_create.c @@ -142,7 +142,7 @@ int main(int argc, char *argv[]) struct lxc_conf lxc_conf = { .networks = lxc_init_list(&lxc_conf.networks), - .chroot = "/mnt/iso", + .rootfs = "/mnt/iso", }; lxc_list_add(&phys.netdev, &ndlist);