<cmdsynopsis>
<command>lxc-monitor</command>
<arg choice="opt">-n <replaceable>name</replaceable></arg>
+ <arg choice="opt">-Q <replaceable>name</replaceable></arg>
</cmdsynopsis>
</refsynopsisdiv>
</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>
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
};
\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,
};
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) {
#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>
};
static struct lxc_monitor mon;
+static int quit;
static int lxc_monitord_fifo_create(struct lxc_monitor *mon)
{
{
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,
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;
}
}