]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
lxccontainer: switch to pidfds whenever possible
authorChristian Brauner <christian.brauner@ubuntu.com>
Wed, 11 Mar 2020 13:36:58 +0000 (14:36 +0100)
committerChristian Brauner <christian.brauner@ubuntu.com>
Wed, 11 Mar 2020 14:59:33 +0000 (15:59 +0100)
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/commands.c
src/lxc/lxccontainer.c
src/lxc/utils.c

index ec3f4233a1ec04b51d02f014a3389f35fbd184a4..08fada3ac2939241e2dc3cb25ce3d3844aa9dfde 100644 (file)
@@ -688,8 +688,17 @@ static int lxc_cmd_stop_callback(int fd, struct lxc_cmd_req *req,
        if (handler->conf->stopsignal)
                stopsignal = handler->conf->stopsignal;
        memset(&rsp, 0, sizeof(rsp));
-       rsp.ret = kill(handler->pid, stopsignal);
+
+       if (handler-> pidfd >= 0)
+               rsp.ret = lxc_raw_pidfd_send_signal(handler->pidfd, stopsignal, NULL, 0);
+       else
+               rsp.ret = kill(handler->pid, stopsignal);
        if (!rsp.ret) {
+               if (handler->pidfd >= 0)
+                       TRACE("Sent signal %d to pidfd %d", stopsignal, handler->pidfd);
+               else
+                       TRACE("Sent signal %d to pidfd %d", stopsignal, handler->pid);
+
                rsp.ret = cgroup_ops->unfreeze(cgroup_ops, -1);
                if (!rsp.ret)
                        return 0;
index 5f9fd1240674c36d7a5800e52aac72f3fd8fcd90..5dddd14eca707abddc861bfbf0ad57b460eea84a 100644 (file)
@@ -1976,8 +1976,9 @@ static bool lxcapi_create(struct lxc_container *c, const char *t,
 
 static bool do_lxcapi_reboot(struct lxc_container *c)
 {
+       __do_close_prot_errno int pidfd = -EBADF;
+       pid_t pid = -1;
        int ret;
-       pid_t pid;
        int rebootsignal = SIGINT;
 
        if (!c)
@@ -1986,18 +1987,23 @@ static bool do_lxcapi_reboot(struct lxc_container *c)
        if (!do_lxcapi_is_running(c))
                return false;
 
-       pid = do_lxcapi_init_pid(c);
-       if (pid <= 0)
-               return false;
+       pidfd = do_lxcapi_init_pidfd(c);
+       if (pidfd < 0) {
+               pid = do_lxcapi_init_pid(c);
+               if (pid <= 0)
+                       return false;
+       }
 
        if (c->lxc_conf && c->lxc_conf->rebootsignal)
                rebootsignal = c->lxc_conf->rebootsignal;
 
-       ret = kill(pid, rebootsignal);
-       if (ret < 0) {
-               WARN("Failed to send signal %d to pid %d", rebootsignal, pid);
-               return false;
-       }
+       if (pidfd >= 0)
+               ret = lxc_raw_pidfd_send_signal(pidfd, rebootsignal, NULL, 0);
+       else
+               ret = kill(pid, rebootsignal);
+       if (ret < 0)
+               return log_warn(false, "Failed to send signal %d to pid %d",
+                               rebootsignal, pid);
 
        return true;
 }
@@ -2006,10 +2012,11 @@ WRAP_API(bool, lxcapi_reboot)
 
 static bool do_lxcapi_reboot2(struct lxc_container *c, int timeout)
 {
-       int killret, ret;
-       pid_t pid;
-       int rebootsignal = SIGINT, state_client_fd = -1;
+       __do_close_prot_errno int pidfd = -EBADF, state_client_fd = -EBADF;
+       int rebootsignal = SIGINT;
+       pid_t pid = -1;
        lxc_state_t states[MAX_STATE] = {0};
+       int killret, ret;
 
        if (!c)
                return false;
@@ -2017,9 +2024,12 @@ static bool do_lxcapi_reboot2(struct lxc_container *c, int timeout)
        if (!do_lxcapi_is_running(c))
                return true;
 
-       pid = do_lxcapi_init_pid(c);
-       if (pid <= 0)
-               return true;
+       pidfd = do_lxcapi_init_pidfd(c);
+       if (pidfd < 0) {
+               pid = do_lxcapi_init_pid(c);
+               if (pid <= 0)
+                       return true;
+       }
 
        if (c->lxc_conf && c->lxc_conf->rebootsignal)
                rebootsignal = c->lxc_conf->rebootsignal;
@@ -2045,21 +2055,18 @@ static bool do_lxcapi_reboot2(struct lxc_container *c, int timeout)
        }
 
        /* Send reboot signal to container. */
-       killret = kill(pid, rebootsignal);
-       if (killret < 0) {
-               if (state_client_fd >= 0)
-                       close(state_client_fd);
-
-               WARN("Failed to send signal %d to pid %d", rebootsignal, pid);
-               return false;
-       }
+       if (pidfd >= 0)
+               killret = lxc_raw_pidfd_send_signal(pidfd, rebootsignal, NULL, 0);
+       else
+               killret = kill(pid, rebootsignal);
+       if (killret < 0)
+               return log_warn(false, "Failed to send signal %d to pid %d", rebootsignal, pid);
        TRACE("Sent signal %d to pid %d", rebootsignal, pid);
 
        if (timeout == 0)
                return true;
 
        ret = lxc_cmd_sock_rcv_state(state_client_fd, timeout);
-       close(state_client_fd);
        if (ret < 0)
                return false;
 
@@ -2074,11 +2081,11 @@ WRAP_API_1(bool, lxcapi_reboot2, int)
 
 static bool do_lxcapi_shutdown(struct lxc_container *c, int timeout)
 {
-       __do_close_prot_errno int state_client_fd = -EBADF;
+       __do_close_prot_errno int pidfd = -EBADF, state_client_fd = -EBADF;
        int haltsignal = SIGPWR;
+       pid_t pid = -1;
        lxc_state_t states[MAX_STATE] = {0};
        int killret, ret;
-       pid_t pid;
 
        if (!c)
                return false;
@@ -2086,9 +2093,12 @@ static bool do_lxcapi_shutdown(struct lxc_container *c, int timeout)
        if (!do_lxcapi_is_running(c))
                return true;
 
-       pid = do_lxcapi_init_pid(c);
-       if (pid <= 0)
-               return true;
+       pidfd = do_lxcapi_init_pidfd(c);
+       if (pidfd < 0) {
+               pid = do_lxcapi_init_pid(c);
+               if (pid <= 0)
+                       return true;
+       }
 
        /* Detect whether we should send SIGRTMIN + 3 (e.g. systemd). */
        if (c->lxc_conf && c->lxc_conf->haltsignal)
@@ -2117,11 +2127,21 @@ static bool do_lxcapi_shutdown(struct lxc_container *c, int timeout)
        }
 
        /* Send shutdown signal to container. */
-       killret = kill(pid, haltsignal);
-       if (killret < 0)
-               return log_warn(false, "Failed to send signal %d to pid %d", haltsignal, pid);
+       if (pidfd >= 0) {
+               killret = lxc_raw_pidfd_send_signal(pidfd, haltsignal, NULL, 0);
+               if (killret < 0)
+                       return log_warn(false, "Failed to send signal %d to pidfd %d",
+                                       haltsignal, pidfd);
 
-       TRACE("Sent signal %d to pid %d", haltsignal, pid);
+               TRACE("Sent signal %d to pidfd %d", haltsignal, pidfd);
+       } else {
+               killret = kill(pid, haltsignal);
+               if (killret < 0)
+                       return log_warn(false, "Failed to send signal %d to pid %d",
+                                       haltsignal, pid);
+
+               TRACE("Sent signal %d to pid %d", haltsignal, pid);
+       }
 
        if (timeout == 0)
                return true;
index 0fda91762f0a16d494e205d4cb9874d0fa0d7b79..8a2eacaf80ccabd3e779e9688950852e752d73e7 100644 (file)
@@ -1869,10 +1869,6 @@ bool lxc_can_use_pidfd(int pidfd)
        if (pidfd < 0)
                return log_error(false, "Kernel does not support pidfds");
 
-       ret = lxc_raw_pidfd_send_signal(pidfd, 0, NULL, 0);
-       if (ret)
-               return log_error_errno(false, errno, "Kernel does not support sending signals through pidfds");
-
        /*
         * We don't care whether or not children were in a waitable state. We
         * just care whether waitid() recognizes P_PIDFD.