Commit 2afd1dc0 by Dwight Engen Committed by Stéphane Graber

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: 's avatarDwight Engen <dwight.engen@oracle.com> Acked-by: 's avatarStéphane Graber <stgraber@ubuntu.com>
parent 84c92abd
...@@ -50,6 +50,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ...@@ -50,6 +50,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
<cmdsynopsis> <cmdsynopsis>
<command>lxc-monitor</command> <command>lxc-monitor</command>
<arg choice="opt">-n <replaceable>name</replaceable></arg> <arg choice="opt">-n <replaceable>name</replaceable></arg>
<arg choice="opt">-Q <replaceable>name</replaceable></arg>
</cmdsynopsis> </cmdsynopsis>
</refsynopsisdiv> </refsynopsisdiv>
...@@ -75,6 +76,27 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ...@@ -75,6 +76,27 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
</refsect1> </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; &commonoptions;
<refsect1> <refsect1>
......
...@@ -35,7 +35,18 @@ ...@@ -35,7 +35,18 @@
lxc_log_define(lxc_monitor_ui, lxc_monitor); 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[] = { static const struct option my_longopts[] = {
{"quit", no_argument, 0, 'Q'},
LXC_COMMON_OPTIONS LXC_COMMON_OPTIONS
}; };
...@@ -48,10 +59,11 @@ lxc-monitor monitors the state of the NAME container\n\ ...@@ -48,10 +59,11 @@ lxc-monitor monitors the state of the NAME container\n\
\n\ \n\
Options :\n\ Options :\n\
-n, --name=NAME NAME for name of the container\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 = ".*", .name = ".*",
.options = my_longopts, .options = my_longopts,
.parser = NULL, .parser = my_parser,
.checker = NULL, .checker = NULL,
.lxcpath_additional = -1, .lxcpath_additional = -1,
}; };
...@@ -74,6 +86,23 @@ int main(int argc, char *argv[]) ...@@ -74,6 +86,23 @@ int main(int argc, char *argv[])
my_args.progname, my_args.quiet, my_args.lxcpath[0])) my_args.progname, my_args.quiet, my_args.lxcpath[0]))
return -1; 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; len = strlen(my_args.name) + 3;
regexp = malloc(len + 3); regexp = malloc(len + 3);
if (!regexp) { if (!regexp) {
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/epoll.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/param.h> #include <sys/param.h>
...@@ -70,6 +71,7 @@ struct lxc_monitor { ...@@ -70,6 +71,7 @@ struct lxc_monitor {
}; };
static struct lxc_monitor mon; static struct lxc_monitor mon;
static int quit;
static int lxc_monitord_fifo_create(struct lxc_monitor *mon) 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, ...@@ -135,8 +137,18 @@ static int lxc_monitord_sock_handler(int fd, uint32_t events, void *data,
{ {
struct lxc_monitor *mon = data; struct lxc_monitor *mon = data;
lxc_monitord_sockfd_remove(mon, fd); if (events & EPOLLIN) {
return 0; 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, static int lxc_monitord_sock_accept(int fd, uint32_t events, void *data,
...@@ -393,7 +405,7 @@ int main(int argc, char *argv[]) ...@@ -393,7 +405,7 @@ int main(int argc, char *argv[])
ret = lxc_mainloop(&mon.descr, 1000 * 30); ret = lxc_mainloop(&mon.descr, 1000 * 30);
if (mon.clientfds_cnt <= 0) if (mon.clientfds_cnt <= 0)
{ {
NOTICE("no clients for 30 seconds, exiting"); NOTICE("no remaining clients, exiting");
break; break;
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment