]> git.proxmox.com Git - mirror_lxc.git/blame - src/lxc/commands.c
commands: port lxc_cmd_add_bpf_device_cgropu() to new helpers
[mirror_lxc.git] / src / lxc / commands.c
CommitLineData
cc73685d 1/* SPDX-License-Identifier: LGPL-2.1+ */
724e753c 2
d38dd64a
CB
3#ifndef _GNU_SOURCE
4#define _GNU_SOURCE 1
5#endif
cf685555 6#include <caps.h>
724e753c 7#include <errno.h>
91480a0f 8#include <fcntl.h>
fe84a562 9#include <malloc.h>
37515ebd 10#include <poll.h>
fe84a562
CB
11#include <signal.h>
12#include <stdio.h>
13#include <stdlib.h>
fe84a562 14#include <sys/param.h>
724e753c
MN
15#include <sys/socket.h>
16#include <sys/un.h>
d38dd64a 17#include <unistd.h>
724e753c 18
fe84a562 19#include "af_unix.h"
5f126977 20#include "cgroups/cgroup.h"
2a63b5cb 21#include "cgroups/cgroup2_devices.h"
724e753c 22#include "commands.h"
bbf5cf35 23#include "commands_utils.h"
fe84a562 24#include "conf.h"
d38dd64a 25#include "config.h"
ef6e34ee 26#include "confile.h"
fe84a562
CB
27#include "log.h"
28#include "lxc.h"
dbc9832d 29#include "lxclock.h"
cdb2a47f 30#include "lxcseccomp.h"
724e753c 31#include "mainloop.h"
5265a60c 32#include "memory_utils.h"
dbc9832d 33#include "monitor.h"
fe84a562 34#include "start.h"
0ed9b1bc 35#include "terminal.h"
fe84a562 36#include "utils.h"
724e753c 37
ded1d23f 38/*
fe84a562
CB
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).
ded1d23f 42 *
fe84a562
CB
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
46 * additional data.
ded1d23f 47 *
fe84a562
CB
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.
80bcb053 51 *
fe84a562
CB
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.
80bcb053
SH
57 *
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
60 * container.
ded1d23f
DL
61 */
62
ac2cecc4 63lxc_log_define(commands, lxc);
724e753c 64
ef6e34ee 65static const char *lxc_cmd_str(lxc_cmd_t cmd)
724e753c 66{
fe84a562 67 static const char *const cmdname[LXC_CMD_MAX] = {
7e85a2c4 68 [LXC_CMD_GET_TTY_FD] = "get_tty_fd",
2a63b5cb
CB
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",
018051e3
CB
83 [LXC_CMD_FREEZE] = "freeze",
84 [LXC_CMD_UNFREEZE] = "unfreeze",
bad788b0 85 [LXC_CMD_GET_CGROUP2_FD] = "get_cgroup2_fd",
746aab51 86 [LXC_CMD_GET_INIT_PIDFD] = "get_init_pidfd",
a9b642ee
CB
87 [LXC_CMD_GET_LIMIT_CGROUP] = "get_limit_cgroup",
88 [LXC_CMD_GET_LIMIT_CGROUP2_FD] = "get_limit_cgroup2_fd",
f797f05e 89 [LXC_CMD_GET_DEVPTS_FD] = "get_devpts_fd",
21405769 90 [LXC_CMD_GET_SECCOMP_NOTIFY_FD] = "get_seccomp_notify_fd",
ef6e048a 91 [LXC_CMD_GET_CGROUP_CTX] = "get_cgroup_ctx",
c206ac24
CB
92 [LXC_CMD_GET_CGROUP_FD] = "get_cgroup_fd",
93 [LXC_CMD_GET_LIMIT_CGROUP_FD] = "get_limit_cgroup_fd",
ef6e34ee 94 };
724e753c 95
f371aca9 96 if (cmd >= LXC_CMD_MAX)
a8007512 97 return "Invalid request";
fe84a562 98
ef6e34ee
DE
99 return cmdname[cmd];
100}
101
ef6e048a
CB
102static int __transfer_cgroup_ctx_fds(struct unix_fds *fds, struct cgroup_ctx *ctx)
103{
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);
109
110 memcpy(ctx->fd, fds->fd, ctx->fd_len * sizeof(__s32));
111 fds->fd_count_ret = 0;
112 return 0;
113}
114
abb6f657
CB
115static int __transfer_cgroup_fd(struct unix_fds *fds, struct cgroup_fd *fd)
116{
117 fd->fd = move_fd(fds->fd[0]);
118 return 0;
119}
120
ef6e34ee
DE
121/*
122 * lxc_cmd_rsp_recv: Receive a response to a command
123 *
124 * @sock : the socket connected to the container
125 * @cmd : command to put response in
126 *
127 * Returns the size of the response message or < 0 on failure
128 *
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.
133 *
7e85a2c4
CB
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.
ef6e34ee
DE
136 */
137static int lxc_cmd_rsp_recv(int sock, struct lxc_cmd_rr *cmd)
138{
abb6f657 139 __do_free void *__private_ptr = NULL;
7e85a2c4 140 struct lxc_cmd_tty_rsp_data *data_console = NULL;
f8cc4ae8 141 call_cleaner(put_unix_fds) struct unix_fds *fds = &(struct unix_fds){};
ef6e34ee 142 struct lxc_cmd_rsp *rsp = &cmd->rsp;
abb6f657 143 int cur_cmd = cmd->req.cmd, fret = 0;
1454e5d9 144 const char *cur_cmdstr;
f8cc4ae8 145 int ret;
ef6e34ee 146
abb6f657
CB
147 /*
148 * Determine whether this command will receive file descriptors and how
149 * many at most.
150 */
1454e5d9
CB
151 cur_cmdstr = lxc_cmd_str(cur_cmd);
152 switch (cur_cmd) {
c206ac24
CB
153 case LXC_CMD_GET_CGROUP_FD:
154 __fallthrough;
155 case LXC_CMD_GET_LIMIT_CGROUP_FD:
156 __fallthrough;
f8cc4ae8
CB
157 case LXC_CMD_GET_CGROUP2_FD:
158 __fallthrough;
a9b642ee 159 case LXC_CMD_GET_LIMIT_CGROUP2_FD:
f8cc4ae8
CB
160 __fallthrough;
161 case LXC_CMD_GET_INIT_PIDFD:
162 __fallthrough;
163 case LXC_CMD_GET_SECCOMP_NOTIFY_FD:
164 __fallthrough;
165 case LXC_CMD_GET_DEVPTS_FD:
166 __fallthrough;
7e85a2c4 167 case LXC_CMD_GET_TTY_FD:
f8cc4ae8
CB
168 fds->fd_count_max = 1;
169 break;
ef6e048a
CB
170 case LXC_CMD_GET_CGROUP_CTX:
171 fds->fd_count_max = CGROUP_CTX_MAX_FD;
f8cc4ae8
CB
172 break;
173 default:
174 fds->fd_count_max = 0;
ef6e048a 175 break;
f8cc4ae8 176 }
abb6f657
CB
177
178 /* Receive the first response including file descriptors if any. */
d17c815d 179 ret = lxc_abstract_unix_recv_fds(sock, fds, rsp, sizeof(*rsp));
23a917e5 180 if (ret < 0)
1454e5d9 181 return syserrno(ret, "Failed to receive response for command \"%s\"", cur_cmdstr);
00df5330 182
abb6f657
CB
183 /*
184 * Verify that we actually received any file descriptors if the command
185 * expects to do so.
186 */
00df5330 187 if (fds->fd_count_max == 0) {
abb6f657 188 WARN("Command \"%s\" received response", cur_cmdstr);
00df5330 189 } else if (fds->fd_count_ret == 0) {
abb6f657 190 TRACE("Command \"%s\" received response without any of the expected %u file descriptors", cur_cmdstr, fds->fd_count_max);
00df5330 191 fret = -EBADF;
abb6f657
CB
192 } else {
193 TRACE("Command \"%s\" received response with %u of %u expected file descriptors", cur_cmdstr, fds->fd_count_ret, fds->fd_count_max);
00df5330 194 }
ef6e34ee 195
abb6f657
CB
196 /*
197 * Ensure that no excessive data is sent unless someone retrieves the
198 * console ringbuffer.
199 */
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);
ef6e34ee 204
abb6f657
CB
205 /*
206 * Prepare buffer for any command that expects to receive additional
207 * data. Note that some don't want any additional data.
208 */
1454e5d9 209 switch (cur_cmd) {
abb6f657 210 case LXC_CMD_GET_CGROUP2_FD: /* no data */
c206ac24 211 __fallthrough;
abb6f657 212 case LXC_CMD_GET_LIMIT_CGROUP2_FD: /* no data */
2092492c 213 __fallthrough;
abb6f657 214 case LXC_CMD_GET_INIT_PIDFD: /* no data */
2092492c 215 __fallthrough;
abb6f657 216 case LXC_CMD_GET_DEVPTS_FD: /* no data */
2092492c 217 __fallthrough;
abb6f657
CB
218 case LXC_CMD_GET_SECCOMP_NOTIFY_FD: /* no data */
219 if (!fret)
220 rsp->data = INT_TO_PTR(move_fd(fds->fd[0]));
221
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 */
2092492c 225 __fallthrough;
abb6f657
CB
226 case LXC_CMD_GET_LIMIT_CGROUP_FD: /* data */
227 if (rsp->datalen > sizeof(struct cgroup_fd))
1454e5d9 228 return syserrno_set(fret ?: -EINVAL, "Invalid response size from server for \"%s\"", cur_cmdstr);
ef6e048a
CB
229
230 /* Don't pointlessly allocate. */
231 rsp->data = (void *)cmd->req.data;
2092492c 232 break;
abb6f657
CB
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);
236
237 /* Don't pointlessly allocate. */
238 rsp->data = (void *)cmd->req.data;
2092492c 239 break;
7e85a2c4 240 case LXC_CMD_GET_TTY_FD: /* data */
abb6f657
CB
241 /*
242 * recv() returns 0 bytes when a tty cannot be allocated,
243 * rsp->ret is < 0 when the peer permission check failed
244 */
245 if (ret == 0 || rsp->ret < 0)
246 return 0;
21405769 247
7e85a2c4 248 __private_ptr = malloc(sizeof(struct lxc_cmd_tty_rsp_data));
abb6f657
CB
249 if (!__private_ptr)
250 return syserrno_set(fret ?: -ENOMEM, "Failed to receive response for command \"%s\"", cur_cmdstr);
7e85a2c4 251 data_console = (struct lxc_cmd_tty_rsp_data *)__private_ptr;
abb6f657
CB
252 data_console->ptxfd = move_fd(fds->fd[0]);
253 data_console->ttynum = PTR_TO_INT(rsp->data);
23a917e5 254
abb6f657
CB
255 rsp->datalen = 0;
256 rsp->data = data_console;
257 break;
258 case LXC_CMD_CONSOLE_LOG: /* data */
259 __private_ptr = zalloc(rsp->datalen + 1);
260 rsp->data = __private_ptr;
261 break;
262 default: /* catch any additional command */
263 if (rsp->datalen > 0) {
264 __private_ptr = zalloc(rsp->datalen);
265 rsp->data = __private_ptr;
266 }
267 break;
268 }
ef6e34ee 269
abb6f657
CB
270 if (rsp->datalen == 0) {
271 DEBUG("Command \"%s\" requested no additional data", cur_cmdstr);
272 /*
7e85a2c4
CB
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
abb6f657
CB
276 * early here.
277 */
278 goto no_data;
279 }
280
281 /*
282 * All commands ending up here expect data so rsp->data must be valid.
283 * Either static or allocated memory.
284 */
23a917e5 285 if (!rsp->data)
abb6f657 286 return syserrno_set(fret ?: -ENOMEM, "Failed to prepare response buffer for command \"%s\"", cur_cmdstr);
fe84a562 287
2a850b2c 288 ret = lxc_recv_nointr(sock, rsp->data, rsp->datalen, 0);
23a917e5 289 if (ret != rsp->datalen)
abb6f657 290 return syserrno(-errno, "Failed to receive response data for command \"%s\": %d != %d", cur_cmdstr, ret, rsp->datalen);
ef6e048a 291
abb6f657
CB
292 switch (cur_cmd) {
293 case LXC_CMD_GET_CGROUP_CTX:
294 if (!fret)
295 ret = __transfer_cgroup_ctx_fds(fds, rsp->data);
296 /* Make sure any received fds are wiped by us. */
297 break;
298 case LXC_CMD_GET_CGROUP_FD:
299 __fallthrough;
300 case LXC_CMD_GET_LIMIT_CGROUP_FD:
301 if (!fret)
302 ret = __transfer_cgroup_fd(fds, rsp->data);
303 /* Make sure any received fds are wiped by us. */
304 break;
ef6e048a 305 }
724e753c 306
abb6f657
CB
307no_data:
308 if (!fret && ret >= 0)
309 move_ptr(__private_ptr);
310
00df5330 311 return fret ?: ret;
724e753c
MN
312}
313
ef6e34ee
DE
314/*
315 * lxc_cmd_rsp_send: Send a command response
316 *
317 * @fd : file descriptor of socket to send response on
318 * @rsp : response to send
319 *
320 * Returns 0 on success, < 0 on failure
321 */
4b5f4bdc 322static int __lxc_cmd_rsp_send(int fd, struct lxc_cmd_rsp *rsp)
ef6e34ee 323{
fe84a562 324 ssize_t ret;
ef6e34ee 325
7fbb15ec 326 ret = lxc_send_nointr(fd, rsp, sizeof(*rsp), MSG_NOSIGNAL);
6c6497ea 327 if (ret < 0 || (size_t)ret != sizeof(*rsp))
4b5f4bdc 328 return syserrno(-errno, "Failed to send command response %zd", ret);
ef6e34ee 329
a674dfe1 330 if (!rsp->data || rsp->datalen <= 0)
fe84a562
CB
331 return 0;
332
7fbb15ec 333 ret = lxc_send_nointr(fd, rsp->data, rsp->datalen, MSG_NOSIGNAL);
6c6497ea 334 if (ret < 0 || ret != (ssize_t)rsp->datalen)
4b5f4bdc 335 return syswarn(-errno, "Failed to send command response %zd", ret);
fe84a562 336
ef6e34ee
DE
337 return 0;
338}
339
4b5f4bdc
CB
340static inline int lxc_cmd_rsp_send_reap(int fd, struct lxc_cmd_rsp *rsp)
341{
342 int ret;
343
344 ret = __lxc_cmd_rsp_send(fd, rsp);
345 if (ret < 0)
346 return ret;
347
348 return LXC_CMD_REAP_CLIENT_FD;
349}
350
254a22e1
CB
351static inline int lxc_cmd_rsp_send_keep(int fd, struct lxc_cmd_rsp *rsp)
352{
353 int ret;
354
355 ret = __lxc_cmd_rsp_send(fd, rsp);
356 if (ret < 0)
357 return ret;
358
359 return 0;
360}
361
c2f40088
CB
362static inline int rsp_one_fd(int fd, int fd_send, struct lxc_cmd_rsp *rsp)
363{
124b60ec 364 ssize_t ret;
c2f40088
CB
365
366 ret = lxc_abstract_unix_send_fds(fd, &fd_send, 1, rsp, sizeof(*rsp));
367 if (ret < 0)
368 return ret;
369
124b60ec
CB
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);
374 }
375
c2f40088
CB
376 return LXC_CMD_REAP_CLIENT_FD;
377}
378
e848413e
CB
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)
9c3eb8d5 382{
ef6e048a
CB
383 ssize_t ret;
384
385 if (fds_len > KERNEL_SCM_MAX_FD) {
386 rsp->ret = -E2BIG;
387 return lxc_cmd_rsp_send_reap(fd, rsp);
388 } else if (fds_len == 0) {
389 rsp->ret = -ENOENT;
390 return lxc_cmd_rsp_send_reap(fd, rsp);
391 }
9c3eb8d5 392
ef6e048a 393 ret = lxc_abstract_unix_send_fds(fd, fds, fds_len, rsp, sizeof(*rsp));
9c3eb8d5
CB
394 if (ret < 0)
395 return ret;
396
ef6e048a
CB
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);
401 }
402
9c3eb8d5
CB
403 return LXC_CMD_REAP_CLIENT_FD;
404}
405
c01c2be6 406static int lxc_cmd_send(const char *name, struct lxc_cmd_rr *cmd,
fe84a562 407 const char *lxcpath, const char *hashed_sock_name)
c01c2be6 408{
f62cf1d4 409 __do_close int client_fd = -EBADF;
fe84a562 410 ssize_t ret = -1;
c01c2be6 411
9dfa4041 412 client_fd = lxc_cmd_connect(name, lxcpath, hashed_sock_name, "command");
2a850b2c 413 if (client_fd < 0)
fe84a562 414 return -1;
c01c2be6 415
fe84a562
CB
416 ret = lxc_abstract_unix_send_credential(client_fd, &cmd->req,
417 sizeof(cmd->req));
2a850b2c 418 if (ret < 0 || (size_t)ret != sizeof(cmd->req))
e96f9291 419 return -1;
9044b79e 420
cdb2a47f
CB
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, &notify_fd, 1, NULL, 0);
424 if (ret <= 0)
425 return -1;
426 } else {
427 if (cmd->req.datalen <= 0)
428 return move_fd(client_fd);
c01c2be6 429
cdb2a47f
CB
430 errno = EMSGSIZE;
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)
434 return -1;
435 }
c01c2be6 436
240fecd0 437 return move_fd(client_fd);
c01c2be6
CB
438}
439
ef6e34ee
DE
440/*
441 * lxc_cmd: Connect to the specified running container, send it a command
442 * request and collect the response
443 *
444 * @name : name of container to connect to
1e8cfdf6 445 * @cmd : command with initialized request to send
ef6e34ee
DE
446 * @stopped : output indicator if the container was not running
447 * @lxcpath : the lxcpath in which the container is running
448 *
449 * Returns the size of the response message on success, < 0 on failure
450 *
7e85a2c4
CB
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.
ef6e34ee 458 */
8a598112 459static int lxc_cmd(const char *name, struct lxc_cmd_rr *cmd, bool *stopped,
88556fd7 460 const char *lxcpath, const char *hashed_sock_name)
724e753c 461{
f62cf1d4 462 __do_close int client_fd = -EBADF;
fe84a562 463 int ret = -1;
dbc9832d
CB
464 bool stay_connected = false;
465
7e85a2c4 466 if (cmd->req.cmd == LXC_CMD_GET_TTY_FD ||
54446942 467 cmd->req.cmd == LXC_CMD_ADD_STATE_CLIENT)
dbc9832d 468 stay_connected = true;
724e753c 469
0ecf64b5
SH
470 *stopped = 0;
471
c01c2be6
CB
472 client_fd = lxc_cmd_send(name, cmd, lxcpath, hashed_sock_name);
473 if (client_fd < 0) {
0437eac5 474 if (IN_SET(errno, ECONNREFUSED, EPIPE))
ef6e34ee 475 *stopped = 1;
3f903c04 476
6c6497ea
CB
477 return log_trace_errno(-1, errno, "Command \"%s\" failed to connect command socket",
478 lxc_cmd_str(cmd->req.cmd));
724e753c
MN
479 }
480
c01c2be6 481 ret = lxc_cmd_rsp_recv(client_fd, cmd);
2a850b2c 482 if (ret < 0 && errno == ECONNRESET)
6b7f85cb 483 *stopped = 1;
6a93ae77 484
ea2a070b
CB
485 TRACE("Opened new command socket connection fd %d for command \"%s\"",
486 client_fd, lxc_cmd_str(cmd->req.cmd));
487
c34ff119 488 if (stay_connected && ret > 0)
240fecd0 489 cmd->rsp.ret = move_fd(client_fd);
43eb6f29 490
1362f2eb 491 return ret;
724e753c
MN
492}
493
b494d2dd
SH
494int lxc_try_cmd(const char *name, const char *lxcpath)
495{
8a598112 496 bool stopped = false;
8a598112 497 int ret;
38d14ebd
CB
498 struct lxc_cmd_rr cmd;
499
500 lxc_cmd_init(&cmd, LXC_CMD_GET_INIT_PID);
b494d2dd 501
88556fd7 502 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
b494d2dd
SH
503 if (stopped)
504 return 0;
505 if (ret > 0 && cmd.rsp.ret < 0) {
506 errno = cmd.rsp.ret;
507 return -1;
508 }
509 if (ret > 0)
510 return 0;
511
8a598112
CB
512 /*
513 * At this point we weren't denied access, and the container *was*
fe84a562
CB
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.
b494d2dd
SH
518 */
519 return 0;
520}
521
e6bc68d6
WB
522/*
523 * Validate that the input is a proper string parameter. If not,
524 * send an EINVAL response and return -1.
525 *
526 * Precondition: there is non-zero-length data available.
527 */
528static int validate_string_request(int fd, const struct lxc_cmd_req *req)
529{
e6bc68d6
WB
530 size_t maxlen = req->datalen - 1;
531 const char *data = req->data;
532
533 if (data[maxlen] == 0 && strnlen(data, maxlen) == maxlen)
534 return 0;
535
536 struct lxc_cmd_rsp rsp = {
da63ea6b
CB
537 .ret = -EINVAL,
538 .datalen = 0,
539 .data = NULL,
e6bc68d6
WB
540 };
541
4b5f4bdc 542 return lxc_cmd_rsp_send_reap(fd, &rsp);
e6bc68d6
WB
543}
544
cc4c0832 545/* Implementations of the commands and their callbacks */
ef6e34ee
DE
546
547/*
548 * lxc_cmd_get_init_pid: Get pid of the container's init process
549 *
550 * @name : name of container to connect to
551 * @lxcpath : the lxcpath in which the container is running
552 *
553 * Returns the pid on success, < 0 on failure
554 */
555pid_t lxc_cmd_get_init_pid(const char *name, const char *lxcpath)
43eb6f29 556{
8a598112 557 bool stopped = false;
8a598112 558 int ret;
22642823
CB
559 pid_t pid;
560 struct lxc_cmd_rr cmd;
561
562 lxc_cmd_init(&cmd, LXC_CMD_GET_INIT_PID);
ef6e34ee 563
88556fd7 564 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
ef6e34ee 565 if (ret < 0)
8ed8a626 566 return -1;
ef6e34ee 567
565eb353 568 pid = PTR_TO_PID(cmd.rsp.data);
9234406b
CB
569 if (pid < 0)
570 return -1;
571
8a598112
CB
572 /*
573 * We need to assume that pid_t can actually hold any pid given to us
9234406b
CB
574 * by the kernel. If it can't it's a libc bug.
575 */
576 return (pid_t)pid;
43eb6f29
DL
577}
578
ef6e34ee 579static int lxc_cmd_get_init_pid_callback(int fd, struct lxc_cmd_req *req,
cdb2a47f
CB
580 struct lxc_handler *handler,
581 struct lxc_epoll_descr *descr)
43eb6f29 582{
9234406b 583 struct lxc_cmd_rsp rsp = {
4b5f4bdc 584 .data = PID_TO_PTR(handler->pid),
9234406b 585 };
ef6e34ee 586
4b5f4bdc 587 return lxc_cmd_rsp_send_reap(fd, &rsp);
43eb6f29
DL
588}
589
746aab51
CB
590int lxc_cmd_get_init_pidfd(const char *name, const char *lxcpath)
591{
8a598112 592 bool stopped = false;
8a598112 593 int pidfd, ret;
7208e700
CB
594 struct lxc_cmd_rr cmd;
595
596 lxc_cmd_init(&cmd, LXC_CMD_GET_INIT_PIDFD);
746aab51
CB
597
598 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
599 if (ret < 0)
600 return log_debug_errno(-1, errno, "Failed to process init pidfd command");
601
602 if (cmd.rsp.ret < 0)
8a95cd82 603 return syserrno_set(cmd.rsp.ret, "Failed to receive init pidfd");
746aab51 604
8a95cd82
CB
605 pidfd = PTR_TO_INT(cmd.rsp.data);
606 if (pidfd < 0)
607 return syserrno_set(pidfd, "Failed to receive init pidfd");
608
609 return pidfd;
746aab51
CB
610}
611
612static 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)
615{
616 struct lxc_cmd_rsp rsp = {
4b5f4bdc 617 .ret = -EBADF,
746aab51 618 };
746aab51
CB
619
620 if (handler->pidfd < 0)
4b5f4bdc
CB
621 return lxc_cmd_rsp_send_reap(fd, &rsp);
622
623 rsp.ret = 0;
c2f40088 624 return rsp_one_fd(fd, handler->pidfd, &rsp);
746aab51
CB
625}
626
f797f05e
CB
627int lxc_cmd_get_devpts_fd(const char *name, const char *lxcpath)
628{
8a598112 629 bool stopped = false;
8a598112 630 int ret;
f7a7b095
CB
631 struct lxc_cmd_rr cmd;
632
633 lxc_cmd_init(&cmd, LXC_CMD_GET_DEVPTS_FD);
f797f05e
CB
634
635 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
636 if (ret < 0)
637 return log_debug_errno(-1, errno, "Failed to process devpts fd command");
638
639 if (cmd.rsp.ret < 0)
640 return log_debug_errno(-EBADF, errno, "Failed to receive devpts fd");
641
642 return PTR_TO_INT(cmd.rsp.data);
643}
644
645static 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)
648{
649 struct lxc_cmd_rsp rsp = {
4b5f4bdc 650 .ret = -EBADF,
f797f05e 651 };
f797f05e 652
4b5f4bdc
CB
653 if (!handler->conf || handler->conf->devpts_fd < 0)
654 return lxc_cmd_rsp_send_reap(fd, &rsp);
655
656 rsp.ret = 0;
c2f40088 657 return rsp_one_fd(fd, handler->conf->devpts_fd, &rsp);
f797f05e
CB
658}
659
21405769
CB
660int lxc_cmd_get_seccomp_notify_fd(const char *name, const char *lxcpath)
661{
a342b11f 662#ifdef HAVE_SECCOMP_NOTIFY
8a598112 663 bool stopped = false;
8a598112 664 int ret;
f0af9082
CB
665 struct lxc_cmd_rr cmd;
666
667 lxc_cmd_init(&cmd, LXC_CMD_GET_SECCOMP_NOTIFY_FD);
21405769
CB
668
669 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
670 if (ret < 0)
671 return log_debug_errno(-1, errno, "Failed to process seccomp notify fd command");
672
673 if (cmd.rsp.ret < 0)
674 return log_debug_errno(-EBADF, errno, "Failed to receive seccomp notify fd");
675
676 return PTR_TO_INT(cmd.rsp.data);
677#else
678 return ret_errno(EOPNOTSUPP);
679#endif
680}
681
682static 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)
685{
a342b11f 686#ifdef HAVE_SECCOMP_NOTIFY
21405769 687 struct lxc_cmd_rsp rsp = {
4b5f4bdc 688 .ret = -EBADF,
21405769 689 };
21405769
CB
690
691 if (!handler->conf || handler->conf->seccomp.notifier.notify_fd < 0)
4b5f4bdc
CB
692 return lxc_cmd_rsp_send_reap(fd, &rsp);
693
694 rsp.ret = 0;
c2f40088 695 return rsp_one_fd(fd, handler->conf->seccomp.notifier.notify_fd, &rsp);
21405769 696#else
4b5f4bdc 697 return syserrno_set(-EOPNOTSUPP, "Seccomp notifier not supported");
21405769
CB
698#endif
699}
700
ef6e048a 701int lxc_cmd_get_cgroup_ctx(const char *name, const char *lxcpath,
ac5eacc6 702 size_t size_ret_ctx, struct cgroup_ctx *ret_ctx)
9c3eb8d5 703{
8a598112 704 bool stopped = false;
8a598112 705 int ret;
19d141f6
CB
706 struct lxc_cmd_rr cmd;
707
708 lxc_cmd_init(&cmd, LXC_CMD_GET_CGROUP_CTX);
709 lxc_cmd_data(&cmd, size_ret_ctx, ret_ctx);
9c3eb8d5 710
9c3eb8d5
CB
711 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
712 if (ret < 0)
d3be623e 713 return log_debug_errno(-1, errno, "Failed to process cgroup context command");
9c3eb8d5
CB
714
715 if (cmd.rsp.ret < 0)
716 return log_debug_errno(-EBADF, errno, "Failed to receive cgroup fds");
717
718 return 0;
719}
720
ef6e048a
CB
721static 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)
9c3eb8d5 724{
f8cc4ae8 725 struct lxc_cmd_rsp rsp = {
ef6e048a 726 .ret = EINVAL,
f8cc4ae8 727 };
9c3eb8d5 728 struct cgroup_ops *cgroup_ops = handler->cgroup_ops;
ef6e048a 729 struct cgroup_ctx ctx_server = {};
f8cc4ae8
CB
730 int ret;
731
ef6e048a
CB
732 ret = copy_struct_from_client(sizeof(struct cgroup_ctx), &ctx_server,
733 req->datalen, req->data);
f8cc4ae8 734 if (ret < 0)
ef6e048a
CB
735 return lxc_cmd_rsp_send_reap(fd, &rsp);
736
737 ret = prepare_cgroup_ctx(cgroup_ops, &ctx_server);
738 if (ret < 0) {
739 rsp.ret = ret;
740 return lxc_cmd_rsp_send_reap(fd, &rsp);
741 }
9c3eb8d5 742
28c738eb 743 rsp.ret = 0;
ef6e048a
CB
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);
9c3eb8d5
CB
747}
748
ef6e34ee
DE
749/*
750 * lxc_cmd_get_clone_flags: Get clone flags container was spawned with
751 *
752 * @name : name of container to connect to
753 * @lxcpath : the lxcpath in which the container is running
754 *
755 * Returns the clone flags on success, < 0 on failure
756 */
757int lxc_cmd_get_clone_flags(const char *name, const char *lxcpath)
758{
8a598112 759 bool stopped = false;
8a598112 760 int ret;
b4e1a2e8
CB
761 struct lxc_cmd_rr cmd;
762
763 lxc_cmd_init(&cmd, LXC_CMD_GET_CLONE_FLAGS);
ef6e34ee 764
88556fd7 765 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
ef6e34ee
DE
766 if (ret < 0)
767 return ret;
43eb6f29 768
ef6e34ee
DE
769 return PTR_TO_INT(cmd.rsp.data);
770}
771
772static int lxc_cmd_get_clone_flags_callback(int fd, struct lxc_cmd_req *req,
cdb2a47f
CB
773 struct lxc_handler *handler,
774 struct lxc_epoll_descr *descr)
26b2d152 775{
6c6497ea
CB
776 struct lxc_cmd_rsp rsp = {
777 .data = INT_TO_PTR(handler->ns_clone_flags),
778 };
ef6e34ee 779
4b5f4bdc 780 return lxc_cmd_rsp_send_reap(fd, &rsp);
ef6e34ee
DE
781}
782
a900cbaf 783static char *lxc_cmd_get_cgroup_path_do(const char *name, const char *lxcpath,
f85d2385 784 const char *controller,
a900cbaf 785 lxc_cmd_t command)
ef6e34ee 786{
8a598112 787 bool stopped = false;
8a598112 788 int ret;
f85d2385 789 struct lxc_cmd_rr cmd;
26b2d152 790
f85d2385
CB
791 lxc_cmd_init(&cmd, command);
792 if (controller)
793 lxc_cmd_data(&cmd, strlen(controller) + 1, controller);
c2aed66d 794
88556fd7 795 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
fe84a562 796 if (ret < 0)
ef6e34ee
DE
797 return NULL;
798
400d579e 799 if (ret == 0) {
a9b642ee 800 if (command == LXC_CMD_GET_LIMIT_CGROUP) {
400d579e
WB
801 /*
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.
807 */
808 return lxc_cmd_get_cgroup_path_do(name, lxcpath,
f85d2385 809 controller,
400d579e
WB
810 LXC_CMD_GET_CGROUP);
811 }
ef6e34ee 812 return NULL;
400d579e 813 }
ef6e34ee 814
fe84a562 815 if (cmd.rsp.ret < 0 || cmd.rsp.datalen < 0)
ef6e34ee 816 return NULL;
3f903c04 817
ef6e34ee
DE
818 return cmd.rsp.data;
819}
820
a900cbaf
WB
821/*
822 * lxc_cmd_get_cgroup_path: Calculate a container's cgroup path for a
f85d2385 823 * particular controller. This is the cgroup path relative to the root
a900cbaf
WB
824 * of the cgroup filesystem.
825 *
826 * @name : name of container to connect to
827 * @lxcpath : the lxcpath in which the container is running
f85d2385 828 * @controller : the controller being asked about
a900cbaf
WB
829 *
830 * Returns the path on success, NULL on failure. The caller must free() the
831 * returned path.
832 */
833char *lxc_cmd_get_cgroup_path(const char *name, const char *lxcpath,
f85d2385 834 const char *controller)
a900cbaf 835{
f85d2385 836 return lxc_cmd_get_cgroup_path_do(name, lxcpath, controller,
a900cbaf
WB
837 LXC_CMD_GET_CGROUP);
838}
839
840/*
a9b642ee 841 * lxc_cmd_get_limit_cgroup_path: Calculate a container's limit cgroup
f85d2385 842 * path for a particular controller. This is the cgroup path relative to the
a900cbaf 843 * root of the cgroup filesystem. This may be the same as the path returned by
a9b642ee 844 * lxc_cmd_get_cgroup_path if the container doesn't have a limit path prefix
a900cbaf
WB
845 * set.
846 *
847 * @name : name of container to connect to
848 * @lxcpath : the lxcpath in which the container is running
f85d2385 849 * @controller : the controller being asked about
a900cbaf
WB
850 *
851 * Returns the path on success, NULL on failure. The caller must free() the
852 * returned path.
853 */
a9b642ee 854char *lxc_cmd_get_limit_cgroup_path(const char *name, const char *lxcpath,
f85d2385 855 const char *controller)
a900cbaf 856{
f85d2385 857 return lxc_cmd_get_cgroup_path_do(name, lxcpath, controller,
a9b642ee 858 LXC_CMD_GET_LIMIT_CGROUP);
a900cbaf
WB
859}
860
861static 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)
ef6e34ee 865{
ea2a070b 866 int ret;
4fb3cba5 867 const char *path;
a900cbaf 868 const void *reqdata;
fe84a562 869 struct lxc_cmd_rsp rsp;
2202afc9 870 struct cgroup_ops *cgroup_ops = handler->cgroup_ops;
a900cbaf 871 const char *(*get_fn)(struct cgroup_ops *ops, const char *controller);
b98f7d6e 872
e6bc68d6
WB
873 if (req->datalen > 0) {
874 ret = validate_string_request(fd, req);
875 if (ret != 0)
876 return ret;
a900cbaf 877 reqdata = req->data;
e6bc68d6 878 } else {
a900cbaf 879 reqdata = NULL;
e6bc68d6 880 }
a900cbaf 881
a9b642ee 882 get_fn = (limiting_cgroup ? cgroup_ops->get_limit_cgroup
29d652a9 883 : cgroup_ops->get_cgroup);
a900cbaf
WB
884
885 path = get_fn(cgroup_ops, reqdata);
886
b98f7d6e
SH
887 if (!path)
888 return -1;
fe84a562 889
4f17323e 890 rsp.ret = 0;
fe84a562
CB
891 rsp.datalen = strlen(path) + 1;
892 rsp.data = (char *)path;
ef6e34ee 893
4b5f4bdc 894 return lxc_cmd_rsp_send_reap(fd, &rsp);
ef6e34ee
DE
895}
896
a900cbaf
WB
897static int lxc_cmd_get_cgroup_callback(int fd, struct lxc_cmd_req *req,
898 struct lxc_handler *handler,
899 struct lxc_epoll_descr *descr)
900{
901 return lxc_cmd_get_cgroup_callback_do(fd, req, handler, descr, false);
902}
903
a9b642ee
CB
904static 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)
a900cbaf
WB
907{
908 return lxc_cmd_get_cgroup_callback_do(fd, req, handler, descr, true);
909}
910
ef6e34ee
DE
911/*
912 * lxc_cmd_get_config_item: Get config item the running container
913 *
914 * @name : name of container to connect to
7fa3f2e9 915 * @item : the configuration item to retrieve (ex: lxc.net.0.veth.pair)
ef6e34ee
DE
916 * @lxcpath : the lxcpath in which the container is running
917 *
918 * Returns the item on success, NULL on failure. The caller must free() the
919 * returned item.
920 */
921char *lxc_cmd_get_config_item(const char *name, const char *item,
922 const char *lxcpath)
923{
8a598112 924 bool stopped = false;
8a598112 925 int ret;
187e46ab
CB
926 struct lxc_cmd_rr cmd;
927
928 if (is_empty_string(item))
929 return NULL;
930
931 lxc_cmd_init(&cmd, LXC_CMD_GET_CONFIG_ITEM);
932 lxc_cmd_data(&cmd, strlen(item) + 1, item);
ef6e34ee 933
88556fd7 934 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
ef6e34ee
DE
935 if (ret < 0)
936 return NULL;
937
938 if (cmd.rsp.ret == 0)
939 return cmd.rsp.data;
fe84a562 940
ef6e34ee
DE
941 return NULL;
942}
943
944static int lxc_cmd_get_config_item_callback(int fd, struct lxc_cmd_req *req,
cdb2a47f
CB
945 struct lxc_handler *handler,
946 struct lxc_epoll_descr *descr)
ef6e34ee 947{
5265a60c 948 __do_free char *cidata = NULL;
ef6e34ee 949 int cilen;
30aec088 950 struct lxc_config_t *item;
fe84a562 951 struct lxc_cmd_rsp rsp;
ef6e34ee
DE
952
953 memset(&rsp, 0, sizeof(rsp));
300df83e 954 item = lxc_get_config(req->data);
30aec088
CB
955 if (!item)
956 goto err1;
fe84a562 957
cccd2219 958 cilen = item->get(req->data, NULL, 0, handler->conf, NULL);
ef6e34ee
DE
959 if (cilen <= 0)
960 goto err1;
961
5265a60c 962 cidata = must_realloc(NULL, cilen + 1);
cccd2219 963 if (item->get(req->data, cidata, cilen + 1, handler->conf, NULL) != cilen)
ef6e34ee 964 goto err1;
fe84a562 965
ef6e34ee
DE
966 cidata[cilen] = '\0';
967 rsp.data = cidata;
968 rsp.datalen = cilen + 1;
969 rsp.ret = 0;
970 goto out;
971
972err1:
973 rsp.ret = -1;
974out:
4b5f4bdc 975 return lxc_cmd_rsp_send_reap(fd, &rsp);
ef6e34ee
DE
976}
977
978/*
979 * lxc_cmd_get_state: Get current state of the container
980 *
981 * @name : name of container to connect to
982 * @lxcpath : the lxcpath in which the container is running
983 *
984 * Returns the state on success, < 0 on failure
985 */
dbc9832d 986int lxc_cmd_get_state(const char *name, const char *lxcpath)
ef6e34ee 987{
8a598112 988 bool stopped = false;
8a598112 989 int ret;
1b08494e
CB
990 struct lxc_cmd_rr cmd;
991
992 lxc_cmd_init(&cmd, LXC_CMD_GET_STATE);
26b2d152 993
88556fd7 994 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
ebdd307d 995 if (ret < 0 && stopped)
ef6e34ee
DE
996 return STOPPED;
997
998 if (ret < 0)
26b2d152 999 return -1;
26b2d152 1000
6c6497ea
CB
1001 if (!ret)
1002 return log_warn(-1, "Container \"%s\" has stopped before sending its state", name);
fe84a562 1003
6c6497ea
CB
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)));
ef6e34ee
DE
1007}
1008
1009static int lxc_cmd_get_state_callback(int fd, struct lxc_cmd_req *req,
cdb2a47f
CB
1010 struct lxc_handler *handler,
1011 struct lxc_epoll_descr *descr)
ef6e34ee 1012{
6c6497ea
CB
1013 struct lxc_cmd_rsp rsp = {
1014 .data = INT_TO_PTR(handler->state),
1015 };
ef6e34ee 1016
4b5f4bdc 1017 return lxc_cmd_rsp_send_reap(fd, &rsp);
ef6e34ee
DE
1018}
1019
1020/*
1021 * lxc_cmd_stop: Stop the container previously started with lxc_start. All
1022 * the processes running inside this container will be killed.
1023 *
1024 * @name : name of container to connect to
1025 * @lxcpath : the lxcpath in which the container is running
1026 *
1027 * Returns 0 on success, < 0 on failure
1028 */
1029int lxc_cmd_stop(const char *name, const char *lxcpath)
1030{
8a598112 1031 bool stopped = false;
8a598112 1032 int ret;
dbdd56c1
CB
1033 struct lxc_cmd_rr cmd;
1034
1035 lxc_cmd_init(&cmd, LXC_CMD_STOP);
ef6e34ee 1036
88556fd7 1037 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
26b2d152 1038 if (ret < 0) {
6c6497ea
CB
1039 if (stopped)
1040 return log_info(0, "Container \"%s\" is already stopped", name);
fe84a562 1041
26b2d152
MN
1042 return -1;
1043 }
1044
fe84a562
CB
1045 /* We do not expect any answer, because we wait for the connection to be
1046 * closed.
95d5b147 1047 */
6c6497ea
CB
1048 if (ret > 0)
1049 return log_error_errno(-1, -cmd.rsp.ret, "Failed to stop container \"%s\"", name);
26b2d152 1050
6c6497ea 1051 return log_info(0, "Container \"%s\" has stopped", name);
26b2d152
MN
1052}
1053
ef6e34ee 1054static int lxc_cmd_stop_callback(int fd, struct lxc_cmd_req *req,
cdb2a47f
CB
1055 struct lxc_handler *handler,
1056 struct lxc_epoll_descr *descr)
d5088cf2 1057{
ef6e34ee 1058 struct lxc_cmd_rsp rsp;
ef6e34ee 1059 int stopsignal = SIGKILL;
2202afc9 1060 struct cgroup_ops *cgroup_ops = handler->cgroup_ops;
ea2a070b 1061 int ret;
ef6e34ee
DE
1062
1063 if (handler->conf->stopsignal)
1064 stopsignal = handler->conf->stopsignal;
1065 memset(&rsp, 0, sizeof(rsp));
9837ee46 1066
8ad4fa68 1067 if (handler->pidfd >= 0)
9837ee46
CB
1068 rsp.ret = lxc_raw_pidfd_send_signal(handler->pidfd, stopsignal, NULL, 0);
1069 else
1070 rsp.ret = kill(handler->pid, stopsignal);
ef6e34ee 1071 if (!rsp.ret) {
9837ee46
CB
1072 if (handler->pidfd >= 0)
1073 TRACE("Sent signal %d to pidfd %d", stopsignal, handler->pidfd);
1074 else
1075 TRACE("Sent signal %d to pidfd %d", stopsignal, handler->pid);
1076
9d47970b 1077 if (pure_unified_layout(cgroup_ops))
c0af7b1c 1078 ret = __cgroup_unfreeze(cgroup_ops->unified->dfd_lim, -1);
9d47970b
CB
1079 else
1080 ret = cgroup_ops->unfreeze(cgroup_ops, -1);
8db8adea
CB
1081 if (ret)
1082 WARN("Failed to unfreeze container \"%s\"", handler->name);
fe84a562 1083
8db8adea 1084 return 0;
018051e3
CB
1085 } else {
1086 rsp.ret = -errno;
ef6e34ee
DE
1087 }
1088
4b5f4bdc 1089 return lxc_cmd_rsp_send_reap(fd, &rsp);
ef6e34ee 1090}
d5088cf2 1091
b5159817 1092/*
2bd158cc 1093 * lxc_cmd_terminal_winch: noop
b5159817
DE
1094 *
1095 * @name : name of container to connect to
1096 * @lxcpath : the lxcpath in which the container is running
1097 *
1098 * Returns 0 on success, < 0 on failure
1099 */
8ccbbf94 1100int lxc_cmd_terminal_winch(const char *name, const char *lxcpath)
b5159817 1101{
b5159817
DE
1102 return 0;
1103}
1104
8ccbbf94 1105static int lxc_cmd_terminal_winch_callback(int fd, struct lxc_cmd_req *req,
cdb2a47f
CB
1106 struct lxc_handler *handler,
1107 struct lxc_epoll_descr *descr)
b5159817 1108{
2bd158cc 1109 /* should never be called */
6c6497ea 1110 return log_error_errno(-1, ENOSYS, "Called lxc_cmd_terminal_winch_callback()");
b5159817
DE
1111}
1112
ef6e34ee 1113/*
7e85a2c4 1114 * lxc_cmd_get_tty_fd: Open an fd to a tty in the container
ef6e34ee
DE
1115 *
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
36a94ce8 1119 * @fd : out: file descriptor for ptx side of pty
ef6e34ee
DE
1120 * @lxcpath : the lxcpath in which the container is running
1121 *
0115f8fd 1122 * Returns fd holding tty allocated on success, < 0 on failure
ef6e34ee 1123 */
7e85a2c4 1124int lxc_cmd_get_tty_fd(const char *name, int *ttynum, int *fd, const char *lxcpath)
ef6e34ee 1125{
7e85a2c4 1126 __do_free struct lxc_cmd_tty_rsp_data *rspdata = NULL;
8a598112 1127 bool stopped = false;
8a598112 1128 int ret;
1a37ba9d
CB
1129 struct lxc_cmd_rr cmd;
1130
1131 lxc_cmd_init(&cmd, LXC_CMD_GET_TTY_FD);
1132 lxc_cmd_data(&cmd, ENCODE_INTO_PTR_LEN, INT_TO_PTR(*ttynum));
d5088cf2 1133
88556fd7 1134 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
ef6e34ee
DE
1135 if (ret < 0)
1136 return ret;
0115f8fd 1137
8259d86d 1138 rspdata = cmd.rsp.data;
6c6497ea
CB
1139 if (cmd.rsp.ret < 0)
1140 return log_error_errno(-1, -cmd.rsp.ret, "Denied access to tty");
d5088cf2 1141
6c6497ea
CB
1142 if (ret == 0)
1143 return log_error(-1, "tty number %d invalid, busy or all ttys busy", *ttynum);
ef6e34ee 1144
36a94ce8 1145 if (rspdata->ptxfd < 0)
6c6497ea 1146 return log_error(-1, "Unable to allocate fd for tty %d", rspdata->ttynum);
ef6e34ee 1147
fe84a562 1148 ret = cmd.rsp.ret; /* socket fd */
36a94ce8 1149 *fd = rspdata->ptxfd;
ef6e34ee 1150 *ttynum = rspdata->ttynum;
fe84a562 1151
6c6497ea 1152 return log_info(ret, "Alloced fd %d for tty %d via socket %d", *fd, rspdata->ttynum, ret);
ef6e34ee
DE
1153}
1154
7e85a2c4
CB
1155static 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)
ef6e34ee 1158{
36a94ce8 1159 int ptxfd, ret;
4b5f4bdc
CB
1160 struct lxc_cmd_rsp rsp = {
1161 .ret = -EBADF,
1162 };
fe84a562 1163 int ttynum = PTR_TO_INT(req->data);
ef6e34ee 1164
36a94ce8
CB
1165 ptxfd = lxc_terminal_allocate(handler->conf, fd, &ttynum);
1166 if (ptxfd < 0)
4b5f4bdc 1167 return lxc_cmd_rsp_send_reap(fd, &rsp);
ef6e34ee 1168
4b5f4bdc 1169 rsp.ret = 0;
ef6e34ee 1170 rsp.data = INT_TO_PTR(ttynum);
36a94ce8 1171 ret = lxc_abstract_unix_send_fds(fd, &ptxfd, 1, &rsp, sizeof(rsp));
fe84a562 1172 if (ret < 0) {
3dfe6f8d 1173 lxc_terminal_free(handler->conf, fd);
4b5f4bdc 1174 return ret;
ef6e34ee
DE
1175 }
1176
4b5f4bdc 1177 return log_debug(0, "Send tty to client");
d5088cf2
CS
1178}
1179
88556fd7
ÇO
1180/*
1181 * lxc_cmd_get_name: Returns the name of the container
1182 *
1183 * @hashed_sock_name: hashed socket name
1184 *
1185 * Returns the name on success, NULL on failure.
1186 */
1187char *lxc_cmd_get_name(const char *hashed_sock_name)
1188{
8a598112 1189 bool stopped = false;
8a598112 1190 int ret;
16fcb1fe
CB
1191 struct lxc_cmd_rr cmd;
1192
1193 lxc_cmd_init(&cmd, LXC_CMD_GET_NAME);
88556fd7
ÇO
1194
1195 ret = lxc_cmd(NULL, &cmd, &stopped, NULL, hashed_sock_name);
fe84a562 1196 if (ret < 0)
88556fd7 1197 return NULL;
88556fd7
ÇO
1198
1199 if (cmd.rsp.ret == 0)
1200 return cmd.rsp.data;
fe84a562 1201
88556fd7
ÇO
1202 return NULL;
1203}
1204
1205static int lxc_cmd_get_name_callback(int fd, struct lxc_cmd_req *req,
cdb2a47f
CB
1206 struct lxc_handler *handler,
1207 struct lxc_epoll_descr *descr)
88556fd7
ÇO
1208{
1209 struct lxc_cmd_rsp rsp;
1210
1211 memset(&rsp, 0, sizeof(rsp));
1212
f0ecc19d 1213 rsp.data = (char *)handler->name;
88556fd7
ÇO
1214 rsp.datalen = strlen(handler->name) + 1;
1215 rsp.ret = 0;
1216
4b5f4bdc 1217 return lxc_cmd_rsp_send_reap(fd, &rsp);
88556fd7
ÇO
1218}
1219
1220/*
1221 * lxc_cmd_get_lxcpath: Returns the lxcpath of the container
1222 *
1223 * @hashed_sock_name: hashed socket name
1224 *
1225 * Returns the lxcpath on success, NULL on failure.
1226 */
1227char *lxc_cmd_get_lxcpath(const char *hashed_sock_name)
1228{
8a598112 1229 bool stopped = false;
8a598112 1230 int ret;
9dca7207
CB
1231 struct lxc_cmd_rr cmd;
1232
1233 lxc_cmd_init(&cmd, LXC_CMD_GET_LXCPATH);
724e753c 1234
88556fd7 1235 ret = lxc_cmd(NULL, &cmd, &stopped, NULL, hashed_sock_name);
fe84a562 1236 if (ret < 0)
88556fd7 1237 return NULL;
88556fd7
ÇO
1238
1239 if (cmd.rsp.ret == 0)
1240 return cmd.rsp.data;
fe84a562 1241
88556fd7
ÇO
1242 return NULL;
1243}
1244
1245static int lxc_cmd_get_lxcpath_callback(int fd, struct lxc_cmd_req *req,
cdb2a47f
CB
1246 struct lxc_handler *handler,
1247 struct lxc_epoll_descr *descr)
88556fd7 1248{
6c6497ea
CB
1249 struct lxc_cmd_rsp rsp = {
1250 .ret = 0,
1251 .data = (char *)handler->lxcpath,
1252 .datalen = strlen(handler->lxcpath) + 1,
1253 };
88556fd7 1254
4b5f4bdc 1255 return lxc_cmd_rsp_send_reap(fd, &rsp);
88556fd7 1256}
ef6e34ee 1257
54446942 1258int lxc_cmd_add_state_client(const char *name, const char *lxcpath,
3d971319 1259 lxc_state_t states[static MAX_STATE],
92e35018 1260 int *state_client_fd)
dbc9832d 1261{
f62cf1d4 1262 __do_close int clientfd = -EBADF;
8a598112 1263 bool stopped = false;
8a598112
CB
1264 int state;
1265 ssize_t ret;
3de3c9e3
CB
1266 struct lxc_cmd_rr cmd;
1267
1268 lxc_cmd_init(&cmd, LXC_CMD_ADD_STATE_CLIENT);
1269 lxc_cmd_data(&cmd, (sizeof(lxc_state_t) * MAX_STATE), states);
dbc9832d 1270
dbc9832d 1271 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
bc631984
CB
1272 if (states[STOPPED] != 0 && stopped != 0)
1273 return STOPPED;
1274
dbc9832d 1275 if (ret < 0) {
f577e061 1276 if (errno != ECONNREFUSED)
6d1400b5 1277 SYSERROR("Failed to execute command");
1278
dbc9832d
CB
1279 return -1;
1280 }
fe84a562 1281
dbc9832d
CB
1282 /* We should now be guaranteed to get an answer from the state sending
1283 * function.
1284 */
cd889e57 1285 clientfd = cmd.rsp.ret;
6c6497ea
CB
1286 if (clientfd < 0)
1287 return log_error_errno(-1, -clientfd, "Failed to receive socket fd");
dbc9832d 1288
bc631984 1289 state = PTR_TO_INT(cmd.rsp.data);
6c6497ea
CB
1290 if (state < MAX_STATE)
1291 return log_trace(state, "Container is already in requested state %s", lxc_state2str(state));
bc631984 1292
240fecd0 1293 *state_client_fd = move_fd(clientfd);
ea2a070b
CB
1294 TRACE("State connection fd %d ready to listen for container state changes", *state_client_fd);
1295 return MAX_STATE;
dbc9832d
CB
1296}
1297
ebbca852 1298static int lxc_cmd_add_state_client_callback(__owns int fd, struct lxc_cmd_req *req,
cdb2a47f
CB
1299 struct lxc_handler *handler,
1300 struct lxc_epoll_descr *descr)
dbc9832d 1301{
4b5f4bdc
CB
1302 struct lxc_cmd_rsp rsp = {
1303 .ret = -EINVAL,
1304 };
dbc9832d 1305
fe84a562 1306 if (req->datalen < 0)
254a22e1 1307 goto reap_fd;
dbc9832d 1308
71fc9c04 1309 if (req->datalen != (sizeof(lxc_state_t) * MAX_STATE))
254a22e1 1310 goto reap_fd;
dbc9832d 1311
fe84a562 1312 if (!req->data)
254a22e1 1313 goto reap_fd;
dbc9832d 1314
c01c2be6 1315 rsp.ret = lxc_add_state_client(fd, handler, (lxc_state_t *)req->data);
44552fb2 1316 if (rsp.ret < 0)
254a22e1 1317 goto reap_fd;
44552fb2 1318
bc631984 1319 rsp.data = INT_TO_PTR(rsp.ret);
dbc9832d 1320
254a22e1
CB
1321 return lxc_cmd_rsp_send_keep(fd, &rsp);
1322
1323reap_fd:
4b5f4bdc 1324 return lxc_cmd_rsp_send_reap(fd, &rsp);
dbc9832d
CB
1325}
1326
2a63b5cb
CB
1327int lxc_cmd_add_bpf_device_cgroup(const char *name, const char *lxcpath,
1328 struct device_item *device)
1329{
8a598112 1330 bool stopped = false;
2a63b5cb 1331 int ret;
9338a6f3 1332 struct lxc_cmd_rr cmd;
2a63b5cb
CB
1333
1334 if (strlen(device->access) > STRLITERALLEN("rwm"))
9338a6f3
CB
1335 return syserrno_set(-EINVAL, "Invalid access mode specified %s", device->access);
1336
1337 lxc_cmd_init(&cmd, LXC_CMD_ADD_BPF_DEVICE_CGROUP);
1338 lxc_cmd_data(&cmd, sizeof(struct device_item), device);
2a63b5cb
CB
1339
1340 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
9338a6f3
CB
1341 if (ret < 0)
1342 return syserrno_set(ret, "Failed to process new bpf device cgroup command");
1343
1344 if (cmd.rsp.ret < 0)
1345 return syserrno_set(cmd.rsp.ret, "Failed to add new bpf device cgroup rule");
2a63b5cb
CB
1346
1347 return 0;
2a63b5cb
CB
1348}
1349
1350static 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)
1353{
4b5f4bdc
CB
1354 struct lxc_cmd_rsp rsp = {
1355 .ret = -EINVAL,
1356 };
0a150695 1357 struct lxc_conf *conf;
2a63b5cb
CB
1358
1359 if (req->datalen <= 0)
4b5f4bdc 1360 goto out;
2a63b5cb
CB
1361
1362 if (req->datalen != sizeof(struct device_item))
4b5f4bdc 1363 goto out;
2a63b5cb
CB
1364
1365 if (!req->data)
4b5f4bdc 1366 goto out;
2a63b5cb 1367
0a150695 1368 conf = handler->conf;
a134099d
CB
1369 if (!bpf_cgroup_devices_update(handler->cgroup_ops,
1370 &conf->bpf_devices,
1371 (struct device_item *)req->data))
0a150695
CB
1372 rsp.ret = -1;
1373 else
1374 rsp.ret = 0;
2a63b5cb 1375
4b5f4bdc
CB
1376out:
1377 return lxc_cmd_rsp_send_reap(fd, &rsp);
2a63b5cb
CB
1378}
1379
191d43cc
CB
1380int lxc_cmd_console_log(const char *name, const char *lxcpath,
1381 struct lxc_console_log *log)
1382{
8a598112
CB
1383 bool stopped = false;
1384 int ret;
191d43cc
CB
1385 struct lxc_cmd_console_log data;
1386 struct lxc_cmd_rr cmd;
1387
1388 data.clear = log->clear;
1389 data.read = log->read;
1390 data.read_max = *log->read_max;
1391
1392 cmd.req.cmd = LXC_CMD_CONSOLE_LOG;
1393 cmd.req.data = &data;
1394 cmd.req.datalen = sizeof(struct lxc_cmd_console_log);
1395
1396 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
1397 if (ret < 0)
1398 return ret;
1399
1400 /* There is nothing to be read from the buffer. So clear any values we
1401 * where passed to clearly indicate to the user that nothing went wrong.
1402 */
63b74cda 1403 if (cmd.rsp.ret == -ENODATA || cmd.rsp.ret == -EFAULT || cmd.rsp.ret == -ENOENT) {
191d43cc
CB
1404 *log->read_max = 0;
1405 log->data = NULL;
1406 }
1407
1408 /* This is a proper error so don't touch any values we were passed. */
1409 if (cmd.rsp.ret < 0)
1410 return cmd.rsp.ret;
1411
1412 *log->read_max = cmd.rsp.datalen;
1413 log->data = cmd.rsp.data;
1414
1415 return 0;
1416}
1417
1418static int lxc_cmd_console_log_callback(int fd, struct lxc_cmd_req *req,
cdb2a47f
CB
1419 struct lxc_handler *handler,
1420 struct lxc_epoll_descr *descr)
191d43cc
CB
1421{
1422 struct lxc_cmd_rsp rsp;
28f3b1cd 1423 uint64_t buffer_size = handler->conf->console.buffer_size;
191d43cc
CB
1424 const struct lxc_cmd_console_log *log = req->data;
1425 struct lxc_ringbuf *buf = &handler->conf->console.ringbuf;
1426
1427 rsp.ret = -EFAULT;
1428 rsp.datalen = 0;
1429 rsp.data = NULL;
28f3b1cd 1430 if (buffer_size <= 0)
191d43cc
CB
1431 goto out;
1432
5928191e
CB
1433 if (log->read || log->write_logfile)
1434 rsp.datalen = lxc_ringbuf_used(buf);
1435
191d43cc
CB
1436 if (log->read)
1437 rsp.data = lxc_ringbuf_get_read_addr(buf);
1438
1439 if (log->read_max > 0 && (log->read_max <= rsp.datalen))
1440 rsp.datalen = log->read_max;
1441
1442 /* there's nothing to read */
63b74cda 1443 rsp.ret = -ENODATA;
191d43cc 1444 if (log->read && (buf->r_off == buf->w_off))
63b74cda
CB
1445 goto out;
1446
63b74cda 1447 rsp.ret = 0;
23e0d9af 1448 if (log->clear)
43366ca2 1449 lxc_ringbuf_clear(buf); /* clear the ringbuffer */
23e0d9af 1450 else if (rsp.datalen > 0)
191d43cc
CB
1451 lxc_ringbuf_move_read_addr(buf, rsp.datalen);
1452
1453out:
4b5f4bdc 1454 return lxc_cmd_rsp_send_reap(fd, &rsp);
191d43cc
CB
1455}
1456
974a8aba
CB
1457int lxc_cmd_serve_state_clients(const char *name, const char *lxcpath,
1458 lxc_state_t state)
1459{
8a598112 1460 bool stopped = false;
974a8aba 1461 struct lxc_cmd_rr cmd = {
6c6497ea
CB
1462 .req = {
1463 .cmd = LXC_CMD_SERVE_STATE_CLIENTS,
1464 .data = INT_TO_PTR(state)
1465 },
974a8aba 1466 };
8a598112 1467 ssize_t ret;
974a8aba
CB
1468
1469 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
6c6497ea
CB
1470 if (ret < 0)
1471 return log_error_errno(-1, errno, "Failed to serve state clients");
974a8aba
CB
1472
1473 return 0;
1474}
1475
1476static int lxc_cmd_serve_state_clients_callback(int fd, struct lxc_cmd_req *req,
cdb2a47f
CB
1477 struct lxc_handler *handler,
1478 struct lxc_epoll_descr *descr)
974a8aba
CB
1479{
1480 int ret;
1481 lxc_state_t state = PTR_TO_INT(req->data);
1482 struct lxc_cmd_rsp rsp = {0};
1483
1484 ret = lxc_serve_state_clients(handler->name, handler, state);
1485 if (ret < 0)
4b5f4bdc 1486 return ret;
974a8aba 1487
4b5f4bdc 1488 return lxc_cmd_rsp_send_reap(fd, &rsp);
974a8aba
CB
1489}
1490
cdb2a47f
CB
1491int lxc_cmd_seccomp_notify_add_listener(const char *name, const char *lxcpath,
1492 int fd,
1493 /* unused */ unsigned int command,
1494 /* unused */ unsigned int flags)
1495{
1496
c3e3c21a 1497#ifdef HAVE_SECCOMP_NOTIFY
8a598112 1498 bool stopped = false;
cdb2a47f
CB
1499 struct lxc_cmd_rr cmd = {
1500 .req = {
1501 .cmd = LXC_CMD_SECCOMP_NOTIFY_ADD_LISTENER,
1502 .data = INT_TO_PTR(fd),
1503 },
1504 };
8a598112 1505 int ret;
cdb2a47f
CB
1506
1507 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
6c6497ea
CB
1508 if (ret < 0)
1509 return log_error_errno(-1, errno, "Failed to add seccomp listener");
cdb2a47f
CB
1510
1511 return cmd.rsp.ret;
1512#else
3d0327ed 1513 return ret_set_errno(-1, ENOSYS);
cdb2a47f
CB
1514#endif
1515}
1516
1517static int lxc_cmd_seccomp_notify_add_listener_callback(int fd,
1518 struct lxc_cmd_req *req,
1519 struct lxc_handler *handler,
1520 struct lxc_epoll_descr *descr)
1521{
1522 struct lxc_cmd_rsp rsp = {0};
cdb2a47f 1523
c3e3c21a
CB
1524#ifdef HAVE_SECCOMP_NOTIFY
1525 int ret;
f62cf1d4 1526 __do_close int recv_fd = -EBADF;
cdb2a47f 1527
d17c815d 1528 ret = lxc_abstract_unix_recv_one_fd(fd, &recv_fd, NULL, 0);
c3e3c21a
CB
1529 if (ret <= 0) {
1530 rsp.ret = -errno;
1531 goto out;
cdb2a47f
CB
1532 }
1533
c3e3c21a
CB
1534 if (!handler->conf->seccomp.notifier.wants_supervision ||
1535 handler->conf->seccomp.notifier.proxy_fd < 0) {
1536 SYSERROR("No seccomp proxy fd specified");
1537 rsp.ret = -EINVAL;
1538 goto out;
1539 }
cdb2a47f 1540
c3e3c21a 1541 ret = lxc_mainloop_add_handler(descr, recv_fd, seccomp_notify_handler,
cdb2a47f 1542 handler);
c3e3c21a
CB
1543 if (ret < 0) {
1544 rsp.ret = -errno;
1545 goto out;
1546 }
68a9e3eb 1547 move_fd(recv_fd);
cdb2a47f 1548
c3e3c21a 1549out:
cdb2a47f
CB
1550#else
1551 rsp.ret = -ENOSYS;
cdb2a47f 1552
c3e3c21a 1553#endif
4b5f4bdc 1554 return lxc_cmd_rsp_send_reap(fd, &rsp);
cdb2a47f
CB
1555}
1556
018051e3
CB
1557int lxc_cmd_freeze(const char *name, const char *lxcpath, int timeout)
1558{
8a598112 1559 bool stopped = false;
018051e3
CB
1560 struct lxc_cmd_rr cmd = {
1561 .req = {
1562 .cmd = LXC_CMD_FREEZE,
1563 .data = INT_TO_PTR(timeout),
1564 },
1565 };
8a598112 1566 int ret;
018051e3
CB
1567
1568 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
1569 if (ret <= 0 || cmd.rsp.ret < 0)
3d0327ed 1570 return log_error_errno(-1, errno, "Failed to freeze container");
018051e3
CB
1571
1572 return cmd.rsp.ret;
1573}
1574
1575static int lxc_cmd_freeze_callback(int fd, struct lxc_cmd_req *req,
1576 struct lxc_handler *handler,
1577 struct lxc_epoll_descr *descr)
1578{
1579 int timeout = PTR_TO_INT(req->data);
1580 struct lxc_cmd_rsp rsp = {
6c6497ea 1581 .ret = -ENOENT,
018051e3
CB
1582 };
1583 struct cgroup_ops *ops = handler->cgroup_ops;
1584
1973b62a 1585 if (pure_unified_layout(ops))
018051e3
CB
1586 rsp.ret = ops->freeze(ops, timeout);
1587
4b5f4bdc 1588 return lxc_cmd_rsp_send_reap(fd, &rsp);
018051e3
CB
1589}
1590
1591int lxc_cmd_unfreeze(const char *name, const char *lxcpath, int timeout)
1592{
8a598112 1593 bool stopped = false;
018051e3
CB
1594 struct lxc_cmd_rr cmd = {
1595 .req = {
1596 .cmd = LXC_CMD_UNFREEZE,
1597 .data = INT_TO_PTR(timeout),
1598 },
1599 };
8a598112 1600 int ret;
018051e3
CB
1601
1602 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
1603 if (ret <= 0 || cmd.rsp.ret < 0)
3d0327ed 1604 return log_error_errno(-1, errno, "Failed to unfreeze container");
018051e3
CB
1605
1606 return cmd.rsp.ret;
1607}
1608
1609static int lxc_cmd_unfreeze_callback(int fd, struct lxc_cmd_req *req,
1610 struct lxc_handler *handler,
1611 struct lxc_epoll_descr *descr)
1612{
1613 int timeout = PTR_TO_INT(req->data);
1614 struct lxc_cmd_rsp rsp = {
6c6497ea 1615 .ret = -ENOENT,
018051e3
CB
1616 };
1617 struct cgroup_ops *ops = handler->cgroup_ops;
1618
1973b62a 1619 if (pure_unified_layout(ops))
018051e3
CB
1620 rsp.ret = ops->unfreeze(ops, timeout);
1621
4b5f4bdc 1622 return lxc_cmd_rsp_send_reap(fd, &rsp);
018051e3
CB
1623}
1624
c206ac24 1625int lxc_cmd_get_cgroup_fd(const char *name, const char *lxcpath,
abb6f657 1626 size_t size_ret_fd, struct cgroup_fd *ret_fd)
c206ac24 1627{
8a598112 1628 bool stopped = false;
c206ac24
CB
1629 struct lxc_cmd_rr cmd = {
1630 .req = {
1631 .cmd = LXC_CMD_GET_CGROUP_FD,
abb6f657
CB
1632 .datalen = sizeof(struct cgroup_fd),
1633 .data = ret_fd,
c206ac24
CB
1634 },
1635 .rsp = {
8a598112 1636 .ret = -ENOSYS,
c206ac24
CB
1637 },
1638 };
8a598112 1639 int ret;
c206ac24
CB
1640
1641 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
1642 if (ret < 0)
abb6f657 1643 return log_debug_errno(-1, errno, "Failed to process cgroup fd command");
c206ac24
CB
1644
1645 if (cmd.rsp.ret < 0)
abb6f657 1646 return log_debug_errno(-EBADF, errno, "Failed to receive cgroup fd");
c206ac24 1647
abb6f657 1648 return 0;
c206ac24
CB
1649}
1650
1651int lxc_cmd_get_limit_cgroup_fd(const char *name, const char *lxcpath,
abb6f657 1652 size_t size_ret_fd, struct cgroup_fd *ret_fd)
c206ac24 1653{
8a598112 1654 bool stopped = false;
c206ac24
CB
1655 struct lxc_cmd_rr cmd = {
1656 .req = {
1657 .cmd = LXC_CMD_GET_LIMIT_CGROUP_FD,
abb6f657
CB
1658 .datalen = sizeof(struct cgroup_fd),
1659 .data = ret_fd,
c206ac24
CB
1660 },
1661 .rsp = {
8a598112 1662 .ret = -ENOSYS,
c206ac24
CB
1663 },
1664 };
8a598112 1665 int ret;
c206ac24
CB
1666
1667 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
1668 if (ret < 0)
abb6f657 1669 return log_debug_errno(-1, errno, "Failed to process limit cgroup fd command");
c206ac24
CB
1670
1671 if (cmd.rsp.ret < 0)
abb6f657 1672 return log_debug_errno(-EBADF, errno, "Failed to receive limit cgroup fd");
c206ac24 1673
abb6f657 1674 return 0;
c206ac24
CB
1675}
1676
1677static int __lxc_cmd_get_cgroup_fd_callback(int fd, struct lxc_cmd_req *req,
1678 struct lxc_handler *handler,
1679 struct lxc_epoll_descr *descr,
abb6f657 1680 bool limit)
c206ac24
CB
1681{
1682 struct lxc_cmd_rsp rsp = {
1683 .ret = -EINVAL,
1684 };
1685 struct cgroup_ops *ops = handler->cgroup_ops;
abb6f657
CB
1686 struct cgroup_fd fd_server = {};
1687 int ret;
c206ac24 1688
abb6f657
CB
1689 ret = copy_struct_from_client(sizeof(struct cgroup_fd), &fd_server,
1690 req->datalen, req->data);
1691 if (ret < 0)
c206ac24
CB
1692 return lxc_cmd_rsp_send_reap(fd, &rsp);
1693
abb6f657
CB
1694 if (strnlen(fd_server.controller, MAX_CGROUP_ROOT_NAMELEN) == 0)
1695 return lxc_cmd_rsp_send_reap(fd, &rsp);
c206ac24 1696
abb6f657
CB
1697 ret = prepare_cgroup_fd(ops, &fd_server, limit);
1698 if (ret < 0) {
1699 rsp.ret = ret;
c206ac24
CB
1700 return lxc_cmd_rsp_send_reap(fd, &rsp);
1701 }
1702
1703 rsp.ret = 0;
abb6f657
CB
1704 rsp.data = &fd_server;
1705 rsp.datalen = min(sizeof(struct cgroup_fd), (size_t)req->datalen);
1706 return rsp_one_fd(fd, fd_server.fd, &rsp);
c206ac24
CB
1707}
1708
1709static int lxc_cmd_get_cgroup_fd_callback(int fd, struct lxc_cmd_req *req,
1710 struct lxc_handler *handler,
1711 struct lxc_epoll_descr *descr)
1712{
1713 return __lxc_cmd_get_cgroup_fd_callback(fd, req, handler, descr, false);
1714}
1715
1716static int lxc_cmd_get_limit_cgroup_fd_callback(int fd, struct lxc_cmd_req *req,
1717 struct lxc_handler *handler,
1718 struct lxc_epoll_descr *descr)
1719{
1720 return __lxc_cmd_get_cgroup_fd_callback(fd, req, handler, descr, true);
1721}
1722
bad788b0
CB
1723int lxc_cmd_get_cgroup2_fd(const char *name, const char *lxcpath)
1724{
8a598112 1725 bool stopped = false;
bad788b0
CB
1726 struct lxc_cmd_rr cmd = {
1727 .req = {
1728 .cmd = LXC_CMD_GET_CGROUP2_FD,
1729 },
d3be623e 1730 .rsp = {
8a598112 1731 .ret = -ENOSYS,
d3be623e 1732 },
bad788b0 1733 };
8a598112 1734 int ret;
bad788b0
CB
1735
1736 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
23a917e5
CB
1737 if (ret < 0)
1738 return -1;
1739
1740 if (cmd.rsp.ret < 0)
a5263e59 1741 return log_debug_errno(cmd.rsp.ret, -cmd.rsp.ret, "Failed to receive cgroup2 fd");
6f7f2966
CB
1742
1743 return PTR_TO_INT(cmd.rsp.data);
1744}
1745
a9b642ee 1746int lxc_cmd_get_limit_cgroup2_fd(const char *name, const char *lxcpath)
6f7f2966 1747{
8a598112 1748 bool stopped = false;
6f7f2966
CB
1749 struct lxc_cmd_rr cmd = {
1750 .req = {
a9b642ee 1751 .cmd = LXC_CMD_GET_LIMIT_CGROUP2_FD,
6f7f2966 1752 },
d3be623e
CB
1753 .rsp = {
1754 .ret = -ENOSYS,
1755 },
6f7f2966 1756 };
8a598112 1757 int ret;
6f7f2966
CB
1758
1759 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
1760 if (ret < 0)
1761 return -1;
1762
1763 if (cmd.rsp.ret < 0)
d3be623e 1764 return syswarn_set(cmd.rsp.ret, "Failed to receive cgroup2 limit fd");
bad788b0
CB
1765
1766 return PTR_TO_INT(cmd.rsp.data);
1767}
1768
a900cbaf
WB
1769static int lxc_cmd_get_cgroup2_fd_callback_do(int fd, struct lxc_cmd_req *req,
1770 struct lxc_handler *handler,
1771 struct lxc_epoll_descr *descr,
1772 bool limiting_cgroup)
bad788b0
CB
1773{
1774 struct lxc_cmd_rsp rsp = {
1775 .ret = -EINVAL,
1776 };
1777 struct cgroup_ops *ops = handler->cgroup_ops;
c2f40088 1778 int send_fd;
bad788b0 1779
1973b62a 1780 if (!pure_unified_layout(ops) || !ops->unified)
4b5f4bdc 1781 return lxc_cmd_rsp_send_reap(fd, &rsp);
bad788b0 1782
c0af7b1c 1783 send_fd = limiting_cgroup ? ops->unified->dfd_lim
e33870e5 1784 : ops->unified->dfd_con;
a900cbaf 1785
4b5f4bdc
CB
1786 if (send_fd < 0) {
1787 rsp.ret = -EBADF;
1788 return lxc_cmd_rsp_send_reap(fd, &rsp);
1789 }
1790
bad788b0 1791 rsp.ret = 0;
c2f40088 1792 return rsp_one_fd(fd, send_fd, &rsp);
bad788b0
CB
1793}
1794
a900cbaf
WB
1795static int lxc_cmd_get_cgroup2_fd_callback(int fd, struct lxc_cmd_req *req,
1796 struct lxc_handler *handler,
1797 struct lxc_epoll_descr *descr)
1798{
1799 return lxc_cmd_get_cgroup2_fd_callback_do(fd, req, handler, descr,
1800 false);
1801}
1802
a9b642ee
CB
1803static int lxc_cmd_get_limit_cgroup2_fd_callback(int fd, struct lxc_cmd_req *req,
1804 struct lxc_handler *handler,
1805 struct lxc_epoll_descr *descr)
a900cbaf
WB
1806{
1807 return lxc_cmd_get_cgroup2_fd_callback_do(fd, req, handler, descr,
1808 true);
1809}
1810
ebc548a1
CB
1811static int lxc_cmd_rsp_send_enosys(int fd, int id)
1812{
1813 struct lxc_cmd_rsp rsp = {
1814 .ret = -ENOSYS,
1815 };
1816
1817 __lxc_cmd_rsp_send(fd, &rsp);
1818 return syserrno_set(-ENOSYS, "Invalid command id %d", id);
1819}
1820
ef6e34ee 1821static int lxc_cmd_process(int fd, struct lxc_cmd_req *req,
cdb2a47f
CB
1822 struct lxc_handler *handler,
1823 struct lxc_epoll_descr *descr)
724e753c 1824{
cdb2a47f
CB
1825 typedef int (*callback)(int, struct lxc_cmd_req *, struct lxc_handler *,
1826 struct lxc_epoll_descr *);
ef6e34ee
DE
1827
1828 callback cb[LXC_CMD_MAX] = {
7e85a2c4 1829 [LXC_CMD_GET_TTY_FD] = lxc_cmd_get_tty_fd_callback,
2a63b5cb
CB
1830 [LXC_CMD_TERMINAL_WINCH] = lxc_cmd_terminal_winch_callback,
1831 [LXC_CMD_STOP] = lxc_cmd_stop_callback,
1832 [LXC_CMD_GET_STATE] = lxc_cmd_get_state_callback,
1833 [LXC_CMD_GET_INIT_PID] = lxc_cmd_get_init_pid_callback,
1834 [LXC_CMD_GET_CLONE_FLAGS] = lxc_cmd_get_clone_flags_callback,
1835 [LXC_CMD_GET_CGROUP] = lxc_cmd_get_cgroup_callback,
1836 [LXC_CMD_GET_CONFIG_ITEM] = lxc_cmd_get_config_item_callback,
1837 [LXC_CMD_GET_NAME] = lxc_cmd_get_name_callback,
1838 [LXC_CMD_GET_LXCPATH] = lxc_cmd_get_lxcpath_callback,
1839 [LXC_CMD_ADD_STATE_CLIENT] = lxc_cmd_add_state_client_callback,
1840 [LXC_CMD_CONSOLE_LOG] = lxc_cmd_console_log_callback,
1841 [LXC_CMD_SERVE_STATE_CLIENTS] = lxc_cmd_serve_state_clients_callback,
1842 [LXC_CMD_SECCOMP_NOTIFY_ADD_LISTENER] = lxc_cmd_seccomp_notify_add_listener_callback,
1843 [LXC_CMD_ADD_BPF_DEVICE_CGROUP] = lxc_cmd_add_bpf_device_cgroup_callback,
018051e3
CB
1844 [LXC_CMD_FREEZE] = lxc_cmd_freeze_callback,
1845 [LXC_CMD_UNFREEZE] = lxc_cmd_unfreeze_callback,
bad788b0 1846 [LXC_CMD_GET_CGROUP2_FD] = lxc_cmd_get_cgroup2_fd_callback,
746aab51 1847 [LXC_CMD_GET_INIT_PIDFD] = lxc_cmd_get_init_pidfd_callback,
a9b642ee
CB
1848 [LXC_CMD_GET_LIMIT_CGROUP] = lxc_cmd_get_limit_cgroup_callback,
1849 [LXC_CMD_GET_LIMIT_CGROUP2_FD] = lxc_cmd_get_limit_cgroup2_fd_callback,
f797f05e 1850 [LXC_CMD_GET_DEVPTS_FD] = lxc_cmd_get_devpts_fd_callback,
21405769 1851 [LXC_CMD_GET_SECCOMP_NOTIFY_FD] = lxc_cmd_get_seccomp_notify_fd_callback,
ef6e048a 1852 [LXC_CMD_GET_CGROUP_CTX] = lxc_cmd_get_cgroup_ctx_callback,
c206ac24
CB
1853 [LXC_CMD_GET_CGROUP_FD] = lxc_cmd_get_cgroup_fd_callback,
1854 [LXC_CMD_GET_LIMIT_CGROUP_FD] = lxc_cmd_get_limit_cgroup_fd_callback,
724e753c
MN
1855 };
1856
23a917e5 1857 if (req->cmd >= LXC_CMD_MAX)
ebc548a1 1858 return lxc_cmd_rsp_send_enosys(fd, req->cmd);
23a917e5 1859
cdb2a47f 1860 return cb[req->cmd](fd, req, handler, descr);
724e753c
MN
1861}
1862
ef6e34ee 1863static void lxc_cmd_fd_cleanup(int fd, struct lxc_handler *handler,
cdb2a47f 1864 struct lxc_epoll_descr *descr, const lxc_cmd_t cmd)
724e753c 1865{
3dfe6f8d 1866 lxc_terminal_free(handler->conf, fd);
724e753c 1867 lxc_mainloop_del_handler(descr, fd);
f6fc1565 1868
cd5369b0 1869 if (cmd == LXC_CMD_ADD_STATE_CLIENT) {
ab92468c
CB
1870 struct lxc_list *cur, *next;
1871
cdb2a47f
CB
1872 lxc_list_for_each_safe(cur, &handler->conf->state_clients, next) {
1873 struct lxc_state_client *client = cur->elem;
1874
1875 if (client->clientfd != fd)
1876 continue;
1877
ab92468c
CB
1878 /*
1879 * Only kick client from list so it can't be found
1880 * anymore. The actual close happens, as for all other
1881 * file descriptors, below.
1882 */
cdb2a47f 1883 lxc_list_del(cur);
cdb2a47f
CB
1884 free(cur->elem);
1885 free(cur);
ab92468c 1886
39e2a438
CB
1887 /*
1888 * No need to walk the whole list. If we found the state
cdb2a47f
CB
1889 * client fd there can't be a second one.
1890 */
ea2a070b 1891 TRACE("Found state client fd %d in state client list for command \"%s\"", fd, lxc_cmd_str(cmd));
ab92468c 1892 break;
cdb2a47f 1893 }
39e2a438
CB
1894
1895 /*
1896 * We didn't add the state client to the list. Either because
1897 * we failed to allocate memory (unlikely) or because the state
1898 * was already reached by the time we were ready to add it. So
1899 * fallthrough and clean it up.
1900 */
ea2a070b 1901 TRACE("Closing state client fd %d for command \"%s\"", fd, lxc_cmd_str(cmd));
f6fc1565 1902 }
cd5369b0 1903
ea2a070b 1904 TRACE("Closing client fd %d for command \"%s\"", fd, lxc_cmd_str(cmd));
cd5369b0 1905 close(fd);
724e753c
MN
1906}
1907
84c92abd
DE
1908static int lxc_cmd_handler(int fd, uint32_t events, void *data,
1909 struct lxc_epoll_descr *descr)
724e753c 1910{
5265a60c 1911 __do_free void *reqdata = NULL;
724e753c 1912 int ret;
ef6e34ee 1913 struct lxc_cmd_req req;
724e753c
MN
1914 struct lxc_handler *handler = data;
1915
aae93dd3 1916 ret = lxc_abstract_unix_rcv_credential(fd, &req, sizeof(req));
ded1d23f 1917 if (ret < 0) {
ea2a070b 1918 SYSERROR("Failed to receive data on command socket for command \"%s\"", lxc_cmd_str(req.cmd));
9044b79e 1919
1920 if (errno == EACCES) {
1921 /* We don't care for the peer, just send and close. */
ea2a070b 1922 struct lxc_cmd_rsp rsp = {
f7a97743 1923 .ret = -EPERM,
ea2a070b 1924 };
9044b79e 1925
4b5f4bdc 1926 __lxc_cmd_rsp_send(fd, &rsp);
9044b79e 1927 }
1928
724e753c
MN
1929 goto out_close;
1930 }
1931
fe84a562 1932 if (ret == 0)
724e753c 1933 goto out_close;
724e753c 1934
ef6e34ee 1935 if (ret != sizeof(req)) {
ea2a070b 1936 WARN("Failed to receive full command request. Ignoring request for \"%s\"", lxc_cmd_str(req.cmd));
ef6e34ee
DE
1937 goto out_close;
1938 }
1939
ea2a070b
CB
1940 if ((req.datalen > LXC_CMD_DATA_MAX) && (req.cmd != LXC_CMD_CONSOLE_LOG)) {
1941 ERROR("Received command data length %d is too large for command \"%s\"", req.datalen, lxc_cmd_str(req.cmd));
724e753c
MN
1942 goto out_close;
1943 }
1944
ef6e34ee 1945 if (req.datalen > 0) {
5265a60c 1946 reqdata = must_realloc(NULL, req.datalen);
e3233f26 1947 ret = lxc_recv_nointr(fd, reqdata, req.datalen, 0);
ef6e34ee 1948 if (ret != req.datalen) {
ea2a070b 1949 WARN("Failed to receive full command request. Ignoring request for \"%s\"", lxc_cmd_str(req.cmd));
ef6e34ee
DE
1950 goto out_close;
1951 }
fe84a562 1952
ef6e34ee
DE
1953 req.data = reqdata;
1954 }
1955
cdb2a47f 1956 ret = lxc_cmd_process(fd, &req, handler, descr);
32fd8d4f
CB
1957 if (ret < 0) {
1958 DEBUG("Failed to process command %s; cleaning up client fd %d", lxc_cmd_str(req.cmd), fd);
1959 goto out_close;
1960 } else if (ret == LXC_CMD_REAP_CLIENT_FD) {
1961 TRACE("Processed command %s; cleaning up client fd %d", lxc_cmd_str(req.cmd), fd);
724e753c 1962 goto out_close;
32fd8d4f
CB
1963 } else {
1964 TRACE("Processed command %s; keeping client fd %d", lxc_cmd_str(req.cmd), fd);
724e753c
MN
1965 }
1966
1967out:
f7a97743 1968 return LXC_MAINLOOP_CONTINUE;
fe84a562 1969
724e753c 1970out_close:
f6fc1565 1971 lxc_cmd_fd_cleanup(fd, handler, descr, req.cmd);
724e753c
MN
1972 goto out;
1973}
1974
84c92abd
DE
1975static int lxc_cmd_accept(int fd, uint32_t events, void *data,
1976 struct lxc_epoll_descr *descr)
724e753c 1977{
f62cf1d4 1978 __do_close int connection = -EBADF;
fe84a562 1979 int opt = 1, ret = -1;
724e753c
MN
1980
1981 connection = accept(fd, NULL, 0);
6c6497ea
CB
1982 if (connection < 0)
1983 return log_error_errno(LXC_MAINLOOP_ERROR, errno, "Failed to accept connection to run command");
724e753c 1984
fe84a562 1985 ret = fcntl(connection, F_SETFD, FD_CLOEXEC);
6c6497ea
CB
1986 if (ret < 0)
1987 return log_error_errno(ret, errno, "Failed to set close-on-exec on incoming command connection");
9ccb2dbc 1988
fe84a562 1989 ret = setsockopt(connection, SOL_SOCKET, SO_PASSCRED, &opt, sizeof(opt));
6c6497ea
CB
1990 if (ret < 0)
1991 return log_error_errno(ret, errno, "Failed to enable necessary credentials on command socket");
724e753c 1992
ef6e34ee 1993 ret = lxc_mainloop_add_handler(descr, connection, lxc_cmd_handler, data);
6c6497ea
CB
1994 if (ret)
1995 return log_error(ret, "Failed to add command handler");
724e753c 1996
ea2a070b 1997 TRACE("Accepted new client as fd %d on command server fd %d", connection, fd);
240fecd0 1998 move_fd(connection);
724e753c 1999 return ret;
724e753c
MN
2000}
2001
6834acff 2002int lxc_server_init(const char *name, const char *lxcpath, const char *suffix)
724e753c 2003{
f62cf1d4 2004 __do_close int fd = -EBADF;
c13e7111 2005 int ret;
b1234129 2006 char path[LXC_AUDS_ADDR_LEN] = {0};
724e753c 2007
5b46db1a 2008 ret = lxc_make_abstract_socket_name(path, sizeof(path), name, lxcpath, NULL, suffix);
fe84a562 2009 if (ret < 0)
9ba8130c 2010 return -1;
724e753c 2011
aae93dd3 2012 fd = lxc_abstract_unix_open(path, SOCK_STREAM, 0);
724e753c 2013 if (fd < 0) {
08aa08fe 2014 if (errno == EADDRINUSE)
fe84a562 2015 ERROR("Container \"%s\" appears to be already running", name);
6d1400b5 2016
6c6497ea 2017 return log_error_errno(-1, errno, "Failed to create command socket %s", &path[1]);
724e753c
MN
2018 }
2019
fe84a562 2020 ret = fcntl(fd, F_SETFD, FD_CLOEXEC);
6c6497ea
CB
2021 if (ret < 0)
2022 return log_error_errno(-1, errno, "Failed to set FD_CLOEXEC on command socket file descriptor");
91480a0f 2023
6c6497ea 2024 return log_trace(move_fd(fd), "Created abstract unix socket \"%s\"", &path[1]);
d2e30e99
DE
2025}
2026
fe84a562 2027int lxc_cmd_mainloop_add(const char *name, struct lxc_epoll_descr *descr,
ef6e34ee 2028 struct lxc_handler *handler)
d2e30e99 2029{
fe84a562 2030 int ret;
d2e30e99 2031
ea2a070b 2032 ret = lxc_mainloop_add_handler(descr, handler->conf->maincmd_fd, lxc_cmd_accept, handler);
6c6497ea 2033 if (ret < 0)
ea2a070b 2034 return log_error(ret, "Failed to add handler for command socket fd %d", handler->conf->maincmd_fd);
724e753c
MN
2035
2036 return ret;
2037}