2 * lxc: linux Container library
4 * (C) Copyright IBM Corp. 2007, 2009
7 * Daniel Lezcano <daniel.lezcano at free.fr>
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
35 #include <sys/param.h>
36 #include <sys/socket.h>
43 #include "commands_utils.h"
51 #include "memory_utils.h"
58 * This file provides the different functions for clients to query/command the
59 * server. The client is typically some lxc tool and the server is typically the
60 * container (ie. lxc-start).
62 * Each command is transactional, the clients send a request to the server and
63 * the server answers the request with a message giving the request's status
64 * (zero or a negative errno value). Both the request and response may contain
67 * Each command is wrapped in a ancillary message in order to pass a credential
68 * making possible to the server to check if the client is allowed to ask for
69 * this command or not.
71 * IMPORTANTLY: Note that semantics for current commands are fixed. If you wish
72 * to make any changes to how, say, LXC_CMD_GET_CONFIG_ITEM works by adding
73 * information to the end of cmd.data, then you must introduce a new
74 * LXC_CMD_GET_CONFIG_ITEM_V2 define with a new number. You may wish to also
75 * mark LXC_CMD_GET_CONFIG_ITEM deprecated in commands.h.
77 * This is necessary in order to avoid having a newly compiled lxc command
78 * communicating with a running (old) monitor from crashing the running
82 lxc_log_define(commands
, lxc
);
84 static const char *lxc_cmd_str(lxc_cmd_t cmd
)
86 static const char *const cmdname
[LXC_CMD_MAX
] = {
87 [LXC_CMD_CONSOLE
] = "console",
88 [LXC_CMD_TERMINAL_WINCH
] = "terminal_winch",
89 [LXC_CMD_STOP
] = "stop",
90 [LXC_CMD_GET_STATE
] = "get_state",
91 [LXC_CMD_GET_INIT_PID
] = "get_init_pid",
92 [LXC_CMD_GET_CLONE_FLAGS
] = "get_clone_flags",
93 [LXC_CMD_GET_CGROUP
] = "get_cgroup",
94 [LXC_CMD_GET_CONFIG_ITEM
] = "get_config_item",
95 [LXC_CMD_GET_NAME
] = "get_name",
96 [LXC_CMD_GET_LXCPATH
] = "get_lxcpath",
97 [LXC_CMD_ADD_STATE_CLIENT
] = "add_state_client",
98 [LXC_CMD_CONSOLE_LOG
] = "console_log",
99 [LXC_CMD_SERVE_STATE_CLIENTS
] = "serve_state_clients",
102 if (cmd
>= LXC_CMD_MAX
)
103 return "Invalid request";
109 * lxc_cmd_rsp_recv: Receive a response to a command
111 * @sock : the socket connected to the container
112 * @cmd : command to put response in
114 * Returns the size of the response message or < 0 on failure
116 * Note that if the command response datalen > 0, then data is
117 * a malloc()ed buffer and should be free()ed by the caller. If
118 * the response data is <= a void * worth of data, it will be
119 * stored directly in data and datalen will be 0.
121 * As a special case, the response for LXC_CMD_CONSOLE is created
122 * here as it contains an fd for the master pty passed through the
125 static int lxc_cmd_rsp_recv(int sock
, struct lxc_cmd_rr
*cmd
)
128 struct lxc_cmd_rsp
*rsp
= &cmd
->rsp
;
130 ret
= lxc_abstract_unix_recv_fds(sock
, &rspfd
, 1, rsp
, sizeof(*rsp
));
132 SYSWARN("Failed to receive response for command \"%s\"",
133 lxc_cmd_str(cmd
->req
.cmd
));
135 if (errno
== ECONNRESET
)
140 TRACE("Command \"%s\" received response", lxc_cmd_str(cmd
->req
.cmd
));
142 if (cmd
->req
.cmd
== LXC_CMD_CONSOLE
) {
143 struct lxc_cmd_console_rsp_data
*rspdata
;
145 /* recv() returns 0 bytes when a tty cannot be allocated,
146 * rsp->ret is < 0 when the peer permission check failed
148 if (ret
== 0 || rsp
->ret
< 0)
151 rspdata
= malloc(sizeof(*rspdata
));
154 ERROR("Failed to allocate response buffer for command \"%s\"",
155 lxc_cmd_str(cmd
->req
.cmd
));
159 rspdata
->masterfd
= rspfd
;
160 rspdata
->ttynum
= PTR_TO_INT(rsp
->data
);
164 if (rsp
->datalen
== 0) {
165 DEBUG("Response data length for command \"%s\" is 0",
166 lxc_cmd_str(cmd
->req
.cmd
));
170 if ((rsp
->datalen
> LXC_CMD_DATA_MAX
) &&
171 (cmd
->req
.cmd
!= LXC_CMD_CONSOLE_LOG
)) {
172 ERROR("Response data for command \"%s\" is too long: %d bytes > %d",
173 lxc_cmd_str(cmd
->req
.cmd
), rsp
->datalen
, LXC_CMD_DATA_MAX
);
177 if (cmd
->req
.cmd
== LXC_CMD_CONSOLE_LOG
) {
178 rsp
->data
= malloc(rsp
->datalen
+ 1);
179 ((char *)rsp
->data
)[rsp
->datalen
] = '\0';
181 rsp
->data
= malloc(rsp
->datalen
);
185 ERROR("Failed to allocate response buffer for command \"%s\"",
186 lxc_cmd_str(cmd
->req
.cmd
));
190 ret
= lxc_recv_nointr(sock
, rsp
->data
, rsp
->datalen
, 0);
191 if (ret
!= rsp
->datalen
) {
192 SYSERROR("Failed to receive response data for command \"%s\"",
193 lxc_cmd_str(cmd
->req
.cmd
));
201 * lxc_cmd_rsp_send: Send a command response
203 * @fd : file descriptor of socket to send response on
204 * @rsp : response to send
206 * Returns 0 on success, < 0 on failure
208 static int lxc_cmd_rsp_send(int fd
, struct lxc_cmd_rsp
*rsp
)
213 ret
= lxc_send_nointr(fd
, rsp
, sizeof(*rsp
), MSG_NOSIGNAL
);
214 if (ret
< 0 || (size_t)ret
!= sizeof(*rsp
)) {
215 SYSERROR("Failed to send command response %zd", ret
);
219 if (!rsp
->data
|| rsp
->datalen
<= 0)
223 ret
= lxc_send_nointr(fd
, rsp
->data
, rsp
->datalen
, MSG_NOSIGNAL
);
224 if (ret
< 0 || ret
!= (ssize_t
)rsp
->datalen
) {
225 SYSWARN("Failed to send command response data %zd", ret
);
232 static int lxc_cmd_send(const char *name
, struct lxc_cmd_rr
*cmd
,
233 const char *lxcpath
, const char *hashed_sock_name
)
235 __do_close_prot_errno
int client_fd
= -EBADF
;
238 client_fd
= lxc_cmd_connect(name
, lxcpath
, hashed_sock_name
, "command");
242 ret
= lxc_abstract_unix_send_credential(client_fd
, &cmd
->req
,
244 if (ret
< 0 || (size_t)ret
!= sizeof(cmd
->req
))
247 if (cmd
->req
.datalen
<= 0)
248 return steal_fd(client_fd
);
251 ret
= lxc_send_nointr(client_fd
, (void *)cmd
->req
.data
,
252 cmd
->req
.datalen
, MSG_NOSIGNAL
);
253 if (ret
< 0 || ret
!= (ssize_t
)cmd
->req
.datalen
)
256 return steal_fd(client_fd
);
260 * lxc_cmd: Connect to the specified running container, send it a command
261 * request and collect the response
263 * @name : name of container to connect to
264 * @cmd : command with initialized request to send
265 * @stopped : output indicator if the container was not running
266 * @lxcpath : the lxcpath in which the container is running
268 * Returns the size of the response message on success, < 0 on failure
270 * Note that there is a special case for LXC_CMD_CONSOLE. For this command
271 * the fd cannot be closed because it is used as a placeholder to indicate
272 * that a particular tty slot is in use. The fd is also used as a signal to
273 * the container that when the caller dies or closes the fd, the container
274 * will notice the fd on its side of the socket in its mainloop select and
275 * then free the slot with lxc_cmd_fd_cleanup(). The socket fd will be
276 * returned in the cmd response structure.
278 static int lxc_cmd(const char *name
, struct lxc_cmd_rr
*cmd
, int *stopped
,
279 const char *lxcpath
, const char *hashed_sock_name
)
281 __do_close_prot_errno
int client_fd
= -EBADF
;
283 bool stay_connected
= false;
285 if (cmd
->req
.cmd
== LXC_CMD_CONSOLE
||
286 cmd
->req
.cmd
== LXC_CMD_ADD_STATE_CLIENT
)
287 stay_connected
= true;
291 client_fd
= lxc_cmd_send(name
, cmd
, lxcpath
, hashed_sock_name
);
293 SYSTRACE("Command \"%s\" failed to connect command socket",
294 lxc_cmd_str(cmd
->req
.cmd
));
296 if (errno
== ECONNREFUSED
|| errno
== EPIPE
)
302 ret
= lxc_cmd_rsp_recv(client_fd
, cmd
);
303 if (ret
< 0 && errno
== ECONNRESET
)
306 if (stay_connected
&& ret
> 0)
307 cmd
->rsp
.ret
= steal_fd(client_fd
);
312 int lxc_try_cmd(const char *name
, const char *lxcpath
)
315 struct lxc_cmd_rr cmd
= {
316 .req
= { .cmd
= LXC_CMD_GET_INIT_PID
},
319 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
322 if (ret
> 0 && cmd
.rsp
.ret
< 0) {
329 /* At this point we weren't denied access, and the container *was*
330 * started. There was some inexplicable error in the protocol. I'm not
331 * clear on whether we should return -1 here, but we didn't receive a
332 * -EACCES, so technically it's not that we're not allowed to control
333 * the container - it's just not behaving.
338 /* Implementations of the commands and their callbacks */
341 * lxc_cmd_get_init_pid: Get pid of the container's init process
343 * @name : name of container to connect to
344 * @lxcpath : the lxcpath in which the container is running
346 * Returns the pid on success, < 0 on failure
348 pid_t
lxc_cmd_get_init_pid(const char *name
, const char *lxcpath
)
352 struct lxc_cmd_rr cmd
= {
354 .cmd
= LXC_CMD_GET_INIT_PID
357 .data
= INTMAX_TO_PTR((intmax_t){-1})
361 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
365 pid
= PTR_TO_INTMAX(cmd
.rsp
.data
);
369 /* We need to assume that pid_t can actually hold any pid given to us
370 * by the kernel. If it can't it's a libc bug.
375 static int lxc_cmd_get_init_pid_callback(int fd
, struct lxc_cmd_req
*req
,
376 struct lxc_handler
*handler
)
378 intmax_t pid
= handler
->pid
;
380 struct lxc_cmd_rsp rsp
= {
381 .data
= INTMAX_TO_PTR(pid
)
384 return lxc_cmd_rsp_send(fd
, &rsp
);
388 * lxc_cmd_get_clone_flags: Get clone flags container was spawned with
390 * @name : name of container to connect to
391 * @lxcpath : the lxcpath in which the container is running
393 * Returns the clone flags on success, < 0 on failure
395 int lxc_cmd_get_clone_flags(const char *name
, const char *lxcpath
)
398 struct lxc_cmd_rr cmd
= {
399 .req
= { .cmd
= LXC_CMD_GET_CLONE_FLAGS
},
402 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
406 return PTR_TO_INT(cmd
.rsp
.data
);
409 static int lxc_cmd_get_clone_flags_callback(int fd
, struct lxc_cmd_req
*req
,
410 struct lxc_handler
*handler
)
412 struct lxc_cmd_rsp rsp
= { .data
= INT_TO_PTR(handler
->ns_clone_flags
) };
414 return lxc_cmd_rsp_send(fd
, &rsp
);
418 * lxc_cmd_get_cgroup_path: Calculate a container's cgroup path for a
419 * particular subsystem. This is the cgroup path relative to the root
420 * of the cgroup filesystem.
422 * @name : name of container to connect to
423 * @lxcpath : the lxcpath in which the container is running
424 * @subsystem : the subsystem being asked about
426 * Returns the path on success, NULL on failure. The caller must free() the
429 char *lxc_cmd_get_cgroup_path(const char *name
, const char *lxcpath
,
430 const char *subsystem
)
433 struct lxc_cmd_rr cmd
= {
435 .cmd
= LXC_CMD_GET_CGROUP
,
441 cmd
.req
.data
= subsystem
;
444 cmd
.req
.datalen
= strlen(subsystem
) + 1;
446 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
453 if (cmd
.rsp
.ret
< 0 || cmd
.rsp
.datalen
< 0)
459 static int lxc_cmd_get_cgroup_callback(int fd
, struct lxc_cmd_req
*req
,
460 struct lxc_handler
*handler
)
463 struct lxc_cmd_rsp rsp
;
464 struct cgroup_ops
*cgroup_ops
= handler
->cgroup_ops
;
466 if (req
->datalen
> 0)
467 path
= cgroup_ops
->get_cgroup(cgroup_ops
, req
->data
);
469 path
= cgroup_ops
->get_cgroup(cgroup_ops
, NULL
);
474 rsp
.datalen
= strlen(path
) + 1;
475 rsp
.data
= (char *)path
;
477 return lxc_cmd_rsp_send(fd
, &rsp
);
481 * lxc_cmd_get_config_item: Get config item the running container
483 * @name : name of container to connect to
484 * @item : the configuration item to retrieve (ex: lxc.net.0.veth.pair)
485 * @lxcpath : the lxcpath in which the container is running
487 * Returns the item on success, NULL on failure. The caller must free() the
490 char *lxc_cmd_get_config_item(const char *name
, const char *item
,
494 struct lxc_cmd_rr cmd
= {
495 .req
= { .cmd
= LXC_CMD_GET_CONFIG_ITEM
,
497 .datalen
= strlen(item
) + 1,
501 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
505 if (cmd
.rsp
.ret
== 0)
511 static int lxc_cmd_get_config_item_callback(int fd
, struct lxc_cmd_req
*req
,
512 struct lxc_handler
*handler
)
514 __do_free
char *cidata
= NULL
;
516 struct lxc_config_t
*item
;
517 struct lxc_cmd_rsp rsp
;
519 memset(&rsp
, 0, sizeof(rsp
));
520 item
= lxc_get_config(req
->data
);
524 cilen
= item
->get(req
->data
, NULL
, 0, handler
->conf
, NULL
);
528 cidata
= must_realloc(NULL
, cilen
+ 1);
529 if (item
->get(req
->data
, cidata
, cilen
+ 1, handler
->conf
, NULL
) != cilen
)
532 cidata
[cilen
] = '\0';
534 rsp
.datalen
= cilen
+ 1;
541 return lxc_cmd_rsp_send(fd
, &rsp
);
545 * lxc_cmd_get_state: Get current state of the container
547 * @name : name of container to connect to
548 * @lxcpath : the lxcpath in which the container is running
550 * Returns the state on success, < 0 on failure
552 int lxc_cmd_get_state(const char *name
, const char *lxcpath
)
555 struct lxc_cmd_rr cmd
= {
556 .req
= { .cmd
= LXC_CMD_GET_STATE
}
559 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
560 if (ret
< 0 && stopped
)
567 WARN("Container \"%s\" has stopped before sending its state", name
);
571 DEBUG("Container \"%s\" is in \"%s\" state", name
,
572 lxc_state2str(PTR_TO_INT(cmd
.rsp
.data
)));
574 return PTR_TO_INT(cmd
.rsp
.data
);
577 static int lxc_cmd_get_state_callback(int fd
, struct lxc_cmd_req
*req
,
578 struct lxc_handler
*handler
)
580 struct lxc_cmd_rsp rsp
= { .data
= INT_TO_PTR(handler
->state
) };
582 return lxc_cmd_rsp_send(fd
, &rsp
);
586 * lxc_cmd_stop: Stop the container previously started with lxc_start. All
587 * the processes running inside this container will be killed.
589 * @name : name of container to connect to
590 * @lxcpath : the lxcpath in which the container is running
592 * Returns 0 on success, < 0 on failure
594 int lxc_cmd_stop(const char *name
, const char *lxcpath
)
597 struct lxc_cmd_rr cmd
= {
598 .req
= { .cmd
= LXC_CMD_STOP
},
601 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
604 INFO("Container \"%s\" is already stopped", name
);
611 /* We do not expect any answer, because we wait for the connection to be
615 errno
= -cmd
.rsp
.ret
;
616 SYSERROR("Failed to stop container \"%s\"", name
);
620 INFO("Container \"%s\" has stopped", name
);
624 static int lxc_cmd_stop_callback(int fd
, struct lxc_cmd_req
*req
,
625 struct lxc_handler
*handler
)
627 struct lxc_cmd_rsp rsp
;
628 int stopsignal
= SIGKILL
;
629 struct cgroup_ops
*cgroup_ops
= handler
->cgroup_ops
;
631 if (handler
->conf
->stopsignal
)
632 stopsignal
= handler
->conf
->stopsignal
;
633 memset(&rsp
, 0, sizeof(rsp
));
634 rsp
.ret
= kill(handler
->pid
, stopsignal
);
636 /* We can't just use lxc_unfreeze() since we are already in the
637 * context of handling the STOP cmd in lxc-start, and calling
638 * lxc_unfreeze() would do another cmd (GET_CGROUP) which would
641 if (!cgroup_ops
->get_cgroup(cgroup_ops
, "freezer"))
644 if (cgroup_ops
->unfreeze(cgroup_ops
))
647 ERROR("Failed to unfreeze container \"%s\"", handler
->name
);
651 return lxc_cmd_rsp_send(fd
, &rsp
);
655 * lxc_cmd_terminal_winch: noop
657 * @name : name of container to connect to
658 * @lxcpath : the lxcpath in which the container is running
660 * Returns 0 on success, < 0 on failure
662 int lxc_cmd_terminal_winch(const char *name
, const char *lxcpath
)
667 static int lxc_cmd_terminal_winch_callback(int fd
, struct lxc_cmd_req
*req
,
668 struct lxc_handler
*handler
)
670 /* should never be called */
675 * lxc_cmd_console: Open an fd to a tty in the container
677 * @name : name of container to connect to
678 * @ttynum : in: the tty to open or -1 for next available
679 * : out: the tty allocated
680 * @fd : out: file descriptor for master side of pty
681 * @lxcpath : the lxcpath in which the container is running
683 * Returns fd holding tty allocated on success, < 0 on failure
685 int lxc_cmd_console(const char *name
, int *ttynum
, int *fd
, const char *lxcpath
)
687 __do_free
struct lxc_cmd_console_rsp_data
*rspdata
= NULL
;
689 struct lxc_cmd_rr cmd
= {
690 .req
= { .cmd
= LXC_CMD_CONSOLE
, .data
= INT_TO_PTR(*ttynum
) },
693 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
697 rspdata
= cmd
.rsp
.data
;
698 if (cmd
.rsp
.ret
< 0) {
699 errno
= -cmd
.rsp
.ret
;
700 SYSERROR("Denied access to tty");
705 ERROR("tty number %d invalid, busy or all ttys busy", *ttynum
);
709 if (rspdata
->masterfd
< 0) {
710 ERROR("Unable to allocate fd for tty %d", rspdata
->ttynum
);
714 ret
= cmd
.rsp
.ret
; /* socket fd */
715 *fd
= rspdata
->masterfd
;
716 *ttynum
= rspdata
->ttynum
;
717 INFO("Alloced fd %d for tty %d via socket %d", *fd
, rspdata
->ttynum
, ret
);
722 static int lxc_cmd_console_callback(int fd
, struct lxc_cmd_req
*req
,
723 struct lxc_handler
*handler
)
726 struct lxc_cmd_rsp rsp
;
727 int ttynum
= PTR_TO_INT(req
->data
);
729 masterfd
= lxc_terminal_allocate(handler
->conf
, fd
, &ttynum
);
733 memset(&rsp
, 0, sizeof(rsp
));
734 rsp
.data
= INT_TO_PTR(ttynum
);
735 ret
= lxc_abstract_unix_send_fds(fd
, &masterfd
, 1, &rsp
, sizeof(rsp
));
737 SYSERROR("Failed to send tty to client");
738 lxc_terminal_free(handler
->conf
, fd
);
745 /* Special indicator to lxc_cmd_handler() to close the fd and do
752 * lxc_cmd_get_name: Returns the name of the container
754 * @hashed_sock_name: hashed socket name
756 * Returns the name on success, NULL on failure.
758 char *lxc_cmd_get_name(const char *hashed_sock_name
)
761 struct lxc_cmd_rr cmd
= {
762 .req
= { .cmd
= LXC_CMD_GET_NAME
},
765 ret
= lxc_cmd(NULL
, &cmd
, &stopped
, NULL
, hashed_sock_name
);
769 if (cmd
.rsp
.ret
== 0)
775 static int lxc_cmd_get_name_callback(int fd
, struct lxc_cmd_req
*req
,
776 struct lxc_handler
*handler
)
778 struct lxc_cmd_rsp rsp
;
780 memset(&rsp
, 0, sizeof(rsp
));
782 rsp
.data
= (char *)handler
->name
;
783 rsp
.datalen
= strlen(handler
->name
) + 1;
786 return lxc_cmd_rsp_send(fd
, &rsp
);
790 * lxc_cmd_get_lxcpath: Returns the lxcpath of the container
792 * @hashed_sock_name: hashed socket name
794 * Returns the lxcpath on success, NULL on failure.
796 char *lxc_cmd_get_lxcpath(const char *hashed_sock_name
)
799 struct lxc_cmd_rr cmd
= {
800 .req
= { .cmd
= LXC_CMD_GET_LXCPATH
},
803 ret
= lxc_cmd(NULL
, &cmd
, &stopped
, NULL
, hashed_sock_name
);
807 if (cmd
.rsp
.ret
== 0)
813 static int lxc_cmd_get_lxcpath_callback(int fd
, struct lxc_cmd_req
*req
,
814 struct lxc_handler
*handler
)
816 struct lxc_cmd_rsp rsp
;
818 memset(&rsp
, 0, sizeof(rsp
));
821 rsp
.data
= (char *)handler
->lxcpath
;
822 rsp
.datalen
= strlen(handler
->lxcpath
) + 1;
824 return lxc_cmd_rsp_send(fd
, &rsp
);
827 int lxc_cmd_add_state_client(const char *name
, const char *lxcpath
,
828 lxc_state_t states
[MAX_STATE
],
829 int *state_client_fd
)
831 __do_close_prot_errno
int clientfd
= -EBADF
;
834 struct lxc_cmd_rr cmd
= {
836 .cmd
= LXC_CMD_ADD_STATE_CLIENT
,
838 .datalen
= (sizeof(lxc_state_t
) * MAX_STATE
)
842 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
843 if (states
[STOPPED
] != 0 && stopped
!= 0)
847 if (errno
!= ECONNREFUSED
)
848 SYSERROR("Failed to execute command");
853 /* We should now be guaranteed to get an answer from the state sending
856 clientfd
= cmd
.rsp
.ret
;
859 SYSERROR("Failed to receive socket fd");
863 state
= PTR_TO_INT(cmd
.rsp
.data
);
864 if (state
< MAX_STATE
) {
865 TRACE("Container is already in requested state %s", lxc_state2str(state
));
869 *state_client_fd
= steal_fd(clientfd
);
870 TRACE("Added state client %d to state client list", *state_client_fd
);
874 static int lxc_cmd_add_state_client_callback(int fd
, struct lxc_cmd_req
*req
,
875 struct lxc_handler
*handler
)
878 struct lxc_cmd_rsp rsp
= {0};
880 if (req
->datalen
< 0)
883 if (req
->datalen
!= (sizeof(lxc_state_t
) * MAX_STATE
))
889 rsp
.ret
= lxc_add_state_client(fd
, handler
, (lxc_state_t
*)req
->data
);
893 rsp
.data
= INT_TO_PTR(rsp
.ret
);
895 ret
= lxc_cmd_rsp_send(fd
, &rsp
);
902 /* Special indicator to lxc_cmd_handler() to close the fd and do related
908 int lxc_cmd_console_log(const char *name
, const char *lxcpath
,
909 struct lxc_console_log
*log
)
912 struct lxc_cmd_console_log data
;
913 struct lxc_cmd_rr cmd
;
915 data
.clear
= log
->clear
;
916 data
.read
= log
->read
;
917 data
.read_max
= *log
->read_max
;
919 cmd
.req
.cmd
= LXC_CMD_CONSOLE_LOG
;
920 cmd
.req
.data
= &data
;
921 cmd
.req
.datalen
= sizeof(struct lxc_cmd_console_log
);
923 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
927 /* There is nothing to be read from the buffer. So clear any values we
928 * where passed to clearly indicate to the user that nothing went wrong.
930 if (cmd
.rsp
.ret
== -ENODATA
|| cmd
.rsp
.ret
== -EFAULT
|| cmd
.rsp
.ret
== -ENOENT
) {
935 /* This is a proper error so don't touch any values we were passed. */
939 *log
->read_max
= cmd
.rsp
.datalen
;
940 log
->data
= cmd
.rsp
.data
;
945 static int lxc_cmd_console_log_callback(int fd
, struct lxc_cmd_req
*req
,
946 struct lxc_handler
*handler
)
948 struct lxc_cmd_rsp rsp
;
949 uint64_t buffer_size
= handler
->conf
->console
.buffer_size
;
950 const struct lxc_cmd_console_log
*log
= req
->data
;
951 struct lxc_ringbuf
*buf
= &handler
->conf
->console
.ringbuf
;
956 if (buffer_size
<= 0)
959 if (log
->read
|| log
->write_logfile
)
960 rsp
.datalen
= lxc_ringbuf_used(buf
);
963 rsp
.data
= lxc_ringbuf_get_read_addr(buf
);
965 if (log
->read_max
> 0 && (log
->read_max
<= rsp
.datalen
))
966 rsp
.datalen
= log
->read_max
;
968 /* there's nothing to read */
970 if (log
->read
&& (buf
->r_off
== buf
->w_off
))
975 lxc_ringbuf_clear(buf
); /* clear the ringbuffer */
976 else if (rsp
.datalen
> 0)
977 lxc_ringbuf_move_read_addr(buf
, rsp
.datalen
);
980 return lxc_cmd_rsp_send(fd
, &rsp
);
983 int lxc_cmd_serve_state_clients(const char *name
, const char *lxcpath
,
988 struct lxc_cmd_rr cmd
= {
990 .cmd
= LXC_CMD_SERVE_STATE_CLIENTS
,
991 .data
= INT_TO_PTR(state
)
995 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
997 SYSERROR("Failed to execute command");
1004 static int lxc_cmd_serve_state_clients_callback(int fd
, struct lxc_cmd_req
*req
,
1005 struct lxc_handler
*handler
)
1008 lxc_state_t state
= PTR_TO_INT(req
->data
);
1009 struct lxc_cmd_rsp rsp
= {0};
1011 ret
= lxc_serve_state_clients(handler
->name
, handler
, state
);
1013 goto reap_client_fd
;
1015 ret
= lxc_cmd_rsp_send(fd
, &rsp
);
1017 goto reap_client_fd
;
1022 /* Special indicator to lxc_cmd_handler() to close the fd and do related
1028 static int lxc_cmd_process(int fd
, struct lxc_cmd_req
*req
,
1029 struct lxc_handler
*handler
)
1031 typedef int (*callback
)(int, struct lxc_cmd_req
*, struct lxc_handler
*);
1033 callback cb
[LXC_CMD_MAX
] = {
1034 [LXC_CMD_CONSOLE
] = lxc_cmd_console_callback
,
1035 [LXC_CMD_TERMINAL_WINCH
] = lxc_cmd_terminal_winch_callback
,
1036 [LXC_CMD_STOP
] = lxc_cmd_stop_callback
,
1037 [LXC_CMD_GET_STATE
] = lxc_cmd_get_state_callback
,
1038 [LXC_CMD_GET_INIT_PID
] = lxc_cmd_get_init_pid_callback
,
1039 [LXC_CMD_GET_CLONE_FLAGS
] = lxc_cmd_get_clone_flags_callback
,
1040 [LXC_CMD_GET_CGROUP
] = lxc_cmd_get_cgroup_callback
,
1041 [LXC_CMD_GET_CONFIG_ITEM
] = lxc_cmd_get_config_item_callback
,
1042 [LXC_CMD_GET_NAME
] = lxc_cmd_get_name_callback
,
1043 [LXC_CMD_GET_LXCPATH
] = lxc_cmd_get_lxcpath_callback
,
1044 [LXC_CMD_ADD_STATE_CLIENT
] = lxc_cmd_add_state_client_callback
,
1045 [LXC_CMD_CONSOLE_LOG
] = lxc_cmd_console_log_callback
,
1046 [LXC_CMD_SERVE_STATE_CLIENTS
] = lxc_cmd_serve_state_clients_callback
,
1049 if (req
->cmd
>= LXC_CMD_MAX
) {
1050 ERROR("Undefined command id %d", req
->cmd
);
1053 return cb
[req
->cmd
](fd
, req
, handler
);
1056 static void lxc_cmd_fd_cleanup(int fd
, struct lxc_handler
*handler
,
1057 struct lxc_epoll_descr
*descr
,
1058 const lxc_cmd_t cmd
)
1060 struct lxc_list
*cur
, *next
;
1062 lxc_terminal_free(handler
->conf
, fd
);
1063 lxc_mainloop_del_handler(descr
, fd
);
1064 if (cmd
!= LXC_CMD_ADD_STATE_CLIENT
) {
1069 lxc_list_for_each_safe(cur
, &handler
->conf
->state_clients
, next
) {
1070 struct lxc_state_client
*client
= cur
->elem
;
1072 if (client
->clientfd
!= fd
)
1075 /* kick client from list */
1077 close(client
->clientfd
);
1080 /* No need to walk the whole list. If we found the state client
1081 * fd there can't be a second one.
1087 static int lxc_cmd_handler(int fd
, uint32_t events
, void *data
,
1088 struct lxc_epoll_descr
*descr
)
1090 __do_free
void *reqdata
= NULL
;
1092 struct lxc_cmd_req req
;
1093 struct lxc_handler
*handler
= data
;
1095 ret
= lxc_abstract_unix_rcv_credential(fd
, &req
, sizeof(req
));
1097 SYSERROR("Failed to receive data on command socket for command "
1098 "\"%s\"", lxc_cmd_str(req
.cmd
));
1100 if (errno
== EACCES
) {
1101 /* We don't care for the peer, just send and close. */
1102 struct lxc_cmd_rsp rsp
= {.ret
= ret
};
1104 lxc_cmd_rsp_send(fd
, &rsp
);
1113 if (ret
!= sizeof(req
)) {
1114 WARN("Failed to receive full command request. Ignoring request "
1115 "for \"%s\"", lxc_cmd_str(req
.cmd
));
1120 if ((req
.datalen
> LXC_CMD_DATA_MAX
) &&
1121 (req
.cmd
!= LXC_CMD_CONSOLE_LOG
)) {
1122 ERROR("Received command data length %d is too large for "
1123 "command \"%s\"", req
.datalen
, lxc_cmd_str(req
.cmd
));
1129 if (req
.datalen
> 0) {
1130 reqdata
= must_realloc(NULL
, req
.datalen
);
1131 ret
= lxc_recv_nointr(fd
, reqdata
, req
.datalen
, 0);
1132 if (ret
!= req
.datalen
) {
1133 WARN("Failed to receive full command request. Ignoring "
1134 "request for \"%s\"", lxc_cmd_str(req
.cmd
));
1135 ret
= LXC_MAINLOOP_ERROR
;
1142 ret
= lxc_cmd_process(fd
, &req
, handler
);
1144 /* This is not an error, but only a request to close fd. */
1145 ret
= LXC_MAINLOOP_CONTINUE
;
1153 lxc_cmd_fd_cleanup(fd
, handler
, descr
, req
.cmd
);
1157 static int lxc_cmd_accept(int fd
, uint32_t events
, void *data
,
1158 struct lxc_epoll_descr
*descr
)
1160 __do_close_prot_errno
int connection
= -EBADF
;
1161 int opt
= 1, ret
= -1;
1163 connection
= accept(fd
, NULL
, 0);
1164 if (connection
< 0) {
1165 SYSERROR("Failed to accept connection to run command");
1166 return LXC_MAINLOOP_ERROR
;
1169 ret
= fcntl(connection
, F_SETFD
, FD_CLOEXEC
);
1171 SYSERROR("Failed to set close-on-exec on incoming command connection");
1175 ret
= setsockopt(connection
, SOL_SOCKET
, SO_PASSCRED
, &opt
, sizeof(opt
));
1177 SYSERROR("Failed to enable necessary credentials on command socket");
1181 ret
= lxc_mainloop_add_handler(descr
, connection
, lxc_cmd_handler
, data
);
1183 ERROR("Failed to add command handler");
1187 steal_fd(connection
);
1191 int lxc_cmd_init(const char *name
, const char *lxcpath
, const char *suffix
)
1193 __do_close_prot_errno
int fd
= -EBADF
;
1195 char path
[LXC_AUDS_ADDR_LEN
] = {0};
1197 ret
= lxc_make_abstract_socket_name(path
, sizeof(path
), name
, lxcpath
, NULL
, suffix
);
1201 fd
= lxc_abstract_unix_open(path
, SOCK_STREAM
, 0);
1203 SYSERROR("Failed to create command socket %s", &path
[1]);
1204 if (errno
== EADDRINUSE
)
1205 ERROR("Container \"%s\" appears to be already running", name
);
1210 ret
= fcntl(fd
, F_SETFD
, FD_CLOEXEC
);
1212 SYSERROR("Failed to set FD_CLOEXEC on command socket file descriptor");
1216 TRACE("Created abstract unix socket \"%s\"", &path
[1]);
1217 return steal_fd(fd
);
1220 int lxc_cmd_mainloop_add(const char *name
, struct lxc_epoll_descr
*descr
,
1221 struct lxc_handler
*handler
)
1223 __do_close_prot_errno
int fd
= handler
->conf
->maincmd_fd
;
1226 ret
= lxc_mainloop_add_handler(descr
, fd
, lxc_cmd_accept
, handler
);
1228 ERROR("Failed to add handler for command socket");