1 /* SPDX-License-Identifier: LGPL-2.1+ */
14 #include <sys/param.h>
15 #include <sys/socket.h>
20 #include "cgroups/cgroup.h"
21 #include "cgroups/cgroup2_devices.h"
23 #include "commands_utils.h"
30 #include "lxcseccomp.h"
32 #include "memory_utils.h"
39 * This file provides the different functions for clients to query/command the
40 * server. The client is typically some lxc tool and the server is typically the
41 * container (ie. lxc-start).
43 * Each command is transactional, the clients send a request to the server and
44 * the server answers the request with a message giving the request's status
45 * (zero or a negative errno value). Both the request and response may contain
48 * Each command is wrapped in a ancillary message in order to pass a credential
49 * making possible to the server to check if the client is allowed to ask for
50 * this command or not.
52 * IMPORTANTLY: Note that semantics for current commands are fixed. If you wish
53 * to make any changes to how, say, LXC_CMD_GET_CONFIG_ITEM works by adding
54 * information to the end of cmd.data, then you must introduce a new
55 * LXC_CMD_GET_CONFIG_ITEM_V2 define with a new number. You may wish to also
56 * mark LXC_CMD_GET_CONFIG_ITEM deprecated in commands.h.
58 * This is necessary in order to avoid having a newly compiled lxc command
59 * communicating with a running (old) monitor from crashing the running
63 lxc_log_define(commands
, lxc
);
65 static const char *lxc_cmd_str(lxc_cmd_t cmd
)
67 static const char *const cmdname
[LXC_CMD_MAX
] = {
68 [LXC_CMD_GET_TTY_FD
] = "get_tty_fd",
69 [LXC_CMD_TERMINAL_WINCH
] = "terminal_winch",
70 [LXC_CMD_STOP
] = "stop",
71 [LXC_CMD_GET_STATE
] = "get_state",
72 [LXC_CMD_GET_INIT_PID
] = "get_init_pid",
73 [LXC_CMD_GET_CLONE_FLAGS
] = "get_clone_flags",
74 [LXC_CMD_GET_CGROUP
] = "get_cgroup",
75 [LXC_CMD_GET_CONFIG_ITEM
] = "get_config_item",
76 [LXC_CMD_GET_NAME
] = "get_name",
77 [LXC_CMD_GET_LXCPATH
] = "get_lxcpath",
78 [LXC_CMD_ADD_STATE_CLIENT
] = "add_state_client",
79 [LXC_CMD_CONSOLE_LOG
] = "console_log",
80 [LXC_CMD_SERVE_STATE_CLIENTS
] = "serve_state_clients",
81 [LXC_CMD_SECCOMP_NOTIFY_ADD_LISTENER
] = "seccomp_notify_add_listener",
82 [LXC_CMD_ADD_BPF_DEVICE_CGROUP
] = "add_bpf_device_cgroup",
83 [LXC_CMD_FREEZE
] = "freeze",
84 [LXC_CMD_UNFREEZE
] = "unfreeze",
85 [LXC_CMD_GET_CGROUP2_FD
] = "get_cgroup2_fd",
86 [LXC_CMD_GET_INIT_PIDFD
] = "get_init_pidfd",
87 [LXC_CMD_GET_LIMIT_CGROUP
] = "get_limit_cgroup",
88 [LXC_CMD_GET_LIMIT_CGROUP2_FD
] = "get_limit_cgroup2_fd",
89 [LXC_CMD_GET_DEVPTS_FD
] = "get_devpts_fd",
90 [LXC_CMD_GET_SECCOMP_NOTIFY_FD
] = "get_seccomp_notify_fd",
91 [LXC_CMD_GET_CGROUP_CTX
] = "get_cgroup_ctx",
92 [LXC_CMD_GET_CGROUP_FD
] = "get_cgroup_fd",
93 [LXC_CMD_GET_LIMIT_CGROUP_FD
] = "get_limit_cgroup_fd",
96 if (cmd
>= LXC_CMD_MAX
)
97 return "Invalid request";
102 static int __transfer_cgroup_ctx_fds(struct unix_fds
*fds
, struct cgroup_ctx
*ctx
)
104 /* This shouldn't be able to happen but better safe than sorry. */
105 if (ctx
->fd_len
!= fds
->fd_count_ret
||
106 fds
->fd_count_ret
> CGROUP_CTX_MAX_FD
)
107 return syswarn_set(-EINVAL
, "Unexpected number of file descriptors received %u != %u",
108 ctx
->fd_len
, fds
->fd_count_ret
);
110 memcpy(ctx
->fd
, fds
->fd
, ctx
->fd_len
* sizeof(__s32
));
111 fds
->fd_count_ret
= 0;
115 static int __transfer_cgroup_fd(struct unix_fds
*fds
, struct cgroup_fd
*fd
)
117 fd
->fd
= move_fd(fds
->fd
[0]);
122 * lxc_cmd_rsp_recv: Receive a response to a command
124 * @sock : the socket connected to the container
125 * @cmd : command to put response in
127 * Returns the size of the response message or < 0 on failure
129 * Note that if the command response datalen > 0, then data is
130 * a malloc()ed buffer and should be free()ed by the caller. If
131 * the response data is <= a void * worth of data, it will be
132 * stored directly in data and datalen will be 0.
134 * As a special case, the response for LXC_CMD_GET_TTY_FD is created here as
135 * it contains an fd for the ptx pty passed through the unix socket.
137 static int lxc_cmd_rsp_recv(int sock
, struct lxc_cmd_rr
*cmd
)
139 __do_free
void *__private_ptr
= NULL
;
140 struct lxc_cmd_tty_rsp_data
*data_console
= NULL
;
141 call_cleaner(put_unix_fds
) struct unix_fds
*fds
= &(struct unix_fds
){};
142 struct lxc_cmd_rsp
*rsp
= &cmd
->rsp
;
143 int cur_cmd
= cmd
->req
.cmd
, fret
= 0;
144 const char *cur_cmdstr
;
148 * Determine whether this command will receive file descriptors and how
151 cur_cmdstr
= lxc_cmd_str(cur_cmd
);
153 case LXC_CMD_GET_CGROUP_FD
:
155 case LXC_CMD_GET_LIMIT_CGROUP_FD
:
157 case LXC_CMD_GET_CGROUP2_FD
:
159 case LXC_CMD_GET_LIMIT_CGROUP2_FD
:
161 case LXC_CMD_GET_INIT_PIDFD
:
163 case LXC_CMD_GET_SECCOMP_NOTIFY_FD
:
165 case LXC_CMD_GET_DEVPTS_FD
:
167 case LXC_CMD_GET_TTY_FD
:
168 fds
->fd_count_max
= 1;
170 case LXC_CMD_GET_CGROUP_CTX
:
171 fds
->fd_count_max
= CGROUP_CTX_MAX_FD
;
174 fds
->fd_count_max
= 0;
178 /* Receive the first response including file descriptors if any. */
179 ret
= lxc_abstract_unix_recv_fds(sock
, fds
, rsp
, sizeof(*rsp
));
181 return syserrno(ret
, "Failed to receive response for command \"%s\"", cur_cmdstr
);
184 * Verify that we actually received any file descriptors if the command
187 if (fds
->fd_count_max
== 0) {
188 WARN("Command \"%s\" received response", cur_cmdstr
);
189 } else if (fds
->fd_count_ret
== 0) {
190 TRACE("Command \"%s\" received response without any of the expected %u file descriptors", cur_cmdstr
, fds
->fd_count_max
);
193 TRACE("Command \"%s\" received response with %u of %u expected file descriptors", cur_cmdstr
, fds
->fd_count_ret
, fds
->fd_count_max
);
197 * Ensure that no excessive data is sent unless someone retrieves the
198 * console ringbuffer.
200 if ((rsp
->datalen
> LXC_CMD_DATA_MAX
) &&
201 (cur_cmd
!= LXC_CMD_CONSOLE_LOG
))
202 return syserrno_set(fret
?: -E2BIG
, "Response data for command \"%s\" is too long: %d bytes > %d",
203 cur_cmdstr
, rsp
->datalen
, LXC_CMD_DATA_MAX
);
206 * Prepare buffer for any command that expects to receive additional
207 * data. Note that some don't want any additional data.
210 case LXC_CMD_GET_CGROUP2_FD
: /* no data */
212 case LXC_CMD_GET_LIMIT_CGROUP2_FD
: /* no data */
214 case LXC_CMD_GET_INIT_PIDFD
: /* no data */
216 case LXC_CMD_GET_DEVPTS_FD
: /* no data */
218 case LXC_CMD_GET_SECCOMP_NOTIFY_FD
: /* no data */
220 rsp
->data
= INT_TO_PTR(move_fd(fds
->fd
[0]));
222 /* Return for any command that doesn't expect additional data. */
223 return log_debug(fret
?: ret
, "Finished processing \"%s\" with file descriptor %d", cur_cmdstr
, PTR_TO_INT(rsp
->data
));
224 case LXC_CMD_GET_CGROUP_FD
: /* data */
226 case LXC_CMD_GET_LIMIT_CGROUP_FD
: /* data */
227 if (rsp
->datalen
> sizeof(struct cgroup_fd
))
228 return syserrno_set(fret
?: -EINVAL
, "Invalid response size from server for \"%s\"", cur_cmdstr
);
230 /* Don't pointlessly allocate. */
231 rsp
->data
= (void *)cmd
->req
.data
;
233 case LXC_CMD_GET_CGROUP_CTX
: /* data */
234 if (rsp
->datalen
> sizeof(struct cgroup_ctx
))
235 return syserrno_set(fret
?: -EINVAL
, "Invalid response size from server for \"%s\"", cur_cmdstr
);
237 /* Don't pointlessly allocate. */
238 rsp
->data
= (void *)cmd
->req
.data
;
240 case LXC_CMD_GET_TTY_FD
: /* data */
242 * recv() returns 0 bytes when a tty cannot be allocated,
243 * rsp->ret is < 0 when the peer permission check failed
245 if (ret
== 0 || rsp
->ret
< 0)
248 __private_ptr
= malloc(sizeof(struct lxc_cmd_tty_rsp_data
));
250 return syserrno_set(fret
?: -ENOMEM
, "Failed to receive response for command \"%s\"", cur_cmdstr
);
251 data_console
= (struct lxc_cmd_tty_rsp_data
*)__private_ptr
;
252 data_console
->ptxfd
= move_fd(fds
->fd
[0]);
253 data_console
->ttynum
= PTR_TO_INT(rsp
->data
);
256 rsp
->data
= data_console
;
258 case LXC_CMD_CONSOLE_LOG
: /* data */
259 __private_ptr
= zalloc(rsp
->datalen
+ 1);
260 rsp
->data
= __private_ptr
;
262 default: /* catch any additional command */
263 if (rsp
->datalen
> 0) {
264 __private_ptr
= zalloc(rsp
->datalen
);
265 rsp
->data
= __private_ptr
;
270 if (rsp
->datalen
== 0) {
271 DEBUG("Command \"%s\" requested no additional data", cur_cmdstr
);
273 * Note that LXC_CMD_GET_TTY_FD historically allocates memory
274 * to return info to the caller. That's why we jump to no_data
275 * so we ensure that the allocated data is wiped if we return
282 * All commands ending up here expect data so rsp->data must be valid.
283 * Either static or allocated memory.
286 return syserrno_set(fret
?: -ENOMEM
, "Failed to prepare response buffer for command \"%s\"", cur_cmdstr
);
288 ret
= lxc_recv_nointr(sock
, rsp
->data
, rsp
->datalen
, 0);
289 if (ret
!= rsp
->datalen
)
290 return syserrno(-errno
, "Failed to receive response data for command \"%s\": %d != %d", cur_cmdstr
, ret
, rsp
->datalen
);
293 case LXC_CMD_GET_CGROUP_CTX
:
295 ret
= __transfer_cgroup_ctx_fds(fds
, rsp
->data
);
296 /* Make sure any received fds are wiped by us. */
298 case LXC_CMD_GET_CGROUP_FD
:
300 case LXC_CMD_GET_LIMIT_CGROUP_FD
:
302 ret
= __transfer_cgroup_fd(fds
, rsp
->data
);
303 /* Make sure any received fds are wiped by us. */
308 if (!fret
&& ret
>= 0)
309 move_ptr(__private_ptr
);
315 * lxc_cmd_rsp_send: Send a command response
317 * @fd : file descriptor of socket to send response on
318 * @rsp : response to send
320 * Returns 0 on success, < 0 on failure
322 static int __lxc_cmd_rsp_send(int fd
, struct lxc_cmd_rsp
*rsp
)
326 ret
= lxc_send_nointr(fd
, rsp
, sizeof(*rsp
), MSG_NOSIGNAL
);
327 if (ret
< 0 || (size_t)ret
!= sizeof(*rsp
))
328 return syserrno(-errno
, "Failed to send command response %zd", ret
);
330 if (!rsp
->data
|| rsp
->datalen
<= 0)
333 ret
= lxc_send_nointr(fd
, rsp
->data
, rsp
->datalen
, MSG_NOSIGNAL
);
334 if (ret
< 0 || ret
!= (ssize_t
)rsp
->datalen
)
335 return syswarn(-errno
, "Failed to send command response %zd", ret
);
340 static inline int lxc_cmd_rsp_send_reap(int fd
, struct lxc_cmd_rsp
*rsp
)
344 ret
= __lxc_cmd_rsp_send(fd
, rsp
);
348 return LXC_CMD_REAP_CLIENT_FD
;
351 static inline int lxc_cmd_rsp_send_keep(int fd
, struct lxc_cmd_rsp
*rsp
)
355 ret
= __lxc_cmd_rsp_send(fd
, rsp
);
362 static inline int rsp_one_fd(int fd
, int fd_send
, struct lxc_cmd_rsp
*rsp
)
366 ret
= lxc_abstract_unix_send_fds(fd
, &fd_send
, 1, rsp
, sizeof(*rsp
));
370 if (rsp
->data
&& rsp
->datalen
> 0) {
371 ret
= lxc_send_nointr(fd
, rsp
->data
, rsp
->datalen
, MSG_NOSIGNAL
);
372 if (ret
< 0 || ret
!= (ssize_t
)rsp
->datalen
)
373 return syswarn(-errno
, "Failed to send command response %zd", ret
);
376 return LXC_CMD_REAP_CLIENT_FD
;
379 __access_r(3, 2) static int rsp_many_fds(int fd
, __u32 fds_len
,
380 const __s32 fds
[static 2],
381 struct lxc_cmd_rsp
*rsp
)
385 if (fds_len
> KERNEL_SCM_MAX_FD
) {
387 return lxc_cmd_rsp_send_reap(fd
, rsp
);
388 } else if (fds_len
== 0) {
390 return lxc_cmd_rsp_send_reap(fd
, rsp
);
393 ret
= lxc_abstract_unix_send_fds(fd
, fds
, fds_len
, rsp
, sizeof(*rsp
));
397 if (rsp
->data
&& rsp
->datalen
> 0) {
398 ret
= lxc_send_nointr(fd
, rsp
->data
, rsp
->datalen
, MSG_NOSIGNAL
);
399 if (ret
< 0 || ret
!= (ssize_t
)rsp
->datalen
)
400 return syswarn(-errno
, "Failed to send command response %zd", ret
);
403 return LXC_CMD_REAP_CLIENT_FD
;
406 static int lxc_cmd_send(const char *name
, struct lxc_cmd_rr
*cmd
,
407 const char *lxcpath
, const char *hashed_sock_name
)
409 __do_close
int client_fd
= -EBADF
;
412 client_fd
= lxc_cmd_connect(name
, lxcpath
, hashed_sock_name
, "command");
416 ret
= lxc_abstract_unix_send_credential(client_fd
, &cmd
->req
,
418 if (ret
< 0 || (size_t)ret
!= sizeof(cmd
->req
))
421 if (cmd
->req
.cmd
== LXC_CMD_SECCOMP_NOTIFY_ADD_LISTENER
) {
422 int notify_fd
= PTR_TO_INT(cmd
->req
.data
);
423 ret
= lxc_abstract_unix_send_fds(client_fd
, ¬ify_fd
, 1, NULL
, 0);
427 if (cmd
->req
.datalen
<= 0)
428 return move_fd(client_fd
);
431 ret
= lxc_send_nointr(client_fd
, (void *)cmd
->req
.data
,
432 cmd
->req
.datalen
, MSG_NOSIGNAL
);
433 if (ret
< 0 || ret
!= (ssize_t
)cmd
->req
.datalen
)
437 return move_fd(client_fd
);
441 * lxc_cmd: Connect to the specified running container, send it a command
442 * request and collect the response
444 * @name : name of container to connect to
445 * @cmd : command with initialized request to send
446 * @stopped : output indicator if the container was not running
447 * @lxcpath : the lxcpath in which the container is running
449 * Returns the size of the response message on success, < 0 on failure
451 * Note that there is a special case for LXC_CMD_GET_TTY_FD. For this command
452 * the fd cannot be closed because it is used as a placeholder to indicate that
453 * a particular tty slot is in use. The fd is also used as a signal to the
454 * container that when the caller dies or closes the fd, the container will
455 * notice the fd on its side of the socket in its mainloop select and then free
456 * the slot with lxc_cmd_fd_cleanup(). The socket fd will be returned in the
457 * cmd response structure.
459 static int lxc_cmd(const char *name
, struct lxc_cmd_rr
*cmd
, bool *stopped
,
460 const char *lxcpath
, const char *hashed_sock_name
)
462 __do_close
int client_fd
= -EBADF
;
464 bool stay_connected
= false;
466 if (cmd
->req
.cmd
== LXC_CMD_GET_TTY_FD
||
467 cmd
->req
.cmd
== LXC_CMD_ADD_STATE_CLIENT
)
468 stay_connected
= true;
472 client_fd
= lxc_cmd_send(name
, cmd
, lxcpath
, hashed_sock_name
);
474 if (IN_SET(errno
, ECONNREFUSED
, EPIPE
))
477 return log_trace_errno(-1, errno
, "Command \"%s\" failed to connect command socket",
478 lxc_cmd_str(cmd
->req
.cmd
));
481 ret
= lxc_cmd_rsp_recv(client_fd
, cmd
);
482 if (ret
< 0 && errno
== ECONNRESET
)
485 TRACE("Opened new command socket connection fd %d for command \"%s\"",
486 client_fd
, lxc_cmd_str(cmd
->req
.cmd
));
488 if (stay_connected
&& ret
> 0)
489 cmd
->rsp
.ret
= move_fd(client_fd
);
494 int lxc_try_cmd(const char *name
, const char *lxcpath
)
496 bool stopped
= false;
498 struct lxc_cmd_rr cmd
;
500 lxc_cmd_init(&cmd
, LXC_CMD_GET_INIT_PID
);
502 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
505 if (ret
> 0 && cmd
.rsp
.ret
< 0) {
513 * At this point we weren't denied access, and the container *was*
514 * started. There was some inexplicable error in the protocol. I'm not
515 * clear on whether we should return -1 here, but we didn't receive a
516 * -EACCES, so technically it's not that we're not allowed to control
517 * the container - it's just not behaving.
523 * Validate that the input is a proper string parameter. If not,
524 * send an EINVAL response and return -1.
526 * Precondition: there is non-zero-length data available.
528 static int validate_string_request(int fd
, const struct lxc_cmd_req
*req
)
530 size_t maxlen
= req
->datalen
- 1;
531 const char *data
= req
->data
;
533 if (data
[maxlen
] == 0 && strnlen(data
, maxlen
) == maxlen
)
536 struct lxc_cmd_rsp rsp
= {
542 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
545 /* Implementations of the commands and their callbacks */
548 * lxc_cmd_get_init_pid: Get pid of the container's init process
550 * @name : name of container to connect to
551 * @lxcpath : the lxcpath in which the container is running
553 * Returns the pid on success, < 0 on failure
555 pid_t
lxc_cmd_get_init_pid(const char *name
, const char *lxcpath
)
557 bool stopped
= false;
560 struct lxc_cmd_rr cmd
;
562 lxc_cmd_init(&cmd
, LXC_CMD_GET_INIT_PID
);
564 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
568 pid
= PTR_TO_PID(cmd
.rsp
.data
);
573 * We need to assume that pid_t can actually hold any pid given to us
574 * by the kernel. If it can't it's a libc bug.
579 static int lxc_cmd_get_init_pid_callback(int fd
, struct lxc_cmd_req
*req
,
580 struct lxc_handler
*handler
,
581 struct lxc_epoll_descr
*descr
)
583 struct lxc_cmd_rsp rsp
= {
584 .data
= PID_TO_PTR(handler
->pid
),
587 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
590 int lxc_cmd_get_init_pidfd(const char *name
, const char *lxcpath
)
592 bool stopped
= false;
594 struct lxc_cmd_rr cmd
;
596 lxc_cmd_init(&cmd
, LXC_CMD_GET_INIT_PIDFD
);
598 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
600 return log_debug_errno(-1, errno
, "Failed to process init pidfd command");
603 return syserrno_set(cmd
.rsp
.ret
, "Failed to receive init pidfd");
605 pidfd
= PTR_TO_INT(cmd
.rsp
.data
);
607 return syserrno_set(pidfd
, "Failed to receive init pidfd");
612 static int lxc_cmd_get_init_pidfd_callback(int fd
, struct lxc_cmd_req
*req
,
613 struct lxc_handler
*handler
,
614 struct lxc_epoll_descr
*descr
)
616 struct lxc_cmd_rsp rsp
= {
620 if (handler
->pidfd
< 0)
621 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
624 return rsp_one_fd(fd
, handler
->pidfd
, &rsp
);
627 int lxc_cmd_get_devpts_fd(const char *name
, const char *lxcpath
)
629 bool stopped
= false;
631 struct lxc_cmd_rr cmd
;
633 lxc_cmd_init(&cmd
, LXC_CMD_GET_DEVPTS_FD
);
635 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
637 return log_debug_errno(-1, errno
, "Failed to process devpts fd command");
640 return log_debug_errno(-EBADF
, errno
, "Failed to receive devpts fd");
642 return PTR_TO_INT(cmd
.rsp
.data
);
645 static int lxc_cmd_get_devpts_fd_callback(int fd
, struct lxc_cmd_req
*req
,
646 struct lxc_handler
*handler
,
647 struct lxc_epoll_descr
*descr
)
649 struct lxc_cmd_rsp rsp
= {
653 if (!handler
->conf
|| handler
->conf
->devpts_fd
< 0)
654 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
657 return rsp_one_fd(fd
, handler
->conf
->devpts_fd
, &rsp
);
660 int lxc_cmd_get_seccomp_notify_fd(const char *name
, const char *lxcpath
)
662 #ifdef HAVE_SECCOMP_NOTIFY
663 bool stopped
= false;
665 struct lxc_cmd_rr cmd
;
667 lxc_cmd_init(&cmd
, LXC_CMD_GET_SECCOMP_NOTIFY_FD
);
669 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
671 return log_debug_errno(-1, errno
, "Failed to process seccomp notify fd command");
674 return log_debug_errno(-EBADF
, errno
, "Failed to receive seccomp notify fd");
676 return PTR_TO_INT(cmd
.rsp
.data
);
678 return ret_errno(EOPNOTSUPP
);
682 static int lxc_cmd_get_seccomp_notify_fd_callback(int fd
, struct lxc_cmd_req
*req
,
683 struct lxc_handler
*handler
,
684 struct lxc_epoll_descr
*descr
)
686 #ifdef HAVE_SECCOMP_NOTIFY
687 struct lxc_cmd_rsp rsp
= {
691 if (!handler
->conf
|| handler
->conf
->seccomp
.notifier
.notify_fd
< 0)
692 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
695 return rsp_one_fd(fd
, handler
->conf
->seccomp
.notifier
.notify_fd
, &rsp
);
697 return syserrno_set(-EOPNOTSUPP
, "Seccomp notifier not supported");
701 int lxc_cmd_get_cgroup_ctx(const char *name
, const char *lxcpath
,
702 size_t size_ret_ctx
, struct cgroup_ctx
*ret_ctx
)
704 bool stopped
= false;
706 struct lxc_cmd_rr cmd
;
708 lxc_cmd_init(&cmd
, LXC_CMD_GET_CGROUP_CTX
);
709 lxc_cmd_data(&cmd
, size_ret_ctx
, ret_ctx
);
711 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
713 return log_debug_errno(-1, errno
, "Failed to process cgroup context command");
716 return log_debug_errno(-EBADF
, errno
, "Failed to receive cgroup fds");
721 static int lxc_cmd_get_cgroup_ctx_callback(int fd
, struct lxc_cmd_req
*req
,
722 struct lxc_handler
*handler
,
723 struct lxc_epoll_descr
*descr
)
725 struct lxc_cmd_rsp rsp
= {
728 struct cgroup_ops
*cgroup_ops
= handler
->cgroup_ops
;
729 struct cgroup_ctx ctx_server
= {};
732 ret
= copy_struct_from_client(sizeof(struct cgroup_ctx
), &ctx_server
,
733 req
->datalen
, req
->data
);
735 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
737 ret
= prepare_cgroup_ctx(cgroup_ops
, &ctx_server
);
740 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
744 rsp
.data
= &ctx_server
;
745 rsp
.datalen
= min(sizeof(struct cgroup_ctx
), (size_t)req
->datalen
);
746 return rsp_many_fds(fd
, ctx_server
.fd_len
, ctx_server
.fd
, &rsp
);
750 * lxc_cmd_get_clone_flags: Get clone flags container was spawned with
752 * @name : name of container to connect to
753 * @lxcpath : the lxcpath in which the container is running
755 * Returns the clone flags on success, < 0 on failure
757 int lxc_cmd_get_clone_flags(const char *name
, const char *lxcpath
)
759 bool stopped
= false;
761 struct lxc_cmd_rr cmd
;
763 lxc_cmd_init(&cmd
, LXC_CMD_GET_CLONE_FLAGS
);
765 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
769 return PTR_TO_INT(cmd
.rsp
.data
);
772 static int lxc_cmd_get_clone_flags_callback(int fd
, struct lxc_cmd_req
*req
,
773 struct lxc_handler
*handler
,
774 struct lxc_epoll_descr
*descr
)
776 struct lxc_cmd_rsp rsp
= {
777 .data
= INT_TO_PTR(handler
->ns_clone_flags
),
780 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
783 static char *lxc_cmd_get_cgroup_path_do(const char *name
, const char *lxcpath
,
784 const char *controller
,
787 bool stopped
= false;
789 struct lxc_cmd_rr cmd
;
791 lxc_cmd_init(&cmd
, command
);
793 lxc_cmd_data(&cmd
, strlen(controller
) + 1, controller
);
795 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
800 if (command
== LXC_CMD_GET_LIMIT_CGROUP
) {
802 * This may indicate that the container was started
803 * under an ealier version before
804 * `cgroup_advanced_isolation` as implemented, there
805 * it sees an unknown command and just closes the
806 * socket, sending us an EOF.
808 return lxc_cmd_get_cgroup_path_do(name
, lxcpath
,
815 if (cmd
.rsp
.ret
< 0 || cmd
.rsp
.datalen
< 0)
822 * lxc_cmd_get_cgroup_path: Calculate a container's cgroup path for a
823 * particular controller. This is the cgroup path relative to the root
824 * of the cgroup filesystem.
826 * @name : name of container to connect to
827 * @lxcpath : the lxcpath in which the container is running
828 * @controller : the controller being asked about
830 * Returns the path on success, NULL on failure. The caller must free() the
833 char *lxc_cmd_get_cgroup_path(const char *name
, const char *lxcpath
,
834 const char *controller
)
836 return lxc_cmd_get_cgroup_path_do(name
, lxcpath
, controller
,
841 * lxc_cmd_get_limit_cgroup_path: Calculate a container's limit cgroup
842 * path for a particular controller. This is the cgroup path relative to the
843 * root of the cgroup filesystem. This may be the same as the path returned by
844 * lxc_cmd_get_cgroup_path if the container doesn't have a limit path prefix
847 * @name : name of container to connect to
848 * @lxcpath : the lxcpath in which the container is running
849 * @controller : the controller being asked about
851 * Returns the path on success, NULL on failure. The caller must free() the
854 char *lxc_cmd_get_limit_cgroup_path(const char *name
, const char *lxcpath
,
855 const char *controller
)
857 return lxc_cmd_get_cgroup_path_do(name
, lxcpath
, controller
,
858 LXC_CMD_GET_LIMIT_CGROUP
);
861 static int lxc_cmd_get_cgroup_callback_do(int fd
, struct lxc_cmd_req
*req
,
862 struct lxc_handler
*handler
,
863 struct lxc_epoll_descr
*descr
,
864 bool limiting_cgroup
)
869 struct lxc_cmd_rsp rsp
;
870 struct cgroup_ops
*cgroup_ops
= handler
->cgroup_ops
;
871 const char *(*get_fn
)(struct cgroup_ops
*ops
, const char *controller
);
873 if (req
->datalen
> 0) {
874 ret
= validate_string_request(fd
, req
);
882 get_fn
= (limiting_cgroup
? cgroup_ops
->get_limit_cgroup
883 : cgroup_ops
->get_cgroup
);
885 path
= get_fn(cgroup_ops
, reqdata
);
891 rsp
.datalen
= strlen(path
) + 1;
892 rsp
.data
= (char *)path
;
894 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
897 static int lxc_cmd_get_cgroup_callback(int fd
, struct lxc_cmd_req
*req
,
898 struct lxc_handler
*handler
,
899 struct lxc_epoll_descr
*descr
)
901 return lxc_cmd_get_cgroup_callback_do(fd
, req
, handler
, descr
, false);
904 static int lxc_cmd_get_limit_cgroup_callback(int fd
, struct lxc_cmd_req
*req
,
905 struct lxc_handler
*handler
,
906 struct lxc_epoll_descr
*descr
)
908 return lxc_cmd_get_cgroup_callback_do(fd
, req
, handler
, descr
, true);
912 * lxc_cmd_get_config_item: Get config item the running container
914 * @name : name of container to connect to
915 * @item : the configuration item to retrieve (ex: lxc.net.0.veth.pair)
916 * @lxcpath : the lxcpath in which the container is running
918 * Returns the item on success, NULL on failure. The caller must free() the
921 char *lxc_cmd_get_config_item(const char *name
, const char *item
,
924 bool stopped
= false;
926 struct lxc_cmd_rr cmd
;
928 if (is_empty_string(item
))
931 lxc_cmd_init(&cmd
, LXC_CMD_GET_CONFIG_ITEM
);
932 lxc_cmd_data(&cmd
, strlen(item
) + 1, item
);
934 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
938 if (cmd
.rsp
.ret
== 0)
944 static int lxc_cmd_get_config_item_callback(int fd
, struct lxc_cmd_req
*req
,
945 struct lxc_handler
*handler
,
946 struct lxc_epoll_descr
*descr
)
948 __do_free
char *cidata
= NULL
;
950 struct lxc_config_t
*item
;
951 struct lxc_cmd_rsp rsp
;
953 memset(&rsp
, 0, sizeof(rsp
));
954 item
= lxc_get_config(req
->data
);
958 cilen
= item
->get(req
->data
, NULL
, 0, handler
->conf
, NULL
);
962 cidata
= must_realloc(NULL
, cilen
+ 1);
963 if (item
->get(req
->data
, cidata
, cilen
+ 1, handler
->conf
, NULL
) != cilen
)
966 cidata
[cilen
] = '\0';
968 rsp
.datalen
= cilen
+ 1;
975 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
979 * lxc_cmd_get_state: Get current state of the container
981 * @name : name of container to connect to
982 * @lxcpath : the lxcpath in which the container is running
984 * Returns the state on success, < 0 on failure
986 int lxc_cmd_get_state(const char *name
, const char *lxcpath
)
988 bool stopped
= false;
990 struct lxc_cmd_rr cmd
;
992 lxc_cmd_init(&cmd
, LXC_CMD_GET_STATE
);
994 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
995 if (ret
< 0 && stopped
)
1002 return log_warn(-1, "Container \"%s\" has stopped before sending its state", name
);
1004 return log_debug(PTR_TO_INT(cmd
.rsp
.data
),
1005 "Container \"%s\" is in \"%s\" state", name
,
1006 lxc_state2str(PTR_TO_INT(cmd
.rsp
.data
)));
1009 static int lxc_cmd_get_state_callback(int fd
, struct lxc_cmd_req
*req
,
1010 struct lxc_handler
*handler
,
1011 struct lxc_epoll_descr
*descr
)
1013 struct lxc_cmd_rsp rsp
= {
1014 .data
= INT_TO_PTR(handler
->state
),
1017 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
1021 * lxc_cmd_stop: Stop the container previously started with lxc_start. All
1022 * the processes running inside this container will be killed.
1024 * @name : name of container to connect to
1025 * @lxcpath : the lxcpath in which the container is running
1027 * Returns 0 on success, < 0 on failure
1029 int lxc_cmd_stop(const char *name
, const char *lxcpath
)
1031 bool stopped
= false;
1033 struct lxc_cmd_rr cmd
;
1035 lxc_cmd_init(&cmd
, LXC_CMD_STOP
);
1037 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
1040 return log_info(0, "Container \"%s\" is already stopped", name
);
1045 /* We do not expect any answer, because we wait for the connection to be
1049 return log_error_errno(-1, -cmd
.rsp
.ret
, "Failed to stop container \"%s\"", name
);
1051 return log_info(0, "Container \"%s\" has stopped", name
);
1054 static int lxc_cmd_stop_callback(int fd
, struct lxc_cmd_req
*req
,
1055 struct lxc_handler
*handler
,
1056 struct lxc_epoll_descr
*descr
)
1058 struct lxc_cmd_rsp rsp
;
1059 int stopsignal
= SIGKILL
;
1060 struct cgroup_ops
*cgroup_ops
= handler
->cgroup_ops
;
1063 if (handler
->conf
->stopsignal
)
1064 stopsignal
= handler
->conf
->stopsignal
;
1065 memset(&rsp
, 0, sizeof(rsp
));
1067 if (handler
->pidfd
>= 0)
1068 rsp
.ret
= lxc_raw_pidfd_send_signal(handler
->pidfd
, stopsignal
, NULL
, 0);
1070 rsp
.ret
= kill(handler
->pid
, stopsignal
);
1072 if (handler
->pidfd
>= 0)
1073 TRACE("Sent signal %d to pidfd %d", stopsignal
, handler
->pidfd
);
1075 TRACE("Sent signal %d to pidfd %d", stopsignal
, handler
->pid
);
1077 if (pure_unified_layout(cgroup_ops
))
1078 ret
= __cgroup_unfreeze(cgroup_ops
->unified
->dfd_lim
, -1);
1080 ret
= cgroup_ops
->unfreeze(cgroup_ops
, -1);
1082 WARN("Failed to unfreeze container \"%s\"", handler
->name
);
1089 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
1093 * lxc_cmd_terminal_winch: noop
1095 * @name : name of container to connect to
1096 * @lxcpath : the lxcpath in which the container is running
1098 * Returns 0 on success, < 0 on failure
1100 int lxc_cmd_terminal_winch(const char *name
, const char *lxcpath
)
1105 static int lxc_cmd_terminal_winch_callback(int fd
, struct lxc_cmd_req
*req
,
1106 struct lxc_handler
*handler
,
1107 struct lxc_epoll_descr
*descr
)
1109 /* should never be called */
1110 return log_error_errno(-1, ENOSYS
, "Called lxc_cmd_terminal_winch_callback()");
1114 * lxc_cmd_get_tty_fd: Open an fd to a tty in the container
1116 * @name : name of container to connect to
1117 * @ttynum : in: the tty to open or -1 for next available
1118 * : out: the tty allocated
1119 * @fd : out: file descriptor for ptx side of pty
1120 * @lxcpath : the lxcpath in which the container is running
1122 * Returns fd holding tty allocated on success, < 0 on failure
1124 int lxc_cmd_get_tty_fd(const char *name
, int *ttynum
, int *fd
, const char *lxcpath
)
1126 __do_free
struct lxc_cmd_tty_rsp_data
*rspdata
= NULL
;
1127 bool stopped
= false;
1129 struct lxc_cmd_rr cmd
;
1131 lxc_cmd_init(&cmd
, LXC_CMD_GET_TTY_FD
);
1132 lxc_cmd_data(&cmd
, ENCODE_INTO_PTR_LEN
, INT_TO_PTR(*ttynum
));
1134 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
1138 rspdata
= cmd
.rsp
.data
;
1139 if (cmd
.rsp
.ret
< 0)
1140 return log_error_errno(-1, -cmd
.rsp
.ret
, "Denied access to tty");
1143 return log_error(-1, "tty number %d invalid, busy or all ttys busy", *ttynum
);
1145 if (rspdata
->ptxfd
< 0)
1146 return log_error(-1, "Unable to allocate fd for tty %d", rspdata
->ttynum
);
1148 ret
= cmd
.rsp
.ret
; /* socket fd */
1149 *fd
= rspdata
->ptxfd
;
1150 *ttynum
= rspdata
->ttynum
;
1152 return log_info(ret
, "Alloced fd %d for tty %d via socket %d", *fd
, rspdata
->ttynum
, ret
);
1155 static int lxc_cmd_get_tty_fd_callback(int fd
, struct lxc_cmd_req
*req
,
1156 struct lxc_handler
*handler
,
1157 struct lxc_epoll_descr
*descr
)
1160 struct lxc_cmd_rsp rsp
= {
1163 int ttynum
= PTR_TO_INT(req
->data
);
1165 ptxfd
= lxc_terminal_allocate(handler
->conf
, fd
, &ttynum
);
1167 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
1170 rsp
.data
= INT_TO_PTR(ttynum
);
1171 ret
= lxc_abstract_unix_send_fds(fd
, &ptxfd
, 1, &rsp
, sizeof(rsp
));
1173 lxc_terminal_free(handler
->conf
, fd
);
1177 return log_debug(0, "Send tty to client");
1181 * lxc_cmd_get_name: Returns the name of the container
1183 * @hashed_sock_name: hashed socket name
1185 * Returns the name on success, NULL on failure.
1187 char *lxc_cmd_get_name(const char *hashed_sock_name
)
1189 bool stopped
= false;
1191 struct lxc_cmd_rr cmd
;
1193 lxc_cmd_init(&cmd
, LXC_CMD_GET_NAME
);
1195 ret
= lxc_cmd(NULL
, &cmd
, &stopped
, NULL
, hashed_sock_name
);
1199 if (cmd
.rsp
.ret
== 0)
1200 return cmd
.rsp
.data
;
1205 static int lxc_cmd_get_name_callback(int fd
, struct lxc_cmd_req
*req
,
1206 struct lxc_handler
*handler
,
1207 struct lxc_epoll_descr
*descr
)
1209 struct lxc_cmd_rsp rsp
;
1211 memset(&rsp
, 0, sizeof(rsp
));
1213 rsp
.data
= (char *)handler
->name
;
1214 rsp
.datalen
= strlen(handler
->name
) + 1;
1217 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
1221 * lxc_cmd_get_lxcpath: Returns the lxcpath of the container
1223 * @hashed_sock_name: hashed socket name
1225 * Returns the lxcpath on success, NULL on failure.
1227 char *lxc_cmd_get_lxcpath(const char *hashed_sock_name
)
1229 bool stopped
= false;
1231 struct lxc_cmd_rr cmd
;
1233 lxc_cmd_init(&cmd
, LXC_CMD_GET_LXCPATH
);
1235 ret
= lxc_cmd(NULL
, &cmd
, &stopped
, NULL
, hashed_sock_name
);
1239 if (cmd
.rsp
.ret
== 0)
1240 return cmd
.rsp
.data
;
1245 static int lxc_cmd_get_lxcpath_callback(int fd
, struct lxc_cmd_req
*req
,
1246 struct lxc_handler
*handler
,
1247 struct lxc_epoll_descr
*descr
)
1249 struct lxc_cmd_rsp rsp
= {
1251 .data
= (char *)handler
->lxcpath
,
1252 .datalen
= strlen(handler
->lxcpath
) + 1,
1255 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
1258 int lxc_cmd_add_state_client(const char *name
, const char *lxcpath
,
1259 lxc_state_t states
[static MAX_STATE
],
1260 int *state_client_fd
)
1262 __do_close
int clientfd
= -EBADF
;
1263 bool stopped
= false;
1266 struct lxc_cmd_rr cmd
;
1268 lxc_cmd_init(&cmd
, LXC_CMD_ADD_STATE_CLIENT
);
1269 lxc_cmd_data(&cmd
, (sizeof(lxc_state_t
) * MAX_STATE
), states
);
1271 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
1272 if (states
[STOPPED
] != 0 && stopped
!= 0)
1276 if (errno
!= ECONNREFUSED
)
1277 SYSERROR("Failed to execute command");
1282 /* We should now be guaranteed to get an answer from the state sending
1285 clientfd
= cmd
.rsp
.ret
;
1287 return log_error_errno(-1, -clientfd
, "Failed to receive socket fd");
1289 state
= PTR_TO_INT(cmd
.rsp
.data
);
1290 if (state
< MAX_STATE
)
1291 return log_trace(state
, "Container is already in requested state %s", lxc_state2str(state
));
1293 *state_client_fd
= move_fd(clientfd
);
1294 TRACE("State connection fd %d ready to listen for container state changes", *state_client_fd
);
1298 static int lxc_cmd_add_state_client_callback(__owns
int fd
, struct lxc_cmd_req
*req
,
1299 struct lxc_handler
*handler
,
1300 struct lxc_epoll_descr
*descr
)
1302 struct lxc_cmd_rsp rsp
= {
1306 if (req
->datalen
< 0)
1309 if (req
->datalen
!= (sizeof(lxc_state_t
) * MAX_STATE
))
1315 rsp
.ret
= lxc_add_state_client(fd
, handler
, (lxc_state_t
*)req
->data
);
1319 rsp
.data
= INT_TO_PTR(rsp
.ret
);
1321 return lxc_cmd_rsp_send_keep(fd
, &rsp
);
1324 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
1327 int lxc_cmd_add_bpf_device_cgroup(const char *name
, const char *lxcpath
,
1328 struct device_item
*device
)
1330 bool stopped
= false;
1332 struct lxc_cmd_rr cmd
;
1334 if (strlen(device
->access
) > STRLITERALLEN("rwm"))
1335 return syserrno_set(-EINVAL
, "Invalid access mode specified %s", device
->access
);
1337 lxc_cmd_init(&cmd
, LXC_CMD_ADD_BPF_DEVICE_CGROUP
);
1338 lxc_cmd_data(&cmd
, sizeof(struct device_item
), device
);
1340 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
1342 return syserrno_set(ret
, "Failed to process new bpf device cgroup command");
1344 if (cmd
.rsp
.ret
< 0)
1345 return syserrno_set(cmd
.rsp
.ret
, "Failed to add new bpf device cgroup rule");
1350 static int lxc_cmd_add_bpf_device_cgroup_callback(int fd
, struct lxc_cmd_req
*req
,
1351 struct lxc_handler
*handler
,
1352 struct lxc_epoll_descr
*descr
)
1354 struct lxc_cmd_rsp rsp
= {
1357 struct lxc_conf
*conf
;
1359 if (req
->datalen
<= 0)
1362 if (req
->datalen
!= sizeof(struct device_item
))
1368 conf
= handler
->conf
;
1369 if (!bpf_cgroup_devices_update(handler
->cgroup_ops
,
1371 (struct device_item
*)req
->data
))
1377 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
1380 int lxc_cmd_console_log(const char *name
, const char *lxcpath
,
1381 struct lxc_console_log
*log
)
1383 bool stopped
= false;
1384 struct lxc_cmd_console_log data
= {
1385 .clear
= log
->clear
,
1387 .read_max
= *log
->read_max
,
1390 struct lxc_cmd_rr cmd
;
1392 lxc_cmd_init(&cmd
, LXC_CMD_CONSOLE_LOG
);
1393 lxc_cmd_data(&cmd
, sizeof(struct lxc_cmd_console_log
), &data
);
1395 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
1399 /* There is nothing to be read from the buffer. So clear any values we
1400 * where passed to clearly indicate to the user that nothing went wrong.
1402 if (cmd
.rsp
.ret
== -ENODATA
|| cmd
.rsp
.ret
== -EFAULT
|| cmd
.rsp
.ret
== -ENOENT
) {
1407 /* This is a proper error so don't touch any values we were passed. */
1408 if (cmd
.rsp
.ret
< 0)
1411 *log
->read_max
= cmd
.rsp
.datalen
;
1412 log
->data
= cmd
.rsp
.data
;
1417 static int lxc_cmd_console_log_callback(int fd
, struct lxc_cmd_req
*req
,
1418 struct lxc_handler
*handler
,
1419 struct lxc_epoll_descr
*descr
)
1421 struct lxc_cmd_rsp rsp
;
1422 uint64_t buffer_size
= handler
->conf
->console
.buffer_size
;
1423 const struct lxc_cmd_console_log
*log
= req
->data
;
1424 struct lxc_ringbuf
*buf
= &handler
->conf
->console
.ringbuf
;
1429 if (buffer_size
<= 0)
1432 if (log
->read
|| log
->write_logfile
)
1433 rsp
.datalen
= lxc_ringbuf_used(buf
);
1436 rsp
.data
= lxc_ringbuf_get_read_addr(buf
);
1438 if (log
->read_max
> 0 && (log
->read_max
<= rsp
.datalen
))
1439 rsp
.datalen
= log
->read_max
;
1441 /* there's nothing to read */
1443 if (log
->read
&& (buf
->r_off
== buf
->w_off
))
1448 lxc_ringbuf_clear(buf
); /* clear the ringbuffer */
1449 else if (rsp
.datalen
> 0)
1450 lxc_ringbuf_move_read_addr(buf
, rsp
.datalen
);
1453 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
1456 int lxc_cmd_serve_state_clients(const char *name
, const char *lxcpath
,
1459 bool stopped
= false;
1461 struct lxc_cmd_rr cmd
;
1463 lxc_cmd_init(&cmd
, LXC_CMD_SERVE_STATE_CLIENTS
);
1464 lxc_cmd_data(&cmd
, ENCODE_INTO_PTR_LEN
, INT_TO_PTR(state
));
1466 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
1468 return log_error_errno(-1, errno
, "Failed to serve state clients");
1473 static int lxc_cmd_serve_state_clients_callback(int fd
, struct lxc_cmd_req
*req
,
1474 struct lxc_handler
*handler
,
1475 struct lxc_epoll_descr
*descr
)
1478 lxc_state_t state
= PTR_TO_INT(req
->data
);
1479 struct lxc_cmd_rsp rsp
= {0};
1481 ret
= lxc_serve_state_clients(handler
->name
, handler
, state
);
1485 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
1488 int lxc_cmd_seccomp_notify_add_listener(const char *name
, const char *lxcpath
,
1490 /* unused */ unsigned int command
,
1491 /* unused */ unsigned int flags
)
1494 #ifdef HAVE_SECCOMP_NOTIFY
1495 bool stopped
= false;
1497 struct lxc_cmd_rr cmd
;
1499 lxc_cmd_init(&cmd
, LXC_CMD_SECCOMP_NOTIFY_ADD_LISTENER
);
1500 lxc_cmd_data(&cmd
, ENCODE_INTO_PTR_LEN
, INT_TO_PTR(fd
));
1502 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
1504 return log_error_errno(-1, errno
, "Failed to add seccomp listener");
1508 return ret_set_errno(-1, ENOSYS
);
1512 static int lxc_cmd_seccomp_notify_add_listener_callback(int fd
,
1513 struct lxc_cmd_req
*req
,
1514 struct lxc_handler
*handler
,
1515 struct lxc_epoll_descr
*descr
)
1517 struct lxc_cmd_rsp rsp
= {0};
1519 #ifdef HAVE_SECCOMP_NOTIFY
1521 __do_close
int recv_fd
= -EBADF
;
1523 ret
= lxc_abstract_unix_recv_one_fd(fd
, &recv_fd
, NULL
, 0);
1529 if (!handler
->conf
->seccomp
.notifier
.wants_supervision
||
1530 handler
->conf
->seccomp
.notifier
.proxy_fd
< 0) {
1531 SYSERROR("No seccomp proxy fd specified");
1536 ret
= lxc_mainloop_add_handler(descr
, recv_fd
, seccomp_notify_handler
,
1549 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
1552 int lxc_cmd_freeze(const char *name
, const char *lxcpath
, int timeout
)
1554 bool stopped
= false;
1556 struct lxc_cmd_rr cmd
;
1558 lxc_cmd_init(&cmd
, LXC_CMD_FREEZE
);
1559 lxc_cmd_data(&cmd
, ENCODE_INTO_PTR_LEN
, INT_TO_PTR(timeout
));
1561 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
1562 if (ret
<= 0 || cmd
.rsp
.ret
< 0)
1563 return log_error_errno(-1, errno
, "Failed to freeze container");
1568 static int lxc_cmd_freeze_callback(int fd
, struct lxc_cmd_req
*req
,
1569 struct lxc_handler
*handler
,
1570 struct lxc_epoll_descr
*descr
)
1572 int timeout
= PTR_TO_INT(req
->data
);
1573 struct lxc_cmd_rsp rsp
= {
1576 struct cgroup_ops
*ops
= handler
->cgroup_ops
;
1578 if (pure_unified_layout(ops
))
1579 rsp
.ret
= ops
->freeze(ops
, timeout
);
1581 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
1584 int lxc_cmd_unfreeze(const char *name
, const char *lxcpath
, int timeout
)
1586 bool stopped
= false;
1587 struct lxc_cmd_rr cmd
;
1590 lxc_cmd_init(&cmd
, LXC_CMD_UNFREEZE
);
1591 lxc_cmd_data(&cmd
, ENCODE_INTO_PTR_LEN
, INT_TO_PTR(timeout
));
1593 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
1594 if (ret
<= 0 || cmd
.rsp
.ret
< 0)
1595 return log_error_errno(-1, errno
, "Failed to unfreeze container");
1600 static int lxc_cmd_unfreeze_callback(int fd
, struct lxc_cmd_req
*req
,
1601 struct lxc_handler
*handler
,
1602 struct lxc_epoll_descr
*descr
)
1604 int timeout
= PTR_TO_INT(req
->data
);
1605 struct lxc_cmd_rsp rsp
= {
1608 struct cgroup_ops
*ops
= handler
->cgroup_ops
;
1610 if (pure_unified_layout(ops
))
1611 rsp
.ret
= ops
->unfreeze(ops
, timeout
);
1613 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
1616 int lxc_cmd_get_cgroup_fd(const char *name
, const char *lxcpath
,
1617 size_t size_ret_fd
, struct cgroup_fd
*ret_fd
)
1619 bool stopped
= false;
1621 struct lxc_cmd_rr cmd
;
1623 lxc_cmd_init(&cmd
, LXC_CMD_GET_CGROUP_FD
);
1624 lxc_cmd_data(&cmd
, sizeof(struct cgroup_fd
), ret_fd
);
1626 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
1628 return log_debug_errno(-1, errno
, "Failed to process cgroup fd command");
1630 if (cmd
.rsp
.ret
< 0)
1631 return log_debug_errno(-EBADF
, errno
, "Failed to receive cgroup fd");
1636 int lxc_cmd_get_limit_cgroup_fd(const char *name
, const char *lxcpath
,
1637 size_t size_ret_fd
, struct cgroup_fd
*ret_fd
)
1639 bool stopped
= false;
1640 struct lxc_cmd_rr cmd
= {
1642 .cmd
= LXC_CMD_GET_LIMIT_CGROUP_FD
,
1643 .datalen
= sizeof(struct cgroup_fd
),
1652 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
1654 return log_debug_errno(-1, errno
, "Failed to process limit cgroup fd command");
1656 if (cmd
.rsp
.ret
< 0)
1657 return log_debug_errno(-EBADF
, errno
, "Failed to receive limit cgroup fd");
1662 static int __lxc_cmd_get_cgroup_fd_callback(int fd
, struct lxc_cmd_req
*req
,
1663 struct lxc_handler
*handler
,
1664 struct lxc_epoll_descr
*descr
,
1667 struct lxc_cmd_rsp rsp
= {
1670 struct cgroup_ops
*ops
= handler
->cgroup_ops
;
1671 struct cgroup_fd fd_server
= {};
1674 ret
= copy_struct_from_client(sizeof(struct cgroup_fd
), &fd_server
,
1675 req
->datalen
, req
->data
);
1677 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
1679 if (strnlen(fd_server
.controller
, MAX_CGROUP_ROOT_NAMELEN
) == 0)
1680 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
1682 ret
= prepare_cgroup_fd(ops
, &fd_server
, limit
);
1685 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
1689 rsp
.data
= &fd_server
;
1690 rsp
.datalen
= min(sizeof(struct cgroup_fd
), (size_t)req
->datalen
);
1691 return rsp_one_fd(fd
, fd_server
.fd
, &rsp
);
1694 static int lxc_cmd_get_cgroup_fd_callback(int fd
, struct lxc_cmd_req
*req
,
1695 struct lxc_handler
*handler
,
1696 struct lxc_epoll_descr
*descr
)
1698 return __lxc_cmd_get_cgroup_fd_callback(fd
, req
, handler
, descr
, false);
1701 static int lxc_cmd_get_limit_cgroup_fd_callback(int fd
, struct lxc_cmd_req
*req
,
1702 struct lxc_handler
*handler
,
1703 struct lxc_epoll_descr
*descr
)
1705 return __lxc_cmd_get_cgroup_fd_callback(fd
, req
, handler
, descr
, true);
1708 int lxc_cmd_get_cgroup2_fd(const char *name
, const char *lxcpath
)
1710 bool stopped
= false;
1711 struct lxc_cmd_rr cmd
= {
1713 .cmd
= LXC_CMD_GET_CGROUP2_FD
,
1721 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
1725 if (cmd
.rsp
.ret
< 0)
1726 return log_debug_errno(cmd
.rsp
.ret
, -cmd
.rsp
.ret
, "Failed to receive cgroup2 fd");
1728 return PTR_TO_INT(cmd
.rsp
.data
);
1731 int lxc_cmd_get_limit_cgroup2_fd(const char *name
, const char *lxcpath
)
1733 bool stopped
= false;
1734 struct lxc_cmd_rr cmd
= {
1736 .cmd
= LXC_CMD_GET_LIMIT_CGROUP2_FD
,
1744 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
1748 if (cmd
.rsp
.ret
< 0)
1749 return syswarn_set(cmd
.rsp
.ret
, "Failed to receive cgroup2 limit fd");
1751 return PTR_TO_INT(cmd
.rsp
.data
);
1754 static int lxc_cmd_get_cgroup2_fd_callback_do(int fd
, struct lxc_cmd_req
*req
,
1755 struct lxc_handler
*handler
,
1756 struct lxc_epoll_descr
*descr
,
1757 bool limiting_cgroup
)
1759 struct lxc_cmd_rsp rsp
= {
1762 struct cgroup_ops
*ops
= handler
->cgroup_ops
;
1765 if (!pure_unified_layout(ops
) || !ops
->unified
)
1766 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
1768 send_fd
= limiting_cgroup
? ops
->unified
->dfd_lim
1769 : ops
->unified
->dfd_con
;
1773 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
1777 return rsp_one_fd(fd
, send_fd
, &rsp
);
1780 static int lxc_cmd_get_cgroup2_fd_callback(int fd
, struct lxc_cmd_req
*req
,
1781 struct lxc_handler
*handler
,
1782 struct lxc_epoll_descr
*descr
)
1784 return lxc_cmd_get_cgroup2_fd_callback_do(fd
, req
, handler
, descr
,
1788 static int lxc_cmd_get_limit_cgroup2_fd_callback(int fd
, struct lxc_cmd_req
*req
,
1789 struct lxc_handler
*handler
,
1790 struct lxc_epoll_descr
*descr
)
1792 return lxc_cmd_get_cgroup2_fd_callback_do(fd
, req
, handler
, descr
,
1796 static int lxc_cmd_rsp_send_enosys(int fd
, int id
)
1798 struct lxc_cmd_rsp rsp
= {
1802 __lxc_cmd_rsp_send(fd
, &rsp
);
1803 return syserrno_set(-ENOSYS
, "Invalid command id %d", id
);
1806 static int lxc_cmd_process(int fd
, struct lxc_cmd_req
*req
,
1807 struct lxc_handler
*handler
,
1808 struct lxc_epoll_descr
*descr
)
1810 typedef int (*callback
)(int, struct lxc_cmd_req
*, struct lxc_handler
*,
1811 struct lxc_epoll_descr
*);
1813 callback cb
[LXC_CMD_MAX
] = {
1814 [LXC_CMD_GET_TTY_FD
] = lxc_cmd_get_tty_fd_callback
,
1815 [LXC_CMD_TERMINAL_WINCH
] = lxc_cmd_terminal_winch_callback
,
1816 [LXC_CMD_STOP
] = lxc_cmd_stop_callback
,
1817 [LXC_CMD_GET_STATE
] = lxc_cmd_get_state_callback
,
1818 [LXC_CMD_GET_INIT_PID
] = lxc_cmd_get_init_pid_callback
,
1819 [LXC_CMD_GET_CLONE_FLAGS
] = lxc_cmd_get_clone_flags_callback
,
1820 [LXC_CMD_GET_CGROUP
] = lxc_cmd_get_cgroup_callback
,
1821 [LXC_CMD_GET_CONFIG_ITEM
] = lxc_cmd_get_config_item_callback
,
1822 [LXC_CMD_GET_NAME
] = lxc_cmd_get_name_callback
,
1823 [LXC_CMD_GET_LXCPATH
] = lxc_cmd_get_lxcpath_callback
,
1824 [LXC_CMD_ADD_STATE_CLIENT
] = lxc_cmd_add_state_client_callback
,
1825 [LXC_CMD_CONSOLE_LOG
] = lxc_cmd_console_log_callback
,
1826 [LXC_CMD_SERVE_STATE_CLIENTS
] = lxc_cmd_serve_state_clients_callback
,
1827 [LXC_CMD_SECCOMP_NOTIFY_ADD_LISTENER
] = lxc_cmd_seccomp_notify_add_listener_callback
,
1828 [LXC_CMD_ADD_BPF_DEVICE_CGROUP
] = lxc_cmd_add_bpf_device_cgroup_callback
,
1829 [LXC_CMD_FREEZE
] = lxc_cmd_freeze_callback
,
1830 [LXC_CMD_UNFREEZE
] = lxc_cmd_unfreeze_callback
,
1831 [LXC_CMD_GET_CGROUP2_FD
] = lxc_cmd_get_cgroup2_fd_callback
,
1832 [LXC_CMD_GET_INIT_PIDFD
] = lxc_cmd_get_init_pidfd_callback
,
1833 [LXC_CMD_GET_LIMIT_CGROUP
] = lxc_cmd_get_limit_cgroup_callback
,
1834 [LXC_CMD_GET_LIMIT_CGROUP2_FD
] = lxc_cmd_get_limit_cgroup2_fd_callback
,
1835 [LXC_CMD_GET_DEVPTS_FD
] = lxc_cmd_get_devpts_fd_callback
,
1836 [LXC_CMD_GET_SECCOMP_NOTIFY_FD
] = lxc_cmd_get_seccomp_notify_fd_callback
,
1837 [LXC_CMD_GET_CGROUP_CTX
] = lxc_cmd_get_cgroup_ctx_callback
,
1838 [LXC_CMD_GET_CGROUP_FD
] = lxc_cmd_get_cgroup_fd_callback
,
1839 [LXC_CMD_GET_LIMIT_CGROUP_FD
] = lxc_cmd_get_limit_cgroup_fd_callback
,
1842 if (req
->cmd
>= LXC_CMD_MAX
)
1843 return lxc_cmd_rsp_send_enosys(fd
, req
->cmd
);
1845 return cb
[req
->cmd
](fd
, req
, handler
, descr
);
1848 static void lxc_cmd_fd_cleanup(int fd
, struct lxc_handler
*handler
,
1849 struct lxc_epoll_descr
*descr
, const lxc_cmd_t cmd
)
1851 lxc_terminal_free(handler
->conf
, fd
);
1852 lxc_mainloop_del_handler(descr
, fd
);
1854 if (cmd
== LXC_CMD_ADD_STATE_CLIENT
) {
1855 struct lxc_list
*cur
, *next
;
1857 lxc_list_for_each_safe(cur
, &handler
->conf
->state_clients
, next
) {
1858 struct lxc_state_client
*client
= cur
->elem
;
1860 if (client
->clientfd
!= fd
)
1864 * Only kick client from list so it can't be found
1865 * anymore. The actual close happens, as for all other
1866 * file descriptors, below.
1873 * No need to walk the whole list. If we found the state
1874 * client fd there can't be a second one.
1876 TRACE("Found state client fd %d in state client list for command \"%s\"", fd
, lxc_cmd_str(cmd
));
1881 * We didn't add the state client to the list. Either because
1882 * we failed to allocate memory (unlikely) or because the state
1883 * was already reached by the time we were ready to add it. So
1884 * fallthrough and clean it up.
1886 TRACE("Closing state client fd %d for command \"%s\"", fd
, lxc_cmd_str(cmd
));
1889 TRACE("Closing client fd %d for command \"%s\"", fd
, lxc_cmd_str(cmd
));
1893 static int lxc_cmd_handler(int fd
, uint32_t events
, void *data
,
1894 struct lxc_epoll_descr
*descr
)
1896 __do_free
void *reqdata
= NULL
;
1898 struct lxc_cmd_req req
;
1899 struct lxc_handler
*handler
= data
;
1901 ret
= lxc_abstract_unix_rcv_credential(fd
, &req
, sizeof(req
));
1903 SYSERROR("Failed to receive data on command socket for command \"%s\"", lxc_cmd_str(req
.cmd
));
1905 if (errno
== EACCES
) {
1906 /* We don't care for the peer, just send and close. */
1907 struct lxc_cmd_rsp rsp
= {
1911 __lxc_cmd_rsp_send(fd
, &rsp
);
1920 if (ret
!= sizeof(req
)) {
1921 WARN("Failed to receive full command request. Ignoring request for \"%s\"", lxc_cmd_str(req
.cmd
));
1925 if ((req
.datalen
> LXC_CMD_DATA_MAX
) && (req
.cmd
!= LXC_CMD_CONSOLE_LOG
)) {
1926 ERROR("Received command data length %d is too large for command \"%s\"", req
.datalen
, lxc_cmd_str(req
.cmd
));
1930 if (req
.datalen
> 0) {
1931 reqdata
= must_realloc(NULL
, req
.datalen
);
1932 ret
= lxc_recv_nointr(fd
, reqdata
, req
.datalen
, 0);
1933 if (ret
!= req
.datalen
) {
1934 WARN("Failed to receive full command request. Ignoring request for \"%s\"", lxc_cmd_str(req
.cmd
));
1941 ret
= lxc_cmd_process(fd
, &req
, handler
, descr
);
1943 DEBUG("Failed to process command %s; cleaning up client fd %d", lxc_cmd_str(req
.cmd
), fd
);
1945 } else if (ret
== LXC_CMD_REAP_CLIENT_FD
) {
1946 TRACE("Processed command %s; cleaning up client fd %d", lxc_cmd_str(req
.cmd
), fd
);
1949 TRACE("Processed command %s; keeping client fd %d", lxc_cmd_str(req
.cmd
), fd
);
1953 return LXC_MAINLOOP_CONTINUE
;
1956 lxc_cmd_fd_cleanup(fd
, handler
, descr
, req
.cmd
);
1960 static int lxc_cmd_accept(int fd
, uint32_t events
, void *data
,
1961 struct lxc_epoll_descr
*descr
)
1963 __do_close
int connection
= -EBADF
;
1964 int opt
= 1, ret
= -1;
1966 connection
= accept(fd
, NULL
, 0);
1968 return log_error_errno(LXC_MAINLOOP_ERROR
, errno
, "Failed to accept connection to run command");
1970 ret
= fcntl(connection
, F_SETFD
, FD_CLOEXEC
);
1972 return log_error_errno(ret
, errno
, "Failed to set close-on-exec on incoming command connection");
1974 ret
= setsockopt(connection
, SOL_SOCKET
, SO_PASSCRED
, &opt
, sizeof(opt
));
1976 return log_error_errno(ret
, errno
, "Failed to enable necessary credentials on command socket");
1978 ret
= lxc_mainloop_add_handler(descr
, connection
, lxc_cmd_handler
, data
);
1980 return log_error(ret
, "Failed to add command handler");
1982 TRACE("Accepted new client as fd %d on command server fd %d", connection
, fd
);
1983 move_fd(connection
);
1987 int lxc_server_init(const char *name
, const char *lxcpath
, const char *suffix
)
1989 __do_close
int fd
= -EBADF
;
1991 char path
[LXC_AUDS_ADDR_LEN
] = {0};
1993 ret
= lxc_make_abstract_socket_name(path
, sizeof(path
), name
, lxcpath
, NULL
, suffix
);
1997 fd
= lxc_abstract_unix_open(path
, SOCK_STREAM
, 0);
1999 if (errno
== EADDRINUSE
)
2000 ERROR("Container \"%s\" appears to be already running", name
);
2002 return log_error_errno(-1, errno
, "Failed to create command socket %s", &path
[1]);
2005 ret
= fcntl(fd
, F_SETFD
, FD_CLOEXEC
);
2007 return log_error_errno(-1, errno
, "Failed to set FD_CLOEXEC on command socket file descriptor");
2009 return log_trace(move_fd(fd
), "Created abstract unix socket \"%s\"", &path
[1]);
2012 int lxc_cmd_mainloop_add(const char *name
, struct lxc_epoll_descr
*descr
,
2013 struct lxc_handler
*handler
)
2017 ret
= lxc_mainloop_add_handler(descr
, handler
->conf
->maincmd_fd
, lxc_cmd_accept
, handler
);
2019 return log_error(ret
, "Failed to add handler for command socket fd %d", handler
->conf
->maincmd_fd
);