1 /* SPDX-License-Identifier: LGPL-2.1+ */
13 #include <sys/param.h>
14 #include <sys/socket.h>
19 #include "cgroups/cgroup.h"
20 #include "cgroups/cgroup2_devices.h"
22 #include "commands_utils.h"
28 #include "lxcseccomp.h"
30 #include "memory_utils.h"
37 * This file provides the different functions for clients to query/command the
38 * server. The client is typically some lxc tool and the server is typically the
39 * container (ie. lxc-start).
41 * Each command is transactional, the clients send a request to the server and
42 * the server answers the request with a message giving the request's status
43 * (zero or a negative errno value). Both the request and response may contain
46 * Each command is wrapped in a ancillary message in order to pass a credential
47 * making possible to the server to check if the client is allowed to ask for
48 * this command or not.
50 * IMPORTANTLY: Note that semantics for current commands are fixed. If you wish
51 * to make any changes to how, say, LXC_CMD_GET_CONFIG_ITEM works by adding
52 * information to the end of cmd.data, then you must introduce a new
53 * LXC_CMD_GET_CONFIG_ITEM_V2 define with a new number. You may wish to also
54 * mark LXC_CMD_GET_CONFIG_ITEM deprecated in commands.h.
56 * This is necessary in order to avoid having a newly compiled lxc command
57 * communicating with a running (old) monitor from crashing the running
61 lxc_log_define(commands
, lxc
);
63 static const char *lxc_cmd_str(lxc_cmd_t cmd
)
65 static const char *const cmdname
[LXC_CMD_MAX
] = {
66 [LXC_CMD_GET_TTY_FD
] = "get_tty_fd",
67 [LXC_CMD_TERMINAL_WINCH
] = "terminal_winch",
68 [LXC_CMD_STOP
] = "stop",
69 [LXC_CMD_GET_STATE
] = "get_state",
70 [LXC_CMD_GET_INIT_PID
] = "get_init_pid",
71 [LXC_CMD_GET_CLONE_FLAGS
] = "get_clone_flags",
72 [LXC_CMD_GET_CGROUP
] = "get_cgroup",
73 [LXC_CMD_GET_CONFIG_ITEM
] = "get_config_item",
74 [LXC_CMD_GET_NAME
] = "get_name",
75 [LXC_CMD_GET_LXCPATH
] = "get_lxcpath",
76 [LXC_CMD_ADD_STATE_CLIENT
] = "add_state_client",
77 [LXC_CMD_CONSOLE_LOG
] = "console_log",
78 [LXC_CMD_SERVE_STATE_CLIENTS
] = "serve_state_clients",
79 [LXC_CMD_SECCOMP_NOTIFY_ADD_LISTENER
] = "seccomp_notify_add_listener",
80 [LXC_CMD_ADD_BPF_DEVICE_CGROUP
] = "add_bpf_device_cgroup",
81 [LXC_CMD_FREEZE
] = "freeze",
82 [LXC_CMD_UNFREEZE
] = "unfreeze",
83 [LXC_CMD_GET_CGROUP2_FD
] = "get_cgroup2_fd",
84 [LXC_CMD_GET_INIT_PIDFD
] = "get_init_pidfd",
85 [LXC_CMD_GET_LIMIT_CGROUP
] = "get_limit_cgroup",
86 [LXC_CMD_GET_LIMIT_CGROUP2_FD
] = "get_limit_cgroup2_fd",
87 [LXC_CMD_GET_DEVPTS_FD
] = "get_devpts_fd",
88 [LXC_CMD_GET_SECCOMP_NOTIFY_FD
] = "get_seccomp_notify_fd",
89 [LXC_CMD_GET_CGROUP_CTX
] = "get_cgroup_ctx",
90 [LXC_CMD_GET_CGROUP_FD
] = "get_cgroup_fd",
91 [LXC_CMD_GET_LIMIT_CGROUP_FD
] = "get_limit_cgroup_fd",
92 [LXC_CMD_GET_SYSTEMD_SCOPE
] = "get_systemd_scope",
95 if (cmd
>= LXC_CMD_MAX
)
96 return "Invalid request";
101 static int __transfer_cgroup_ctx_fds(struct unix_fds
*fds
, struct cgroup_ctx
*ctx
)
103 /* This shouldn't be able to happen but better safe than sorry. */
104 if (ctx
->fd_len
!= fds
->fd_count_ret
||
105 fds
->fd_count_ret
> CGROUP_CTX_MAX_FD
)
106 return syswarn_set(-EINVAL
, "Unexpected number of file descriptors received %u != %u",
107 ctx
->fd_len
, fds
->fd_count_ret
);
109 memcpy(ctx
->fd
, fds
->fd
, ctx
->fd_len
* sizeof(__s32
));
110 fds
->fd_count_ret
= 0;
114 static int __transfer_cgroup_fd(struct unix_fds
*fds
, struct cgroup_fd
*fd
)
116 fd
->fd
= move_fd(fds
->fd
[0]);
120 static ssize_t
lxc_cmd_rsp_recv_fds(int fd_sock
, struct unix_fds
*fds
,
121 struct lxc_cmd_rsp
*rsp
,
122 const char *cur_cmdstr
)
126 ret
= lxc_abstract_unix_recv_fds(fd_sock
, fds
, rsp
, sizeof(*rsp
));
128 return log_error(ret
, "Failed to receive file descriptors for command \"%s\"", cur_cmdstr
);
131 * If we end up here with fewer or more file descriptors the caller
132 * must have set flags to indicate that they are fine with this.
133 * Otherwise the call would have failed.
136 if (fds
->flags
& UNIX_FDS_RECEIVED_EXACT
)
137 return log_debug(ret
, "Received exact number of file descriptors %u == %u for command \"%s\"",
138 fds
->fd_count_max
, fds
->fd_count_ret
, cur_cmdstr
);
140 if (fds
->flags
& UNIX_FDS_RECEIVED_LESS
)
141 return log_debug(ret
, "Received less file descriptors %u < %u for command \"%s\"",
142 fds
->fd_count_ret
, fds
->fd_count_max
, cur_cmdstr
);
144 if (fds
->flags
& UNIX_FDS_RECEIVED_MORE
)
145 return log_debug(ret
, "Received more file descriptors (excessive fds were automatically closed) %u > %u for command \"%s\"",
146 fds
->fd_count_ret
, fds
->fd_count_max
, cur_cmdstr
);
148 DEBUG("Command \"%s\" received response", cur_cmdstr
);
153 * lxc_cmd_rsp_recv: Receive a response to a command
155 * @sock : the socket connected to the container
156 * @cmd : command to put response in
158 * Returns the size of the response message or < 0 on failure
160 * Note that if the command response datalen > 0, then data is
161 * a malloc()ed buffer and should be free()ed by the caller. If
162 * the response data is <= a void * worth of data, it will be
163 * stored directly in data and datalen will be 0.
165 * As a special case, the response for LXC_CMD_GET_TTY_FD is created here as
166 * it contains an fd for the ptx pty passed through the unix socket.
168 static ssize_t
lxc_cmd_rsp_recv(int sock
, struct lxc_cmd_rr
*cmd
)
170 __do_free
void *__data
= NULL
;
171 call_cleaner(put_unix_fds
) struct unix_fds
*fds
= &(struct unix_fds
){
172 .fd
[0 ... KERNEL_SCM_MAX_FD
- 1] = -EBADF
,
174 struct lxc_cmd_rsp
*rsp
= &cmd
->rsp
;
175 int cur_cmd
= cmd
->req
.cmd
;
176 const char *cur_cmdstr
;
180 * Determine whether this command will receive file descriptors and how
183 cur_cmdstr
= lxc_cmd_str(cur_cmd
);
185 case LXC_CMD_GET_CGROUP_FD
:
187 case LXC_CMD_GET_LIMIT_CGROUP_FD
:
189 case LXC_CMD_GET_CGROUP2_FD
:
191 case LXC_CMD_GET_LIMIT_CGROUP2_FD
:
193 case LXC_CMD_GET_INIT_PIDFD
:
195 case LXC_CMD_GET_SECCOMP_NOTIFY_FD
:
197 case LXC_CMD_GET_DEVPTS_FD
:
198 fds
->fd_count_max
= 1;
200 * The kernel might not support the required features or the
201 * server might be too old.
203 fds
->flags
= UNIX_FDS_ACCEPT_EXACT
| UNIX_FDS_ACCEPT_NONE
;
205 case LXC_CMD_GET_TTY_FD
:
207 * The requested terminal can be busy so it's perfectly fine
208 * for LXC_CMD_GET_TTY to receive no file descriptor.
210 fds
->fd_count_max
= 1;
211 fds
->flags
= UNIX_FDS_ACCEPT_EXACT
| UNIX_FDS_ACCEPT_NONE
;
213 case LXC_CMD_GET_CGROUP_CTX
:
214 fds
->fd_count_max
= CGROUP_CTX_MAX_FD
;
216 * The container might run without any cgroup support at all,
217 * i.e. no writable cgroup hierarchy was found.
219 fds
->flags
|= UNIX_FDS_ACCEPT_LESS
| UNIX_FDS_ACCEPT_NONE
;
222 fds
->fd_count_max
= 0;
226 /* Receive the first response including file descriptors if any. */
227 bytes_recv
= lxc_cmd_rsp_recv_fds(sock
, fds
, rsp
, cur_cmdstr
);
232 * Ensure that no excessive data is sent unless someone retrieves the
233 * console ringbuffer.
235 if ((rsp
->datalen
> LXC_CMD_DATA_MAX
) &&
236 (cur_cmd
!= LXC_CMD_CONSOLE_LOG
))
237 return syserror_set(-E2BIG
, "Response data for command \"%s\" is too long: %d bytes > %d",
238 cur_cmdstr
, rsp
->datalen
, LXC_CMD_DATA_MAX
);
241 * Prepare buffer for any command that expects to receive additional
242 * data. Note that some don't want any additional data.
245 case LXC_CMD_GET_CGROUP2_FD
: /* no data */
247 case LXC_CMD_GET_LIMIT_CGROUP2_FD
: /* no data */
249 case LXC_CMD_GET_INIT_PIDFD
: /* no data */
251 case LXC_CMD_GET_DEVPTS_FD
: /* no data */
253 case LXC_CMD_GET_SECCOMP_NOTIFY_FD
: /* no data */
254 rsp
->data
= INT_TO_PTR(move_fd(fds
->fd
[0]));
255 return log_debug(0, "Finished processing \"%s\" with file descriptor %d", cur_cmdstr
, PTR_TO_INT(rsp
->data
));
256 case LXC_CMD_GET_CGROUP_FD
: /* data */
258 case LXC_CMD_GET_LIMIT_CGROUP_FD
: /* data */
259 if ((size_t)rsp
->datalen
> sizeof(struct cgroup_fd
))
260 return syserror_set(-EINVAL
, "Invalid response size from server for \"%s\"", cur_cmdstr
);
262 /* Don't pointlessly allocate. */
263 rsp
->data
= (void *)cmd
->req
.data
;
265 case LXC_CMD_GET_CGROUP_CTX
: /* data */
266 if ((size_t)rsp
->datalen
> sizeof(struct cgroup_ctx
))
267 return syserror_set(-EINVAL
, "Invalid response size from server for \"%s\"", cur_cmdstr
);
269 /* Don't pointlessly allocate. */
270 rsp
->data
= (void *)cmd
->req
.data
;
272 case LXC_CMD_GET_TTY_FD
: /* data */
274 * recv() returns 0 bytes when a tty cannot be allocated,
275 * rsp->ret is < 0 when the peer permission check failed.
277 if (bytes_recv
== 0 || rsp
->ret
< 0)
280 __data
= malloc(sizeof(struct lxc_cmd_tty_rsp_data
));
282 struct lxc_cmd_tty_rsp_data
*tty
= __data
;
284 tty
->ptxfd
= move_fd(fds
->fd
[0]);
285 tty
->ttynum
= PTR_TO_INT(rsp
->data
);
290 return syserror_set(-ENOMEM
, "Failed to receive response for command \"%s\"", cur_cmdstr
);
291 case LXC_CMD_CONSOLE_LOG
: /* data */
292 if (rsp
->datalen
> 0)
293 __data
= zalloc(rsp
->datalen
+ 1);
296 default: /* catch any additional command */
297 if (rsp
->datalen
> 0) {
298 __data
= zalloc(rsp
->datalen
);
304 if (rsp
->datalen
> 0) {
308 * All commands ending up here expect data so rsp->data must be valid.
309 * Either static or allocated memory.
312 return syserror_set(-ENOMEM
, "Failed to prepare response buffer for command \"%s\"",
315 bytes_recv
= lxc_recv_nointr(sock
, rsp
->data
, rsp
->datalen
, 0);
316 if (bytes_recv
!= rsp
->datalen
)
317 return syserror("Failed to receive response data for command \"%s\": %zd != %d",
318 cur_cmdstr
, bytes_recv
, rsp
->datalen
);
321 case LXC_CMD_GET_CGROUP_CTX
:
322 err
= __transfer_cgroup_ctx_fds(fds
, rsp
->data
);
324 case LXC_CMD_GET_CGROUP_FD
:
326 case LXC_CMD_GET_LIMIT_CGROUP_FD
:
327 err
= __transfer_cgroup_fd(fds
, rsp
->data
);
333 return syserror_ret(err
, "Failed to transfer file descriptors for command \"%s\"", cur_cmdstr
);
341 * lxc_cmd_rsp_send: Send a command response
343 * @fd : file descriptor of socket to send response on
344 * @rsp : response to send
346 * Returns 0 on success, < 0 on failure
348 static int __lxc_cmd_rsp_send(int fd
, struct lxc_cmd_rsp
*rsp
)
352 ret
= lxc_send_nointr(fd
, rsp
, sizeof(*rsp
), MSG_NOSIGNAL
);
353 if (ret
< 0 || (size_t)ret
!= sizeof(*rsp
))
354 return syserror("Failed to send command response %zd", ret
);
356 if (!rsp
->data
|| rsp
->datalen
<= 0)
359 ret
= lxc_send_nointr(fd
, rsp
->data
, rsp
->datalen
, MSG_NOSIGNAL
);
360 if (ret
< 0 || ret
!= (ssize_t
)rsp
->datalen
)
361 return syswarn("Failed to send command response %zd", ret
);
366 static inline int lxc_cmd_rsp_send_reap(int fd
, struct lxc_cmd_rsp
*rsp
)
370 ret
= __lxc_cmd_rsp_send(fd
, rsp
);
374 return LXC_CMD_REAP_CLIENT_FD
;
377 static inline int lxc_cmd_rsp_send_keep(int fd
, struct lxc_cmd_rsp
*rsp
)
381 ret
= __lxc_cmd_rsp_send(fd
, rsp
);
388 static inline int rsp_one_fd_reap(int fd
, int fd_send
, struct lxc_cmd_rsp
*rsp
)
392 ret
= lxc_abstract_unix_send_fds(fd
, &fd_send
, 1, rsp
, sizeof(*rsp
));
396 if (rsp
->data
&& rsp
->datalen
> 0) {
397 ret
= lxc_send_nointr(fd
, rsp
->data
, rsp
->datalen
, MSG_NOSIGNAL
);
398 if (ret
< 0 || ret
!= (ssize_t
)rsp
->datalen
)
399 return syswarn("Failed to send command response %zd", ret
);
402 return LXC_CMD_REAP_CLIENT_FD
;
405 static inline int rsp_one_fd_keep(int fd
, int fd_send
, struct lxc_cmd_rsp
*rsp
)
409 ret
= rsp_one_fd_reap(fd
, fd_send
, rsp
);
410 if (ret
== LXC_CMD_REAP_CLIENT_FD
)
411 ret
= LXC_CMD_KEEP_CLIENT_FD
;
416 __access_r(3, 2) static int rsp_many_fds_reap(int fd
, __u32 fds_len
,
417 const __s32 fds
[static 2],
418 struct lxc_cmd_rsp
*rsp
)
422 if (fds_len
> KERNEL_SCM_MAX_FD
) {
424 return lxc_cmd_rsp_send_reap(fd
, rsp
);
425 } else if (fds_len
== 0) {
427 return lxc_cmd_rsp_send_reap(fd
, rsp
);
430 ret
= lxc_abstract_unix_send_fds(fd
, fds
, fds_len
, rsp
, sizeof(*rsp
));
434 if (rsp
->data
&& rsp
->datalen
> 0) {
435 ret
= lxc_send_nointr(fd
, rsp
->data
, rsp
->datalen
, MSG_NOSIGNAL
);
436 if (ret
< 0 || ret
!= (ssize_t
)rsp
->datalen
)
437 return syswarn("Failed to send command response %zd", ret
);
440 return LXC_CMD_REAP_CLIENT_FD
;
443 static int lxc_cmd_send(const char *name
, struct lxc_cmd_rr
*cmd
,
444 const char *lxcpath
, const char *hashed_sock_name
)
446 __do_close
int client_fd
= -EBADF
;
449 client_fd
= lxc_cmd_connect(name
, lxcpath
, hashed_sock_name
, "command");
453 ret
= lxc_abstract_unix_send_credential(client_fd
, &cmd
->req
,
455 if (ret
< 0 || (size_t)ret
!= sizeof(cmd
->req
))
458 if (cmd
->req
.cmd
== LXC_CMD_SECCOMP_NOTIFY_ADD_LISTENER
) {
459 int notify_fd
= PTR_TO_INT(cmd
->req
.data
);
460 ret
= lxc_abstract_unix_send_fds(client_fd
, ¬ify_fd
, 1, NULL
, 0);
464 if (cmd
->req
.datalen
<= 0)
465 return move_fd(client_fd
);
468 ret
= lxc_send_nointr(client_fd
, (void *)cmd
->req
.data
,
469 cmd
->req
.datalen
, MSG_NOSIGNAL
);
470 if (ret
< 0 || ret
!= (ssize_t
)cmd
->req
.datalen
)
474 return move_fd(client_fd
);
478 * lxc_cmd: Connect to the specified running container, send it a command
479 * request and collect the response
481 * @name : name of container to connect to
482 * @cmd : command with initialized request to send
483 * @stopped : output indicator if the container was not running
484 * @lxcpath : the lxcpath in which the container is running
486 * Returns the size of the response message on success, < 0 on failure
488 * Note that there is a special case for LXC_CMD_GET_TTY_FD. For this command
489 * the fd cannot be closed because it is used as a placeholder to indicate that
490 * a particular tty slot is in use. The fd is also used as a signal to the
491 * container that when the caller dies or closes the fd, the container will
492 * notice the fd on its side of the socket in its mainloop select and then free
493 * the slot with lxc_cmd_fd_cleanup(). The socket fd will be returned in the
494 * cmd response structure.
496 static ssize_t
lxc_cmd(const char *name
, struct lxc_cmd_rr
*cmd
, bool *stopped
,
497 const char *lxcpath
, const char *hashed_sock_name
)
499 __do_close
int client_fd
= -EBADF
;
500 bool stay_connected
= false;
503 if (cmd
->req
.cmd
== LXC_CMD_GET_TTY_FD
||
504 cmd
->req
.cmd
== LXC_CMD_ADD_STATE_CLIENT
)
505 stay_connected
= true;
509 client_fd
= lxc_cmd_send(name
, cmd
, lxcpath
, hashed_sock_name
);
511 if (errno
== ECONNREFUSED
|| errno
== EPIPE
)
514 return systrace("Command \"%s\" failed to connect command socket", lxc_cmd_str(cmd
->req
.cmd
));
517 ret
= lxc_cmd_rsp_recv(client_fd
, cmd
);
518 if (ret
< 0 && errno
== ECONNRESET
)
521 TRACE("Opened new command socket connection fd %d for command \"%s\"",
522 client_fd
, lxc_cmd_str(cmd
->req
.cmd
));
524 if (stay_connected
&& ret
> 0)
525 cmd
->rsp
.ret
= move_fd(client_fd
);
530 int lxc_try_cmd(const char *name
, const char *lxcpath
)
532 bool stopped
= false;
534 struct lxc_cmd_rr cmd
;
536 lxc_cmd_init(&cmd
, LXC_CMD_GET_INIT_PID
);
538 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
541 if (ret
> 0 && cmd
.rsp
.ret
< 0) {
549 * At this point we weren't denied access, and the container *was*
550 * started. There was some inexplicable error in the protocol. I'm not
551 * clear on whether we should return -1 here, but we didn't receive a
552 * -EACCES, so technically it's not that we're not allowed to control
553 * the container - it's just not behaving.
559 * Validate that the input is a proper string parameter. If not,
560 * send an EINVAL response and return -1.
562 * Precondition: there is non-zero-length data available.
564 static int validate_string_request(int fd
, const struct lxc_cmd_req
*req
)
566 size_t maxlen
= req
->datalen
- 1;
567 const char *data
= req
->data
;
569 if (data
[maxlen
] == 0 && strnlen(data
, maxlen
) == maxlen
)
572 struct lxc_cmd_rsp rsp
= {
578 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
581 /* Implementations of the commands and their callbacks */
584 * lxc_cmd_get_init_pid: Get pid of the container's init process
586 * @name : name of container to connect to
587 * @lxcpath : the lxcpath in which the container is running
589 * Returns the pid on success, < 0 on failure
591 pid_t
lxc_cmd_get_init_pid(const char *name
, const char *lxcpath
)
593 bool stopped
= false;
596 struct lxc_cmd_rr cmd
;
598 lxc_cmd_init(&cmd
, LXC_CMD_GET_INIT_PID
);
600 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
604 pid
= PTR_TO_PID(cmd
.rsp
.data
);
609 * We need to assume that pid_t can actually hold any pid given to us
610 * by the kernel. If it can't it's a libc bug.
615 static int lxc_cmd_get_init_pid_callback(int fd
, struct lxc_cmd_req
*req
,
616 struct lxc_handler
*handler
,
617 struct lxc_async_descr
*descr
)
619 struct lxc_cmd_rsp rsp
= {
620 .data
= PID_TO_PTR(handler
->pid
),
623 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
626 int lxc_cmd_get_init_pidfd(const char *name
, const char *lxcpath
)
628 bool stopped
= false;
631 struct lxc_cmd_rr cmd
;
633 lxc_cmd_init(&cmd
, LXC_CMD_GET_INIT_PIDFD
);
635 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
637 return sysdebug("Failed to process \"%s\"",
638 lxc_cmd_str(LXC_CMD_GET_INIT_PIDFD
));
641 return sysdebug_set(cmd
.rsp
.ret
, "Failed to receive file descriptor for \"%s\"",
642 lxc_cmd_str(LXC_CMD_GET_INIT_PIDFD
));
644 fd
= PTR_TO_INT(cmd
.rsp
.data
);
646 return sysdebug_set(fd
, "Received invalid file descriptor for \"%s\"",
647 lxc_cmd_str(LXC_CMD_GET_INIT_PIDFD
));
652 static int lxc_cmd_get_init_pidfd_callback(int fd
, struct lxc_cmd_req
*req
,
653 struct lxc_handler
*handler
,
654 struct lxc_async_descr
*descr
)
656 struct lxc_cmd_rsp rsp
= {
660 if (handler
->pidfd
< 0)
661 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
664 return rsp_one_fd_reap(fd
, handler
->pidfd
, &rsp
);
667 int lxc_cmd_get_devpts_fd(const char *name
, const char *lxcpath
)
669 bool stopped
= false;
672 struct lxc_cmd_rr cmd
;
674 lxc_cmd_init(&cmd
, LXC_CMD_GET_DEVPTS_FD
);
676 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
678 return sysdebug("Failed to process \"%s\"",
679 lxc_cmd_str(LXC_CMD_GET_DEVPTS_FD
));
682 return sysdebug_set(cmd
.rsp
.ret
, "Failed to receive file descriptor for \"%s\"",
683 lxc_cmd_str(LXC_CMD_GET_DEVPTS_FD
));
685 fd
= PTR_TO_INT(cmd
.rsp
.data
);
687 return sysdebug_set(fd
, "Received invalid file descriptor for \"%s\"",
688 lxc_cmd_str(LXC_CMD_GET_DEVPTS_FD
));
692 static int lxc_cmd_get_devpts_fd_callback(int fd
, struct lxc_cmd_req
*req
,
693 struct lxc_handler
*handler
,
694 struct lxc_async_descr
*descr
)
696 struct lxc_cmd_rsp rsp
= {
700 if (handler
->conf
->devpts_fd
< 0)
701 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
704 return rsp_one_fd_reap(fd
, handler
->conf
->devpts_fd
, &rsp
);
707 int lxc_cmd_get_seccomp_notify_fd(const char *name
, const char *lxcpath
)
709 #if HAVE_DECL_SECCOMP_NOTIFY_FD
710 bool stopped
= false;
713 struct lxc_cmd_rr cmd
;
715 lxc_cmd_init(&cmd
, LXC_CMD_GET_SECCOMP_NOTIFY_FD
);
717 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
719 return sysdebug("Failed to process \"%s\"",
720 lxc_cmd_str(LXC_CMD_GET_SECCOMP_NOTIFY_FD
));
723 return sysdebug_set(cmd
.rsp
.ret
, "Failed to receive file descriptor for \"%s\"",
724 lxc_cmd_str(LXC_CMD_GET_SECCOMP_NOTIFY_FD
));
726 fd
= PTR_TO_INT(cmd
.rsp
.data
);
728 return sysdebug_set(fd
, "Received invalid file descriptor for \"%s\"",
729 lxc_cmd_str(LXC_CMD_GET_SECCOMP_NOTIFY_FD
));
732 return ret_errno(ENOSYS
);
736 static int lxc_cmd_get_seccomp_notify_fd_callback(int fd
, struct lxc_cmd_req
*req
,
737 struct lxc_handler
*handler
,
738 struct lxc_async_descr
*descr
)
740 #if HAVE_DECL_SECCOMP_NOTIFY_FD
741 struct lxc_cmd_rsp rsp
= {
745 if (handler
->conf
->seccomp
.notifier
.notify_fd
< 0)
746 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
749 return rsp_one_fd_reap(fd
, handler
->conf
->seccomp
.notifier
.notify_fd
, &rsp
);
751 return syserror_set(-EOPNOTSUPP
, "Seccomp notifier not supported");
755 int lxc_cmd_get_cgroup_ctx(const char *name
, const char *lxcpath
,
756 size_t size_ret_ctx
, struct cgroup_ctx
*ret_ctx
)
758 bool stopped
= false;
760 struct lxc_cmd_rr cmd
;
762 lxc_cmd_init(&cmd
, LXC_CMD_GET_CGROUP_CTX
);
763 lxc_cmd_data(&cmd
, size_ret_ctx
, ret_ctx
);
765 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
767 return sysdebug("Failed to process \"%s\"",
768 lxc_cmd_str(LXC_CMD_GET_CGROUP_CTX
));
770 if (cmd
.rsp
.ret
< 0) {
771 /* Container does not have any writable cgroups. */
772 if (ret_ctx
->fd_len
== 0)
775 return sysdebug_set(cmd
.rsp
.ret
, "Failed to receive file descriptor for \"%s\"",
776 lxc_cmd_str(LXC_CMD_GET_CGROUP_CTX
));
782 static int lxc_cmd_get_cgroup_ctx_callback(int fd
, struct lxc_cmd_req
*req
,
783 struct lxc_handler
*handler
,
784 struct lxc_async_descr
*descr
)
786 struct lxc_cmd_rsp rsp
= {
789 struct cgroup_ops
*cgroup_ops
= handler
->cgroup_ops
;
790 struct cgroup_ctx ctx_server
= {};
793 ret
= copy_struct_from_client(sizeof(struct cgroup_ctx
), &ctx_server
,
794 req
->datalen
, req
->data
);
796 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
798 ret
= prepare_cgroup_ctx(cgroup_ops
, &ctx_server
);
801 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
805 rsp
.data
= &ctx_server
;
806 rsp
.datalen
= min(sizeof(struct cgroup_ctx
), (size_t)req
->datalen
);
807 return rsp_many_fds_reap(fd
, ctx_server
.fd_len
, ctx_server
.fd
, &rsp
);
811 * lxc_cmd_get_clone_flags: Get clone flags container was spawned with
813 * @name : name of container to connect to
814 * @lxcpath : the lxcpath in which the container is running
816 * Returns the clone flags on success, < 0 on failure
818 int lxc_cmd_get_clone_flags(const char *name
, const char *lxcpath
)
820 bool stopped
= false;
822 struct lxc_cmd_rr cmd
;
824 lxc_cmd_init(&cmd
, LXC_CMD_GET_CLONE_FLAGS
);
826 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
830 return PTR_TO_INT(cmd
.rsp
.data
);
833 static int lxc_cmd_get_clone_flags_callback(int fd
, struct lxc_cmd_req
*req
,
834 struct lxc_handler
*handler
,
835 struct lxc_async_descr
*descr
)
837 struct lxc_cmd_rsp rsp
= {
838 .data
= INT_TO_PTR(handler
->ns_clone_flags
),
841 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
844 static char *lxc_cmd_get_cgroup_path_callback(const char *name
,
846 const char *controller
,
849 bool stopped
= false;
851 struct lxc_cmd_rr cmd
;
853 lxc_cmd_init(&cmd
, command
);
855 lxc_cmd_data(&cmd
, strlen(controller
) + 1, controller
);
857 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
862 if (command
== LXC_CMD_GET_LIMIT_CGROUP
) {
864 * This may indicate that the container was started
865 * under an ealier version before
866 * `cgroup_advanced_isolation` as implemented, there
867 * it sees an unknown command and just closes the
868 * socket, sending us an EOF.
870 return lxc_cmd_get_cgroup_path_callback(name
, lxcpath
,
877 if (cmd
.rsp
.ret
< 0 || cmd
.rsp
.datalen
< 0)
884 * lxc_cmd_get_cgroup_path: Calculate a container's cgroup path for a
885 * particular controller. This is the cgroup path relative to the root
886 * of the cgroup filesystem.
888 * @name : name of container to connect to
889 * @lxcpath : the lxcpath in which the container is running
890 * @controller : the controller being asked about
892 * Returns the path on success, NULL on failure. The caller must free() the
895 char *lxc_cmd_get_cgroup_path(const char *name
, const char *lxcpath
,
896 const char *controller
)
898 return lxc_cmd_get_cgroup_path_callback(name
, lxcpath
, controller
,
903 * lxc_cmd_get_limit_cgroup_path: Calculate a container's limit cgroup
904 * path for a particular controller. This is the cgroup path relative to the
905 * root of the cgroup filesystem. This may be the same as the path returned by
906 * lxc_cmd_get_cgroup_path if the container doesn't have a limit path prefix
909 * @name : name of container to connect to
910 * @lxcpath : the lxcpath in which the container is running
911 * @controller : the controller being asked about
913 * Returns the path on success, NULL on failure. The caller must free() the
916 char *lxc_cmd_get_limit_cgroup_path(const char *name
, const char *lxcpath
,
917 const char *controller
)
919 return lxc_cmd_get_cgroup_path_callback(name
, lxcpath
, controller
,
920 LXC_CMD_GET_LIMIT_CGROUP
);
923 static int __lxc_cmd_get_cgroup_callback(int fd
, struct lxc_cmd_req
*req
,
924 struct lxc_handler
*handler
,
925 struct lxc_async_descr
*descr
,
926 bool limiting_cgroup
)
931 struct lxc_cmd_rsp rsp
;
932 struct cgroup_ops
*cgroup_ops
= handler
->cgroup_ops
;
933 const char *(*get_fn
)(struct cgroup_ops
*ops
, const char *controller
);
935 if (req
->datalen
> 0) {
936 ret
= validate_string_request(fd
, req
);
944 get_fn
= (limiting_cgroup
? cgroup_ops
->get_limit_cgroup
945 : cgroup_ops
->get_cgroup
);
947 path
= get_fn(cgroup_ops
, reqdata
);
953 rsp
.datalen
= strlen(path
) + 1;
954 rsp
.data
= (char *)path
;
956 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
959 static int lxc_cmd_get_cgroup_callback(int fd
, struct lxc_cmd_req
*req
,
960 struct lxc_handler
*handler
,
961 struct lxc_async_descr
*descr
)
963 return __lxc_cmd_get_cgroup_callback(fd
, req
, handler
, descr
, false);
966 static int lxc_cmd_get_limit_cgroup_callback(int fd
, struct lxc_cmd_req
*req
,
967 struct lxc_handler
*handler
,
968 struct lxc_async_descr
*descr
)
970 return __lxc_cmd_get_cgroup_callback(fd
, req
, handler
, descr
, true);
974 * lxc_cmd_get_config_item: Get config item the running container
976 * @name : name of container to connect to
977 * @item : the configuration item to retrieve (ex: lxc.net.0.veth.pair)
978 * @lxcpath : the lxcpath in which the container is running
980 * Returns the item on success, NULL on failure. The caller must free() the
983 char *lxc_cmd_get_config_item(const char *name
, const char *item
,
986 bool stopped
= false;
988 struct lxc_cmd_rr cmd
;
990 if (is_empty_string(item
))
993 lxc_cmd_init(&cmd
, LXC_CMD_GET_CONFIG_ITEM
);
994 lxc_cmd_data(&cmd
, strlen(item
) + 1, item
);
996 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
1000 if (cmd
.rsp
.ret
== 0)
1001 return cmd
.rsp
.data
;
1006 static int lxc_cmd_get_config_item_callback(int fd
, struct lxc_cmd_req
*req
,
1007 struct lxc_handler
*handler
,
1008 struct lxc_async_descr
*descr
)
1010 __do_free
char *cidata
= NULL
;
1012 struct lxc_config_t
*item
;
1013 struct lxc_cmd_rsp rsp
;
1015 memset(&rsp
, 0, sizeof(rsp
));
1016 item
= lxc_get_config(req
->data
);
1017 cilen
= item
->get(req
->data
, NULL
, 0, handler
->conf
, NULL
);
1021 cidata
= must_realloc(NULL
, cilen
+ 1);
1022 if (item
->get(req
->data
, cidata
, cilen
+ 1, handler
->conf
, NULL
) != cilen
)
1025 cidata
[cilen
] = '\0';
1027 rsp
.datalen
= cilen
+ 1;
1034 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
1038 * lxc_cmd_get_state: Get current state of the container
1040 * @name : name of container to connect to
1041 * @lxcpath : the lxcpath in which the container is running
1043 * Returns the state on success, < 0 on failure
1045 int lxc_cmd_get_state(const char *name
, const char *lxcpath
)
1047 bool stopped
= false;
1049 struct lxc_cmd_rr cmd
;
1051 lxc_cmd_init(&cmd
, LXC_CMD_GET_STATE
);
1053 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
1054 if (ret
< 0 && stopped
)
1061 return log_warn(-1, "Container \"%s\" has stopped before sending its state", name
);
1063 return log_debug(PTR_TO_INT(cmd
.rsp
.data
),
1064 "Container \"%s\" is in \"%s\" state", name
,
1065 lxc_state2str(PTR_TO_INT(cmd
.rsp
.data
)));
1068 static int lxc_cmd_get_state_callback(int fd
, struct lxc_cmd_req
*req
,
1069 struct lxc_handler
*handler
,
1070 struct lxc_async_descr
*descr
)
1072 struct lxc_cmd_rsp rsp
= {
1073 .data
= INT_TO_PTR(handler
->state
),
1076 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
1080 * lxc_cmd_stop: Stop the container previously started with lxc_start. All
1081 * the processes running inside this container will be killed.
1083 * @name : name of container to connect to
1084 * @lxcpath : the lxcpath in which the container is running
1086 * Returns 0 on success, < 0 on failure
1088 int lxc_cmd_stop(const char *name
, const char *lxcpath
)
1090 bool stopped
= false;
1092 struct lxc_cmd_rr cmd
;
1094 lxc_cmd_init(&cmd
, LXC_CMD_STOP
);
1096 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
1099 return log_info(0, "Container \"%s\" is already stopped", name
);
1104 /* We do not expect any answer, because we wait for the connection to be
1108 return log_error_errno(-1, -cmd
.rsp
.ret
, "Failed to stop container \"%s\"", name
);
1110 return log_info(0, "Container \"%s\" has stopped", name
);
1113 static int lxc_cmd_stop_callback(int fd
, struct lxc_cmd_req
*req
,
1114 struct lxc_handler
*handler
,
1115 struct lxc_async_descr
*descr
)
1117 struct lxc_cmd_rsp rsp
;
1118 int stopsignal
= SIGKILL
;
1119 struct cgroup_ops
*cgroup_ops
= handler
->cgroup_ops
;
1122 if (handler
->conf
->stopsignal
)
1123 stopsignal
= handler
->conf
->stopsignal
;
1124 memset(&rsp
, 0, sizeof(rsp
));
1126 if (handler
->pidfd
>= 0)
1127 rsp
.ret
= lxc_raw_pidfd_send_signal(handler
->pidfd
, stopsignal
, NULL
, 0);
1129 rsp
.ret
= kill(handler
->pid
, stopsignal
);
1131 if (handler
->pidfd
>= 0)
1132 TRACE("Sent signal %d to pidfd %d", stopsignal
, handler
->pidfd
);
1134 TRACE("Sent signal %d to pidfd %d", stopsignal
, handler
->pid
);
1136 if (pure_unified_layout(cgroup_ops
))
1137 ret
= __cgroup_unfreeze(cgroup_ops
->unified
->dfd_lim
, -1);
1139 ret
= cgroup_ops
->unfreeze(cgroup_ops
, -1);
1141 WARN("Failed to unfreeze container \"%s\"", handler
->name
);
1148 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
1152 * lxc_cmd_terminal_winch: noop
1154 * @name : name of container to connect to
1155 * @lxcpath : the lxcpath in which the container is running
1157 * Returns 0 on success, < 0 on failure
1159 int lxc_cmd_terminal_winch(const char *name
, const char *lxcpath
)
1164 static int lxc_cmd_terminal_winch_callback(int fd
, struct lxc_cmd_req
*req
,
1165 struct lxc_handler
*handler
,
1166 struct lxc_async_descr
*descr
)
1168 /* should never be called */
1169 return syserror_set(-ENOSYS
, "Called lxc_cmd_terminal_winch_callback()");
1173 * lxc_cmd_get_tty_fd: Open an fd to a tty in the container
1175 * @name : name of container to connect to
1176 * @ttynum : in: the tty to open or -1 for next available
1177 * : out: the tty allocated
1178 * @fd : out: file descriptor for ptx side of pty
1179 * @lxcpath : the lxcpath in which the container is running
1181 * Returns fd holding tty allocated on success, < 0 on failure
1183 int lxc_cmd_get_tty_fd(const char *name
, int *ttynum
, int *fd
, const char *lxcpath
)
1185 __do_free
struct lxc_cmd_tty_rsp_data
*rspdata
= NULL
;
1186 bool stopped
= false;
1188 struct lxc_cmd_rr cmd
;
1190 lxc_cmd_init(&cmd
, LXC_CMD_GET_TTY_FD
);
1191 lxc_cmd_data(&cmd
, ENCODE_INTO_PTR_LEN
, INT_TO_PTR(*ttynum
));
1193 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
1195 return sysdebug("Failed to process \"%s\"",
1196 lxc_cmd_str(LXC_CMD_GET_TTY_FD
));
1198 rspdata
= cmd
.rsp
.data
;
1199 if (cmd
.rsp
.ret
< 0)
1200 return log_error_errno(-1, -cmd
.rsp
.ret
, "Denied access to tty");
1203 return log_error(-1, "tty number %d invalid, busy or all ttys busy", *ttynum
);
1205 if (rspdata
->ptxfd
< 0)
1206 return log_error(-1, "Unable to allocate fd for tty %d", rspdata
->ttynum
);
1208 ret
= cmd
.rsp
.ret
; /* socket fd */
1209 *fd
= rspdata
->ptxfd
;
1210 *ttynum
= rspdata
->ttynum
;
1212 INFO("Alloced fd %d for tty %d via socket %zd", *fd
, rspdata
->ttynum
, ret
);
1216 static int lxc_cmd_get_tty_fd_callback(int fd
, struct lxc_cmd_req
*req
,
1217 struct lxc_handler
*handler
,
1218 struct lxc_async_descr
*descr
)
1220 struct lxc_cmd_rsp rsp
= {
1223 int ptxfd
, ret
, ttynum
;
1225 ttynum
= PTR_TO_INT(req
->data
);
1226 ptxfd
= lxc_terminal_allocate(handler
->conf
, fd
, &ttynum
);
1228 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
1231 rsp
.data
= INT_TO_PTR(ttynum
);
1232 ret
= rsp_one_fd_keep(fd
, ptxfd
, &rsp
);
1234 lxc_terminal_free(handler
->conf
, fd
);
1238 DEBUG("Send tty to client");
1243 * lxc_cmd_get_name: Returns the name of the container
1245 * @hashed_sock_name: hashed socket name
1247 * Returns the name on success, NULL on failure.
1249 char *lxc_cmd_get_name(const char *hashed_sock_name
)
1251 bool stopped
= false;
1253 struct lxc_cmd_rr cmd
;
1255 lxc_cmd_init(&cmd
, LXC_CMD_GET_NAME
);
1257 ret
= lxc_cmd(NULL
, &cmd
, &stopped
, NULL
, hashed_sock_name
);
1261 if (cmd
.rsp
.ret
== 0)
1262 return cmd
.rsp
.data
;
1267 static int lxc_cmd_get_name_callback(int fd
, struct lxc_cmd_req
*req
,
1268 struct lxc_handler
*handler
,
1269 struct lxc_async_descr
*descr
)
1271 struct lxc_cmd_rsp rsp
;
1273 memset(&rsp
, 0, sizeof(rsp
));
1275 rsp
.data
= (char *)handler
->name
;
1276 rsp
.datalen
= strlen(handler
->name
) + 1;
1279 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
1283 * lxc_cmd_get_lxcpath: Returns the lxcpath of the container
1285 * @hashed_sock_name: hashed socket name
1287 * Returns the lxcpath on success, NULL on failure.
1289 char *lxc_cmd_get_lxcpath(const char *hashed_sock_name
)
1291 bool stopped
= false;
1293 struct lxc_cmd_rr cmd
;
1295 lxc_cmd_init(&cmd
, LXC_CMD_GET_LXCPATH
);
1297 ret
= lxc_cmd(NULL
, &cmd
, &stopped
, NULL
, hashed_sock_name
);
1301 if (cmd
.rsp
.ret
== 0)
1302 return cmd
.rsp
.data
;
1307 static int lxc_cmd_get_lxcpath_callback(int fd
, struct lxc_cmd_req
*req
,
1308 struct lxc_handler
*handler
,
1309 struct lxc_async_descr
*descr
)
1311 struct lxc_cmd_rsp rsp
= {
1313 .data
= (char *)handler
->lxcpath
,
1314 .datalen
= strlen(handler
->lxcpath
) + 1,
1317 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
1320 char *lxc_cmd_get_systemd_scope(const char *name
, const char *lxcpath
)
1322 bool stopped
= false;
1324 struct lxc_cmd_rr cmd
;
1326 lxc_cmd_init(&cmd
, LXC_CMD_GET_SYSTEMD_SCOPE
);
1328 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
1332 if (cmd
.rsp
.ret
== 0)
1333 return cmd
.rsp
.data
;
1338 static int lxc_cmd_get_systemd_scope_callback(int fd
, struct lxc_cmd_req
*req
,
1339 struct lxc_handler
*handler
,
1340 struct lxc_async_descr
*descr
)
1342 __do_free
char *scope
= NULL
;
1343 struct lxc_cmd_rsp rsp
= {
1347 // cgroup_meta.systemd_scope is the full cgroup path to the scope.
1348 // The caller just wants the actual scope name, that is, basename().
1349 // (XXX - or do we want the caller to massage it? I'm undecided)
1350 if (handler
->conf
->cgroup_meta
.systemd_scope
) {
1351 scope
= strrchr(handler
->conf
->cgroup_meta
.systemd_scope
, '/');
1352 if (scope
&& *scope
)
1354 if (scope
&& *scope
)
1355 scope
= strdup(scope
);
1363 rsp
.datalen
= strlen(scope
) + 1;
1366 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
1369 int lxc_cmd_add_state_client(const char *name
, const char *lxcpath
,
1370 lxc_state_t states
[static MAX_STATE
],
1371 int *state_client_fd
)
1373 __do_close
int clientfd
= -EBADF
;
1374 bool stopped
= false;
1377 struct lxc_cmd_rr cmd
;
1379 lxc_cmd_init(&cmd
, LXC_CMD_ADD_STATE_CLIENT
);
1380 lxc_cmd_data(&cmd
, (sizeof(lxc_state_t
) * MAX_STATE
), states
);
1382 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
1383 if (states
[STOPPED
] != 0 && stopped
!= 0)
1387 if (errno
!= ECONNREFUSED
)
1388 SYSERROR("Failed to execute command");
1393 /* We should now be guaranteed to get an answer from the state sending
1396 clientfd
= cmd
.rsp
.ret
;
1398 return log_error_errno(-1, -clientfd
, "Failed to receive socket fd");
1400 state
= PTR_TO_INT(cmd
.rsp
.data
);
1401 if (state
< MAX_STATE
)
1402 return log_trace(state
, "Container is already in requested state %s", lxc_state2str(state
));
1404 *state_client_fd
= move_fd(clientfd
);
1405 TRACE("State connection fd %d ready to listen for container state changes", *state_client_fd
);
1409 static int lxc_cmd_add_state_client_callback(__owns
int fd
, struct lxc_cmd_req
*req
,
1410 struct lxc_handler
*handler
,
1411 struct lxc_async_descr
*descr
)
1413 struct lxc_cmd_rsp rsp
= {
1417 if (req
->datalen
< 0)
1420 if (req
->datalen
!= (sizeof(lxc_state_t
) * MAX_STATE
))
1426 rsp
.ret
= lxc_add_state_client(fd
, handler
, (lxc_state_t
*)req
->data
);
1430 rsp
.data
= INT_TO_PTR(rsp
.ret
);
1432 return lxc_cmd_rsp_send_keep(fd
, &rsp
);
1435 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
1438 int lxc_cmd_add_bpf_device_cgroup(const char *name
, const char *lxcpath
,
1439 struct device_item
*device
)
1441 bool stopped
= false;
1443 struct lxc_cmd_rr cmd
;
1445 if (strlen(device
->access
) > STRLITERALLEN("rwm"))
1446 return syserror_set(-EINVAL
, "Invalid access mode specified %s", device
->access
);
1448 lxc_cmd_init(&cmd
, LXC_CMD_ADD_BPF_DEVICE_CGROUP
);
1449 lxc_cmd_data(&cmd
, sizeof(struct device_item
), device
);
1451 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
1453 return syserror_set(ret
, "Failed to process new bpf device cgroup command");
1455 if (cmd
.rsp
.ret
< 0)
1456 return syserror_set(cmd
.rsp
.ret
, "Failed to add new bpf device cgroup rule");
1461 static int lxc_cmd_add_bpf_device_cgroup_callback(int fd
, struct lxc_cmd_req
*req
,
1462 struct lxc_handler
*handler
,
1463 struct lxc_async_descr
*descr
)
1465 struct lxc_cmd_rsp rsp
= {
1468 struct lxc_conf
*conf
;
1470 if (req
->datalen
<= 0)
1473 if (req
->datalen
!= sizeof(struct device_item
))
1479 conf
= handler
->conf
;
1480 if (!bpf_cgroup_devices_update(handler
->cgroup_ops
,
1482 (struct device_item
*)req
->data
))
1488 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
1491 int lxc_cmd_console_log(const char *name
, const char *lxcpath
,
1492 struct lxc_console_log
*log
)
1494 bool stopped
= false;
1495 struct lxc_cmd_console_log data
= {
1496 .clear
= log
->clear
,
1498 .read_max
= *log
->read_max
,
1501 struct lxc_cmd_rr cmd
;
1503 lxc_cmd_init(&cmd
, LXC_CMD_CONSOLE_LOG
);
1504 lxc_cmd_data(&cmd
, sizeof(struct lxc_cmd_console_log
), &data
);
1506 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
1510 /* There is nothing to be read from the buffer. So clear any values we
1511 * where passed to clearly indicate to the user that nothing went wrong.
1513 if (cmd
.rsp
.ret
== -ENODATA
|| cmd
.rsp
.ret
== -EFAULT
|| cmd
.rsp
.ret
== -ENOENT
) {
1518 /* This is a proper error so don't touch any values we were passed. */
1519 if (cmd
.rsp
.ret
< 0)
1522 *log
->read_max
= cmd
.rsp
.datalen
;
1523 log
->data
= cmd
.rsp
.data
;
1528 static int lxc_cmd_console_log_callback(int fd
, struct lxc_cmd_req
*req
,
1529 struct lxc_handler
*handler
,
1530 struct lxc_async_descr
*descr
)
1532 struct lxc_cmd_rsp rsp
;
1533 uint64_t buffer_size
= handler
->conf
->console
.buffer_size
;
1534 const struct lxc_cmd_console_log
*log
= req
->data
;
1535 struct lxc_ringbuf
*buf
= &handler
->conf
->console
.ringbuf
;
1540 if (buffer_size
<= 0)
1543 if (log
->read
|| log
->write_logfile
)
1544 rsp
.datalen
= lxc_ringbuf_used(buf
);
1547 rsp
.data
= lxc_ringbuf_get_read_addr(buf
);
1549 if (log
->read_max
> 0 && (log
->read_max
<= (uint64_t)rsp
.datalen
))
1550 rsp
.datalen
= log
->read_max
;
1552 /* there's nothing to read */
1554 if (log
->read
&& (buf
->r_off
== buf
->w_off
))
1559 lxc_ringbuf_clear(buf
); /* clear the ringbuffer */
1560 else if (rsp
.datalen
> 0)
1561 lxc_ringbuf_move_read_addr(buf
, rsp
.datalen
);
1564 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
1567 int lxc_cmd_serve_state_clients(const char *name
, const char *lxcpath
,
1570 bool stopped
= false;
1572 struct lxc_cmd_rr cmd
;
1574 lxc_cmd_init(&cmd
, LXC_CMD_SERVE_STATE_CLIENTS
);
1575 lxc_cmd_data(&cmd
, ENCODE_INTO_PTR_LEN
, INT_TO_PTR(state
));
1577 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
1579 return log_error_errno(-1, errno
, "Failed to serve state clients");
1584 static int lxc_cmd_serve_state_clients_callback(int fd
, struct lxc_cmd_req
*req
,
1585 struct lxc_handler
*handler
,
1586 struct lxc_async_descr
*descr
)
1589 lxc_state_t state
= PTR_TO_INT(req
->data
);
1590 struct lxc_cmd_rsp rsp
= {0};
1592 ret
= lxc_serve_state_clients(handler
->name
, handler
, state
);
1596 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
1599 int lxc_cmd_seccomp_notify_add_listener(const char *name
, const char *lxcpath
,
1601 /* unused */ unsigned int command
,
1602 /* unused */ unsigned int flags
)
1605 #if HAVE_DECL_SECCOMP_NOTIFY_FD
1606 bool stopped
= false;
1608 struct lxc_cmd_rr cmd
;
1610 lxc_cmd_init(&cmd
, LXC_CMD_SECCOMP_NOTIFY_ADD_LISTENER
);
1611 lxc_cmd_data(&cmd
, ENCODE_INTO_PTR_LEN
, INT_TO_PTR(fd
));
1613 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
1615 return log_error_errno(-1, errno
, "Failed to add seccomp listener");
1619 return ret_set_errno(-1, ENOSYS
);
1623 static int lxc_cmd_seccomp_notify_add_listener_callback(int fd
,
1624 struct lxc_cmd_req
*req
,
1625 struct lxc_handler
*handler
,
1626 struct lxc_async_descr
*descr
)
1628 struct lxc_cmd_rsp rsp
= {0};
1630 #if HAVE_DECL_SECCOMP_NOTIFY_FD
1632 __do_close
int recv_fd
= -EBADF
;
1634 ret
= lxc_abstract_unix_recv_one_fd(fd
, &recv_fd
, NULL
, 0);
1640 if (!handler
->conf
->seccomp
.notifier
.wants_supervision
||
1641 handler
->conf
->seccomp
.notifier
.proxy_fd
< 0) {
1642 SYSERROR("No seccomp proxy fd specified");
1647 ret
= lxc_mainloop_add_handler(descr
, recv_fd
,
1648 seccomp_notify_handler
,
1649 seccomp_notify_cleanup_handler
,
1650 handler
, "seccomp_notify_handler");
1662 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
1665 int lxc_cmd_freeze(const char *name
, const char *lxcpath
, int timeout
)
1667 bool stopped
= false;
1669 struct lxc_cmd_rr cmd
;
1671 lxc_cmd_init(&cmd
, LXC_CMD_FREEZE
);
1672 lxc_cmd_data(&cmd
, ENCODE_INTO_PTR_LEN
, INT_TO_PTR(timeout
));
1674 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
1675 if (ret
<= 0 || cmd
.rsp
.ret
< 0)
1676 return log_error_errno(-1, errno
, "Failed to freeze container");
1681 static int lxc_cmd_freeze_callback(int fd
, struct lxc_cmd_req
*req
,
1682 struct lxc_handler
*handler
,
1683 struct lxc_async_descr
*descr
)
1685 int timeout
= PTR_TO_INT(req
->data
);
1686 struct lxc_cmd_rsp rsp
= {
1689 struct cgroup_ops
*ops
= handler
->cgroup_ops
;
1691 if (pure_unified_layout(ops
))
1692 rsp
.ret
= ops
->freeze(ops
, timeout
);
1694 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
1697 int lxc_cmd_unfreeze(const char *name
, const char *lxcpath
, int timeout
)
1699 bool stopped
= false;
1701 struct lxc_cmd_rr cmd
;
1703 lxc_cmd_init(&cmd
, LXC_CMD_UNFREEZE
);
1704 lxc_cmd_data(&cmd
, ENCODE_INTO_PTR_LEN
, INT_TO_PTR(timeout
));
1706 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
1707 if (ret
<= 0 || cmd
.rsp
.ret
< 0)
1708 return log_error_errno(-1, errno
, "Failed to unfreeze container");
1713 static int lxc_cmd_unfreeze_callback(int fd
, struct lxc_cmd_req
*req
,
1714 struct lxc_handler
*handler
,
1715 struct lxc_async_descr
*descr
)
1717 int timeout
= PTR_TO_INT(req
->data
);
1718 struct lxc_cmd_rsp rsp
= {
1721 struct cgroup_ops
*ops
= handler
->cgroup_ops
;
1723 if (pure_unified_layout(ops
))
1724 rsp
.ret
= ops
->unfreeze(ops
, timeout
);
1726 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
1729 int lxc_cmd_get_cgroup_fd(const char *name
, const char *lxcpath
,
1730 size_t size_ret_fd
, struct cgroup_fd
*ret_fd
)
1732 bool stopped
= false;
1734 struct lxc_cmd_rr cmd
;
1736 lxc_cmd_init(&cmd
, LXC_CMD_GET_CGROUP_FD
);
1737 lxc_cmd_data(&cmd
, sizeof(struct cgroup_fd
), ret_fd
);
1739 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
1741 return sysdebug("Failed to process \"%s\"",
1742 lxc_cmd_str(LXC_CMD_GET_CGROUP_FD
));
1744 if (cmd
.rsp
.ret
< 0)
1745 return sysdebug_set(cmd
.rsp
.ret
, "Failed to receive file descriptor for \"%s\"",
1746 lxc_cmd_str(LXC_CMD_GET_CGROUP_FD
));
1751 int lxc_cmd_get_limit_cgroup_fd(const char *name
, const char *lxcpath
,
1752 size_t size_ret_fd
, struct cgroup_fd
*ret_fd
)
1754 bool stopped
= false;
1756 struct lxc_cmd_rr cmd
;
1758 lxc_cmd_init(&cmd
, LXC_CMD_GET_LIMIT_CGROUP_FD
);
1759 lxc_cmd_data(&cmd
, sizeof(struct cgroup_fd
), ret_fd
);
1761 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
1763 return sysdebug("Failed to process \"%s\"",
1764 lxc_cmd_str(LXC_CMD_GET_CGROUP_FD
));
1766 if (cmd
.rsp
.ret
< 0)
1767 return sysdebug_set(cmd
.rsp
.ret
, "Failed to receive file descriptor for \"%s\"",
1768 lxc_cmd_str(LXC_CMD_GET_CGROUP_FD
));
1773 static int __lxc_cmd_get_cgroup_fd_callback(int fd
, struct lxc_cmd_req
*req
,
1774 struct lxc_handler
*handler
,
1775 struct lxc_async_descr
*descr
,
1778 struct lxc_cmd_rsp rsp
= {
1781 struct cgroup_ops
*ops
= handler
->cgroup_ops
;
1782 struct cgroup_fd fd_server
= {};
1785 ret
= copy_struct_from_client(sizeof(struct cgroup_fd
), &fd_server
,
1786 req
->datalen
, req
->data
);
1788 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
1790 if (strnlen(fd_server
.controller
, MAX_CGROUP_ROOT_NAMELEN
) == 0)
1791 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
1793 ret
= prepare_cgroup_fd(ops
, &fd_server
, limit
);
1796 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
1800 rsp
.data
= &fd_server
;
1801 rsp
.datalen
= min(sizeof(struct cgroup_fd
), (size_t)req
->datalen
);
1802 return rsp_one_fd_reap(fd
, fd_server
.fd
, &rsp
);
1805 static int lxc_cmd_get_cgroup_fd_callback(int fd
, struct lxc_cmd_req
*req
,
1806 struct lxc_handler
*handler
,
1807 struct lxc_async_descr
*descr
)
1809 return __lxc_cmd_get_cgroup_fd_callback(fd
, req
, handler
, descr
, false);
1812 static int lxc_cmd_get_limit_cgroup_fd_callback(int fd
, struct lxc_cmd_req
*req
,
1813 struct lxc_handler
*handler
,
1814 struct lxc_async_descr
*descr
)
1816 return __lxc_cmd_get_cgroup_fd_callback(fd
, req
, handler
, descr
, true);
1819 int lxc_cmd_get_cgroup2_fd(const char *name
, const char *lxcpath
)
1821 bool stopped
= false;
1824 struct lxc_cmd_rr cmd
;
1826 lxc_cmd_init(&cmd
, LXC_CMD_GET_CGROUP2_FD
);
1828 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
1830 return sysdebug("Failed to process \"%s\"",
1831 lxc_cmd_str(LXC_CMD_GET_CGROUP2_FD
));
1833 if (cmd
.rsp
.ret
< 0)
1834 return sysdebug_set(cmd
.rsp
.ret
, "Failed to receive file descriptor for \"%s\"",
1835 lxc_cmd_str(LXC_CMD_GET_CGROUP2_FD
));
1837 fd
= PTR_TO_INT(cmd
.rsp
.data
);
1839 return sysdebug_set(fd
, "Received invalid file descriptor for \"%s\"",
1840 lxc_cmd_str(LXC_CMD_GET_CGROUP2_FD
));
1844 int lxc_cmd_get_limit_cgroup2_fd(const char *name
, const char *lxcpath
)
1846 bool stopped
= false;
1849 struct lxc_cmd_rr cmd
;
1851 lxc_cmd_init(&cmd
, LXC_CMD_GET_LIMIT_CGROUP2_FD
);
1853 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
1855 return sysdebug("Failed to process \"%s\"",
1856 lxc_cmd_str(LXC_CMD_GET_CGROUP2_FD
));
1858 if (cmd
.rsp
.ret
< 0)
1859 return sysdebug_set(cmd
.rsp
.ret
, "Failed to receive file descriptor for \"%s\"",
1860 lxc_cmd_str(LXC_CMD_GET_CGROUP2_FD
));
1862 fd
= PTR_TO_INT(cmd
.rsp
.data
);
1864 return sysdebug_set(fd
, "Received invalid file descriptor for \"%s\"",
1865 lxc_cmd_str(LXC_CMD_GET_CGROUP2_FD
));
1869 static int __lxc_cmd_get_cgroup2_fd_callback(int fd
, struct lxc_cmd_req
*req
,
1870 struct lxc_handler
*handler
,
1871 struct lxc_async_descr
*descr
,
1872 bool limiting_cgroup
)
1874 struct lxc_cmd_rsp rsp
= {
1877 struct cgroup_ops
*ops
= handler
->cgroup_ops
;
1880 if (!pure_unified_layout(ops
) || !ops
->unified
)
1881 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
1883 send_fd
= limiting_cgroup
? ops
->unified
->dfd_lim
1884 : ops
->unified
->dfd_con
;
1888 return lxc_cmd_rsp_send_reap(fd
, &rsp
);
1892 return rsp_one_fd_reap(fd
, send_fd
, &rsp
);
1895 static int lxc_cmd_get_cgroup2_fd_callback(int fd
, struct lxc_cmd_req
*req
,
1896 struct lxc_handler
*handler
,
1897 struct lxc_async_descr
*descr
)
1899 return __lxc_cmd_get_cgroup2_fd_callback(fd
, req
, handler
, descr
, false);
1902 static int lxc_cmd_get_limit_cgroup2_fd_callback(int fd
, struct lxc_cmd_req
*req
,
1903 struct lxc_handler
*handler
,
1904 struct lxc_async_descr
*descr
)
1906 return __lxc_cmd_get_cgroup2_fd_callback(fd
, req
, handler
, descr
, true);
1909 static int lxc_cmd_rsp_send_enosys(int fd
, int id
)
1911 struct lxc_cmd_rsp rsp
= {
1915 __lxc_cmd_rsp_send(fd
, &rsp
);
1916 return syserror_set(-ENOSYS
, "Invalid command id %d", id
);
1919 static int lxc_cmd_process(int fd
, struct lxc_cmd_req
*req
,
1920 struct lxc_handler
*handler
,
1921 struct lxc_async_descr
*descr
)
1923 typedef int (*callback
)(int, struct lxc_cmd_req
*, struct lxc_handler
*,
1924 struct lxc_async_descr
*);
1926 callback cb
[LXC_CMD_MAX
] = {
1927 [LXC_CMD_GET_TTY_FD
] = lxc_cmd_get_tty_fd_callback
,
1928 [LXC_CMD_TERMINAL_WINCH
] = lxc_cmd_terminal_winch_callback
,
1929 [LXC_CMD_STOP
] = lxc_cmd_stop_callback
,
1930 [LXC_CMD_GET_STATE
] = lxc_cmd_get_state_callback
,
1931 [LXC_CMD_GET_INIT_PID
] = lxc_cmd_get_init_pid_callback
,
1932 [LXC_CMD_GET_CLONE_FLAGS
] = lxc_cmd_get_clone_flags_callback
,
1933 [LXC_CMD_GET_CGROUP
] = lxc_cmd_get_cgroup_callback
,
1934 [LXC_CMD_GET_CONFIG_ITEM
] = lxc_cmd_get_config_item_callback
,
1935 [LXC_CMD_GET_NAME
] = lxc_cmd_get_name_callback
,
1936 [LXC_CMD_GET_LXCPATH
] = lxc_cmd_get_lxcpath_callback
,
1937 [LXC_CMD_ADD_STATE_CLIENT
] = lxc_cmd_add_state_client_callback
,
1938 [LXC_CMD_CONSOLE_LOG
] = lxc_cmd_console_log_callback
,
1939 [LXC_CMD_SERVE_STATE_CLIENTS
] = lxc_cmd_serve_state_clients_callback
,
1940 [LXC_CMD_SECCOMP_NOTIFY_ADD_LISTENER
] = lxc_cmd_seccomp_notify_add_listener_callback
,
1941 [LXC_CMD_ADD_BPF_DEVICE_CGROUP
] = lxc_cmd_add_bpf_device_cgroup_callback
,
1942 [LXC_CMD_FREEZE
] = lxc_cmd_freeze_callback
,
1943 [LXC_CMD_UNFREEZE
] = lxc_cmd_unfreeze_callback
,
1944 [LXC_CMD_GET_CGROUP2_FD
] = lxc_cmd_get_cgroup2_fd_callback
,
1945 [LXC_CMD_GET_INIT_PIDFD
] = lxc_cmd_get_init_pidfd_callback
,
1946 [LXC_CMD_GET_LIMIT_CGROUP
] = lxc_cmd_get_limit_cgroup_callback
,
1947 [LXC_CMD_GET_LIMIT_CGROUP2_FD
] = lxc_cmd_get_limit_cgroup2_fd_callback
,
1948 [LXC_CMD_GET_DEVPTS_FD
] = lxc_cmd_get_devpts_fd_callback
,
1949 [LXC_CMD_GET_SECCOMP_NOTIFY_FD
] = lxc_cmd_get_seccomp_notify_fd_callback
,
1950 [LXC_CMD_GET_CGROUP_CTX
] = lxc_cmd_get_cgroup_ctx_callback
,
1951 [LXC_CMD_GET_CGROUP_FD
] = lxc_cmd_get_cgroup_fd_callback
,
1952 [LXC_CMD_GET_LIMIT_CGROUP_FD
] = lxc_cmd_get_limit_cgroup_fd_callback
,
1953 [LXC_CMD_GET_SYSTEMD_SCOPE
] = lxc_cmd_get_systemd_scope_callback
,
1956 if (req
->cmd
>= LXC_CMD_MAX
)
1957 return lxc_cmd_rsp_send_enosys(fd
, req
->cmd
);
1959 return cb
[req
->cmd
](fd
, req
, handler
, descr
);
1962 static void lxc_cmd_fd_cleanup(int fd
, struct lxc_handler
*handler
,
1963 const lxc_cmd_t cmd
)
1965 if (cmd
== LXC_CMD_ADD_STATE_CLIENT
) {
1966 struct lxc_state_client
*client
, *nclient
;
1968 list_for_each_entry_safe(client
, nclient
, &handler
->conf
->state_clients
, head
) {
1969 if (client
->clientfd
!= fd
)
1972 list_del(&client
->head
);
1976 * No need to walk the whole list. If we found the state
1977 * client fd there can't be a second one.
1979 TRACE("Found state client fd %d in state client list for command \"%s\"", fd
, lxc_cmd_str(cmd
));
1984 * We didn't add the state client to the list. Either because
1985 * we failed to allocate memory (unlikely) or because the state
1986 * was already reached by the time we were ready to add it. So
1987 * fallthrough and clean it up.
1989 TRACE("Deleted state client fd %d for command \"%s\"", fd
, lxc_cmd_str(cmd
));
1993 * We're not closing the client fd here. They will instead be notified
1994 * from the mainloop when it calls the cleanup handler. This will cause
1995 * a slight delay but is semantically cleaner then what we used to do.
1999 static int lxc_cmd_cleanup_handler(int fd
, void *data
)
2001 struct lxc_handler
*handler
= data
;
2003 lxc_terminal_free(handler
->conf
, fd
);
2005 TRACE("Closing client fd %d for \"%s\"", fd
, __FUNCTION__
);
2010 static int lxc_cmd_handler(int fd
, uint32_t events
, void *data
,
2011 struct lxc_async_descr
*descr
)
2013 __do_free
void *reqdata
= NULL
;
2015 struct lxc_cmd_req req
;
2016 struct lxc_handler
*handler
= data
;
2018 ret
= lxc_abstract_unix_rcv_credential(fd
, &req
, sizeof(req
));
2020 SYSERROR("Failed to receive data on command socket for command \"%s\"", lxc_cmd_str(req
.cmd
));
2022 if (errno
== EACCES
) {
2023 /* We don't care for the peer, just send and close. */
2024 struct lxc_cmd_rsp rsp
= {
2028 __lxc_cmd_rsp_send(fd
, &rsp
);
2037 if (ret
!= sizeof(req
)) {
2038 WARN("Failed to receive full command request. Ignoring request for \"%s\"", lxc_cmd_str(req
.cmd
));
2042 if ((req
.datalen
> LXC_CMD_DATA_MAX
) && (req
.cmd
!= LXC_CMD_CONSOLE_LOG
)) {
2043 ERROR("Received command data length %d is too large for command \"%s\"", req
.datalen
, lxc_cmd_str(req
.cmd
));
2047 if (req
.datalen
> 0) {
2048 reqdata
= must_realloc(NULL
, req
.datalen
);
2049 ret
= lxc_recv_nointr(fd
, reqdata
, req
.datalen
, 0);
2050 if (ret
!= req
.datalen
) {
2051 WARN("Failed to receive full command request. Ignoring request for \"%s\"", lxc_cmd_str(req
.cmd
));
2058 ret
= lxc_cmd_process(fd
, &req
, handler
, descr
);
2060 DEBUG("Failed to process command %s; cleaning up client fd %d", lxc_cmd_str(req
.cmd
), fd
);
2064 if (ret
== LXC_CMD_REAP_CLIENT_FD
) {
2065 TRACE("Processed command %s; cleaning up client fd %d", lxc_cmd_str(req
.cmd
), fd
);
2069 TRACE("Processed command %s; keeping client fd %d", lxc_cmd_str(req
.cmd
), fd
);
2070 return LXC_MAINLOOP_CONTINUE
;
2073 lxc_cmd_fd_cleanup(fd
, handler
, req
.cmd
);
2074 return LXC_MAINLOOP_DISARM
;
2077 static int lxc_cmd_accept(int fd
, uint32_t events
, void *data
,
2078 struct lxc_async_descr
*descr
)
2080 __do_close
int connection
= -EBADF
;
2081 int opt
= 1, ret
= -1;
2083 connection
= accept4(fd
, NULL
, 0, SOCK_CLOEXEC
);
2085 return log_error_errno(LXC_MAINLOOP_ERROR
, errno
, "Failed to accept connection to run command");
2087 ret
= setsockopt(connection
, SOL_SOCKET
, SO_PASSCRED
, &opt
, sizeof(opt
));
2089 return log_error_errno(ret
, errno
, "Failed to enable necessary credentials on command socket");
2091 ret
= lxc_mainloop_add_oneshot_handler(descr
, connection
,
2093 lxc_cmd_cleanup_handler
,
2094 data
, "lxc_cmd_handler");
2096 return log_error(ret
, "Failed to add command handler");
2098 TRACE("Accepted new client as fd %d on command server fd %d", connection
, fd
);
2099 move_fd(connection
);
2103 int lxc_server_init(const char *name
, const char *lxcpath
, const char *suffix
)
2105 __do_close
int fd
= -EBADF
;
2107 char path
[LXC_AUDS_ADDR_LEN
] = {0};
2109 ret
= lxc_make_abstract_socket_name(path
, sizeof(path
), name
, lxcpath
, NULL
, suffix
);
2113 fd
= lxc_abstract_unix_open(path
, SOCK_STREAM
, 0);
2115 if (errno
== EADDRINUSE
)
2116 ERROR("Container \"%s\" appears to be already running", name
);
2118 return log_error_errno(-1, errno
, "Failed to create command socket %s", &path
[1]);
2121 return log_trace(move_fd(fd
), "Created abstract unix socket \"%s\"", &path
[1]);
2124 int lxc_cmd_mainloop_add(const char *name
, struct lxc_async_descr
*descr
,
2125 struct lxc_handler
*handler
)
2129 ret
= lxc_mainloop_add_handler(descr
, handler
->conf
->maincmd_fd
,
2131 default_cleanup_handler
,
2132 handler
, "lxc_cmd_accept");
2134 return log_error(ret
, "Failed to add handler for command socket fd %d", handler
->conf
->maincmd_fd
);