]> git.proxmox.com Git - mirror_lxc.git/blobdiff - src/lxc/cmd/lxc_monitord.c
mainloop: add io_uring support
[mirror_lxc.git] / src / lxc / cmd / lxc_monitord.c
index 3ec7a756daa922b0b79c57ad4dc0a01343de4caa..a18712b64b4e22293d1b62702b6899e887460fca 100644 (file)
@@ -28,7 +28,7 @@
 #include "log.h"
 #include "mainloop.h"
 #include "monitor.h"
-#include "raw_syscalls.h"
+#include "process_utils.h"
 #include "utils.h"
 
 #define CLIENTFDS_CHUNK 64
@@ -37,8 +37,6 @@ lxc_log_define(lxc_monitord, lxc);
 
 sigjmp_buf mark;
 
-static void lxc_monitord_cleanup(void);
-
 /*
  * Defines the structure to store the monitor information
  * @lxcpath        : the path being monitored
@@ -56,7 +54,7 @@ struct lxc_monitor {
        int *clientfds;
        int clientfds_size;
        int clientfds_cnt;
-       struct lxc_epoll_descr descr;
+       struct lxc_async_descr descr;
 };
 
 static struct lxc_monitor monitor;
@@ -113,31 +111,27 @@ static int lxc_monitord_fifo_delete(struct lxc_monitor *mon)
        return 0;
 }
 
-static void lxc_monitord_sockfd_remove(struct lxc_monitor *mon, int fd)
+static int lxc_monitord_sockfd_remove(struct lxc_monitor *mon, int fd)
 {
        int i;
 
-       if (lxc_mainloop_del_handler(&mon->descr, fd))
-               CRIT("File descriptor %d not found in mainloop", fd);
-       close(fd);
-
        for (i = 0; i < mon->clientfds_cnt; i++)
                if (mon->clientfds[i] == fd)
                        break;
 
        if (i >= mon->clientfds_cnt) {
                CRIT("File descriptor %d not found in clients array", fd);
-               lxc_monitord_cleanup();
-               exit(EXIT_FAILURE);
+               return LXC_MAINLOOP_ERROR;
        }
 
        memmove(&mon->clientfds[i], &mon->clientfds[i+1],
                (mon->clientfds_cnt - i - 1) * sizeof(mon->clientfds[0]));
        mon->clientfds_cnt--;
+       return LXC_MAINLOOP_DISARM;
 }
 
 static int lxc_monitord_sock_handler(int fd, uint32_t events, void *data,
-                                    struct lxc_epoll_descr *descr)
+                                    struct lxc_async_descr *descr)
 {
        struct lxc_monitor *mon = data;
 
@@ -146,18 +140,20 @@ static int lxc_monitord_sock_handler(int fd, uint32_t events, void *data,
                char buf[4];
 
                rc = lxc_read_nointr(fd, buf, sizeof(buf));
-               if (rc > 0 && !strncmp(buf, "quit", 4))
+               if (rc > 0 && !strncmp(buf, "quit", 4)) {
                        quit = LXC_MAINLOOP_CLOSE;
+                       return LXC_MAINLOOP_CLOSE;
+               }
        }
 
        if (events & EPOLLHUP)
-               lxc_monitord_sockfd_remove(mon, fd);
+               return lxc_monitord_sockfd_remove(mon, fd);
 
        return quit;
 }
 
 static int lxc_monitord_sock_accept(int fd, uint32_t events, void *data,
-                                   struct lxc_epoll_descr *descr)
+                                   struct lxc_async_descr *descr)
 {
        int ret, clientfd;
        struct lxc_monitor *mon = data;
@@ -202,7 +198,9 @@ static int lxc_monitord_sock_accept(int fd, uint32_t events, void *data,
        }
 
        ret = lxc_mainloop_add_handler(&mon->descr, clientfd,
-                                      lxc_monitord_sock_handler, mon);
+                                      lxc_monitord_sock_handler,
+                                      default_cleanup_handler,
+                                      mon, "lxc_monitord_sock_handler");
        if (ret < 0) {
                ERROR("Failed to add socket handler");
                goto err1;
@@ -264,26 +262,20 @@ static int lxc_monitord_create(struct lxc_monitor *mon)
 
 static void lxc_monitord_delete(struct lxc_monitor *mon)
 {
-       int i;
-
-       lxc_mainloop_del_handler(&mon->descr, mon->listenfd);
        lxc_abstract_unix_close(mon->listenfd);
        lxc_monitord_sock_delete(mon);
 
-       lxc_mainloop_del_handler(&mon->descr, mon->fifofd);
        lxc_monitord_fifo_delete(mon);
        close(mon->fifofd);
 
-       for (i = 0; i < mon->clientfds_cnt; i++) {
-               lxc_mainloop_del_handler(&mon->descr, mon->clientfds[i]);
+       for (int i = 0; i < mon->clientfds_cnt; i++)
                close(mon->clientfds[i]);
-       }
 
        mon->clientfds_cnt = 0;
 }
 
 static int lxc_monitord_fifo_handler(int fd, uint32_t events, void *data,
-                                    struct lxc_epoll_descr *descr)
+                                    struct lxc_async_descr *descr)
 {
        int ret, i;
        struct lxc_msg msglxc;
@@ -310,14 +302,18 @@ static int lxc_monitord_mainloop_add(struct lxc_monitor *mon)
        int ret;
 
        ret = lxc_mainloop_add_handler(&mon->descr, mon->fifofd,
-                                      lxc_monitord_fifo_handler, mon);
+                                      lxc_monitord_fifo_handler,
+                                      default_cleanup_handler,
+                                      mon, "lxc_monitord_fifo_handler");
        if (ret < 0) {
                ERROR("Failed to add to mainloop monitor handler for fifo");
                return -1;
        }
 
        ret = lxc_mainloop_add_handler(&mon->descr, mon->listenfd,
-                                      lxc_monitord_sock_accept, mon);
+                                      lxc_monitord_sock_accept,
+                                      default_cleanup_handler,
+                                      mon, "lxc_monitord_sock_accept");
        if (ret < 0) {
                ERROR("Failed to add to mainloop monitor handler for listen socket");
                return -1;
@@ -326,11 +322,6 @@ static int lxc_monitord_mainloop_add(struct lxc_monitor *mon)
        return 0;
 }
 
-static void lxc_monitord_cleanup(void)
-{
-       lxc_monitord_delete(&monitor);
-}
-
 static void lxc_monitord_sig_handler(int sig)
 {
        siglongjmp(mark, 1);
@@ -338,41 +329,46 @@ static void lxc_monitord_sig_handler(int sig)
 
 int main(int argc, char *argv[])
 {
-       int ret, pipefd;
-       char logpath[PATH_MAX];
+       int ret, pipefd = -1;
        sigset_t mask;
-       char *lxcpath = argv[1];
+       const char *lxcpath = NULL;
        bool mainloop_opened = false;
        bool monitord_created = false;
-       struct lxc_log log;
+       bool persistent = false;
 
-       if (argc != 3) {
-               fprintf(stderr,
-                       "Usage: lxc-monitord lxcpath sync-pipe-fd\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);
+       if (argc > 1 && !strcmp(argv[1], "--daemon")) {
+               persistent = true;
+               --argc;
+               ++argv;
        }
 
-       ret = snprintf(logpath, sizeof(logpath), "%s/lxc-monitord.log",
-                      (strcmp(LXCPATH, lxcpath) ? lxcpath : LOGPATH));
-       if (ret < 0 || ret >= sizeof(logpath))
-               exit(EXIT_FAILURE);
-
-       log.name = NULL;
-       log.file = logpath;
-       log.level = "DEBUG";
-       log.prefix = "lxc-monitord";
-       log.quiet = 0;
-       log.lxcpath = lxcpath;
+       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);
+               }
+       }
 
-       ret = lxc_log_init(&log);
-       if (ret)
-               INFO("Failed to open log file %s, log will be lost", lxcpath);
-       lxc_log_options_no_override();
+       if (argc > 1) {
+               if (lxc_safe_int(argv[1], &pipefd) < 0)
+                       exit(EXIT_FAILURE);
+               --argc;
+               ++argv;
+       }
 
-       if (lxc_safe_int(argv[2], &pipefd) < 0)
+       if (argc != 1 || (persistent != (pipefd == -1))) {
+               fprintf(stderr,
+                       "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);
+       }
 
        if (sigfillset(&mask) ||
            sigdelset(&mask, SIGILL)  ||
@@ -406,15 +402,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 +423,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;
@@ -446,11 +444,11 @@ on_signal:
        ret = EXIT_SUCCESS;
 
 on_error:
-       if (monitord_created)
-               lxc_monitord_cleanup();
-
        if (mainloop_opened)
                lxc_mainloop_close(&monitor.descr);
 
+       if (monitord_created)
+               lxc_monitord_delete(&monitor);
+
        exit(ret);
 }