Unverified Commit a848f32a by Stéphane Graber Committed by GitHub

Merge pull request #1931 from brauner/2017-11-20/fix_state_socket

commands: fix state socket implementation
parents 4671db7a f6fc1565
...@@ -229,7 +229,7 @@ static int lxc_cmd_send(const char *name, struct lxc_cmd_rr *cmd, ...@@ -229,7 +229,7 @@ static int lxc_cmd_send(const char *name, struct lxc_cmd_rr *cmd,
int client_fd; int client_fd;
ssize_t ret = -1; ssize_t ret = -1;
client_fd = lxc_cmd_connect(name, lxcpath, hashed_sock_name); client_fd = lxc_cmd_connect(name, lxcpath, hashed_sock_name, "command");
if (client_fd < 0) { if (client_fd < 0) {
if (client_fd == -ECONNREFUSED) if (client_fd == -ECONNREFUSED)
return -ECONNREFUSED; return -ECONNREFUSED;
...@@ -1152,11 +1152,32 @@ static int lxc_cmd_process(int fd, struct lxc_cmd_req *req, ...@@ -1152,11 +1152,32 @@ static int lxc_cmd_process(int fd, struct lxc_cmd_req *req,
} }
static void lxc_cmd_fd_cleanup(int fd, struct lxc_handler *handler, static void lxc_cmd_fd_cleanup(int fd, struct lxc_handler *handler,
struct lxc_epoll_descr *descr) struct lxc_epoll_descr *descr,
const lxc_cmd_t cmd)
{ {
struct state_client *client;
struct lxc_list *cur, *next;
lxc_console_free(handler->conf, fd); lxc_console_free(handler->conf, fd);
lxc_mainloop_del_handler(descr, fd); lxc_mainloop_del_handler(descr, fd);
close(fd); if (cmd != LXC_CMD_ADD_STATE_CLIENT) {
close(fd);
return;
}
process_lock();
lxc_list_for_each_safe(cur, &handler->state_clients, next) {
client = cur->elem;
if (client->clientfd != fd)
continue;
/* kick client from list */
close(client->clientfd);
lxc_list_del(cur);
free(cur->elem);
free(cur);
}
process_unlock();
} }
static int lxc_cmd_handler(int fd, uint32_t events, void *data, static int lxc_cmd_handler(int fd, uint32_t events, void *data,
...@@ -1242,7 +1263,7 @@ out: ...@@ -1242,7 +1263,7 @@ out:
return ret; return ret;
out_close: out_close:
lxc_cmd_fd_cleanup(fd, handler, descr); lxc_cmd_fd_cleanup(fd, handler, descr, req.cmd);
goto out; goto out;
} }
...@@ -1284,8 +1305,7 @@ out_close: ...@@ -1284,8 +1305,7 @@ out_close:
goto out; goto out;
} }
int lxc_cmd_init(const char *name, struct lxc_handler *handler, int lxc_cmd_init(const char *name, const char *lxcpath, const char *suffix)
const char *lxcpath)
{ {
int fd, len, ret; int fd, len, ret;
char path[sizeof(((struct sockaddr_un *)0)->sun_path)] = {0}; char path[sizeof(((struct sockaddr_un *)0)->sun_path)] = {0};
...@@ -1297,9 +1317,10 @@ int lxc_cmd_init(const char *name, struct lxc_handler *handler, ...@@ -1297,9 +1317,10 @@ int lxc_cmd_init(const char *name, struct lxc_handler *handler,
* because we print the sockname out sometimes. * because we print the sockname out sometimes.
*/ */
len = sizeof(path) - 2; len = sizeof(path) - 2;
ret = lxc_make_abstract_socket_name(offset, len, name, lxcpath, NULL, "command"); ret = lxc_make_abstract_socket_name(offset, len, name, lxcpath, NULL, suffix);
if (ret < 0) if (ret < 0)
return -1; return -1;
TRACE("Creating abstract unix socket \"%s\"", offset);
fd = lxc_abstract_unix_open(path, SOCK_STREAM, 0); fd = lxc_abstract_unix_open(path, SOCK_STREAM, 0);
if (fd < 0) { if (fd < 0) {
...@@ -1317,8 +1338,7 @@ int lxc_cmd_init(const char *name, struct lxc_handler *handler, ...@@ -1317,8 +1338,7 @@ int lxc_cmd_init(const char *name, struct lxc_handler *handler,
return -1; return -1;
} }
handler->conf->maincmd_fd = fd; return fd;
return 0;
} }
int lxc_cmd_mainloop_add(const char *name, struct lxc_epoll_descr *descr, int lxc_cmd_mainloop_add(const char *name, struct lxc_epoll_descr *descr,
......
...@@ -126,8 +126,7 @@ extern int lxc_cmd_add_state_client(const char *name, const char *lxcpath, ...@@ -126,8 +126,7 @@ extern int lxc_cmd_add_state_client(const char *name, const char *lxcpath,
struct lxc_epoll_descr; struct lxc_epoll_descr;
struct lxc_handler; struct lxc_handler;
extern int lxc_cmd_init(const char *name, struct lxc_handler *handler, extern int lxc_cmd_init(const char *name, const char *lxcpath, const char *suffix);
const char *lxcpath);
extern int lxc_cmd_mainloop_add(const char *name, struct lxc_epoll_descr *descr, extern int lxc_cmd_mainloop_add(const char *name, struct lxc_epoll_descr *descr,
struct lxc_handler *handler); struct lxc_handler *handler);
extern int lxc_try_cmd(const char *name, const char *lxcpath); extern int lxc_try_cmd(const char *name, const char *lxcpath);
......
...@@ -68,16 +68,14 @@ again: ...@@ -68,16 +68,14 @@ again:
goto again; goto again;
} }
ERROR("failed to receive message: %s", strerror(errno)); ERROR("Failed to receive message: %s", strerror(errno));
return -1; return -1;
} }
if (ret == 0) { if (ret < 0)
ERROR("length of message was 0");
return -1; return -1;
}
TRACE("received state %s from state client %d", TRACE("Received state %s from state client %d",
lxc_state2str(msg.value), state_client_fd); lxc_state2str(msg.value), state_client_fd);
return msg.value; return msg.value;
...@@ -163,7 +161,7 @@ int lxc_make_abstract_socket_name(char *path, int len, const char *lxcname, ...@@ -163,7 +161,7 @@ int lxc_make_abstract_socket_name(char *path, int len, const char *lxcname,
} }
int lxc_cmd_connect(const char *name, const char *lxcpath, int lxc_cmd_connect(const char *name, const char *lxcpath,
const char *hashed_sock_name) const char *hashed_sock_name, const char *suffix)
{ {
int ret, client_fd; int ret, client_fd;
char path[sizeof(((struct sockaddr_un *)0)->sun_path)] = {0}; char path[sizeof(((struct sockaddr_un *)0)->sun_path)] = {0};
...@@ -176,7 +174,7 @@ int lxc_cmd_connect(const char *name, const char *lxcpath, ...@@ -176,7 +174,7 @@ int lxc_cmd_connect(const char *name, const char *lxcpath,
*/ */
size_t len = sizeof(path) - 2; size_t len = sizeof(path) - 2;
ret = lxc_make_abstract_socket_name(offset, len, name, lxcpath, ret = lxc_make_abstract_socket_name(offset, len, name, lxcpath,
hashed_sock_name, "command"); hashed_sock_name, suffix);
if (ret < 0) if (ret < 0)
return -1; return -1;
......
...@@ -79,6 +79,6 @@ extern int lxc_add_state_client(int state_client_fd, ...@@ -79,6 +79,6 @@ extern int lxc_add_state_client(int state_client_fd,
* >= 0 client fd * >= 0 client fd
*/ */
extern int lxc_cmd_connect(const char *name, const char *lxcpath, extern int lxc_cmd_connect(const char *name, const char *lxcpath,
const char *hashed_sock_name); const char *hashed_sock_name, const char *suffix);
#endif /* __LXC_COMMANDS_UTILS_H */ #endif /* __LXC_COMMANDS_UTILS_H */
...@@ -801,6 +801,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a ...@@ -801,6 +801,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
NULL, NULL,
}; };
char **init_cmd = NULL; char **init_cmd = NULL;
int keepfds[3] = {-1, -1, -1};
/* container does exist */ /* container does exist */
if (!c) if (!c)
...@@ -921,11 +922,11 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a ...@@ -921,11 +922,11 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
ret = lxc_check_inherited(conf, true, keepfds[0] = handler->conf->maincmd_fd;
(int[]){handler->conf->maincmd_fd, keepfds[1] = handler->state_socket_pair[0];
handler->state_socket_pair[0], keepfds[2] = handler->state_socket_pair[1];
handler->state_socket_pair[1]}, ret = lxc_check_inherited(conf, true, keepfds,
3); sizeof(keepfds) / sizeof(keepfds[0]));
if (ret < 0) if (ret < 0)
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
...@@ -1010,11 +1011,11 @@ reboot: ...@@ -1010,11 +1011,11 @@ reboot:
} }
} }
ret = lxc_check_inherited(conf, daemonize, keepfds[0] = handler->conf->maincmd_fd;
(int[]){handler->conf->maincmd_fd, keepfds[1] = handler->state_socket_pair[0];
handler->state_socket_pair[0], keepfds[2] = handler->state_socket_pair[1];
handler->state_socket_pair[1]}, ret = lxc_check_inherited(conf, daemonize, keepfds,
3); sizeof(keepfds) / sizeof(keepfds[0]));
if (ret < 0) { if (ret < 0) {
lxc_free_handler(handler); lxc_free_handler(handler);
ret = 1; ret = 1;
...@@ -1816,7 +1817,7 @@ static bool do_lxcapi_shutdown(struct lxc_container *c, int timeout) ...@@ -1816,7 +1817,7 @@ static bool do_lxcapi_shutdown(struct lxc_container *c, int timeout)
if (c->lxc_conf && c->lxc_conf->haltsignal) if (c->lxc_conf && c->lxc_conf->haltsignal)
haltsignal = c->lxc_conf->haltsignal; haltsignal = c->lxc_conf->haltsignal;
INFO("Using signal number '%d' as halt signal.", haltsignal); INFO("Using signal number '%d' as halt signal", haltsignal);
/* Add a new state client before sending the shutdown signal so that we /* Add a new state client before sending the shutdown signal so that we
* don't miss a state. * don't miss a state.
...@@ -1827,13 +1828,14 @@ static bool do_lxcapi_shutdown(struct lxc_container *c, int timeout) ...@@ -1827,13 +1828,14 @@ static bool do_lxcapi_shutdown(struct lxc_container *c, int timeout)
/* Send shutdown signal to container. */ /* Send shutdown signal to container. */
if (kill(pid, haltsignal) < 0) if (kill(pid, haltsignal) < 0)
WARN("Could not send signal %d to pid %d.", haltsignal, pid); WARN("Could not send signal %d to pid %d", haltsignal, pid);
/* Retrieve the state. */ /* Retrieve the state. */
if (state_client_fd >= 0) { if (state_client_fd >= 0) {
int state; int state;
state = lxc_cmd_sock_rcv_state(state_client_fd, timeout); state = lxc_cmd_sock_rcv_state(state_client_fd, timeout);
close(state_client_fd); close(state_client_fd);
TRACE("Received state \"%s\"", lxc_state2str(state));
if (state != STOPPED) if (state != STOPPED)
return false; return false;
retv = true; retv = true;
......
...@@ -347,10 +347,10 @@ static int lxc_serve_state_clients(const char *name, ...@@ -347,10 +347,10 @@ static int lxc_serve_state_clients(const char *name,
* lxc_cmd_add_state_client() to miss a state. * lxc_cmd_add_state_client() to miss a state.
*/ */
handler->state = state; handler->state = state;
TRACE("set container state to %s", lxc_state2str(state)); TRACE("Set container state to %s", lxc_state2str(state));
if (lxc_list_empty(&handler->state_clients)) { if (lxc_list_empty(&handler->state_clients)) {
TRACE("no state clients registered"); TRACE("No state clients registered");
process_unlock(); process_unlock();
lxc_monitor_send_state(name, state, handler->lxcpath); lxc_monitor_send_state(name, state, handler->lxcpath);
return 0; return 0;
...@@ -363,12 +363,12 @@ static int lxc_serve_state_clients(const char *name, ...@@ -363,12 +363,12 @@ static int lxc_serve_state_clients(const char *name,
client = cur->elem; client = cur->elem;
if (!client->states[state]) { if (!client->states[state]) {
TRACE("state %s not registered for state client %d", TRACE("State %s not registered for state client %d",
lxc_state2str(state), client->clientfd); lxc_state2str(state), client->clientfd);
continue; continue;
} }
TRACE("sending state %s to state client %d", TRACE("Sending state %s to state client %d",
lxc_state2str(state), client->clientfd); lxc_state2str(state), client->clientfd);
again: again:
...@@ -379,7 +379,8 @@ static int lxc_serve_state_clients(const char *name, ...@@ -379,7 +379,8 @@ static int lxc_serve_state_clients(const char *name,
goto again; goto again;
} }
ERROR("failed to send message to client"); ERROR("%s - Failed to send message to client",
strerror(errno));
} }
/* kick client from list */ /* kick client from list */
...@@ -553,12 +554,12 @@ struct lxc_handler *lxc_init_handler(const char *name, struct lxc_conf *conf, ...@@ -553,12 +554,12 @@ struct lxc_handler *lxc_init_handler(const char *name, struct lxc_conf *conf,
handler->state_socket_pair[1]); handler->state_socket_pair[1]);
} }
if (lxc_cmd_init(name, handler, lxcpath)) { handler->conf->maincmd_fd = lxc_cmd_init(name, lxcpath, "command");
ERROR("failed to set up command socket"); if (handler->conf->maincmd_fd < 0) {
ERROR("Failed to set up command socket");
goto on_error; goto on_error;
} }
TRACE("Unix domain socket %d for command server is ready",
TRACE("unix domain socket %d for command server is ready",
handler->conf->maincmd_fd); handler->conf->maincmd_fd);
return handler; return handler;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment