commands: non-functional changes

parent 51d1ec4f
......@@ -21,53 +21,54 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdio.h>
#include "config.h"
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <malloc.h>
#include <poll.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/param.h>
#include <malloc.h>
#include <stdlib.h>
#include "log.h"
#include "lxc.h"
#include "conf.h"
#include "start.h" /* for struct lxc_handler */
#include "utils.h"
#include "af_unix.h"
#include "cgroup.h"
#include "commands.h"
#include "commands_utils.h"
#include "console.h"
#include "conf.h"
#include "confile.h"
#include "console.h"
#include "log.h"
#include "lxc.h"
#include "lxclock.h"
#include "mainloop.h"
#include "monitor.h"
#include "af_unix.h"
#include "config.h"
#include "start.h"
#include "utils.h"
/*
* This file provides the different functions for clients to
* query/command the server. The client is typically some lxc
* tool and the server is typically the container (ie. lxc-start).
* This file provides the different functions for clients to query/command the
* server. The client is typically some lxc tool and the server is typically the
* container (ie. lxc-start).
*
* Each command is transactional, the clients send a request to
* the server and the server answers the request with a message
* giving the request's status (zero or a negative errno value).
* Both the request and response may contain additional data.
* Each command is transactional, the clients send a request to the server and
* the server answers the request with a message giving the request's status
* (zero or a negative errno value). Both the request and response may contain
* additional data.
*
* 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.
* 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.
*
* IMPORTANTLY: Note that semantics for current commands are fixed. If you
* wish to make any changes to how, say, LXC_CMD_GET_CONFIG_ITEM works by
* adding information to the end of cmd.data, then you must introduce a new
* LXC_CMD_GET_CONFIG_ITEM_V2 define with a new number. You may wish to
* also mark LXC_CMD_GET_CONFIG_ITEM deprecated in commands.h.
* IMPORTANTLY: Note that semantics for current commands are fixed. If you wish
* to make any changes to how, say, LXC_CMD_GET_CONFIG_ITEM works by adding
* information to the end of cmd.data, then you must introduce a new
* LXC_CMD_GET_CONFIG_ITEM_V2 define with a new number. You may wish to also
* mark LXC_CMD_GET_CONFIG_ITEM deprecated in commands.h.
*
* This is necessary in order to avoid having a newly compiled lxc command
* communicating with a running (old) monitor from crashing the running
......@@ -78,7 +79,7 @@ lxc_log_define(lxc_commands, lxc);
static const char *lxc_cmd_str(lxc_cmd_t cmd)
{
static const char * const cmdname[LXC_CMD_MAX] = {
static const char *const cmdname[LXC_CMD_MAX] = {
[LXC_CMD_CONSOLE] = "console",
[LXC_CMD_CONSOLE_WINCH] = "console_winch",
[LXC_CMD_STOP] = "stop",
......@@ -94,6 +95,7 @@ static const char *lxc_cmd_str(lxc_cmd_t cmd)
if (cmd >= LXC_CMD_MAX)
return "Unknown cmd";
return cmdname[cmd];
}
......@@ -121,11 +123,11 @@ static int lxc_cmd_rsp_recv(int sock, struct lxc_cmd_rr *cmd)
ret = lxc_abstract_unix_recv_fds(sock, &rspfd, 1, rsp, sizeof(*rsp));
if (ret < 0) {
WARN("Command %s failed to receive response: %s.",
lxc_cmd_str(cmd->req.cmd), strerror(errno));
WARN("%s - Failed to receive response for command \"%s\"",
strerror(errno), lxc_cmd_str(cmd->req.cmd));
return -1;
}
TRACE("Command \"%s received response", lxc_cmd_str(cmd->req.cmd));
TRACE("Command \"%s\" received response", lxc_cmd_str(cmd->req.cmd));
if (cmd->req.cmd == LXC_CMD_CONSOLE) {
struct lxc_cmd_console_rsp_data *rspdata;
......@@ -138,9 +140,9 @@ static int lxc_cmd_rsp_recv(int sock, struct lxc_cmd_rr *cmd)
rspdata = malloc(sizeof(*rspdata));
if (!rspdata) {
ERROR("Command %s couldn't allocate response buffer.",
ERROR("Failed to allocate response buffer for command \"%s\"",
lxc_cmd_str(cmd->req.cmd));
return -1;
return -ENOMEM;
}
rspdata->masterfd = rspfd;
rspdata->ttynum = PTR_TO_INT(rsp->data);
......@@ -148,26 +150,30 @@ static int lxc_cmd_rsp_recv(int sock, struct lxc_cmd_rr *cmd)
}
if (rsp->datalen == 0) {
DEBUG("command %s response data length is 0",
DEBUG("Response data length for command \"%s\" is 0",
lxc_cmd_str(cmd->req.cmd));
return ret;
}
if (rsp->datalen > LXC_CMD_DATA_MAX) {
ERROR("Command %s response data %d too long.",
lxc_cmd_str(cmd->req.cmd), rsp->datalen);
errno = EFBIG;
return -1;
ERROR("%s - Response data for command \"%s\" is too long: %d "
"bytes > %d", strerror(errno), lxc_cmd_str(cmd->req.cmd),
rsp->datalen, LXC_CMD_DATA_MAX);
return -EFBIG;
}
rsp->data = malloc(rsp->datalen);
if (!rsp->data) {
ERROR("Command %s was unable to allocate response buffer.",
lxc_cmd_str(cmd->req.cmd));
return -1;
errno = ENOMEM;
ERROR("%s - Failed to allocate response buffer for command "
"\"%s\"", strerror(errno), lxc_cmd_str(cmd->req.cmd));
return -ENOMEM;
}
ret = recv(sock, rsp->data, rsp->datalen, 0);
if (ret != rsp->datalen) {
ERROR("Command %s failed to receive response data: %s.",
ERROR("%s - Failed to receive response data for command \"%s\"",
lxc_cmd_str(cmd->req.cmd), strerror(errno));
if (ret >= 0)
ret = -1;
......@@ -186,43 +192,45 @@ static int lxc_cmd_rsp_recv(int sock, struct lxc_cmd_rr *cmd)
*/
static int lxc_cmd_rsp_send(int fd, struct lxc_cmd_rsp *rsp)
{
int ret;
ssize_t ret;
ret = send(fd, rsp, sizeof(*rsp), 0);
if (ret != sizeof(*rsp)) {
ERROR("Failed to send command response %d: %s.", ret,
strerror(errno));
if (ret < 0 || (size_t)ret != sizeof(*rsp)) {
ERROR("%s - Failed to send command response %zd",
strerror(errno), ret);
return -1;
}
if (rsp->datalen > 0) {
ret = send(fd, rsp->data, rsp->datalen, 0);
if (ret != rsp->datalen) {
WARN("Failed to send command response data %d: %s.",
ret, strerror(errno));
return -1;
}
if (rsp->datalen <= 0)
return 0;
ret = send(fd, rsp->data, rsp->datalen, 0);
if (ret < 0 || ret != (ssize_t)rsp->datalen) {
WARN("%s - Failed to send command response data %zd",
strerror(errno), ret);
return -1;
}
return 0;
}
static int lxc_cmd_send(const char *name, struct lxc_cmd_rr *cmd,
const char *lxcpath, const char *hashed_sock_name)
const char *lxcpath, const char *hashed_sock_name)
{
int client_fd;
int ret = -1;
ssize_t ret = -1;
client_fd = lxc_cmd_connect(name, lxcpath, hashed_sock_name);
if (client_fd < 0 && client_fd == -ECONNREFUSED)
return -ECONNREFUSED;
else if (client_fd < 0)
return -1;
if (client_fd < 0) {
if (client_fd == -ECONNREFUSED)
return -ECONNREFUSED;
TRACE("Command \"%s\" connected to command socket",
lxc_cmd_str(cmd->req.cmd));
return -1;
}
ret = lxc_abstract_unix_send_credential(client_fd, &cmd->req, sizeof(cmd->req));
if (ret != sizeof(cmd->req)) {
ret = lxc_abstract_unix_send_credential(client_fd, &cmd->req,
sizeof(cmd->req));
if (ret < 0 || (size_t)ret != sizeof(cmd->req)) {
close(client_fd);
if (errno == EPIPE)
......@@ -234,22 +242,20 @@ static int lxc_cmd_send(const char *name, struct lxc_cmd_rr *cmd,
return -1;
}
TRACE("Command \"%s\" requested data of length %d",
lxc_cmd_str(cmd->req.cmd), cmd->req.datalen);
if (cmd->req.datalen <= 0)
return client_fd;
if (cmd->req.datalen > 0) {
ret = send(client_fd, cmd->req.data, cmd->req.datalen, MSG_NOSIGNAL);
if (ret != cmd->req.datalen) {
close(client_fd);
ret = send(client_fd, cmd->req.data, cmd->req.datalen, MSG_NOSIGNAL);
if (ret < 0 || ret != (ssize_t)cmd->req.datalen) {
close(client_fd);
if (errno == EPIPE)
return -EPIPE;
if (errno == EPIPE)
return -EPIPE;
if (ret >= 0)
return -EMSGSIZE;
if (ret >= 0)
return -EMSGSIZE;
return -1;
}
return -1;
}
return client_fd;
......@@ -277,7 +283,8 @@ static int lxc_cmd_send(const char *name, struct lxc_cmd_rr *cmd,
static int lxc_cmd(const char *name, struct lxc_cmd_rr *cmd, int *stopped,
const char *lxcpath, const char *hashed_sock_name)
{
int client_fd, ret = -1;
int client_fd;
int ret = -1;
bool stay_connected = false;
if (cmd->req.cmd == LXC_CMD_CONSOLE ||
......@@ -286,13 +293,10 @@ static int lxc_cmd(const char *name, struct lxc_cmd_rr *cmd, int *stopped,
*stopped = 0;
TRACE("command %s tries to connect command socket",
lxc_cmd_str(cmd->req.cmd));
client_fd = lxc_cmd_send(name, cmd, lxcpath, hashed_sock_name);
if (client_fd < 0) {
TRACE("command %s failed to connect command socket: %s",
lxc_cmd_str(cmd->req.cmd), strerror(errno));
TRACE("%s - Command \"%s\" failed to connect command socket",
strerror(errno), lxc_cmd_str(cmd->req.cmd));
if (client_fd == -ECONNREFUSED) {
*stopped = 1;
return -1;
......@@ -308,6 +312,7 @@ static int lxc_cmd(const char *name, struct lxc_cmd_rr *cmd, int *stopped,
out:
if (!stay_connected || ret <= 0)
close(client_fd);
if (stay_connected && ret > 0)
cmd->rsp.ret = client_fd;
......@@ -326,7 +331,6 @@ int lxc_try_cmd(const char *name, const char *lxcpath)
};
ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
if (stopped)
return 0;
if (ret > 0 && cmd.rsp.ret < 0) {
......@@ -336,14 +340,11 @@ int lxc_try_cmd(const char *name, const char *lxcpath)
if (ret > 0)
return 0;
/*
* At this point we weren't denied access, and the
* container *was* started. There was some inexplicable
* error in the protocol.
* I'm not clear on whether we should return -1 here, but
* we didn't receive a -EACCES, so technically it's not that
* we're not allowed to control the container - it's just not
* behaving.
/* At this point we weren't denied access, and the container *was*
* started. There was some inexplicable error in the protocol. I'm not
* clear on whether we should return -1 here, but we didn't receive a
* -EACCES, so technically it's not that we're not allowed to control
* the container - it's just not behaving.
*/
return 0;
}
......@@ -423,37 +424,26 @@ static int lxc_cmd_get_clone_flags_callback(int fd, struct lxc_cmd_req *req,
* returned path.
*/
char *lxc_cmd_get_cgroup_path(const char *name, const char *lxcpath,
const char *subsystem)
const char *subsystem)
{
int ret, stopped;
struct lxc_cmd_rr cmd = {
.req = {
.cmd = LXC_CMD_GET_CGROUP,
.datalen = strlen(subsystem)+1,
.datalen = strlen(subsystem) + 1,
.data = subsystem,
},
};
ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
if (ret < 0) {
TRACE("command %s failed for container \"%s\": %s.",
lxc_cmd_str(cmd.req.cmd), name, strerror(errno));
if (ret < 0)
return NULL;
}
if (!ret) {
WARN("container \"%s\" has stopped before sending its state", name);
if (ret == 0)
return NULL;
}
if (cmd.rsp.ret < 0 || cmd.rsp.datalen < 0) {
ERROR("command %s failed for container \"%s\": %s",
lxc_cmd_str(cmd.req.cmd), name, strerror(-cmd.rsp.ret));
if (cmd.rsp.ret < 0 || cmd.rsp.datalen < 0)
return NULL;
}
TRACE("command %s successful for container \"%s\"",
lxc_cmd_str(cmd.req.cmd), name);
return cmd.rsp.data;
}
......@@ -461,8 +451,8 @@ char *lxc_cmd_get_cgroup_path(const char *name, const char *lxcpath,
static int lxc_cmd_get_cgroup_callback(int fd, struct lxc_cmd_req *req,
struct lxc_handler *handler)
{
struct lxc_cmd_rsp rsp;
const char *path;
struct lxc_cmd_rsp rsp;
if (req->datalen < 1)
return -1;
......@@ -470,9 +460,10 @@ static int lxc_cmd_get_cgroup_callback(int fd, struct lxc_cmd_req *req,
path = cgroup_get_cgroup(handler, req->data);
if (!path)
return -1;
rsp.datalen = strlen(path) + 1,
rsp.data = (char *)path;
rsp.ret = 0;
rsp.datalen = strlen(path) + 1;
rsp.data = (char *)path;
return lxc_cmd_rsp_send(fd, &rsp);
}
......@@ -494,7 +485,7 @@ char *lxc_cmd_get_config_item(const char *name, const char *item,
struct lxc_cmd_rr cmd = {
.req = { .cmd = LXC_CMD_GET_CONFIG_ITEM,
.data = item,
.datalen = strlen(item)+1,
.datalen = strlen(item) + 1,
},
};
......@@ -504,6 +495,7 @@ char *lxc_cmd_get_config_item(const char *name, const char *item,
if (cmd.rsp.ret == 0)
return cmd.rsp.data;
return NULL;
}
......@@ -511,9 +503,9 @@ static int lxc_cmd_get_config_item_callback(int fd, struct lxc_cmd_req *req,
struct lxc_handler *handler)
{
int cilen;
struct lxc_cmd_rsp rsp;
char *cidata;
struct lxc_config_t *item;
struct lxc_cmd_rsp rsp;
memset(&rsp, 0, sizeof(rsp));
item = lxc_getconfig(req->data);
......@@ -526,6 +518,7 @@ static int lxc_cmd_get_config_item_callback(int fd, struct lxc_cmd_req *req,
cidata = alloca(cilen + 1);
if (item->get(req->data, cidata, cilen + 1, handler->conf) != cilen)
goto err1;
cidata[cilen] = '\0';
rsp.data = cidata;
rsp.datalen = cilen + 1;
......@@ -561,12 +554,13 @@ int lxc_cmd_get_state(const char *name, const char *lxcpath)
return -1;
if (!ret) {
WARN("Container \"%s\" has stopped before sending its state.", name);
WARN("Container \"%s\" has stopped before sending its state", name);
return -1;
}
DEBUG("Container \"%s\" is in \"%s\" state.", name,
DEBUG("Container \"%s\" is in \"%s\" state", name,
lxc_state2str(PTR_TO_INT(cmd.rsp.data)));
return PTR_TO_INT(cmd.rsp.data);
}
......@@ -597,22 +591,23 @@ int lxc_cmd_stop(const char *name, const char *lxcpath)
ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
if (ret < 0) {
if (stopped) {
INFO("Container \"%s\" is already stopped.", name);
INFO("Container \"%s\" is already stopped", name);
return 0;
}
return -1;
}
/* we do not expect any answer, because we wait for the connection to be
* closed
/* We do not expect any answer, because we wait for the connection to be
* closed.
*/
if (ret > 0) {
ERROR("Failed to stop container \"%s\": %s.", name,
strerror(-cmd.rsp.ret));
ERROR("%s - Failed to stop container \"%s\"",
strerror(-cmd.rsp.ret), name);
return -1;
}
INFO("Container \"%s\" has stopped.", name);
INFO("Container \"%s\" has stopped", name);
return 0;
}
......@@ -627,14 +622,15 @@ static int lxc_cmd_stop_callback(int fd, struct lxc_cmd_req *req,
memset(&rsp, 0, sizeof(rsp));
rsp.ret = kill(handler->pid, stopsignal);
if (!rsp.ret) {
/* we can't just use lxc_unfreeze() since we are already in the
/* We can't just use lxc_unfreeze() since we are already in the
* context of handling the STOP cmd in lxc-start, and calling
* lxc_unfreeze() would do another cmd (GET_CGROUP) which would
* deadlock us
* deadlock us.
*/
if (cgroup_unfreeze(handler))
return 0;
ERROR("Failed to unfreeze container \"%s\".", handler->name);
ERROR("Failed to unfreeze container \"%s\"", handler->name);
rsp.ret = -1;
}
......@@ -669,6 +665,7 @@ static int lxc_cmd_console_winch_callback(int fd, struct lxc_cmd_req *req,
struct lxc_cmd_rsp rsp = { .data = 0 };
lxc_console_sigwinch(SIGWINCH);
return lxc_cmd_rsp_send(fd, &rsp);
}
......@@ -696,27 +693,28 @@ int lxc_cmd_console(const char *name, int *ttynum, int *fd, const char *lxcpath)
return ret;
if (cmd.rsp.ret < 0) {
ERROR("Console access denied: %s.", strerror(-cmd.rsp.ret));
ERROR("%s - Denied access to tty", strerror(-cmd.rsp.ret));
ret = -1;
goto out;
}
if (ret == 0) {
ERROR("Console %d invalid, busy or all consoles busy.", *ttynum);
ERROR("tty number %d invalid, busy or all ttys busy", *ttynum);
ret = -1;
goto out;
}
rspdata = cmd.rsp.data;
if (rspdata->masterfd < 0) {
ERROR("Unable to allocate fd for tty %d.", rspdata->ttynum);
ERROR("Unable to allocate fd for tty %d", rspdata->ttynum);
goto out;
}
ret = cmd.rsp.ret; /* sock fd */
ret = cmd.rsp.ret; /* socket fd */
*fd = rspdata->masterfd;
*ttynum = rspdata->ttynum;
INFO("tty %d allocated fd %d sock %d.", rspdata->ttynum, *fd, ret);
INFO("Alloced fd %d for tty %d via socket %d", *fd, rspdata->ttynum, ret);
out:
free(cmd.rsp.data);
return ret;
......@@ -725,9 +723,9 @@ out:
static int lxc_cmd_console_callback(int fd, struct lxc_cmd_req *req,
struct lxc_handler *handler)
{
int ttynum = PTR_TO_INT(req->data);
int masterfd;
int masterfd, ret;
struct lxc_cmd_rsp rsp;
int ttynum = PTR_TO_INT(req->data);
masterfd = lxc_console_allocate(handler->conf, fd, &ttynum);
if (masterfd < 0)
......@@ -735,8 +733,9 @@ static int lxc_cmd_console_callback(int fd, struct lxc_cmd_req *req,
memset(&rsp, 0, sizeof(rsp));
rsp.data = INT_TO_PTR(ttynum);
if (lxc_abstract_unix_send_fds(fd, &masterfd, 1, &rsp, sizeof(rsp)) < 0) {
ERROR("Failed to send tty to client.");
ret = lxc_abstract_unix_send_fds(fd, &masterfd, 1, &rsp, sizeof(rsp));
if (ret < 0) {
ERROR("Failed to send tty to client");
lxc_console_free(handler->conf, fd);
goto out_close;
}
......@@ -744,8 +743,8 @@ static int lxc_cmd_console_callback(int fd, struct lxc_cmd_req *req,
return 0;
out_close:
/* special indicator to lxc_cmd_handler() to close the fd and do
* related cleanup
/* Special indicator to lxc_cmd_handler() to close the fd and do
* related cleanup.
*/
return 1;
}
......@@ -765,17 +764,17 @@ char *lxc_cmd_get_name(const char *hashed_sock_name)
};
ret = lxc_cmd(NULL, &cmd, &stopped, NULL, hashed_sock_name);
if (ret < 0) {
if (ret < 0)
return NULL;
}
if (cmd.rsp.ret == 0)
return cmd.rsp.data;
return NULL;
}
static int lxc_cmd_get_name_callback(int fd, struct lxc_cmd_req *req,
struct lxc_handler *handler)
struct lxc_handler *handler)
{
struct lxc_cmd_rsp rsp;
......@@ -803,12 +802,12 @@ char *lxc_cmd_get_lxcpath(const char *hashed_sock_name)
};
ret = lxc_cmd(NULL, &cmd, &stopped, NULL, hashed_sock_name);
if (ret < 0) {
if (ret < 0)
return NULL;
}
if (cmd.rsp.ret == 0)
return cmd.rsp.data;
return NULL;
}
......@@ -819,9 +818,9 @@ static int lxc_cmd_get_lxcpath_callback(int fd, struct lxc_cmd_req *req,
memset(&rsp, 0, sizeof(rsp));
rsp.ret = 0;
rsp.data = (char *)handler->lxcpath;
rsp.datalen = strlen(handler->lxcpath) + 1;
rsp.ret = 0;
return lxc_cmd_rsp_send(fd, &rsp);
}
......@@ -849,53 +848,49 @@ int lxc_cmd_add_state_client(const char *name, const char *lxcpath,
state = lxc_getstate(name, lxcpath);
if (state < 0) {
process_unlock();
TRACE("failed to retrieve state of container: %s",
strerror(errno));
TRACE("%s - Failed to retrieve state of container", strerror(errno));
return -1;
} else if (states[state]) {
process_unlock();
TRACE("container is %s state", lxc_state2str(state));
TRACE("Container is %s state", lxc_state2str(state));
return state;
}
if ((state == STARTING) && !states[RUNNING] && !states[STOPPING] && !states[STOPPED]) {
process_unlock();
TRACE("container is in %s state and caller requested to be "
"informed about a previous state",
lxc_state2str(state));
TRACE("Container is in %s state and caller requested to be "
"informed about a previous state", lxc_state2str(state));
return state;
} else if ((state == RUNNING) && !states[STOPPING] && !states[STOPPED]) {
process_unlock();
TRACE("container is in %s state and caller requested to be "
"informed about a previous state",
lxc_state2str(state));
TRACE("Container is in %s state and caller requested to be "
"informed about a previous state", lxc_state2str(state));
return state;
} else if ((state == STOPPING) && !states[STOPPED]) {
process_unlock();
TRACE("container is in %s state and caller requested to be "
"informed about a previous state",
lxc_state2str(state));
TRACE("Container is in %s state and caller requested to be "
"informed about a previous state", lxc_state2str(state));
return state;
} else if ((state == STOPPED) || (state == ABORTING)) {
process_unlock();
TRACE("container is in %s state and caller requested to be "
"informed about a previous state",
lxc_state2str(state));
TRACE("Container is in %s state and caller requested to be "
"informed about a previous state", lxc_state2str(state));
return state;
}
ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
process_unlock();
if (ret < 0) {
ERROR("failed to execute command: %s", strerror(errno));
ERROR("%s - Failed to execute command", strerror(errno));
return -1;
}
/* We should now be guaranteed to get an answer from the state sending
* function.
*/
if (cmd.rsp.ret < 0) {
ERROR("failed to receive socket fd");
ERROR("Failed to receive socket fd");
return -1;
}
......@@ -908,20 +903,14 @@ static int lxc_cmd_add_state_client_callback(int fd, struct lxc_cmd_req *req,
{
struct lxc_cmd_rsp rsp = {0};
if (req->datalen < 0) {
TRACE("Requested datalen was < 0");
if (req->datalen < 0)
return -1;
}
if (req->datalen > (sizeof(lxc_state_t) * MAX_STATE)) {
TRACE("Requested datalen was too large");
if (req->datalen > (sizeof(lxc_state_t) * MAX_STATE))
return -1;
}
if (!req->data) {
TRACE("No states requested");
if (!req->data)
return -1;
}
rsp.ret = lxc_add_state_client(fd, handler, (lxc_state_t *)req->data);
if (rsp.ret < 0)
......@@ -952,7 +941,7 @@ static int lxc_cmd_process(int fd, struct lxc_cmd_req *req,
};
if (req->cmd >= LXC_CMD_MAX) {
ERROR("Undefined command id %d received.", req->cmd);
ERROR("Undefined command id %d", req->cmd);
return -1;
}
return cb[req->cmd](fd, req, handler);
......@@ -975,38 +964,34 @@ static int lxc_cmd_handler(int fd, uint32_t events, void *data,
ret = lxc_abstract_unix_rcv_credential(fd, &req, sizeof(req));
if (ret == -EACCES) {
/* we don't care for the peer, just send and close */
struct lxc_cmd_rsp rsp = { .ret = ret };
/* We don't care for the peer, just send and close. */
struct lxc_cmd_rsp rsp = {.ret = ret};
lxc_cmd_rsp_send(fd, &rsp);
goto out_close;
}
TRACE("Processing \"%s\" command", lxc_cmd_str(req.cmd));
if (ret < 0) {
SYSERROR("Failed to receive data on command socket for \"%s\"",
lxc_cmd_str(req.cmd));
SYSERROR("Failed to receive data on command socket for command "
"\"%s\"", lxc_cmd_str(req.cmd));
goto out_close;
}
if (!ret) {
DEBUG("Peer has disconnected for \"%s\"", lxc_cmd_str(req.cmd));
if (ret == 0)
goto out_close;
}
if (ret != sizeof(req)) {
WARN("Failed to receive full command request. Ignoring request "
"for \"%s\"",
lxc_cmd_str(req.cmd));
"for \"%s\"", lxc_cmd_str(req.cmd));
ret = -1;
goto out_close;
}
if (req.datalen > LXC_CMD_DATA_MAX) {
ERROR("Received command data length %d is too large for "
"command \"%s\"",
req.datalen, lxc_cmd_str(req.cmd));
ret = -1;
"command \"%s\"", req.datalen, lxc_cmd_str(req.cmd));
errno = EFBIG;
ret = -EFBIG;
goto out_close;
}
......@@ -1017,23 +1002,24 @@ static int lxc_cmd_handler(int fd, uint32_t events, void *data,
ret = recv(fd, reqdata, req.datalen, 0);
if (ret != req.datalen) {
WARN("Failed to receive full command request. Ignoring "
"request for \"%s\"",
lxc_cmd_str(req.cmd));
"request for \"%s\"", lxc_cmd_str(req.cmd));
ret = -1;
goto out_close;
}
req.data = reqdata;
}
ret = lxc_cmd_process(fd, &req, handler);
if (ret) {
/* this is not an error, but only a request to close fd */
/* This is not an error, but only a request to close fd. */
ret = 0;
goto out_close;
}
out:
return ret;
out_close:
lxc_cmd_fd_cleanup(fd, handler, descr);
goto out;
......@@ -1042,7 +1028,8 @@ out_close:
static int lxc_cmd_accept(int fd, uint32_t events, void *data,
struct lxc_epoll_descr *descr)
{
int opt = 1, ret = -1, connection;
int connection;
int opt = 1, ret = -1;
connection = accept(fd, NULL, 0);
if (connection < 0) {
......@@ -1050,20 +1037,21 @@ static int lxc_cmd_accept(int fd, uint32_t events, void *data,
return -1;
}
if (fcntl(connection, F_SETFD, FD_CLOEXEC)) {
SYSERROR("Failed to set close-on-exec on incoming command connection.");
ret = fcntl(connection, F_SETFD, FD_CLOEXEC);
if (ret < 0) {
SYSERROR("Failed to set close-on-exec on incoming command connection");
goto out_close;
}
if (setsockopt(connection, SOL_SOCKET,
SO_PASSCRED, &opt, sizeof(opt))) {
SYSERROR("Failed to enable necessary credentials on command socket.");
ret = setsockopt(connection, SOL_SOCKET, SO_PASSCRED, &opt, sizeof(opt));
if (ret < 0) {
SYSERROR("Failed to enable necessary credentials on command socket");
goto out_close;
}
ret = lxc_mainloop_add_handler(descr, connection, lxc_cmd_handler, data);
if (ret) {
ERROR("Failed to add command handler.");
ERROR("Failed to add command handler");
goto out_close;
}
......@@ -1078,10 +1066,9 @@ out_close:
int lxc_cmd_init(const char *name, struct lxc_handler *handler,
const char *lxcpath)
{
int fd;
char path[sizeof(((struct sockaddr_un *)0)->sun_path)] = { 0 };
int fd, len, ret;
char path[sizeof(((struct sockaddr_un *)0)->sun_path)] = {0};
char *offset = &path[1];
int len;
/* -2 here because this is an abstract unix socket so it needs a
* leading \0, and we null terminate, so it needs a trailing \0.
......@@ -1089,21 +1076,22 @@ int lxc_cmd_init(const char *name, struct lxc_handler *handler,
* because we print the sockname out sometimes.
*/
len = sizeof(path) - 2;
if (lxc_make_abstract_socket_name(offset, len, name, lxcpath, NULL,
"command"))
ret = lxc_make_abstract_socket_name(offset, len, name, lxcpath, NULL, "command");
if (ret < 0)
return -1;
fd = lxc_abstract_unix_open(path, SOCK_STREAM, 0);
if (fd < 0) {
ERROR("Failed to create the command service point %s: %s.",
offset, strerror(errno));
ERROR("%s - Failed to create command socket %s",
strerror(errno), offset);
if (errno == EADDRINUSE)
ERROR("Container \"%s\" appears to be already running!", name);
ERROR("Container \"%s\" appears to be already running", name);
return -1;
}
if (fcntl(fd, F_SETFD, FD_CLOEXEC)) {
SYSERROR("Failed to set FD_CLOEXEC on signal file descriptor.");
ret = fcntl(fd, F_SETFD, FD_CLOEXEC);
if (ret < 0) {
SYSERROR("Failed to set FD_CLOEXEC on command socket file descriptor");
close(fd);
return -1;
}
......@@ -1112,15 +1100,15 @@ int lxc_cmd_init(const char *name, struct lxc_handler *handler,
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,
struct lxc_handler *handler)
{
int ret, fd = handler->conf->maincmd_fd;
int ret;
int fd = handler->conf->maincmd_fd;
ret = lxc_mainloop_add_handler(descr, fd, lxc_cmd_accept, handler);
if (ret) {
ERROR("Failed to add handler for command socket.");
if (ret < 0) {
ERROR("Failed to add handler for command socket");
close(fd);
}
......
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