]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
commands: add LXC_CMD_SERVE_STATE_CLIENTS 2089/head
authorChristian Brauner <christian.brauner@ubuntu.com>
Wed, 17 Jan 2018 19:46:04 +0000 (20:46 +0100)
committerChristian Brauner <christian.brauner@ubuntu.com>
Wed, 17 Jan 2018 23:43:58 +0000 (00:43 +0100)
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/commands.c
src/lxc/commands.h
src/lxc/freezer.c
src/lxc/start.c
src/lxc/start.h
src/lxc/state.c

index 814ce88c1f1e2d515cce93b6fb7fe7669399b5e8..b4d0e3979b4f46bb5213c010f868132d7742c039 100644 (file)
@@ -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) {
index bfdb03997abe2e579ac4d659abea8f2227f9460d..e24ef7a5c1c6205e181507724f0e06fd80bfde25 100644 (file)
@@ -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;
index ae4909ee9d858fc0b4f7609a0b67e59c4dcb0f58..96d54be3deb7c34dd96f05ebd902687a45b444eb 100644 (file)
@@ -31,6 +31,7 @@
 #include <sys/types.h>
 #include <sys/param.h>
 
+#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);
 }
index f6e1a961f32c62fde3c37b4a6ec7f44bd595f83b..89a194fd1c45c83fc30ea312457e8a9f930e50c4 100644 (file)
@@ -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)) {
index bfa4c9062c855b1608715b918e15e4042da8398f..50315404560ed8c00b3aa419ab0a9fb26919a7de 100644 (file)
@@ -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,
index 13b99d8ff09471f137917c4e60a2641e8451fcd8..c7882851cd25d82e5cb8519bc59dd4e76cd791be 100644 (file)
@@ -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));