]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
lxccontainer: restore non-blocking shutdown
authorChristian Brauner <christian.brauner@ubuntu.com>
Fri, 24 Nov 2017 22:19:34 +0000 (23:19 +0100)
committerChristian Brauner <christian.brauner@ubuntu.com>
Sun, 17 Dec 2017 14:58:41 +0000 (15:58 +0100)
If timeout is set to 0 don't block.

Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/lxccontainer.c

index 4ef0ee8588f18fe0a0aa9f5c14a0858cdd8be0ce..608eb85feb5ee967ef32aa7a78e960fb3145aa88 100644 (file)
@@ -1732,10 +1732,9 @@ WRAP_API(bool, lxcapi_reboot)
 
 static bool do_lxcapi_shutdown(struct lxc_container *c, int timeout)
 {
-       int ret, state_client_fd = -1;
-       bool retv = false;
+       int killret, ret;
        pid_t pid;
-       int haltsignal = SIGPWR;
+       int haltsignal = SIGPWR, state_client_fd = -1;
        lxc_state_t states[MAX_STATE] = {0};
 
        if (!c)
@@ -1743,6 +1742,7 @@ 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;
@@ -1754,37 +1754,49 @@ static bool do_lxcapi_shutdown(struct lxc_container *c, int timeout)
        if (c->lxc_conf && c->lxc_conf->haltsignal)
                haltsignal = c->lxc_conf->haltsignal;
 
-       INFO("Using signal number '%d' as halt signal", haltsignal);
-
        /* Add a new state client before sending the shutdown signal so that we
         * don't miss a state.
         */
-       states[STOPPED] = 1;
-       ret = lxc_cmd_add_state_client(c->name, c->config_path, states,
-                                      &state_client_fd);
+       if (timeout != 0) {
+               states[STOPPED] = 1;
+               ret = lxc_cmd_add_state_client(c->name, c->config_path, states,
+                                              &state_client_fd);
+               if (ret < 0)
+                       return false;
 
-       /* Send shutdown signal to container. */
-       if (kill(pid, haltsignal) < 0)
-               WARN("Could not send signal %d to pid %d", haltsignal, pid);
+               if (state_client_fd < 0)
+                       return false;
+
+               if (ret == STOPPED)
+                       return true;
 
-       /* Retrieve the state. */
-       if (state_client_fd >= 0) {
-               int state;
-               state = lxc_cmd_sock_rcv_state(state_client_fd, timeout);
-               close(state_client_fd);
-               TRACE("Received state \"%s\"", lxc_state2str(state));
-               if (state != STOPPED)
+               if (ret < MAX_STATE)
                        return false;
-               retv = true;
-       } else if (ret == STOPPED) {
-               TRACE("Container is already stopped");
-               retv = true;
-       } else {
-               TRACE("Received state \"%s\" instead of expected \"STOPPED\"",
-                     lxc_state2str(ret));
        }
 
-       return retv;
+       /* Send shutdown signal to container. */
+       killret = kill(pid, haltsignal);
+       if (killret < 0) {
+               WARN("Could not send signal %d to pid %d", haltsignal, pid);
+               if (state_client_fd >= 0)
+                       close(state_client_fd);
+               return false;
+       }
+       TRACE("Sent signal %d to pid %d", haltsignal, 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;
+
+       TRACE("Received state \"%s\"", lxc_state2str(ret));
+       if (ret != STOPPED)
+               return false;
+
+       return true;
 }
 
 WRAP_API_1(bool, lxcapi_shutdown, int)