]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
let lxc-monitor command ask a lxc-monitord instance to quit
authorDwight Engen <dwight.engen@oracle.com>
Fri, 6 Dec 2013 20:36:50 +0000 (15:36 -0500)
committerStéphane Graber <stgraber@ubuntu.com>
Fri, 6 Dec 2013 21:03:23 +0000 (16:03 -0500)
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 <dwight.engen@oracle.com>
Acked-by: Stéphane Graber <stgraber@ubuntu.com>
doc/lxc-monitor.sgml.in
src/lxc/lxc_monitor.c
src/lxc/lxc_monitord.c

index abd668a4527d1280c5432f02cdeffe60004d17f5..e57314e58ef26700235f6af6b585b095af90aa9f 100644 (file)
@@ -50,6 +50,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
     <cmdsynopsis>
       <command>lxc-monitor</command>
       <arg choice="opt">-n <replaceable>name</replaceable></arg>
+      <arg choice="opt">-Q <replaceable>name</replaceable></arg>
     </cmdsynopsis>
   </refsynopsisdiv>
 
@@ -75,6 +76,27 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
   </refsect1>
 
+  <refsect1>
+    <title>Options</title>
+
+    <variablelist>
+      <varlistentry>
+       <term>
+         <option>-Q, --quit</option>
+       </term>
+       <listitem>
+         <para>
+           Ask the lxc-monitord daemon on each given <command>lxcpath</command>
+           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 <command>lxcpath</command> is on.
+         </para>
+       </listitem>
+      </varlistentry>
+     </variablelist>
+  </refsect1>
+
   &commonoptions;
 
   <refsect1>
index 4f5630882782356dc59b8d3318d75d2d11f8f0b1..63ab68be48a9e52c0bccf05eeb934a8567ab63b0 100644 (file)
 
 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) {
index 381b2d6e767e7180f1b04d9d12007bf8ea484ab5..fc83f01bf522b49d1b879d100f6a7b100fadf2f4 100644 (file)
@@ -29,6 +29,7 @@
 #include <string.h>
 #include <stdlib.h>
 #include <fcntl.h>
+#include <sys/epoll.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/param.h>
@@ -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;
                }
        }