From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Wolfgang Bumiller Date: Tue, 31 Mar 2020 15:22:42 +0200 Subject: [PATCH] allow running lxc-monitord as a system daemon lxc-monitord instances are spawned on demand and, if this happens from a service, the daemon is considered part of it by systemd, as it is running in the same cgroups. This can be avoided by leaving it running permanently. Signed-off-by: Wolfgang Bumiller --- .gitignore | 1 + config/init/systemd/Makefile.am | 10 +++--- configure.ac | 1 + lxc.spec.in | 1 + src/lxc/cmd/lxc_monitord.c | 60 +++++++++++++++++++++++---------- 5 files changed, 52 insertions(+), 21 deletions(-) diff --git a/config/init/systemd/Makefile.am b/config/init/systemd/Makefile.am index c448850d1..4a4fde5e7 100644 --- a/config/init/systemd/Makefile.am +++ b/config/init/systemd/Makefile.am @@ -2,19 +2,21 @@ EXTRA_DIST = \ lxc-apparmor-load \ lxc.service.in \ lxc@.service.in \ - lxc-net.service.in + lxc-net.service.in \ + lxc-monitord.service.in if INIT_SCRIPT_SYSTEMD -BUILT_SOURCES = lxc.service lxc@.service lxc-net.service +BUILT_SOURCES = lxc.service lxc@.service lxc-net.service lxc-monitord.service -install-systemd: lxc.service lxc@.service lxc-net.service lxc-apparmor-load +install-systemd: lxc.service lxc@.service lxc-net.service lxc-monitord.service lxc-apparmor-load $(MKDIR_P) $(DESTDIR)$(SYSTEMD_UNIT_DIR) - $(INSTALL_DATA) lxc.service lxc@.service lxc-net.service $(DESTDIR)$(SYSTEMD_UNIT_DIR)/ + $(INSTALL_DATA) lxc.service lxc@.service lxc-net.service lxc-monitord.service $(DESTDIR)$(SYSTEMD_UNIT_DIR)/ uninstall-systemd: rm -f $(DESTDIR)$(SYSTEMD_UNIT_DIR)/lxc.service rm -f $(DESTDIR)$(SYSTEMD_UNIT_DIR)/lxc@.service rm -f $(DESTDIR)$(SYSTEMD_UNIT_DIR)/lxc-net.service + rm -f $(DESTDIR)$(SYSTEMD_UNIT_DIR)/lxc-monitord.service rmdir $(DESTDIR)$(SYSTEMD_UNIT_DIR) || : pkglibexec_SCRIPTS = lxc-apparmor-load diff --git a/configure.ac b/configure.ac index e30ea6f6e..16c5ab8c4 100644 --- a/configure.ac +++ b/configure.ac @@ -913,6 +913,7 @@ AC_CONFIG_FILES([ config/init/systemd/lxc.service config/init/systemd/lxc@.service config/init/systemd/lxc-net.service + config/init/systemd/lxc-monitord.service config/init/sysvinit/Makefile config/init/sysvinit/lxc-containers config/init/sysvinit/lxc-net diff --git a/lxc.spec.in b/lxc.spec.in index ec6321c33..ea6789fb6 100644 --- a/lxc.spec.in +++ b/lxc.spec.in @@ -251,6 +251,7 @@ fi %{_unitdir}/lxc-net.service %{_unitdir}/lxc.service %{_unitdir}/lxc@.service +%{_unitdir}/lxc-monitord.service %else %{_sysconfdir}/rc.d/init.d/lxc %{_sysconfdir}/rc.d/init.d/lxc-net diff --git a/src/lxc/cmd/lxc_monitord.c b/src/lxc/cmd/lxc_monitord.c index bcb289ca6..da7db2820 100644 --- a/src/lxc/cmd/lxc_monitord.c +++ b/src/lxc/cmd/lxc_monitord.c @@ -338,17 +338,44 @@ static void lxc_monitord_sig_handler(int sig) int main(int argc, char *argv[]) { - int ret, pipefd; + int ret, pipefd = -1; char logpath[PATH_MAX]; sigset_t mask; - char *lxcpath = argv[1]; + const char *lxcpath = NULL; bool mainloop_opened = false; bool monitord_created = false; + bool persistent = false; struct lxc_log log; - if (argc != 3) { + if (argc > 1 && !strcmp(argv[1], "--daemon")) { + persistent = true; + --argc; + ++argv; + } + + if (argc > 1) { + lxcpath = argv[1]; + --argc; + ++argv; + } else { + lxcpath = lxc_global_config_value("lxc.lxcpath"); + if (!lxcpath) { + ERROR("Failed to get default lxcpath"); + exit(EXIT_FAILURE); + } + } + + if (argc > 1) { + if (lxc_safe_int(argv[1], &pipefd) < 0) + exit(EXIT_FAILURE); + --argc; + ++argv; + } + + if (argc != 1 || (persistent != (pipefd == -1))) { fprintf(stderr, - "Usage: lxc-monitord lxcpath sync-pipe-fd\n\n" + "Usage: lxc-monitord lxcpath sync-pipe-fd\n" + " lxc-monitord --daemon lxcpath\n\n" "NOTE: lxc-monitord is intended for use by lxc internally\n" " and does not need to be run by hand\n\n"); exit(EXIT_FAILURE); @@ -371,9 +398,6 @@ int main(int argc, char *argv[]) INFO("Failed to open log file %s, log will be lost", lxcpath); lxc_log_options_no_override(); - if (lxc_safe_int(argv[2], &pipefd) < 0) - exit(EXIT_FAILURE); - if (sigfillset(&mask) || sigdelset(&mask, SIGILL) || sigdelset(&mask, SIGSEGV) || @@ -406,15 +430,17 @@ int main(int argc, char *argv[]) goto on_error; monitord_created = true; - /* sync with parent, we're ignoring the return from write - * because regardless if it works or not, the following - * close will sync us with the parent process. the - * if-empty-statement construct is to quiet the - * warn-unused-result warning. - */ - if (lxc_write_nointr(pipefd, "S", 1)) - ; - close(pipefd); + if (pipefd != -1) { + /* sync with parent, we're ignoring the return from write + * because regardless if it works or not, the following + * close will sync us with the parent process. the + * if-empty-statement construct is to quiet the + * warn-unused-result warning. + */ + if (lxc_write_nointr(pipefd, "S", 1)) + ; + close(pipefd); + } if (lxc_monitord_mainloop_add(&monitor)) { ERROR("Failed to add mainloop handlers"); @@ -425,7 +451,7 @@ int main(int argc, char *argv[]) lxc_raw_getpid(), monitor.lxcpath); for (;;) { - ret = lxc_mainloop(&monitor.descr, 1000 * 30); + ret = lxc_mainloop(&monitor.descr, persistent ? -1 : 1000 * 30); if (ret) { ERROR("mainloop returned an error"); break;