mirror of
https://git.proxmox.com/git/mirror_lxc
synced 2025-08-16 09:01:09 +00:00
Merge pull request #2089 from brauner/2018-01-17/restore_blocking_wait
lxccontainer: restore blocking wait()
This commit is contained in:
commit
dc4f8fb11a
@ -93,6 +93,7 @@ static const char *lxc_cmd_str(lxc_cmd_t cmd)
|
||||
[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)
|
||||
@ -859,6 +860,7 @@ int lxc_cmd_add_state_client(const char *name, const char *lxcpath,
|
||||
return STOPPED;
|
||||
|
||||
if (ret < 0) {
|
||||
if (errno != ECONNREFUSED)
|
||||
ERROR("%s - Failed to execute command", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
@ -1055,6 +1057,51 @@ 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)
|
||||
{
|
||||
@ -1073,6 +1120,7 @@ static int lxc_cmd_process(int fd, struct lxc_cmd_req *req,
|
||||
[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) {
|
||||
|
@ -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;
|
||||
|
@ -31,57 +31,74 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#include "commands.h"
|
||||
#include "error.h"
|
||||
#include "state.h"
|
||||
#include "monitor.h"
|
||||
#include "log.h"
|
||||
#include "lxc.h"
|
||||
#include "monitor.h"
|
||||
#include "parse.h"
|
||||
#include "state.h"
|
||||
|
||||
lxc_log_define(lxc_freezer, lxc);
|
||||
|
||||
lxc_state_t freezer_state(const char *name, const char *lxcpath)
|
||||
{
|
||||
int ret;
|
||||
char v[100];
|
||||
if (lxc_cgroup_get("freezer.state", v, 100, name, lxcpath) < 0)
|
||||
|
||||
ret = lxc_cgroup_get("freezer.state", v, sizeof(v), name, lxcpath);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
|
||||
if (v[strlen(v)-1] == '\n')
|
||||
v[strlen(v)-1] = '\0';
|
||||
v[99] = '\0';
|
||||
v[lxc_char_right_gc(v, strlen(v))] = '\0';
|
||||
|
||||
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;
|
||||
|
||||
if (lxc_cgroup_set("freezer.state", state, name, lxcpath) < 0) {
|
||||
ERROR("Failed to freeze %s:%s", lxcpath, name);
|
||||
ret = lxc_cgroup_set("freezer.state", state, name, lxcpath);
|
||||
if (ret < 0) {
|
||||
ERROR("Failed to freeze %s", name);
|
||||
return -1;
|
||||
}
|
||||
while (1) {
|
||||
if (lxc_cgroup_get("freezer.state", v, 100, name, lxcpath) < 0) {
|
||||
ERROR("Failed to get new freezer state for %s:%s", lxcpath, name);
|
||||
|
||||
for (;;) {
|
||||
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;
|
||||
}
|
||||
if (v[strlen(v)-1] == '\n')
|
||||
v[strlen(v)-1] = '\0';
|
||||
if (strncmp(v, state, strlen(state)) == 0) {
|
||||
if (name)
|
||||
lxc_monitor_send_state(name, freeze ? FROZEN : THAWED, lxcpath);
|
||||
|
||||
v[99] = '\0';
|
||||
v[lxc_char_right_gc(v, strlen(v))] = '\0';
|
||||
|
||||
ret = strncmp(v, state, state_len);
|
||||
if (ret == 0) {
|
||||
lxc_cmd_serve_state_clients(name, lxcpath, new_state);
|
||||
lxc_monitor_send_state(name, new_state, lxcpath);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -349,8 +349,7 @@ 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,
|
||||
int lxc_serve_state_clients(const char *name, struct lxc_handler *handler,
|
||||
lxc_state_t state)
|
||||
{
|
||||
ssize_t ret;
|
||||
@ -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();
|
||||
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)) {
|
||||
|
@ -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,
|
||||
|
@ -115,13 +115,26 @@ extern int lxc_wait(const char *lxcname, const char *states, int timeout,
|
||||
if (fillwaitedstates(states, s))
|
||||
return -1;
|
||||
|
||||
for (;;) {
|
||||
state = lxc_cmd_sock_get_state(lxcname, lxcpath, s, timeout);
|
||||
if (state < 0) {
|
||||
SYSERROR("failed to receive state from monitor");
|
||||
if (state >= 0)
|
||||
break;
|
||||
|
||||
if (errno != ECONNREFUSED) {
|
||||
SYSERROR("Failed to receive state from monitor");
|
||||
return -1;
|
||||
}
|
||||
|
||||
TRACE("retrieved state of container %s", lxc_state2str(state));
|
||||
if (timeout > 0)
|
||||
timeout--;
|
||||
|
||||
if (timeout == 0)
|
||||
return -1;
|
||||
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
TRACE("Retrieved state of container %s", lxc_state2str(state));
|
||||
if (!s[state])
|
||||
return -1;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user