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)
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) {
#include <sys/types.h>
#include <sys/param.h>
+#include "commands.h"
#include "error.h"
#include "log.h"
#include "lxc.h"
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;
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) {
}
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;
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;
}
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);
}