Beispiel #1
0
/*
 * lxc_cmd: Connect to the specified running container, send it a command
 * request and collect the response
 *
 * @name           : name of container to connect to
 * @cmd            : command with initialized request to send
 * @stopped        : output indicator if the container was not running
 * @lxcpath        : the lxcpath in which the container is running
 *
 * Returns the size of the response message on success, < 0 on failure
 *
 * Note that there is a special case for LXC_CMD_CONSOLE. For this command
 * the fd cannot be closed because it is used as a placeholder to indicate
 * that a particular tty slot is in use. The fd is also used as a signal to
 * the container that when the caller dies or closes the fd, the container
 * will notice the fd on its side of the socket in its mainloop select and
 * then free the slot with lxc_cmd_fd_cleanup(). The socket fd will be
 * returned in the cmd response structure.
 */
static int lxc_cmd(const char *name, struct lxc_cmd_rr *cmd, int *stopped,
		   const char *lxcpath, const char *hashed_sock_name)
{
	__do_close_prot_errno int client_fd = -EBADF;
	int ret = -1;
	bool stay_connected = false;

	if (cmd->req.cmd == LXC_CMD_CONSOLE ||
	    cmd->req.cmd == LXC_CMD_ADD_STATE_CLIENT)
		stay_connected = true;

	*stopped = 0;

	client_fd = lxc_cmd_send(name, cmd, lxcpath, hashed_sock_name);
	if (client_fd < 0) {
		SYSTRACE("Command \"%s\" failed to connect command socket",
		         lxc_cmd_str(cmd->req.cmd));

		if (errno == ECONNREFUSED || errno == EPIPE)
			*stopped = 1;

		return -1;
	}

	ret = lxc_cmd_rsp_recv(client_fd, cmd);
	if (ret < 0 && errno == ECONNRESET)
		*stopped = 1;

	if (stay_connected && ret > 0)
		cmd->rsp.ret = move_fd(client_fd);

	return ret;
}
Beispiel #2
0
/*
 * lxc_cmd: Connect to the specified running container, send it a command
 * request and collect the response
 *
 * @name           : name of container to connect to
 * @cmd            : command with initialized request to send
 * @stopped        : output indicator if the container was not running
 * @lxcpath        : the lxcpath in which the container is running
 *
 * Returns the size of the response message on success, < 0 on failure
 *
 * Note that there is a special case for LXC_CMD_CONSOLE. For this command
 * the fd cannot be closed because it is used as a placeholder to indicate
 * that a particular tty slot is in use. The fd is also used as a signal to
 * the container that when the caller dies or closes the fd, the container
 * will notice the fd on its side of the socket in its mainloop select and
 * then free the slot with lxc_cmd_fd_cleanup(). The socket fd will be
 * returned in the cmd response structure.
 */
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, saved_errno;
	int ret = -1;
	bool stay_connected = false;

	if (cmd->req.cmd == LXC_CMD_CONSOLE ||
	    cmd->req.cmd == LXC_CMD_ADD_STATE_CLIENT)
		stay_connected = true;

	*stopped = 0;

	client_fd = lxc_cmd_send(name, cmd, lxcpath, hashed_sock_name);
	if (client_fd < 0) {
		SYSTRACE("Command \"%s\" failed to connect command socket",
		         lxc_cmd_str(cmd->req.cmd));

		if (errno == ECONNREFUSED)
			*stopped = 1;

		if (errno == EPIPE) {
			*stopped = 1;
			client_fd = 0;
		}

		return -1;
	}

	ret = lxc_cmd_rsp_recv(client_fd, cmd);
	if (ret < 0 && errno == ECONNRESET)
		*stopped = 1;

	if (!stay_connected || ret <= 0)
		if (client_fd >= 0) {
			saved_errno = errno;
			close(client_fd);
			errno = saved_errno;
		}

	if (stay_connected && ret > 0)
		cmd->rsp.ret = client_fd;

	return ret;
}