>From c4af03c0e6b74e550161e4c8382fb9d0889e4fe3 Mon Sep 17 00:00:00 2001 From: Dwight Engen <dwight.en...@oracle.com> Date: Thu, 25 Apr 2013 11:45:26 -0400 Subject: [PATCH] lxc-monitor multiple paths
Signed-off-by: Dwight Engen <dwight.en...@oracle.com> --- doc/lxc-monitor.sgml.in | 7 ++++++ lxc.spec.in | 1 - src/lxc/arguments.c | 27 +++++++++++++++++++++-- src/lxc/arguments.h | 3 ++- src/lxc/lxc.h | 31 ++++++++++++++++++++++----- src/lxc/lxc_attach.c | 6 +++--- src/lxc/lxc_cgroup.c | 4 ++-- src/lxc/lxc_console.c | 2 +- src/lxc/lxc_execute.c | 4 ++-- src/lxc/lxc_freeze.c | 2 +- src/lxc/lxc_info.c | 4 ++-- src/lxc/lxc_kill.c | 2 +- src/lxc/lxc_monitor.c | 32 ++++++++++++++++++++------- src/lxc/lxc_restart.c | 4 ++-- src/lxc/lxc_start.c | 4 ++-- src/lxc/lxc_stop.c | 2 +- src/lxc/lxc_unfreeze.c | 2 +- src/lxc/lxc_wait.c | 4 ++-- src/lxc/monitor.c | 57 ++++++++++++++++++++++++++++++++----------------- 19 files changed, 141 insertions(+), 57 deletions(-) diff --git a/doc/lxc-monitor.sgml.in b/doc/lxc-monitor.sgml.in index eae6f82..07b9389 100644 --- a/doc/lxc-monitor.sgml.in +++ b/doc/lxc-monitor.sgml.in @@ -63,6 +63,13 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA to monitor all the containers, several of them or just one. </para> + <para> + The <option>-P, --lxcpath</option>=PATH option may be specified multiple + times to monitor more than one container path. Note however that + containers with the same name in multiple paths will be + indistinguishable in the output. + </para> + </refsect1> &commonoptions; diff --git a/lxc.spec.in b/lxc.spec.in index 5e520c5..2f2387c 100644 --- a/lxc.spec.in +++ b/lxc.spec.in @@ -84,7 +84,6 @@ PATH=$PATH:/usr/sbin:/sbin %configure $args \ --enable-python \ %endif --disable-rpath \ - --enable-configpath-log \ --with-config-path=/container make %{?_smp_mflags} diff --git a/src/lxc/arguments.c b/src/lxc/arguments.c index f61c6eb..ab56e4c 100644 --- a/src/lxc/arguments.c +++ b/src/lxc/arguments.c @@ -150,13 +150,25 @@ See the %s man page for further information.\n\n", exit(code); } +static int lxc_arguments_lxcpath_add(struct lxc_arguments *args, + const char *lxcpath) +{ + args->lxcpath = realloc(args->lxcpath, (args->lxcpath_cnt + 1) * + sizeof(args->lxcpath[0])); + if (args->lxcpath == NULL) { + lxc_error(args, "no memory"); + return ENOMEM; + } + args->lxcpath[args->lxcpath_cnt++] = lxcpath; + return 0; +} + extern int lxc_arguments_parse(struct lxc_arguments *args, int argc, char * const argv[]) { char shortopts[256]; int ret = 0; - args->lxcpath = default_lxc_path(); ret = build_shortopts(args->options, shortopts, sizeof(shortopts)); if (ret < 0) { lxc_error(args, "build_shortopts() failed : %s", @@ -176,7 +188,11 @@ extern int lxc_arguments_parse(struct lxc_arguments *args, case 'l': args->log_priority = optarg; break; case 'c': args->console = optarg; break; case 'q': args->quiet = 1; break; - case 'P': args->lxcpath = optarg; break; + case 'P': + ret = lxc_arguments_lxcpath_add(args, optarg); + if (ret < 0) + return ret; + break; case OPT_USAGE: print_usage(args->options, args); case '?': print_help(args, 1); case 'h': print_help(args, 0); @@ -195,6 +211,13 @@ extern int lxc_arguments_parse(struct lxc_arguments *args, args->argv = &argv[optind]; args->argc = argc - optind; + /* If no lxcpaths were given, use default */ + if (!args->lxcpath_cnt) { + ret = lxc_arguments_lxcpath_add(args, default_lxc_path()); + if (ret < 0) + return ret; + } + /* Check the command options */ if (!args->name) { diff --git a/src/lxc/arguments.h b/src/lxc/arguments.h index 6f6826b..c952c76 100644 --- a/src/lxc/arguments.h +++ b/src/lxc/arguments.h @@ -47,7 +47,8 @@ struct lxc_arguments { const char *console; const char *console_log; const char *pidfile; - const char *lxcpath; + const char **lxcpath; + int lxcpath_cnt; /* for lxc-checkpoint/restart */ const char *statefile; diff --git a/src/lxc/lxc.h b/src/lxc/lxc.h index db921f0..9057757 100644 --- a/src/lxc/lxc.h +++ b/src/lxc/lxc.h @@ -28,6 +28,7 @@ extern "C" { #endif #include <stddef.h> +#include <sys/types.h> #include <lxc/state.h> struct lxc_msg; @@ -77,17 +78,37 @@ extern int lxc_execute(const char *name, char *const argv[], int quiet, extern int lxc_monitor_open(const char *lxcpath); /* - * Read the state of the container if this one has changed - * The function will block until there is an event available - * @fd : the file descriptor provided by lxc_monitor_open - * @state : the variable which will be filled with the state + * Blocking read for the next container state change + * @fd : the file descriptor provided by lxc_monitor_open + * @msg : the variable which will be filled with the state * Returns 0 if the monitored container has exited, > 0 if - * data was readen, < 0 otherwise + * data was read, < 0 otherwise */ extern int lxc_monitor_read(int fd, struct lxc_msg *msg); + +/* + * Blocking read for the next container state change with timeout + * @fd : the file descriptor provided by lxc_monitor_open + * @msg : the variable which will be filled with the state + * @timeout : the timeout in seconds to wait for a state change + * Returns 0 if the monitored container has exited, > 0 if + * data was read, < 0 otherwise + */ extern int lxc_monitor_read_timeout(int fd, struct lxc_msg *msg, int timeout); /* + * Blocking read from multiple monitors for the next container state + * change with timeout + * @rfds : an fd_set of file descriptors provided by lxc_monitor_open + * @nfds : the maximum fd number in rfds + 1 + * @msg : the variable which will be filled with the state + * @timeout : the timeout in seconds to wait for a state change + * Returns 0 if the monitored container has exited, > 0 if + * data was read, < 0 otherwise + */ +extern int lxc_monitor_read_fdset(fd_set *rfds, int nfds, struct lxc_msg *msg, int timeout); + +/* * Close the fd associated with the monitoring * @fd : the file descriptor provided by lxc_monitor_open * Returns 0 on success, < 0 otherwise diff --git a/src/lxc/lxc_attach.c b/src/lxc/lxc_attach.c index e5619df..03d49a8 100644 --- a/src/lxc/lxc_attach.c +++ b/src/lxc/lxc_attach.c @@ -165,7 +165,7 @@ int main(int argc, char *argv[]) if (ret) return ret; - init_pid = get_init_pid(my_args.name, my_args.lxcpath); + init_pid = get_init_pid(my_args.name, my_args.lxcpath[0]); if (init_pid < 0) { ERROR("failed to get the init pid"); return -1; @@ -183,7 +183,7 @@ int main(int argc, char *argv[]) * by asking lxc-start */ if (namespace_flags == -1) { - namespace_flags = lxc_get_clone_flags(my_args.name, my_args.lxcpath); + namespace_flags = lxc_get_clone_flags(my_args.name, my_args.lxcpath[0]); /* call failed */ if (namespace_flags == -1) { ERROR("failed to automatically determine the " @@ -256,7 +256,7 @@ int main(int argc, char *argv[]) } if (!elevated_privileges) { - ret = lxc_cgroup_attach(grandchild, my_args.name, my_args.lxcpath); + ret = lxc_cgroup_attach(grandchild, my_args.name, my_args.lxcpath[0]); if (ret < 0) { ERROR("failed to attach process to cgroup"); return -1; diff --git a/src/lxc/lxc_cgroup.c b/src/lxc/lxc_cgroup.c index f7c88a8..f521965 100644 --- a/src/lxc/lxc_cgroup.c +++ b/src/lxc/lxc_cgroup.c @@ -78,7 +78,7 @@ int main(int argc, char *argv[]) value = my_args.argv[1]; if (value) { - if (lxc_cgroup_set(my_args.name, state_object, value, my_args.lxcpath)) { + if (lxc_cgroup_set(my_args.name, state_object, value, my_args.lxcpath[0])) { ERROR("failed to assign '%s' value to '%s' for '%s'", value, state_object, my_args.name); return -1; @@ -88,7 +88,7 @@ int main(int argc, char *argv[]) int ret; char buffer[len]; - ret = lxc_cgroup_get(my_args.name, state_object, buffer, len, my_args.lxcpath); + ret = lxc_cgroup_get(my_args.name, state_object, buffer, len, my_args.lxcpath[0]); if (ret < 0) { ERROR("failed to retrieve value of '%s' for '%s'", state_object, my_args.name); diff --git a/src/lxc/lxc_console.c b/src/lxc/lxc_console.c index f6659f6..932f7d8 100644 --- a/src/lxc/lxc_console.c +++ b/src/lxc/lxc_console.c @@ -202,7 +202,7 @@ int main(int argc, char *argv[]) return -1; } - err = lxc_console(my_args.name, my_args.ttynum, &master, my_args.lxcpath); + err = lxc_console(my_args.name, my_args.ttynum, &master, my_args.lxcpath[0]); if (err) goto out; diff --git a/src/lxc/lxc_execute.c b/src/lxc/lxc_execute.c index 41e29aa..0e99cf8 100644 --- a/src/lxc/lxc_execute.c +++ b/src/lxc/lxc_execute.c @@ -110,7 +110,7 @@ int main(int argc, char *argv[]) else { int rc; - rc = asprintf(&rcfile, "%s/%s/config", my_args.lxcpath, my_args.name); + rc = asprintf(&rcfile, "%s/%s/config", my_args.lxcpath[0], my_args.name); if (rc == -1) { SYSERROR("failed to allocate memory"); return -1; @@ -137,5 +137,5 @@ int main(int argc, char *argv[]) if (lxc_config_define_load(&defines, conf)) return -1; - return lxc_execute(my_args.name, my_args.argv, my_args.quiet, conf, my_args.lxcpath); + return lxc_execute(my_args.name, my_args.argv, my_args.quiet, conf, my_args.lxcpath[0]); } diff --git a/src/lxc/lxc_freeze.c b/src/lxc/lxc_freeze.c index b52ab5b..8019715 100644 --- a/src/lxc/lxc_freeze.c +++ b/src/lxc/lxc_freeze.c @@ -58,6 +58,6 @@ int main(int argc, char *argv[]) my_args.progname, my_args.quiet)) return -1; - return lxc_freeze(my_args.name, my_args.lxcpath); + return lxc_freeze(my_args.name, my_args.lxcpath[0]); } diff --git a/src/lxc/lxc_info.c b/src/lxc/lxc_info.c index 3fcead5..c6619cf 100644 --- a/src/lxc/lxc_info.c +++ b/src/lxc/lxc_info.c @@ -87,7 +87,7 @@ int main(int argc, char *argv[]) state = pid = true; if (state || test_state) { - ret = lxc_getstate(my_args.name, my_args.lxcpath); + ret = lxc_getstate(my_args.name, my_args.lxcpath[0]); if (ret < 0) return 1; if (test_state) @@ -97,7 +97,7 @@ int main(int argc, char *argv[]) } if (pid) - printf("pid:%10d\n", get_init_pid(my_args.name, my_args.lxcpath)); + printf("pid:%10d\n", get_init_pid(my_args.name, my_args.lxcpath[0])); return 0; } diff --git a/src/lxc/lxc_kill.c b/src/lxc/lxc_kill.c index ba00aa8..3627f0f 100644 --- a/src/lxc/lxc_kill.c +++ b/src/lxc/lxc_kill.c @@ -76,7 +76,7 @@ int main(int argc, char *argv[], char *envp[]) } else sig=SIGKILL; - pid = get_init_pid(my_args.name, my_args.lxcpath); + pid = get_init_pid(my_args.name, my_args.lxcpath[0]); if (pid < 0) { ERROR("failed to get the init pid"); return -1; diff --git a/src/lxc/lxc_monitor.c b/src/lxc/lxc_monitor.c index 0ca829f..b1e4ded 100644 --- a/src/lxc/lxc_monitor.c +++ b/src/lxc/lxc_monitor.c @@ -59,8 +59,8 @@ int main(int argc, char *argv[]) char *regexp; struct lxc_msg msg; regex_t preg; - int fd; - int len, rc; + fd_set rfds, rfds_save; + int len, rc, i, nfds = -1; if (lxc_arguments_parse(&my_args, argc, argv)) return -1; @@ -87,16 +87,33 @@ int main(int argc, char *argv[]) return -1; } - lxc_monitord_spawn(my_args.lxcpath); + if (my_args.lxcpath_cnt > FD_SETSIZE) { + ERROR("too many paths requested, only the first %d will be monitored", FD_SETSIZE); + my_args.lxcpath_cnt = FD_SETSIZE; + } - fd = lxc_monitor_open(my_args.lxcpath); - if (fd < 0) - return -1; + FD_ZERO(&rfds); + for (i = 0; i < my_args.lxcpath_cnt; i++) { + int fd; + + lxc_monitord_spawn(my_args.lxcpath[i]); + + fd = lxc_monitor_open(my_args.lxcpath[i]); + if (fd < 0) + return -1; + FD_SET(fd, &rfds); + if (fd > nfds) + nfds = fd; + } + memcpy(&rfds_save, &rfds, sizeof(rfds_save)); + nfds++; setlinebuf(stdout); for (;;) { - if (lxc_monitor_read(fd, &msg) < 0) + memcpy(&rfds, &rfds_save, sizeof(rfds)); + + if (lxc_monitor_read_fdset(&rfds, nfds, &msg, -1) < 0) return -1; msg.name[sizeof(msg.name)-1] = '\0'; @@ -118,4 +135,3 @@ int main(int argc, char *argv[]) return 0; } - diff --git a/src/lxc/lxc_restart.c b/src/lxc/lxc_restart.c index 118d4b8..d9a8f29 100644 --- a/src/lxc/lxc_restart.c +++ b/src/lxc/lxc_restart.c @@ -133,7 +133,7 @@ int main(int argc, char *argv[]) else { int rc; - rc = asprintf(&rcfile, "%s/%s/config", my_args.lxcpath, my_args.name); + rc = asprintf(&rcfile, "%s/%s/config", my_args.lxcpath[0], my_args.name); if (rc == -1) { SYSERROR("failed to allocate memory"); return -1; @@ -172,7 +172,7 @@ int main(int argc, char *argv[]) } } - ret = lxc_restart(my_args.name, sfd, conf, my_args.flags, my_args.lxcpath); + ret = lxc_restart(my_args.name, sfd, conf, my_args.flags, my_args.lxcpath[0]); if (my_args.statefile) close(sfd); diff --git a/src/lxc/lxc_start.c b/src/lxc/lxc_start.c index 957fdb0..c79bebe 100644 --- a/src/lxc/lxc_start.c +++ b/src/lxc/lxc_start.c @@ -174,7 +174,7 @@ int main(int argc, char *argv[]) else { int rc; - rc = asprintf(&rcfile, "%s/%s/config", my_args.lxcpath, my_args.name); + rc = asprintf(&rcfile, "%s/%s/config", my_args.lxcpath[0], my_args.name); if (rc == -1) { SYSERROR("failed to allocate memory"); return err; @@ -252,7 +252,7 @@ int main(int argc, char *argv[]) if (my_args.close_all_fds) conf->close_all_fds = 1; - err = lxc_start(my_args.name, args, conf, my_args.lxcpath); + err = lxc_start(my_args.name, args, conf, my_args.lxcpath[0]); /* * exec ourself, that requires to have all opened fd diff --git a/src/lxc/lxc_stop.c b/src/lxc/lxc_stop.c index b4d9f23..924db78 100644 --- a/src/lxc/lxc_stop.c +++ b/src/lxc/lxc_stop.c @@ -58,5 +58,5 @@ int main(int argc, char *argv[]) my_args.progname, my_args.quiet)) return -1; - return lxc_stop(my_args.name, my_args.lxcpath); + return lxc_stop(my_args.name, my_args.lxcpath[0]); } diff --git a/src/lxc/lxc_unfreeze.c b/src/lxc/lxc_unfreeze.c index 0bb5dc5..3496def 100644 --- a/src/lxc/lxc_unfreeze.c +++ b/src/lxc/lxc_unfreeze.c @@ -57,6 +57,6 @@ int main(int argc, char *argv[]) my_args.progname, my_args.quiet)) return -1; - return lxc_unfreeze(my_args.name, my_args.lxcpath); + return lxc_unfreeze(my_args.name, my_args.lxcpath[0]); } diff --git a/src/lxc/lxc_wait.c b/src/lxc/lxc_wait.c index b2e6c0a..408b779 100644 --- a/src/lxc/lxc_wait.c +++ b/src/lxc/lxc_wait.c @@ -87,10 +87,10 @@ int main(int argc, char *argv[]) my_args.progname, my_args.quiet)) return -1; - if (lxc_monitord_spawn(my_args.lxcpath) < 0) { + if (lxc_monitord_spawn(my_args.lxcpath[0]) < 0) { ERROR("failed to spawn monitor daemon"); return -1; } - return lxc_wait(strdup(my_args.name), my_args.states, my_args.timeout, my_args.lxcpath); + return lxc_wait(strdup(my_args.name), my_args.states, my_args.timeout, my_args.lxcpath[0]); } diff --git a/src/lxc/monitor.c b/src/lxc/monitor.c index 0521e9a..60d9577 100644 --- a/src/lxc/monitor.c +++ b/src/lxc/monitor.c @@ -147,33 +147,50 @@ err1: return ret; } -int lxc_monitor_read_timeout(int fd, struct lxc_msg *msglxc, int timeout) +int lxc_monitor_read_fdset(fd_set *rfds, int nfds, struct lxc_msg *msg, + int timeout) { - fd_set rfds; - struct timeval tv; - int ret; + struct timeval tval,*tv = NULL; + int ret,i; if (timeout != -1) { - FD_ZERO(&rfds); - FD_SET(fd, &rfds); - - tv.tv_sec = timeout; - tv.tv_usec = 0; - - ret = select(fd+1, &rfds, NULL, NULL, &tv); - if (ret == -1) - return -1; - else if (!ret) - return -2; // timed out + tv = &tval; + tv->tv_sec = timeout; + tv->tv_usec = 0; } - ret = recv(fd, msglxc, sizeof(*msglxc), 0); - if (ret <= 0) { - SYSERROR("client failed to recv (monitord died?) %s", - strerror(errno)); + ret = select(nfds, rfds, NULL, NULL, tv); + if (ret == -1) return -1; + else if (ret == 0) + return -2; // timed out + + /* only read from the first ready fd, the others will remain ready + * for when this routine is called again + */ + for (i = 0; i < nfds; i++) { + if (FD_ISSET(i, rfds)) { + ret = recv(i, msg, sizeof(*msg), 0); + if (ret <= 0) { + SYSERROR("client failed to recv (monitord died?) %s", + strerror(errno)); + return -1; + } + return ret; + } } - return ret; + SYSERROR("no ready fd found?"); + return -1; +} + +int lxc_monitor_read_timeout(int fd, struct lxc_msg *msg, int timeout) +{ + fd_set rfds; + + FD_ZERO(&rfds); + FD_SET(fd, &rfds); + + return lxc_monitor_read_fdset(&rfds, fd+1, msg, timeout); } int lxc_monitor_read(int fd, struct lxc_msg *msg) -- 1.8.1.4 ------------------------------------------------------------------------------ Try New Relic Now & We'll Send You this Cool Shirt New Relic is the only SaaS-based application performance monitoring service that delivers powerful full stack analytics. Optimize and monitor your browser, app, & servers with just a few lines of code. Try New Relic and get this awesome Nerd Life shirt! http://p.sf.net/sfu/newrelic_d2d_apr _______________________________________________ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel