From: Christian Brauner Date: Wed, 17 Jan 2018 19:46:04 +0000 (+0100) Subject: commands: add LXC_CMD_SERVE_STATE_CLIENTS X-Git-Tag: lxc-3.0.0.beta1~75^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=974a8abaf32183e32dc6b43cec53129721f03fb1;p=thirdparty%2Flxc.git commands: add LXC_CMD_SERVE_STATE_CLIENTS Signed-off-by: Christian Brauner --- diff --git a/src/lxc/commands.c b/src/lxc/commands.c index 814ce88c1..b4d0e3979 100644 --- a/src/lxc/commands.c +++ b/src/lxc/commands.c @@ -81,18 +81,19 @@ lxc_log_define(lxc_commands, lxc); static const char *lxc_cmd_str(lxc_cmd_t cmd) { static const char *const cmdname[LXC_CMD_MAX] = { - [LXC_CMD_CONSOLE] = "console", - [LXC_CMD_CONSOLE_WINCH] = "console_winch", - [LXC_CMD_STOP] = "stop", - [LXC_CMD_GET_STATE] = "get_state", - [LXC_CMD_GET_INIT_PID] = "get_init_pid", - [LXC_CMD_GET_CLONE_FLAGS] = "get_clone_flags", - [LXC_CMD_GET_CGROUP] = "get_cgroup", - [LXC_CMD_GET_CONFIG_ITEM] = "get_config_item", - [LXC_CMD_GET_NAME] = "get_name", - [LXC_CMD_GET_LXCPATH] = "get_lxcpath", - [LXC_CMD_ADD_STATE_CLIENT] = "add_state_client", - [LXC_CMD_CONSOLE_LOG] = "console_log", + [LXC_CMD_CONSOLE] = "console", + [LXC_CMD_CONSOLE_WINCH] = "console_winch", + [LXC_CMD_STOP] = "stop", + [LXC_CMD_GET_STATE] = "get_state", + [LXC_CMD_GET_INIT_PID] = "get_init_pid", + [LXC_CMD_GET_CLONE_FLAGS] = "get_clone_flags", + [LXC_CMD_GET_CGROUP] = "get_cgroup", + [LXC_CMD_GET_CONFIG_ITEM] = "get_config_item", + [LXC_CMD_GET_NAME] = "get_name", + [LXC_CMD_GET_LXCPATH] = "get_lxcpath", + [LXC_CMD_ADD_STATE_CLIENT] = "add_state_client", + [LXC_CMD_CONSOLE_LOG] = "console_log", + [LXC_CMD_SERVE_STATE_CLIENTS] = "serve_state_clients", }; if (cmd >= LXC_CMD_MAX) @@ -1056,24 +1057,70 @@ out: return lxc_cmd_rsp_send(fd, &rsp); } +int lxc_cmd_serve_state_clients(const char *name, const char *lxcpath, + lxc_state_t state) +{ + int stopped; + ssize_t ret; + struct lxc_cmd_rr cmd = { + .req = { + .cmd = LXC_CMD_SERVE_STATE_CLIENTS, + .data = INT_TO_PTR(state) + }, + }; + + ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL); + if (ret < 0) { + ERROR("%s - Failed to execute command", strerror(errno)); + return -1; + } + + return 0; +} + +static int lxc_cmd_serve_state_clients_callback(int fd, struct lxc_cmd_req *req, + struct lxc_handler *handler) +{ + int ret; + lxc_state_t state = PTR_TO_INT(req->data); + struct lxc_cmd_rsp rsp = {0}; + + ret = lxc_serve_state_clients(handler->name, handler, state); + if (ret < 0) + goto reap_client_fd; + + ret = lxc_cmd_rsp_send(fd, &rsp); + if (ret < 0) + goto reap_client_fd; + + return 0; + +reap_client_fd: + /* Special indicator to lxc_cmd_handler() to close the fd and do related + * cleanup. + */ + return 1; +} + static int lxc_cmd_process(int fd, struct lxc_cmd_req *req, struct lxc_handler *handler) { typedef int (*callback)(int, struct lxc_cmd_req *, struct lxc_handler *); callback cb[LXC_CMD_MAX] = { - [LXC_CMD_CONSOLE] = lxc_cmd_console_callback, - [LXC_CMD_CONSOLE_WINCH] = lxc_cmd_console_winch_callback, - [LXC_CMD_STOP] = lxc_cmd_stop_callback, - [LXC_CMD_GET_STATE] = lxc_cmd_get_state_callback, - [LXC_CMD_GET_INIT_PID] = lxc_cmd_get_init_pid_callback, - [LXC_CMD_GET_CLONE_FLAGS] = lxc_cmd_get_clone_flags_callback, - [LXC_CMD_GET_CGROUP] = lxc_cmd_get_cgroup_callback, - [LXC_CMD_GET_CONFIG_ITEM] = lxc_cmd_get_config_item_callback, - [LXC_CMD_GET_NAME] = lxc_cmd_get_name_callback, - [LXC_CMD_GET_LXCPATH] = lxc_cmd_get_lxcpath_callback, - [LXC_CMD_ADD_STATE_CLIENT] = lxc_cmd_add_state_client_callback, - [LXC_CMD_CONSOLE_LOG] = lxc_cmd_console_log_callback, + [LXC_CMD_CONSOLE] = lxc_cmd_console_callback, + [LXC_CMD_CONSOLE_WINCH] = lxc_cmd_console_winch_callback, + [LXC_CMD_STOP] = lxc_cmd_stop_callback, + [LXC_CMD_GET_STATE] = lxc_cmd_get_state_callback, + [LXC_CMD_GET_INIT_PID] = lxc_cmd_get_init_pid_callback, + [LXC_CMD_GET_CLONE_FLAGS] = lxc_cmd_get_clone_flags_callback, + [LXC_CMD_GET_CGROUP] = lxc_cmd_get_cgroup_callback, + [LXC_CMD_GET_CONFIG_ITEM] = lxc_cmd_get_config_item_callback, + [LXC_CMD_GET_NAME] = lxc_cmd_get_name_callback, + [LXC_CMD_GET_LXCPATH] = lxc_cmd_get_lxcpath_callback, + [LXC_CMD_ADD_STATE_CLIENT] = lxc_cmd_add_state_client_callback, + [LXC_CMD_CONSOLE_LOG] = lxc_cmd_console_log_callback, + [LXC_CMD_SERVE_STATE_CLIENTS] = lxc_cmd_serve_state_clients_callback, }; if (req->cmd >= LXC_CMD_MAX) { diff --git a/src/lxc/commands.h b/src/lxc/commands.h index bfdb03997..e24ef7a5c 100644 --- a/src/lxc/commands.h +++ b/src/lxc/commands.h @@ -50,6 +50,7 @@ typedef enum { LXC_CMD_GET_LXCPATH, LXC_CMD_ADD_STATE_CLIENT, LXC_CMD_CONSOLE_LOG, + LXC_CMD_SERVE_STATE_CLIENTS, LXC_CMD_MAX, } lxc_cmd_t; @@ -116,6 +117,8 @@ extern int lxc_cmd_stop(const char *name, const char *lxcpath); extern int lxc_cmd_add_state_client(const char *name, const char *lxcpath, lxc_state_t states[MAX_STATE], int *state_client_fd); +extern int lxc_cmd_serve_state_clients(const char *name, const char *lxcpath, + lxc_state_t state); struct lxc_epoll_descr; struct lxc_handler; diff --git a/src/lxc/freezer.c b/src/lxc/freezer.c index ae4909ee9..96d54be3d 100644 --- a/src/lxc/freezer.c +++ b/src/lxc/freezer.c @@ -31,6 +31,7 @@ #include #include +#include "commands.h" #include "error.h" #include "log.h" #include "lxc.h" @@ -45,7 +46,7 @@ lxc_state_t freezer_state(const char *name, const char *lxcpath) int ret; char v[100]; - ret = lxc_cgroup_get("freezer.state", v, 100, name, lxcpath); + ret = lxc_cgroup_get("freezer.state", v, sizeof(v), name, lxcpath); if (ret < 0) return -1; @@ -55,11 +56,13 @@ lxc_state_t freezer_state(const char *name, const char *lxcpath) return lxc_str2state(v); } -static int do_freeze_thaw(int freeze, const char *name, const char *lxcpath) +static int do_freeze_thaw(bool freeze, const char *name, const char *lxcpath) { int ret; char v[100]; const char *state = freeze ? "FROZEN" : "THAWED"; + size_t state_len = 6; + lxc_state_t new_state = freeze ? FROZEN : THAWED; ret = lxc_cgroup_set("freezer.state", state, name, lxcpath); if (ret < 0) { @@ -68,7 +71,7 @@ static int do_freeze_thaw(int freeze, const char *name, const char *lxcpath) } for (;;) { - ret = lxc_cgroup_get("freezer.state", v, 100, name, lxcpath); + ret = lxc_cgroup_get("freezer.state", v, sizeof(v), name, lxcpath); if (ret < 0) { ERROR("Failed to get freezer state of %s", name); return -1; @@ -77,9 +80,10 @@ static int do_freeze_thaw(int freeze, const char *name, const char *lxcpath) v[99] = '\0'; v[lxc_char_right_gc(v, strlen(v))] = '\0'; - ret = strncmp(v, state, strlen(state)); + ret = strncmp(v, state, state_len); if (ret == 0) { - lxc_monitor_send_state(name, freeze ? FROZEN : THAWED, lxcpath); + lxc_cmd_serve_state_clients(name, lxcpath, new_state); + lxc_monitor_send_state(name, new_state, lxcpath); return 0; } @@ -89,11 +93,12 @@ static int do_freeze_thaw(int freeze, const char *name, const char *lxcpath) int lxc_freeze(const char *name, const char *lxcpath) { + lxc_cmd_serve_state_clients(name, lxcpath, FREEZING); lxc_monitor_send_state(name, FREEZING, lxcpath); - return do_freeze_thaw(1, name, lxcpath); + return do_freeze_thaw(true, name, lxcpath); } int lxc_unfreeze(const char *name, const char *lxcpath) { - return do_freeze_thaw(0, name, lxcpath); + return do_freeze_thaw(false, name, lxcpath); } diff --git a/src/lxc/start.c b/src/lxc/start.c index f6e1a961f..89a194fd1 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c @@ -349,9 +349,8 @@ static int signal_handler(int fd, uint32_t events, void *data, return LXC_MAINLOOP_CLOSE; } -static int lxc_serve_state_clients(const char *name, - struct lxc_handler *handler, - lxc_state_t state) +int lxc_serve_state_clients(const char *name, struct lxc_handler *handler, + lxc_state_t state) { ssize_t ret; struct lxc_list *cur, *next; @@ -359,7 +358,11 @@ static int lxc_serve_state_clients(const char *name, struct lxc_msg msg = {.type = lxc_msg_state, .value = state}; process_lock(); - handler->state = state; + if (state == THAWED) + handler->state = RUNNING; + else + handler->state = state; + TRACE("Set container state to %s", lxc_state2str(state)); if (lxc_list_empty(&handler->conf->state_clients)) { diff --git a/src/lxc/start.h b/src/lxc/start.h index bfa4c9062..503154045 100644 --- a/src/lxc/start.h +++ b/src/lxc/start.h @@ -117,7 +117,11 @@ struct lxc_operations { }; extern int lxc_poll(const char *name, struct lxc_handler *handler); -extern int lxc_set_state(const char *name, struct lxc_handler *handler, lxc_state_t state); +extern int lxc_set_state(const char *name, struct lxc_handler *handler, + lxc_state_t state); +extern int lxc_serve_state_clients(const char *name, + struct lxc_handler *handler, + lxc_state_t state); extern void lxc_abort(const char *name, struct lxc_handler *handler); extern struct lxc_handler *lxc_init_handler(const char *name, struct lxc_conf *conf, diff --git a/src/lxc/state.c b/src/lxc/state.c index 13b99d8ff..c7882851c 100644 --- a/src/lxc/state.c +++ b/src/lxc/state.c @@ -125,13 +125,13 @@ extern int lxc_wait(const char *lxcname, const char *states, int timeout, return -1; } - sleep(1); - if (timeout > 0) timeout--; if (timeout == 0) return -1; + + sleep(1); } TRACE("Retrieved state of container %s", lxc_state2str(state));