lxccontainer: restore non-blocking shutdown

If timeout is set to 0 don't block.

Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
This commit is contained in:
Christian Brauner 2017-11-24 23:19:34 +01:00
parent bc631984fc
commit f8bdb6dcc4
No known key found for this signature in database
GPG Key ID: 8EB056D53EECB12D

View File

@ -1862,10 +1862,9 @@ WRAP_API_1(bool, lxcapi_reboot2, int)
static bool do_lxcapi_shutdown(struct lxc_container *c, int timeout) static bool do_lxcapi_shutdown(struct lxc_container *c, int timeout)
{ {
int ret, state_client_fd = -1; int killret, ret;
bool retv = false;
pid_t pid; pid_t pid;
int haltsignal = SIGPWR; int haltsignal = SIGPWR, state_client_fd = -1;
lxc_state_t states[MAX_STATE] = {0}; lxc_state_t states[MAX_STATE] = {0};
if (!c) if (!c)
@ -1873,6 +1872,7 @@ static bool do_lxcapi_shutdown(struct lxc_container *c, int timeout)
if (!do_lxcapi_is_running(c)) if (!do_lxcapi_is_running(c))
return true; return true;
pid = do_lxcapi_init_pid(c); pid = do_lxcapi_init_pid(c);
if (pid <= 0) if (pid <= 0)
return true; return true;
@ -1884,37 +1884,49 @@ static bool do_lxcapi_shutdown(struct lxc_container *c, int timeout)
if (c->lxc_conf && c->lxc_conf->haltsignal) if (c->lxc_conf && c->lxc_conf->haltsignal)
haltsignal = 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 /* Add a new state client before sending the shutdown signal so that we
* don't miss a state. * don't miss a state.
*/ */
if (timeout != 0) {
states[STOPPED] = 1; states[STOPPED] = 1;
ret = lxc_cmd_add_state_client(c->name, c->config_path, states, ret = lxc_cmd_add_state_client(c->name, c->config_path, states,
&state_client_fd); &state_client_fd);
if (ret < 0)
/* Send shutdown signal to container. */ return false;
if (kill(pid, haltsignal) < 0)
WARN("Could not send signal %d to pid %d", haltsignal, pid); if (state_client_fd < 0)
return false;
/* Retrieve the state. */
if (state_client_fd >= 0) { if (ret == STOPPED)
int state; return true;
state = lxc_cmd_sock_rcv_state(state_client_fd, timeout);
close(state_client_fd); if (ret < MAX_STATE)
TRACE("Received state \"%s\"", lxc_state2str(state));
if (state != STOPPED)
return false; 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) WRAP_API_1(bool, lxcapi_shutdown, int)