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-2.0.10~405 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b59956a4fdf93393657c3b715775ac9f2bf7955b;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 d3db288ec..a2f57e79c 100644 --- a/src/lxc/commands.c +++ b/src/lxc/commands.c @@ -80,17 +80,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] = "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) @@ -909,23 +911,81 @@ reap_client_fd: return 1; } +static int lxc_cmd_console_log_callback(int fd, struct lxc_cmd_req *req, + struct lxc_handler *handler) +{ + struct lxc_cmd_rsp rsp = {0}; + + rsp.ret = -ENOSYS; + lxc_cmd_rsp_send(fd, &rsp); + + return -ENOSYS; +} + +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] = 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 dfcc6707e..9e56d85ea 100644 --- a/src/lxc/commands.h +++ b/src/lxc/commands.h @@ -48,6 +48,8 @@ typedef enum { LXC_CMD_GET_NAME, LXC_CMD_GET_LXCPATH, LXC_CMD_ADD_STATE_CLIENT, + LXC_CMD_CONSOLE_LOG, + LXC_CMD_SERVE_STATE_CLIENTS, LXC_CMD_MAX, } lxc_cmd_t; @@ -106,6 +108,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 4a9132d0f..855de4bf4 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c @@ -340,9 +340,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; @@ -350,7 +349,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->state_clients)) { diff --git a/src/lxc/start.h b/src/lxc/start.h index 63706b466..8658d26e4 100644 --- a/src/lxc/start.h +++ b/src/lxc/start.h @@ -122,7 +122,11 @@ struct state_client { }; 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 0193b77fa..45d08b15c 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));