From: Dwight Engen Date: Fri, 6 Dec 2013 20:36:50 +0000 (-0500) Subject: let lxc-monitor command ask a lxc-monitord instance to quit X-Git-Tag: lxc-1.0.0.beta1~47 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2afd1dc05ba38eacdfe5a9c79addaf3a7d182dbf;p=thirdparty%2Flxc.git let lxc-monitor command ask a lxc-monitord instance to quit Once lxc-monitord receives a quit request from lxc-monitor, it will then return from the mainloop every time an event occurs on any of its fds and check if it has any clients left. When there are no more it exits. This allows lxc-monitord to quit immediately instead of waiting the normal 30 seconds for more clients, potentially freeing up lxcpath for unmounting. Signed-off-by: Dwight Engen Acked-by: Stéphane Graber --- diff --git a/doc/lxc-monitor.sgml.in b/doc/lxc-monitor.sgml.in index abd668a45..e57314e58 100644 --- a/doc/lxc-monitor.sgml.in +++ b/doc/lxc-monitor.sgml.in @@ -50,6 +50,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA lxc-monitor -n name + -Q name @@ -75,6 +76,27 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Options + + + + + + + + + Ask the lxc-monitord daemon on each given lxcpath + to quit. After receiving this command, lxc-monitord will exit + immediately as soon as it has no clients instead of waiting the + normal 30 seconds for new clients. This is useful if you need to + unmount the filesystem lxcpath is on. + + + + + + &commonoptions; diff --git a/src/lxc/lxc_monitor.c b/src/lxc/lxc_monitor.c index 4f5630882..63ab68be4 100644 --- a/src/lxc/lxc_monitor.c +++ b/src/lxc/lxc_monitor.c @@ -35,7 +35,18 @@ lxc_log_define(lxc_monitor_ui, lxc_monitor); +static bool quit_monitord; + +static int my_parser(struct lxc_arguments* args, int c, char* arg) +{ + switch (c) { + case 'Q': quit_monitord = true; break; + } + return 0; +} + static const struct option my_longopts[] = { + {"quit", no_argument, 0, 'Q'}, LXC_COMMON_OPTIONS }; @@ -48,10 +59,11 @@ lxc-monitor monitors the state of the NAME container\n\ \n\ Options :\n\ -n, --name=NAME NAME for name of the container\n\ - NAME may be a regular expression", + NAME may be a regular expression\n\ + -Q, --quit tell lxc-monitord to quit\n", .name = ".*", .options = my_longopts, - .parser = NULL, + .parser = my_parser, .checker = NULL, .lxcpath_additional = -1, }; @@ -74,6 +86,23 @@ int main(int argc, char *argv[]) my_args.progname, my_args.quiet, my_args.lxcpath[0])) return -1; + if (quit_monitord) { + int ret = EXIT_SUCCESS; + for (i = 0; i < my_args.lxcpath_cnt; i++) { + int fd; + + fd = lxc_monitor_open(my_args.lxcpath[i]); + if (fd < 0) { + ERROR("Unable to open monitor on path:%s", my_args.lxcpath[i]); + ret = EXIT_FAILURE; + continue; + } + write(fd, "quit", 4); + close(fd); + } + return ret; + } + len = strlen(my_args.name) + 3; regexp = malloc(len + 3); if (!regexp) { diff --git a/src/lxc/lxc_monitord.c b/src/lxc/lxc_monitord.c index 381b2d6e7..fc83f01bf 100644 --- a/src/lxc/lxc_monitord.c +++ b/src/lxc/lxc_monitord.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -70,6 +71,7 @@ struct lxc_monitor { }; static struct lxc_monitor mon; +static int quit; static int lxc_monitord_fifo_create(struct lxc_monitor *mon) { @@ -135,8 +137,18 @@ static int lxc_monitord_sock_handler(int fd, uint32_t events, void *data, { struct lxc_monitor *mon = data; - lxc_monitord_sockfd_remove(mon, fd); - return 0; + if (events & EPOLLIN) { + int rc; + char buf[4]; + + rc = read(fd, buf, sizeof(buf)); + if (rc > 0 && !strncmp(buf, "quit", 4)) + quit = 1; + } + + if (events & EPOLLHUP) + lxc_monitord_sockfd_remove(mon, fd); + return quit; } static int lxc_monitord_sock_accept(int fd, uint32_t events, void *data, @@ -393,7 +405,7 @@ int main(int argc, char *argv[]) ret = lxc_mainloop(&mon.descr, 1000 * 30); if (mon.clientfds_cnt <= 0) { - NOTICE("no clients for 30 seconds, exiting"); + NOTICE("no remaining clients, exiting"); break; } }