diff --git a/src/lxc/commands.c b/src/lxc/commands.c index 1ae9d24e1..262e780d1 100644 --- a/src/lxc/commands.c +++ b/src/lxc/commands.c @@ -36,11 +36,24 @@ #include "mainloop.h" #include "af_unix.h" +/* + * This file provides the different functions to have the client + * and the server to communicate + * + * Each command is transactional, the client send a request to + * the server and the server answer the request with a message + * giving the request's status (zero or a negative errno value). + * + * Each command is wrapped in a ancillary message in order to pass + * a credential making possible to the server to check if the client + * is allowed to ask for this command or not. + * + */ + lxc_log_define(lxc_commands, lxc); -/*---------------------------------------------------------------------------- - * functions used by processes requesting command to lxc-start - *--------------------------------------------------------------------------*/ +#define abstractname "LXCPATH/%s/command" + static int receive_answer(int sock, struct lxc_answer *answer) { int ret; @@ -53,13 +66,13 @@ static int receive_answer(int sock, struct lxc_answer *answer) } extern int lxc_command(const char *name, struct lxc_command *command, - int *stopped) + int *stopped) { int sock, ret = -1; char path[sizeof(((struct sockaddr_un *)0)->sun_path)] = { 0 }; char *offset = &path[1]; - sprintf(offset, "/var/run/lxc/%s/command", name); + sprintf(offset, abstractname, name); sock = lxc_af_unix_connect(path); if (sock < 0 && errno == ECONNREFUSED) { @@ -94,26 +107,19 @@ out_close: goto out; } -/*---------------------------------------------------------------------------- - * functions used by lxc-start process - *--------------------------------------------------------------------------*/ -extern void lxc_console_remove_fd(int fd, struct lxc_tty_info *tty_info); -extern int lxc_console_callback(int fd, struct lxc_request *request, - struct lxc_handler *handler); -extern int lxc_stop_callback(int fd, struct lxc_request *request, - struct lxc_handler *handler); -extern int lxc_state_callback(int fd, struct lxc_request *request, - struct lxc_handler *handler); +extern void lxc_console_remove_fd(int, struct lxc_tty_info *); +extern int lxc_console_callback(int, struct lxc_request *, struct lxc_handler *); +extern int lxc_stop_callback(int, struct lxc_request *, struct lxc_handler *); +extern int lxc_state_callback(int, struct lxc_request *, struct lxc_handler *); static int trigger_command(int fd, struct lxc_request *request, - struct lxc_handler *handler) + struct lxc_handler *handler) { - typedef int (*callback)(int, struct lxc_request *, - struct lxc_handler *); + typedef int (*callback)(int, struct lxc_request *, struct lxc_handler *); callback cb[LXC_COMMAND_MAX] = { - [LXC_COMMAND_TTY] = lxc_console_callback, - [LXC_COMMAND_STOP] = lxc_stop_callback, + [LXC_COMMAND_TTY] = lxc_console_callback, + [LXC_COMMAND_STOP] = lxc_stop_callback, [LXC_COMMAND_STATE] = lxc_state_callback, }; @@ -124,15 +130,14 @@ static int trigger_command(int fd, struct lxc_request *request, } static void command_fd_cleanup(int fd, struct lxc_handler *handler, - struct lxc_epoll_descr *descr) + struct lxc_epoll_descr *descr) { lxc_console_remove_fd(fd, &handler->tty_info); lxc_mainloop_del_handler(descr, fd); close(fd); } -static int command_handler(int fd, void *data, - struct lxc_epoll_descr *descr) +static int command_handler(int fd, void *data, struct lxc_epoll_descr *descr) { int ret; struct lxc_request request; @@ -144,7 +149,9 @@ static int command_handler(int fd, void *data, struct lxc_answer answer = { .ret = ret }; send(fd, &answer, sizeof(answer), 0); goto out_close; - } else if (ret < 0) { + } + + if (ret < 0) { SYSERROR("failed to receive data on command socket"); goto out_close; } @@ -176,7 +183,7 @@ out_close: static int incoming_command_handler(int fd, void *data, struct lxc_epoll_descr *descr) { - int ret = 1, connection; + int opt = 1, ret = -1, connection; connection = accept(fd, NULL, 0); if (connection < 0) { @@ -184,7 +191,7 @@ static int incoming_command_handler(int fd, void *data, return -1; } - if (setsockopt(connection, SOL_SOCKET, SO_PASSCRED, &ret, sizeof(ret))) { + if (setsockopt(connection, SOL_SOCKET, SO_PASSCRED, &opt, sizeof(opt))) { SYSERROR("failed to enable credential on socket"); goto out_close; } @@ -210,7 +217,7 @@ extern int lxc_command_mainloop_add(const char *name, struct lxc_epoll_descr *de char path[sizeof(((struct sockaddr_un *)0)->sun_path)] = { 0 }; char *offset = &path[1]; - sprintf(offset, "/var/run/lxc/%s/command", name); + sprintf(offset, abstractname, name); fd = lxc_af_unix_open(path, SOCK_STREAM, 0); if (fd < 0) { @@ -218,8 +225,7 @@ extern int lxc_command_mainloop_add(const char *name, struct lxc_epoll_descr *de return -1; } - ret = lxc_mainloop_add_handler(descr, fd, incoming_command_handler, - handler); + ret = lxc_mainloop_add_handler(descr, fd, incoming_command_handler, handler); if (ret) { ERROR("failed to add handler for command socket"); close(fd);