]> git.proxmox.com Git - mirror_lxc.git/blame - src/lxc/commands.c
lxccontainer.h: document seccomp_notify_fd()
[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"
f2363e38 20#include "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] = {
2a63b5cb
CB
68 [LXC_CMD_CONSOLE] = "console",
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",
ef6e34ee 86 };
724e753c 87
f371aca9 88 if (cmd >= LXC_CMD_MAX)
a8007512 89 return "Invalid request";
fe84a562 90
ef6e34ee
DE
91 return cmdname[cmd];
92}
93
94/*
95 * lxc_cmd_rsp_recv: Receive a response to a command
96 *
97 * @sock : the socket connected to the container
98 * @cmd : command to put response in
99 *
100 * Returns the size of the response message or < 0 on failure
101 *
102 * Note that if the command response datalen > 0, then data is
103 * a malloc()ed buffer and should be free()ed by the caller. If
104 * the response data is <= a void * worth of data, it will be
105 * stored directly in data and datalen will be 0.
106 *
107 * As a special case, the response for LXC_CMD_CONSOLE is created
0115f8fd
DE
108 * here as it contains an fd for the master pty passed through the
109 * unix socket.
ef6e34ee
DE
110 */
111static int lxc_cmd_rsp_recv(int sock, struct lxc_cmd_rr *cmd)
112{
23a917e5
CB
113 __do_close_prot_errno int fd_rsp = -EBADF;
114 int ret;
ef6e34ee
DE
115 struct lxc_cmd_rsp *rsp = &cmd->rsp;
116
23a917e5
CB
117 ret = lxc_abstract_unix_recv_fds(sock, &fd_rsp, 1, rsp, sizeof(*rsp));
118 if (ret < 0)
119 return log_warn_errno(-1,
120 errno, "Failed to receive response for command \"%s\"",
121 lxc_cmd_str(cmd->req.cmd));
fe84a562 122 TRACE("Command \"%s\" received response", lxc_cmd_str(cmd->req.cmd));
ef6e34ee
DE
123
124 if (cmd->req.cmd == LXC_CMD_CONSOLE) {
125 struct lxc_cmd_console_rsp_data *rspdata;
126
0115f8fd
DE
127 /* recv() returns 0 bytes when a tty cannot be allocated,
128 * rsp->ret is < 0 when the peer permission check failed
129 */
130 if (ret == 0 || rsp->ret < 0)
131 return 0;
132
ef6e34ee 133 rspdata = malloc(sizeof(*rspdata));
23a917e5
CB
134 if (!rspdata)
135 return log_warn_errno(-1,
136 ENOMEM, "Failed to receive response for command \"%s\"",
137 lxc_cmd_str(cmd->req.cmd));
2a850b2c 138
23a917e5 139 rspdata->masterfd = move_fd(fd_rsp);
ef6e34ee
DE
140 rspdata->ttynum = PTR_TO_INT(rsp->data);
141 rsp->data = rspdata;
142 }
143
23a917e5
CB
144 if (cmd->req.cmd == LXC_CMD_GET_CGROUP2_FD) {
145 int cgroup2_fd = move_fd(fd_rsp);
146 rsp->data = INT_TO_PTR(cgroup2_fd);
860e7c43 147 }
fe84a562 148
23a917e5
CB
149 if (rsp->datalen == 0)
150 return log_debug(ret,
151 "Response data length for command \"%s\" is 0",
152 lxc_cmd_str(cmd->req.cmd));
153
191d43cc 154 if ((rsp->datalen > LXC_CMD_DATA_MAX) &&
23a917e5
CB
155 (cmd->req.cmd != LXC_CMD_CONSOLE_LOG))
156 return log_error(-1, "Response data for command \"%s\" is too long: %d bytes > %d",
157 lxc_cmd_str(cmd->req.cmd), rsp->datalen,
158 LXC_CMD_DATA_MAX);
ef6e34ee 159
191d43cc
CB
160 if (cmd->req.cmd == LXC_CMD_CONSOLE_LOG) {
161 rsp->data = malloc(rsp->datalen + 1);
162 ((char *)rsp->data)[rsp->datalen] = '\0';
163 } else {
164 rsp->data = malloc(rsp->datalen);
165 }
23a917e5
CB
166 if (!rsp->data)
167 return log_error_errno(-1,
168 ENOMEM, "Failed to allocate response buffer for command \"%s\"",
169 lxc_cmd_str(cmd->req.cmd));
fe84a562 170
2a850b2c 171 ret = lxc_recv_nointr(sock, rsp->data, rsp->datalen, 0);
23a917e5
CB
172 if (ret != rsp->datalen)
173 return log_error_errno(-1,
174 errno, "Failed to receive response data for command \"%s\"",
175 lxc_cmd_str(cmd->req.cmd));
724e753c
MN
176
177 return ret;
178}
179
ef6e34ee
DE
180/*
181 * lxc_cmd_rsp_send: Send a command response
182 *
183 * @fd : file descriptor of socket to send response on
184 * @rsp : response to send
185 *
186 * Returns 0 on success, < 0 on failure
187 */
188static int lxc_cmd_rsp_send(int fd, struct lxc_cmd_rsp *rsp)
189{
fe84a562 190 ssize_t ret;
ef6e34ee 191
7fbb15ec
CB
192 errno = EMSGSIZE;
193 ret = lxc_send_nointr(fd, rsp, sizeof(*rsp), MSG_NOSIGNAL);
6c6497ea
CB
194 if (ret < 0 || (size_t)ret != sizeof(*rsp))
195 return log_error_errno(-1, errno, "Failed to send command response %zd", ret);
ef6e34ee 196
a674dfe1 197 if (!rsp->data || rsp->datalen <= 0)
fe84a562
CB
198 return 0;
199
7fbb15ec
CB
200 errno = EMSGSIZE;
201 ret = lxc_send_nointr(fd, rsp->data, rsp->datalen, MSG_NOSIGNAL);
6c6497ea
CB
202 if (ret < 0 || ret != (ssize_t)rsp->datalen)
203 return log_warn_errno(-1, errno, "Failed to send command response data %zd", ret);
fe84a562 204
ef6e34ee
DE
205 return 0;
206}
207
c01c2be6 208static int lxc_cmd_send(const char *name, struct lxc_cmd_rr *cmd,
fe84a562 209 const char *lxcpath, const char *hashed_sock_name)
c01c2be6 210{
e96f9291 211 __do_close_prot_errno int client_fd = -EBADF;
fe84a562 212 ssize_t ret = -1;
c01c2be6 213
9dfa4041 214 client_fd = lxc_cmd_connect(name, lxcpath, hashed_sock_name, "command");
2a850b2c 215 if (client_fd < 0)
fe84a562 216 return -1;
c01c2be6 217
fe84a562
CB
218 ret = lxc_abstract_unix_send_credential(client_fd, &cmd->req,
219 sizeof(cmd->req));
2a850b2c 220 if (ret < 0 || (size_t)ret != sizeof(cmd->req))
e96f9291 221 return -1;
9044b79e 222
cdb2a47f
CB
223 if (cmd->req.cmd == LXC_CMD_SECCOMP_NOTIFY_ADD_LISTENER) {
224 int notify_fd = PTR_TO_INT(cmd->req.data);
225 ret = lxc_abstract_unix_send_fds(client_fd, &notify_fd, 1, NULL, 0);
226 if (ret <= 0)
227 return -1;
228 } else {
229 if (cmd->req.datalen <= 0)
230 return move_fd(client_fd);
c01c2be6 231
cdb2a47f
CB
232 errno = EMSGSIZE;
233 ret = lxc_send_nointr(client_fd, (void *)cmd->req.data,
234 cmd->req.datalen, MSG_NOSIGNAL);
235 if (ret < 0 || ret != (ssize_t)cmd->req.datalen)
236 return -1;
237 }
c01c2be6 238
240fecd0 239 return move_fd(client_fd);
c01c2be6
CB
240}
241
ef6e34ee
DE
242/*
243 * lxc_cmd: Connect to the specified running container, send it a command
244 * request and collect the response
245 *
246 * @name : name of container to connect to
1e8cfdf6 247 * @cmd : command with initialized request to send
ef6e34ee
DE
248 * @stopped : output indicator if the container was not running
249 * @lxcpath : the lxcpath in which the container is running
250 *
251 * Returns the size of the response message on success, < 0 on failure
252 *
253 * Note that there is a special case for LXC_CMD_CONSOLE. For this command
254 * the fd cannot be closed because it is used as a placeholder to indicate
255 * that a particular tty slot is in use. The fd is also used as a signal to
256 * the container that when the caller dies or closes the fd, the container
0115f8fd
DE
257 * will notice the fd on its side of the socket in its mainloop select and
258 * then free the slot with lxc_cmd_fd_cleanup(). The socket fd will be
259 * returned in the cmd response structure.
ef6e34ee
DE
260 */
261static int lxc_cmd(const char *name, struct lxc_cmd_rr *cmd, int *stopped,
88556fd7 262 const char *lxcpath, const char *hashed_sock_name)
724e753c 263{
c34ff119 264 __do_close_prot_errno int client_fd = -EBADF;
fe84a562 265 int ret = -1;
dbc9832d
CB
266 bool stay_connected = false;
267
268 if (cmd->req.cmd == LXC_CMD_CONSOLE ||
54446942 269 cmd->req.cmd == LXC_CMD_ADD_STATE_CLIENT)
dbc9832d 270 stay_connected = true;
724e753c 271
0ecf64b5
SH
272 *stopped = 0;
273
c01c2be6
CB
274 client_fd = lxc_cmd_send(name, cmd, lxcpath, hashed_sock_name);
275 if (client_fd < 0) {
00e5ca13 276 if (errno == ECONNREFUSED || errno == EPIPE)
ef6e34ee 277 *stopped = 1;
3f903c04 278
6c6497ea
CB
279 return log_trace_errno(-1, errno, "Command \"%s\" failed to connect command socket",
280 lxc_cmd_str(cmd->req.cmd));
724e753c
MN
281 }
282
c01c2be6 283 ret = lxc_cmd_rsp_recv(client_fd, cmd);
2a850b2c 284 if (ret < 0 && errno == ECONNRESET)
6b7f85cb 285 *stopped = 1;
6a93ae77 286
ea2a070b
CB
287 TRACE("Opened new command socket connection fd %d for command \"%s\"",
288 client_fd, lxc_cmd_str(cmd->req.cmd));
289
c34ff119 290 if (stay_connected && ret > 0)
240fecd0 291 cmd->rsp.ret = move_fd(client_fd);
43eb6f29 292
1362f2eb 293 return ret;
724e753c
MN
294}
295
b494d2dd
SH
296int lxc_try_cmd(const char *name, const char *lxcpath)
297{
0ecf64b5 298 int stopped, ret;
b494d2dd
SH
299 struct lxc_cmd_rr cmd = {
300 .req = { .cmd = LXC_CMD_GET_INIT_PID },
301 };
302
88556fd7 303 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
b494d2dd
SH
304 if (stopped)
305 return 0;
306 if (ret > 0 && cmd.rsp.ret < 0) {
307 errno = cmd.rsp.ret;
308 return -1;
309 }
310 if (ret > 0)
311 return 0;
312
fe84a562
CB
313 /* At this point we weren't denied access, and the container *was*
314 * started. There was some inexplicable error in the protocol. I'm not
315 * clear on whether we should return -1 here, but we didn't receive a
316 * -EACCES, so technically it's not that we're not allowed to control
317 * the container - it's just not behaving.
b494d2dd
SH
318 */
319 return 0;
320}
321
cc4c0832 322/* Implementations of the commands and their callbacks */
ef6e34ee
DE
323
324/*
325 * lxc_cmd_get_init_pid: Get pid of the container's init process
326 *
327 * @name : name of container to connect to
328 * @lxcpath : the lxcpath in which the container is running
329 *
330 * Returns the pid on success, < 0 on failure
331 */
332pid_t lxc_cmd_get_init_pid(const char *name, const char *lxcpath)
43eb6f29 333{
0ecf64b5 334 int ret, stopped;
565eb353 335 pid_t pid = -1;
ef6e34ee 336 struct lxc_cmd_rr cmd = {
e8cd1208
CB
337 .req = {
338 .cmd = LXC_CMD_GET_INIT_PID
339 },
340 .rsp = {
565eb353 341 .data = PID_TO_PTR(pid)
e8cd1208 342 }
ef6e34ee
DE
343 };
344
88556fd7 345 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
ef6e34ee 346 if (ret < 0)
8ed8a626 347 return -1;
ef6e34ee 348
565eb353 349 pid = PTR_TO_PID(cmd.rsp.data);
9234406b
CB
350 if (pid < 0)
351 return -1;
352
353 /* We need to assume that pid_t can actually hold any pid given to us
354 * by the kernel. If it can't it's a libc bug.
355 */
356 return (pid_t)pid;
43eb6f29
DL
357}
358
ef6e34ee 359static int lxc_cmd_get_init_pid_callback(int fd, struct lxc_cmd_req *req,
cdb2a47f
CB
360 struct lxc_handler *handler,
361 struct lxc_epoll_descr *descr)
43eb6f29 362{
ea2a070b 363 int ret;
9234406b 364 struct lxc_cmd_rsp rsp = {
565eb353 365 .data = PID_TO_PTR(handler->pid)
9234406b 366 };
ef6e34ee 367
ea2a070b
CB
368 ret = lxc_cmd_rsp_send(fd, &rsp);
369 if (ret < 0)
370 return LXC_CMD_REAP_CLIENT_FD;
371
372 return 0;
43eb6f29
DL
373}
374
ef6e34ee
DE
375/*
376 * lxc_cmd_get_clone_flags: Get clone flags container was spawned with
377 *
378 * @name : name of container to connect to
379 * @lxcpath : the lxcpath in which the container is running
380 *
381 * Returns the clone flags on success, < 0 on failure
382 */
383int lxc_cmd_get_clone_flags(const char *name, const char *lxcpath)
384{
0ecf64b5 385 int ret, stopped;
ef6e34ee 386 struct lxc_cmd_rr cmd = {
6c6497ea
CB
387 .req = {
388 .cmd = LXC_CMD_GET_CLONE_FLAGS,
389 },
ef6e34ee
DE
390 };
391
88556fd7 392 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
ef6e34ee
DE
393 if (ret < 0)
394 return ret;
43eb6f29 395
ef6e34ee
DE
396 return PTR_TO_INT(cmd.rsp.data);
397}
398
399static int lxc_cmd_get_clone_flags_callback(int fd, struct lxc_cmd_req *req,
cdb2a47f
CB
400 struct lxc_handler *handler,
401 struct lxc_epoll_descr *descr)
26b2d152 402{
ea2a070b 403 int ret;
6c6497ea
CB
404 struct lxc_cmd_rsp rsp = {
405 .data = INT_TO_PTR(handler->ns_clone_flags),
406 };
ef6e34ee 407
ea2a070b
CB
408 ret = lxc_cmd_rsp_send(fd, &rsp);
409 if (ret < 0)
410 return LXC_CMD_REAP_CLIENT_FD;
411
412 return 0;
ef6e34ee
DE
413}
414
415/*
416 * lxc_cmd_get_cgroup_path: Calculate a container's cgroup path for a
417 * particular subsystem. This is the cgroup path relative to the root
418 * of the cgroup filesystem.
419 *
ef6e34ee
DE
420 * @name : name of container to connect to
421 * @lxcpath : the lxcpath in which the container is running
b98f7d6e 422 * @subsystem : the subsystem being asked about
ef6e34ee
DE
423 *
424 * Returns the path on success, NULL on failure. The caller must free() the
425 * returned path.
426 */
b98f7d6e 427char *lxc_cmd_get_cgroup_path(const char *name, const char *lxcpath,
fe84a562 428 const char *subsystem)
ef6e34ee 429{
0ecf64b5 430 int ret, stopped;
ef6e34ee 431 struct lxc_cmd_rr cmd = {
b98f7d6e
SH
432 .req = {
433 .cmd = LXC_CMD_GET_CGROUP,
b98f7d6e 434 .data = subsystem,
c2aed66d 435 .datalen = 0,
b98f7d6e 436 },
26b2d152
MN
437 };
438
c2aed66d
CB
439 cmd.req.data = subsystem;
440 cmd.req.datalen = 0;
441 if (subsystem)
442 cmd.req.datalen = strlen(subsystem) + 1;
443
88556fd7 444 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
fe84a562 445 if (ret < 0)
ef6e34ee
DE
446 return NULL;
447
fe84a562 448 if (ret == 0)
ef6e34ee 449 return NULL;
ef6e34ee 450
fe84a562 451 if (cmd.rsp.ret < 0 || cmd.rsp.datalen < 0)
ef6e34ee 452 return NULL;
3f903c04 453
ef6e34ee
DE
454 return cmd.rsp.data;
455}
456
457static int lxc_cmd_get_cgroup_callback(int fd, struct lxc_cmd_req *req,
cdb2a47f
CB
458 struct lxc_handler *handler,
459 struct lxc_epoll_descr *descr)
ef6e34ee 460{
ea2a070b 461 int ret;
4fb3cba5 462 const char *path;
fe84a562 463 struct lxc_cmd_rsp rsp;
2202afc9 464 struct cgroup_ops *cgroup_ops = handler->cgroup_ops;
b98f7d6e 465
c2aed66d 466 if (req->datalen > 0)
2202afc9 467 path = cgroup_ops->get_cgroup(cgroup_ops, req->data);
c2aed66d 468 else
2202afc9 469 path = cgroup_ops->get_cgroup(cgroup_ops, NULL);
b98f7d6e
SH
470 if (!path)
471 return -1;
fe84a562 472
4f17323e 473 rsp.ret = 0;
fe84a562
CB
474 rsp.datalen = strlen(path) + 1;
475 rsp.data = (char *)path;
ef6e34ee 476
ea2a070b
CB
477 ret = lxc_cmd_rsp_send(fd, &rsp);
478 if (ret < 0)
479 return LXC_CMD_REAP_CLIENT_FD;
480
481 return 0;
ef6e34ee
DE
482}
483
484/*
485 * lxc_cmd_get_config_item: Get config item the running container
486 *
487 * @name : name of container to connect to
7fa3f2e9 488 * @item : the configuration item to retrieve (ex: lxc.net.0.veth.pair)
ef6e34ee
DE
489 * @lxcpath : the lxcpath in which the container is running
490 *
491 * Returns the item on success, NULL on failure. The caller must free() the
492 * returned item.
493 */
494char *lxc_cmd_get_config_item(const char *name, const char *item,
495 const char *lxcpath)
496{
0ecf64b5 497 int ret, stopped;
ef6e34ee
DE
498 struct lxc_cmd_rr cmd = {
499 .req = { .cmd = LXC_CMD_GET_CONFIG_ITEM,
500 .data = item,
fe84a562 501 .datalen = strlen(item) + 1,
ef6e34ee
DE
502 },
503 };
504
88556fd7 505 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
ef6e34ee
DE
506 if (ret < 0)
507 return NULL;
508
509 if (cmd.rsp.ret == 0)
510 return cmd.rsp.data;
fe84a562 511
ef6e34ee
DE
512 return NULL;
513}
514
515static int lxc_cmd_get_config_item_callback(int fd, struct lxc_cmd_req *req,
cdb2a47f
CB
516 struct lxc_handler *handler,
517 struct lxc_epoll_descr *descr)
ef6e34ee 518{
5265a60c 519 __do_free char *cidata = NULL;
ef6e34ee 520 int cilen;
30aec088 521 struct lxc_config_t *item;
fe84a562 522 struct lxc_cmd_rsp rsp;
ef6e34ee
DE
523
524 memset(&rsp, 0, sizeof(rsp));
300df83e 525 item = lxc_get_config(req->data);
30aec088
CB
526 if (!item)
527 goto err1;
fe84a562 528
cccd2219 529 cilen = item->get(req->data, NULL, 0, handler->conf, NULL);
ef6e34ee
DE
530 if (cilen <= 0)
531 goto err1;
532
5265a60c 533 cidata = must_realloc(NULL, cilen + 1);
cccd2219 534 if (item->get(req->data, cidata, cilen + 1, handler->conf, NULL) != cilen)
ef6e34ee 535 goto err1;
fe84a562 536
ef6e34ee
DE
537 cidata[cilen] = '\0';
538 rsp.data = cidata;
539 rsp.datalen = cilen + 1;
540 rsp.ret = 0;
541 goto out;
542
543err1:
544 rsp.ret = -1;
545out:
ea2a070b
CB
546 cilen = lxc_cmd_rsp_send(fd, &rsp);
547 if (cilen < 0)
548 return LXC_CMD_REAP_CLIENT_FD;
549
550 return 0;
ef6e34ee
DE
551}
552
553/*
554 * lxc_cmd_get_state: Get current state of the container
555 *
556 * @name : name of container to connect to
557 * @lxcpath : the lxcpath in which the container is running
558 *
559 * Returns the state on success, < 0 on failure
560 */
dbc9832d 561int lxc_cmd_get_state(const char *name, const char *lxcpath)
ef6e34ee 562{
0ecf64b5 563 int ret, stopped;
ef6e34ee 564 struct lxc_cmd_rr cmd = {
6c6497ea
CB
565 .req = {
566 .cmd = LXC_CMD_GET_STATE,
567 },
ef6e34ee 568 };
26b2d152 569
88556fd7 570 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
ebdd307d 571 if (ret < 0 && stopped)
ef6e34ee
DE
572 return STOPPED;
573
574 if (ret < 0)
26b2d152 575 return -1;
26b2d152 576
6c6497ea
CB
577 if (!ret)
578 return log_warn(-1, "Container \"%s\" has stopped before sending its state", name);
fe84a562 579
6c6497ea
CB
580 return log_debug(PTR_TO_INT(cmd.rsp.data),
581 "Container \"%s\" is in \"%s\" state", name,
582 lxc_state2str(PTR_TO_INT(cmd.rsp.data)));
ef6e34ee
DE
583}
584
585static int lxc_cmd_get_state_callback(int fd, struct lxc_cmd_req *req,
cdb2a47f
CB
586 struct lxc_handler *handler,
587 struct lxc_epoll_descr *descr)
ef6e34ee 588{
ea2a070b 589 int ret;
6c6497ea
CB
590 struct lxc_cmd_rsp rsp = {
591 .data = INT_TO_PTR(handler->state),
592 };
ef6e34ee 593
ea2a070b
CB
594 ret = lxc_cmd_rsp_send(fd, &rsp);
595 if (ret < 0)
596 return LXC_CMD_REAP_CLIENT_FD;
597
598 return 0;
ef6e34ee
DE
599}
600
601/*
602 * lxc_cmd_stop: Stop the container previously started with lxc_start. All
603 * the processes running inside this container will be killed.
604 *
605 * @name : name of container to connect to
606 * @lxcpath : the lxcpath in which the container is running
607 *
608 * Returns 0 on success, < 0 on failure
609 */
610int lxc_cmd_stop(const char *name, const char *lxcpath)
611{
0ecf64b5 612 int ret, stopped;
ef6e34ee 613 struct lxc_cmd_rr cmd = {
6c6497ea
CB
614 .req = {
615 .cmd = LXC_CMD_STOP,
616 },
ef6e34ee
DE
617 };
618
88556fd7 619 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
26b2d152 620 if (ret < 0) {
6c6497ea
CB
621 if (stopped)
622 return log_info(0, "Container \"%s\" is already stopped", name);
fe84a562 623
26b2d152
MN
624 return -1;
625 }
626
fe84a562
CB
627 /* We do not expect any answer, because we wait for the connection to be
628 * closed.
95d5b147 629 */
6c6497ea
CB
630 if (ret > 0)
631 return log_error_errno(-1, -cmd.rsp.ret, "Failed to stop container \"%s\"", name);
26b2d152 632
6c6497ea 633 return log_info(0, "Container \"%s\" has stopped", name);
26b2d152
MN
634}
635
ef6e34ee 636static int lxc_cmd_stop_callback(int fd, struct lxc_cmd_req *req,
cdb2a47f
CB
637 struct lxc_handler *handler,
638 struct lxc_epoll_descr *descr)
d5088cf2 639{
ef6e34ee 640 struct lxc_cmd_rsp rsp;
ef6e34ee 641 int stopsignal = SIGKILL;
2202afc9 642 struct cgroup_ops *cgroup_ops = handler->cgroup_ops;
ea2a070b 643 int ret;
ef6e34ee
DE
644
645 if (handler->conf->stopsignal)
646 stopsignal = handler->conf->stopsignal;
647 memset(&rsp, 0, sizeof(rsp));
648 rsp.ret = kill(handler->pid, stopsignal);
649 if (!rsp.ret) {
018051e3
CB
650 rsp.ret = cgroup_ops->unfreeze(cgroup_ops, -1);
651 if (!rsp.ret)
95d5b147 652 return 0;
fe84a562
CB
653
654 ERROR("Failed to unfreeze container \"%s\"", handler->name);
018051e3
CB
655 rsp.ret = -errno;
656 } else {
657 rsp.ret = -errno;
ef6e34ee
DE
658 }
659
ea2a070b
CB
660 ret = lxc_cmd_rsp_send(fd, &rsp);
661 if (ret < 0)
662 return LXC_CMD_REAP_CLIENT_FD;
663
664 return 0;
ef6e34ee 665}
d5088cf2 666
b5159817 667/*
2bd158cc 668 * lxc_cmd_terminal_winch: noop
b5159817
DE
669 *
670 * @name : name of container to connect to
671 * @lxcpath : the lxcpath in which the container is running
672 *
673 * Returns 0 on success, < 0 on failure
674 */
8ccbbf94 675int lxc_cmd_terminal_winch(const char *name, const char *lxcpath)
b5159817 676{
b5159817
DE
677 return 0;
678}
679
8ccbbf94 680static int lxc_cmd_terminal_winch_callback(int fd, struct lxc_cmd_req *req,
cdb2a47f
CB
681 struct lxc_handler *handler,
682 struct lxc_epoll_descr *descr)
b5159817 683{
2bd158cc 684 /* should never be called */
6c6497ea 685 return log_error_errno(-1, ENOSYS, "Called lxc_cmd_terminal_winch_callback()");
b5159817
DE
686}
687
ef6e34ee
DE
688/*
689 * lxc_cmd_console: Open an fd to a tty in the container
690 *
691 * @name : name of container to connect to
692 * @ttynum : in: the tty to open or -1 for next available
693 * : out: the tty allocated
694 * @fd : out: file descriptor for master side of pty
695 * @lxcpath : the lxcpath in which the container is running
696 *
0115f8fd 697 * Returns fd holding tty allocated on success, < 0 on failure
ef6e34ee
DE
698 */
699int lxc_cmd_console(const char *name, int *ttynum, int *fd, const char *lxcpath)
700{
8259d86d 701 __do_free struct lxc_cmd_console_rsp_data *rspdata = NULL;
0ecf64b5 702 int ret, stopped;
ef6e34ee 703 struct lxc_cmd_rr cmd = {
6c6497ea
CB
704 .req = {
705 .cmd = LXC_CMD_CONSOLE,
706 .data = INT_TO_PTR(*ttynum),
707 },
ef6e34ee 708 };
d5088cf2 709
88556fd7 710 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
ef6e34ee
DE
711 if (ret < 0)
712 return ret;
0115f8fd 713
8259d86d 714 rspdata = cmd.rsp.data;
6c6497ea
CB
715 if (cmd.rsp.ret < 0)
716 return log_error_errno(-1, -cmd.rsp.ret, "Denied access to tty");
d5088cf2 717
6c6497ea
CB
718 if (ret == 0)
719 return log_error(-1, "tty number %d invalid, busy or all ttys busy", *ttynum);
ef6e34ee 720
6c6497ea
CB
721 if (rspdata->masterfd < 0)
722 return log_error(-1, "Unable to allocate fd for tty %d", rspdata->ttynum);
ef6e34ee 723
fe84a562 724 ret = cmd.rsp.ret; /* socket fd */
0115f8fd 725 *fd = rspdata->masterfd;
ef6e34ee 726 *ttynum = rspdata->ttynum;
fe84a562 727
6c6497ea 728 return log_info(ret, "Alloced fd %d for tty %d via socket %d", *fd, rspdata->ttynum, ret);
ef6e34ee
DE
729}
730
731static int lxc_cmd_console_callback(int fd, struct lxc_cmd_req *req,
cdb2a47f
CB
732 struct lxc_handler *handler,
733 struct lxc_epoll_descr *descr)
ef6e34ee 734{
fe84a562 735 int masterfd, ret;
ef6e34ee 736 struct lxc_cmd_rsp rsp;
fe84a562 737 int ttynum = PTR_TO_INT(req->data);
ef6e34ee 738
c1ee47cd 739 masterfd = lxc_terminal_allocate(handler->conf, fd, &ttynum);
b5159817 740 if (masterfd < 0)
ea2a070b 741 return LXC_CMD_REAP_CLIENT_FD;
ef6e34ee 742
ef6e34ee
DE
743 memset(&rsp, 0, sizeof(rsp));
744 rsp.data = INT_TO_PTR(ttynum);
fe84a562
CB
745 ret = lxc_abstract_unix_send_fds(fd, &masterfd, 1, &rsp, sizeof(rsp));
746 if (ret < 0) {
3dfe6f8d 747 lxc_terminal_free(handler->conf, fd);
ea2a070b
CB
748 return log_error_errno(LXC_CMD_REAP_CLIENT_FD, errno,
749 "Failed to send tty to client");
ef6e34ee
DE
750 }
751
ef6e34ee 752 return 0;
d5088cf2
CS
753}
754
88556fd7
ÇO
755/*
756 * lxc_cmd_get_name: Returns the name of the container
757 *
758 * @hashed_sock_name: hashed socket name
759 *
760 * Returns the name on success, NULL on failure.
761 */
762char *lxc_cmd_get_name(const char *hashed_sock_name)
763{
764 int ret, stopped;
765 struct lxc_cmd_rr cmd = {
6c6497ea
CB
766 .req = {
767 .cmd = LXC_CMD_GET_NAME,
768 },
88556fd7
ÇO
769 };
770
771 ret = lxc_cmd(NULL, &cmd, &stopped, NULL, hashed_sock_name);
fe84a562 772 if (ret < 0)
88556fd7 773 return NULL;
88556fd7
ÇO
774
775 if (cmd.rsp.ret == 0)
776 return cmd.rsp.data;
fe84a562 777
88556fd7
ÇO
778 return NULL;
779}
780
781static int lxc_cmd_get_name_callback(int fd, struct lxc_cmd_req *req,
cdb2a47f
CB
782 struct lxc_handler *handler,
783 struct lxc_epoll_descr *descr)
88556fd7 784{
ea2a070b 785 int ret;
88556fd7
ÇO
786 struct lxc_cmd_rsp rsp;
787
788 memset(&rsp, 0, sizeof(rsp));
789
f0ecc19d 790 rsp.data = (char *)handler->name;
88556fd7
ÇO
791 rsp.datalen = strlen(handler->name) + 1;
792 rsp.ret = 0;
793
ea2a070b
CB
794 ret = lxc_cmd_rsp_send(fd, &rsp);
795 if (ret < 0)
796 return LXC_CMD_REAP_CLIENT_FD;
797
798 return 0;
88556fd7
ÇO
799}
800
801/*
802 * lxc_cmd_get_lxcpath: Returns the lxcpath of the container
803 *
804 * @hashed_sock_name: hashed socket name
805 *
806 * Returns the lxcpath on success, NULL on failure.
807 */
808char *lxc_cmd_get_lxcpath(const char *hashed_sock_name)
809{
810 int ret, stopped;
811 struct lxc_cmd_rr cmd = {
6c6497ea
CB
812 .req = {
813 .cmd = LXC_CMD_GET_LXCPATH,
814 },
88556fd7 815 };
724e753c 816
88556fd7 817 ret = lxc_cmd(NULL, &cmd, &stopped, NULL, hashed_sock_name);
fe84a562 818 if (ret < 0)
88556fd7 819 return NULL;
88556fd7
ÇO
820
821 if (cmd.rsp.ret == 0)
822 return cmd.rsp.data;
fe84a562 823
88556fd7
ÇO
824 return NULL;
825}
826
827static int lxc_cmd_get_lxcpath_callback(int fd, struct lxc_cmd_req *req,
cdb2a47f
CB
828 struct lxc_handler *handler,
829 struct lxc_epoll_descr *descr)
88556fd7 830{
ea2a070b 831 int ret;
6c6497ea
CB
832 struct lxc_cmd_rsp rsp = {
833 .ret = 0,
834 .data = (char *)handler->lxcpath,
835 .datalen = strlen(handler->lxcpath) + 1,
836 };
88556fd7 837
ea2a070b
CB
838 ret = lxc_cmd_rsp_send(fd, &rsp);
839 if (ret < 0)
840 return LXC_CMD_REAP_CLIENT_FD;
841
842 return 0;
88556fd7 843}
ef6e34ee 844
54446942 845int lxc_cmd_add_state_client(const char *name, const char *lxcpath,
92e35018
CB
846 lxc_state_t states[MAX_STATE],
847 int *state_client_fd)
dbc9832d 848{
cd889e57 849 __do_close_prot_errno int clientfd = -EBADF;
bc631984 850 int state, stopped;
dbc9832d 851 ssize_t ret;
dbc9832d 852 struct lxc_cmd_rr cmd = {
6c6497ea
CB
853 .req = {
854 .cmd = LXC_CMD_ADD_STATE_CLIENT,
855 .data = states,
856 .datalen = (sizeof(lxc_state_t) * MAX_STATE)
857 },
dbc9832d
CB
858 };
859
dbc9832d 860 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
bc631984
CB
861 if (states[STOPPED] != 0 && stopped != 0)
862 return STOPPED;
863
dbc9832d 864 if (ret < 0) {
f577e061 865 if (errno != ECONNREFUSED)
6d1400b5 866 SYSERROR("Failed to execute command");
867
dbc9832d
CB
868 return -1;
869 }
fe84a562 870
dbc9832d
CB
871 /* We should now be guaranteed to get an answer from the state sending
872 * function.
873 */
cd889e57 874 clientfd = cmd.rsp.ret;
6c6497ea
CB
875 if (clientfd < 0)
876 return log_error_errno(-1, -clientfd, "Failed to receive socket fd");
dbc9832d 877
bc631984 878 state = PTR_TO_INT(cmd.rsp.data);
6c6497ea
CB
879 if (state < MAX_STATE)
880 return log_trace(state, "Container is already in requested state %s", lxc_state2str(state));
bc631984 881
240fecd0 882 *state_client_fd = move_fd(clientfd);
ea2a070b
CB
883 TRACE("State connection fd %d ready to listen for container state changes", *state_client_fd);
884 return MAX_STATE;
dbc9832d
CB
885}
886
ebbca852 887static int lxc_cmd_add_state_client_callback(__owns int fd, struct lxc_cmd_req *req,
cdb2a47f
CB
888 struct lxc_handler *handler,
889 struct lxc_epoll_descr *descr)
dbc9832d 890{
44552fb2 891 int ret;
dbc9832d 892 struct lxc_cmd_rsp rsp = {0};
dbc9832d 893
fe84a562 894 if (req->datalen < 0)
ea2a070b 895 return LXC_CMD_REAP_CLIENT_FD;
dbc9832d 896
71fc9c04 897 if (req->datalen != (sizeof(lxc_state_t) * MAX_STATE))
ea2a070b 898 return LXC_CMD_REAP_CLIENT_FD;
dbc9832d 899
fe84a562 900 if (!req->data)
ea2a070b 901 return LXC_CMD_REAP_CLIENT_FD;
dbc9832d 902
c01c2be6 903 rsp.ret = lxc_add_state_client(fd, handler, (lxc_state_t *)req->data);
44552fb2 904 if (rsp.ret < 0)
ea2a070b 905 return LXC_CMD_REAP_CLIENT_FD;
44552fb2 906
bc631984 907 rsp.data = INT_TO_PTR(rsp.ret);
dbc9832d 908
44552fb2
CB
909 ret = lxc_cmd_rsp_send(fd, &rsp);
910 if (ret < 0)
ea2a070b 911 return LXC_CMD_REAP_CLIENT_FD;
44552fb2
CB
912
913 return 0;
dbc9832d
CB
914}
915
2a63b5cb
CB
916int lxc_cmd_add_bpf_device_cgroup(const char *name, const char *lxcpath,
917 struct device_item *device)
918{
919#ifdef HAVE_STRUCT_BPF_CGROUP_DEV_CTX
920 int stopped = 0;
921 struct lxc_cmd_rr cmd = {
6c6497ea
CB
922 .req = {
923 .cmd = LXC_CMD_ADD_BPF_DEVICE_CGROUP,
924 .data = device,
925 .datalen = sizeof(struct device_item),
926 },
2a63b5cb
CB
927 };
928 int ret;
929
930 if (strlen(device->access) > STRLITERALLEN("rwm"))
3d0327ed 931 return log_error_errno(-1, EINVAL, "Invalid access mode specified %s",
2a63b5cb
CB
932 device->access);
933
934 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
935 if (ret < 0 || cmd.rsp.ret < 0)
3d0327ed 936 return log_error_errno(-1, errno, "Failed to add new bpf device cgroup rule");
2a63b5cb
CB
937
938 return 0;
939#else
3d0327ed 940 return ret_set_errno(-1, ENOSYS);
2a63b5cb
CB
941#endif
942}
943
944static int lxc_cmd_add_bpf_device_cgroup_callback(int fd, struct lxc_cmd_req *req,
945 struct lxc_handler *handler,
946 struct lxc_epoll_descr *descr)
947{
948#ifdef HAVE_STRUCT_BPF_CGROUP_DEV_CTX
949 __do_bpf_program_free struct bpf_program *devices = NULL;
950 struct lxc_cmd_rsp rsp = {0};
951 struct lxc_conf *conf = handler->conf;
952 struct hierarchy *unified = handler->cgroup_ops->unified;
2a63b5cb
CB
953 int ret;
954 struct lxc_list *it;
955 struct device_item *device;
956 struct bpf_program *devices_old;
957
958 if (req->datalen <= 0)
ea2a070b 959 return LXC_CMD_REAP_CLIENT_FD;
2a63b5cb
CB
960
961 if (req->datalen != sizeof(struct device_item))
ea2a070b 962 return LXC_CMD_REAP_CLIENT_FD;
2a63b5cb
CB
963
964 if (!req->data)
ea2a070b 965 return LXC_CMD_REAP_CLIENT_FD;
2a63b5cb
CB
966 device = (struct device_item *)req->data;
967
968 rsp.ret = -1;
969 if (!unified)
970 goto respond;
971
972 ret = bpf_list_add_device(conf, device);
973 if (ret < 0)
974 goto respond;
975
976 devices = bpf_program_new(BPF_PROG_TYPE_CGROUP_DEVICE);
977 if (!devices)
978 goto respond;
979
980 ret = bpf_program_init(devices);
981 if (ret)
982 goto respond;
983
984 lxc_list_for_each(it, &conf->devices) {
985 struct device_item *cur = it->elem;
986
987 ret = bpf_program_append_device(devices, cur);
988 if (ret)
989 goto respond;
990 }
991
992 ret = bpf_program_finalize(devices);
993 if (ret)
994 goto respond;
995
996 ret = bpf_program_cgroup_attach(devices, BPF_CGROUP_DEVICE,
997 unified->container_full_path,
998 BPF_F_ALLOW_MULTI);
999 if (ret)
1000 goto respond;
1001
1002 /* Replace old bpf program. */
1003 devices_old = move_ptr(conf->cgroup2_devices);
1004 conf->cgroup2_devices = move_ptr(devices);
1005 devices = move_ptr(devices_old);
1006
1007 rsp.ret = 0;
1008
1009respond:
1010 ret = lxc_cmd_rsp_send(fd, &rsp);
1011 if (ret < 0)
ea2a070b 1012 return LXC_CMD_REAP_CLIENT_FD;
2a63b5cb
CB
1013
1014 return 0;
2a63b5cb 1015#else
3d0327ed 1016 return ret_set_errno(-1, ENOSYS);
2a63b5cb
CB
1017#endif
1018}
1019
191d43cc
CB
1020int lxc_cmd_console_log(const char *name, const char *lxcpath,
1021 struct lxc_console_log *log)
1022{
1023 int ret, stopped;
1024 struct lxc_cmd_console_log data;
1025 struct lxc_cmd_rr cmd;
1026
1027 data.clear = log->clear;
1028 data.read = log->read;
1029 data.read_max = *log->read_max;
1030
1031 cmd.req.cmd = LXC_CMD_CONSOLE_LOG;
1032 cmd.req.data = &data;
1033 cmd.req.datalen = sizeof(struct lxc_cmd_console_log);
1034
1035 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
1036 if (ret < 0)
1037 return ret;
1038
1039 /* There is nothing to be read from the buffer. So clear any values we
1040 * where passed to clearly indicate to the user that nothing went wrong.
1041 */
63b74cda 1042 if (cmd.rsp.ret == -ENODATA || cmd.rsp.ret == -EFAULT || cmd.rsp.ret == -ENOENT) {
191d43cc
CB
1043 *log->read_max = 0;
1044 log->data = NULL;
1045 }
1046
1047 /* This is a proper error so don't touch any values we were passed. */
1048 if (cmd.rsp.ret < 0)
1049 return cmd.rsp.ret;
1050
1051 *log->read_max = cmd.rsp.datalen;
1052 log->data = cmd.rsp.data;
1053
1054 return 0;
1055}
1056
1057static int lxc_cmd_console_log_callback(int fd, struct lxc_cmd_req *req,
cdb2a47f
CB
1058 struct lxc_handler *handler,
1059 struct lxc_epoll_descr *descr)
191d43cc
CB
1060{
1061 struct lxc_cmd_rsp rsp;
28f3b1cd 1062 uint64_t buffer_size = handler->conf->console.buffer_size;
191d43cc
CB
1063 const struct lxc_cmd_console_log *log = req->data;
1064 struct lxc_ringbuf *buf = &handler->conf->console.ringbuf;
1065
1066 rsp.ret = -EFAULT;
1067 rsp.datalen = 0;
1068 rsp.data = NULL;
28f3b1cd 1069 if (buffer_size <= 0)
191d43cc
CB
1070 goto out;
1071
5928191e
CB
1072 if (log->read || log->write_logfile)
1073 rsp.datalen = lxc_ringbuf_used(buf);
1074
191d43cc
CB
1075 if (log->read)
1076 rsp.data = lxc_ringbuf_get_read_addr(buf);
1077
1078 if (log->read_max > 0 && (log->read_max <= rsp.datalen))
1079 rsp.datalen = log->read_max;
1080
1081 /* there's nothing to read */
63b74cda 1082 rsp.ret = -ENODATA;
191d43cc 1083 if (log->read && (buf->r_off == buf->w_off))
63b74cda
CB
1084 goto out;
1085
63b74cda 1086 rsp.ret = 0;
23e0d9af 1087 if (log->clear)
43366ca2 1088 lxc_ringbuf_clear(buf); /* clear the ringbuffer */
23e0d9af 1089 else if (rsp.datalen > 0)
191d43cc
CB
1090 lxc_ringbuf_move_read_addr(buf, rsp.datalen);
1091
1092out:
1093 return lxc_cmd_rsp_send(fd, &rsp);
1094}
1095
974a8aba
CB
1096int lxc_cmd_serve_state_clients(const char *name, const char *lxcpath,
1097 lxc_state_t state)
1098{
1099 int stopped;
1100 ssize_t ret;
1101 struct lxc_cmd_rr cmd = {
6c6497ea
CB
1102 .req = {
1103 .cmd = LXC_CMD_SERVE_STATE_CLIENTS,
1104 .data = INT_TO_PTR(state)
1105 },
974a8aba
CB
1106 };
1107
1108 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
6c6497ea
CB
1109 if (ret < 0)
1110 return log_error_errno(-1, errno, "Failed to serve state clients");
974a8aba
CB
1111
1112 return 0;
1113}
1114
1115static int lxc_cmd_serve_state_clients_callback(int fd, struct lxc_cmd_req *req,
cdb2a47f
CB
1116 struct lxc_handler *handler,
1117 struct lxc_epoll_descr *descr)
974a8aba
CB
1118{
1119 int ret;
1120 lxc_state_t state = PTR_TO_INT(req->data);
1121 struct lxc_cmd_rsp rsp = {0};
1122
1123 ret = lxc_serve_state_clients(handler->name, handler, state);
1124 if (ret < 0)
ea2a070b 1125 return LXC_CMD_REAP_CLIENT_FD;
974a8aba
CB
1126
1127 ret = lxc_cmd_rsp_send(fd, &rsp);
1128 if (ret < 0)
ea2a070b 1129 return LXC_CMD_REAP_CLIENT_FD;
974a8aba
CB
1130
1131 return 0;
974a8aba
CB
1132}
1133
cdb2a47f
CB
1134int lxc_cmd_seccomp_notify_add_listener(const char *name, const char *lxcpath,
1135 int fd,
1136 /* unused */ unsigned int command,
1137 /* unused */ unsigned int flags)
1138{
1139
c3e3c21a 1140#ifdef HAVE_SECCOMP_NOTIFY
cdb2a47f
CB
1141 int ret, stopped;
1142 struct lxc_cmd_rr cmd = {
1143 .req = {
1144 .cmd = LXC_CMD_SECCOMP_NOTIFY_ADD_LISTENER,
1145 .data = INT_TO_PTR(fd),
1146 },
1147 };
1148
1149 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
6c6497ea
CB
1150 if (ret < 0)
1151 return log_error_errno(-1, errno, "Failed to add seccomp listener");
cdb2a47f
CB
1152
1153 return cmd.rsp.ret;
1154#else
3d0327ed 1155 return ret_set_errno(-1, ENOSYS);
cdb2a47f
CB
1156#endif
1157}
1158
1159static int lxc_cmd_seccomp_notify_add_listener_callback(int fd,
1160 struct lxc_cmd_req *req,
1161 struct lxc_handler *handler,
1162 struct lxc_epoll_descr *descr)
1163{
1164 struct lxc_cmd_rsp rsp = {0};
cdb2a47f 1165
c3e3c21a
CB
1166#ifdef HAVE_SECCOMP_NOTIFY
1167 int ret;
cdb2a47f 1168 __do_close_prot_errno int recv_fd = -EBADF;
cdb2a47f 1169
c3e3c21a
CB
1170 ret = lxc_abstract_unix_recv_fds(fd, &recv_fd, 1, NULL, 0);
1171 if (ret <= 0) {
1172 rsp.ret = -errno;
1173 goto out;
cdb2a47f
CB
1174 }
1175
c3e3c21a
CB
1176 if (!handler->conf->seccomp.notifier.wants_supervision ||
1177 handler->conf->seccomp.notifier.proxy_fd < 0) {
1178 SYSERROR("No seccomp proxy fd specified");
1179 rsp.ret = -EINVAL;
1180 goto out;
1181 }
cdb2a47f 1182
c3e3c21a 1183 ret = lxc_mainloop_add_handler(descr, recv_fd, seccomp_notify_handler,
cdb2a47f 1184 handler);
c3e3c21a
CB
1185 if (ret < 0) {
1186 rsp.ret = -errno;
1187 goto out;
1188 }
68a9e3eb 1189 move_fd(recv_fd);
cdb2a47f 1190
c3e3c21a 1191out:
cdb2a47f
CB
1192#else
1193 rsp.ret = -ENOSYS;
cdb2a47f 1194
c3e3c21a
CB
1195#endif
1196 return lxc_cmd_rsp_send(fd, &rsp);
cdb2a47f
CB
1197}
1198
018051e3
CB
1199int lxc_cmd_freeze(const char *name, const char *lxcpath, int timeout)
1200{
1201 int ret, stopped;
1202 struct lxc_cmd_rr cmd = {
1203 .req = {
1204 .cmd = LXC_CMD_FREEZE,
1205 .data = INT_TO_PTR(timeout),
1206 },
1207 };
1208
1209 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
1210 if (ret <= 0 || cmd.rsp.ret < 0)
3d0327ed 1211 return log_error_errno(-1, errno, "Failed to freeze container");
018051e3
CB
1212
1213 return cmd.rsp.ret;
1214}
1215
1216static int lxc_cmd_freeze_callback(int fd, struct lxc_cmd_req *req,
1217 struct lxc_handler *handler,
1218 struct lxc_epoll_descr *descr)
1219{
1220 int timeout = PTR_TO_INT(req->data);
1221 struct lxc_cmd_rsp rsp = {
6c6497ea 1222 .ret = -ENOENT,
018051e3
CB
1223 };
1224 struct cgroup_ops *ops = handler->cgroup_ops;
1225
1973b62a 1226 if (pure_unified_layout(ops))
018051e3
CB
1227 rsp.ret = ops->freeze(ops, timeout);
1228
1229 return lxc_cmd_rsp_send(fd, &rsp);
1230}
1231
1232int lxc_cmd_unfreeze(const char *name, const char *lxcpath, int timeout)
1233{
1234 int ret, stopped;
1235 struct lxc_cmd_rr cmd = {
1236 .req = {
1237 .cmd = LXC_CMD_UNFREEZE,
1238 .data = INT_TO_PTR(timeout),
1239 },
1240 };
1241
1242 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
1243 if (ret <= 0 || cmd.rsp.ret < 0)
3d0327ed 1244 return log_error_errno(-1, errno, "Failed to unfreeze container");
018051e3
CB
1245
1246 return cmd.rsp.ret;
1247}
1248
1249static int lxc_cmd_unfreeze_callback(int fd, struct lxc_cmd_req *req,
1250 struct lxc_handler *handler,
1251 struct lxc_epoll_descr *descr)
1252{
1253 int timeout = PTR_TO_INT(req->data);
1254 struct lxc_cmd_rsp rsp = {
6c6497ea 1255 .ret = -ENOENT,
018051e3
CB
1256 };
1257 struct cgroup_ops *ops = handler->cgroup_ops;
1258
1973b62a 1259 if (pure_unified_layout(ops))
018051e3
CB
1260 rsp.ret = ops->unfreeze(ops, timeout);
1261
1262 return lxc_cmd_rsp_send(fd, &rsp);
1263}
1264
bad788b0
CB
1265int lxc_cmd_get_cgroup2_fd(const char *name, const char *lxcpath)
1266{
1267 int ret, stopped;
1268 struct lxc_cmd_rr cmd = {
1269 .req = {
1270 .cmd = LXC_CMD_GET_CGROUP2_FD,
1271 },
1272 };
1273
1274 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
23a917e5
CB
1275 if (ret < 0)
1276 return -1;
1277
1278 if (cmd.rsp.ret < 0)
900b6606 1279 return log_debug_errno(-1, errno, "Failed to receive cgroup2 fd");
bad788b0
CB
1280
1281 return PTR_TO_INT(cmd.rsp.data);
1282}
1283
1284static int lxc_cmd_get_cgroup2_fd_callback(int fd, struct lxc_cmd_req *req,
1285 struct lxc_handler *handler,
1286 struct lxc_epoll_descr *descr)
1287{
1288 struct lxc_cmd_rsp rsp = {
1289 .ret = -EINVAL,
1290 };
1291 struct cgroup_ops *ops = handler->cgroup_ops;
1292 int ret;
1293
1973b62a 1294 if (!pure_unified_layout(ops) || !ops->unified)
bad788b0
CB
1295 return lxc_cmd_rsp_send(fd, &rsp);
1296
1297 rsp.ret = 0;
1973b62a 1298 ret = lxc_abstract_unix_send_fds(fd, &ops->unified->cgfd_con, 1, &rsp,
bad788b0
CB
1299 sizeof(rsp));
1300 if (ret < 0)
a804c19b 1301 return log_error(LXC_CMD_REAP_CLIENT_FD, "Failed to send cgroup2 fd");
bad788b0
CB
1302
1303 return 0;
1304}
1305
ef6e34ee 1306static int lxc_cmd_process(int fd, struct lxc_cmd_req *req,
cdb2a47f
CB
1307 struct lxc_handler *handler,
1308 struct lxc_epoll_descr *descr)
724e753c 1309{
cdb2a47f
CB
1310 typedef int (*callback)(int, struct lxc_cmd_req *, struct lxc_handler *,
1311 struct lxc_epoll_descr *);
ef6e34ee
DE
1312
1313 callback cb[LXC_CMD_MAX] = {
2a63b5cb
CB
1314 [LXC_CMD_CONSOLE] = lxc_cmd_console_callback,
1315 [LXC_CMD_TERMINAL_WINCH] = lxc_cmd_terminal_winch_callback,
1316 [LXC_CMD_STOP] = lxc_cmd_stop_callback,
1317 [LXC_CMD_GET_STATE] = lxc_cmd_get_state_callback,
1318 [LXC_CMD_GET_INIT_PID] = lxc_cmd_get_init_pid_callback,
1319 [LXC_CMD_GET_CLONE_FLAGS] = lxc_cmd_get_clone_flags_callback,
1320 [LXC_CMD_GET_CGROUP] = lxc_cmd_get_cgroup_callback,
1321 [LXC_CMD_GET_CONFIG_ITEM] = lxc_cmd_get_config_item_callback,
1322 [LXC_CMD_GET_NAME] = lxc_cmd_get_name_callback,
1323 [LXC_CMD_GET_LXCPATH] = lxc_cmd_get_lxcpath_callback,
1324 [LXC_CMD_ADD_STATE_CLIENT] = lxc_cmd_add_state_client_callback,
1325 [LXC_CMD_CONSOLE_LOG] = lxc_cmd_console_log_callback,
1326 [LXC_CMD_SERVE_STATE_CLIENTS] = lxc_cmd_serve_state_clients_callback,
1327 [LXC_CMD_SECCOMP_NOTIFY_ADD_LISTENER] = lxc_cmd_seccomp_notify_add_listener_callback,
1328 [LXC_CMD_ADD_BPF_DEVICE_CGROUP] = lxc_cmd_add_bpf_device_cgroup_callback,
018051e3
CB
1329 [LXC_CMD_FREEZE] = lxc_cmd_freeze_callback,
1330 [LXC_CMD_UNFREEZE] = lxc_cmd_unfreeze_callback,
bad788b0 1331 [LXC_CMD_GET_CGROUP2_FD] = lxc_cmd_get_cgroup2_fd_callback,
724e753c
MN
1332 };
1333
23a917e5
CB
1334 if (req->cmd >= LXC_CMD_MAX)
1335 return log_error_errno(-1, ENOENT, "Undefined command id %d", req->cmd);
1336
cdb2a47f 1337 return cb[req->cmd](fd, req, handler, descr);
724e753c
MN
1338}
1339
ef6e34ee 1340static void lxc_cmd_fd_cleanup(int fd, struct lxc_handler *handler,
cdb2a47f 1341 struct lxc_epoll_descr *descr, const lxc_cmd_t cmd)
724e753c 1342{
3dfe6f8d 1343 lxc_terminal_free(handler->conf, fd);
724e753c 1344 lxc_mainloop_del_handler(descr, fd);
f6fc1565 1345
cd5369b0 1346 if (cmd == LXC_CMD_ADD_STATE_CLIENT) {
ab92468c
CB
1347 struct lxc_list *cur, *next;
1348
cdb2a47f
CB
1349 lxc_list_for_each_safe(cur, &handler->conf->state_clients, next) {
1350 struct lxc_state_client *client = cur->elem;
1351
1352 if (client->clientfd != fd)
1353 continue;
1354
ab92468c
CB
1355 /*
1356 * Only kick client from list so it can't be found
1357 * anymore. The actual close happens, as for all other
1358 * file descriptors, below.
1359 */
cdb2a47f 1360 lxc_list_del(cur);
cdb2a47f
CB
1361 free(cur->elem);
1362 free(cur);
ab92468c 1363
39e2a438
CB
1364 /*
1365 * No need to walk the whole list. If we found the state
cdb2a47f
CB
1366 * client fd there can't be a second one.
1367 */
ea2a070b 1368 TRACE("Found state client fd %d in state client list for command \"%s\"", fd, lxc_cmd_str(cmd));
ab92468c 1369 break;
cdb2a47f 1370 }
39e2a438
CB
1371
1372 /*
1373 * We didn't add the state client to the list. Either because
1374 * we failed to allocate memory (unlikely) or because the state
1375 * was already reached by the time we were ready to add it. So
1376 * fallthrough and clean it up.
1377 */
ea2a070b 1378 TRACE("Closing state client fd %d for command \"%s\"", fd, lxc_cmd_str(cmd));
f6fc1565 1379 }
cd5369b0 1380
ea2a070b 1381 TRACE("Closing client fd %d for command \"%s\"", fd, lxc_cmd_str(cmd));
cd5369b0 1382 close(fd);
724e753c
MN
1383}
1384
84c92abd
DE
1385static int lxc_cmd_handler(int fd, uint32_t events, void *data,
1386 struct lxc_epoll_descr *descr)
724e753c 1387{
5265a60c 1388 __do_free void *reqdata = NULL;
724e753c 1389 int ret;
ef6e34ee 1390 struct lxc_cmd_req req;
724e753c
MN
1391 struct lxc_handler *handler = data;
1392
aae93dd3 1393 ret = lxc_abstract_unix_rcv_credential(fd, &req, sizeof(req));
ded1d23f 1394 if (ret < 0) {
ea2a070b 1395 SYSERROR("Failed to receive data on command socket for command \"%s\"", lxc_cmd_str(req.cmd));
9044b79e 1396
1397 if (errno == EACCES) {
1398 /* We don't care for the peer, just send and close. */
ea2a070b
CB
1399 struct lxc_cmd_rsp rsp = {
1400 .ret = ret,
1401 };
9044b79e 1402
1403 lxc_cmd_rsp_send(fd, &rsp);
1404 }
1405
724e753c
MN
1406 goto out_close;
1407 }
1408
fe84a562 1409 if (ret == 0)
724e753c 1410 goto out_close;
724e753c 1411
ef6e34ee 1412 if (ret != sizeof(req)) {
ea2a070b 1413 WARN("Failed to receive full command request. Ignoring request for \"%s\"", lxc_cmd_str(req.cmd));
ef6e34ee
DE
1414 ret = -1;
1415 goto out_close;
1416 }
1417
ea2a070b
CB
1418 if ((req.datalen > LXC_CMD_DATA_MAX) && (req.cmd != LXC_CMD_CONSOLE_LOG)) {
1419 ERROR("Received command data length %d is too large for command \"%s\"", req.datalen, lxc_cmd_str(req.cmd));
fe84a562
CB
1420 errno = EFBIG;
1421 ret = -EFBIG;
724e753c
MN
1422 goto out_close;
1423 }
1424
ef6e34ee 1425 if (req.datalen > 0) {
5265a60c 1426 reqdata = must_realloc(NULL, req.datalen);
e3233f26 1427 ret = lxc_recv_nointr(fd, reqdata, req.datalen, 0);
ef6e34ee 1428 if (ret != req.datalen) {
ea2a070b 1429 WARN("Failed to receive full command request. Ignoring request for \"%s\"", lxc_cmd_str(req.cmd));
b2a48508 1430 ret = LXC_MAINLOOP_ERROR;
ef6e34ee
DE
1431 goto out_close;
1432 }
fe84a562 1433
ef6e34ee
DE
1434 req.data = reqdata;
1435 }
1436
cdb2a47f 1437 ret = lxc_cmd_process(fd, &req, handler, descr);
724e753c 1438 if (ret) {
fe84a562 1439 /* This is not an error, but only a request to close fd. */
b2a48508 1440 ret = LXC_MAINLOOP_CONTINUE;
724e753c
MN
1441 goto out_close;
1442 }
1443
1444out:
1445 return ret;
fe84a562 1446
724e753c 1447out_close:
f6fc1565 1448 lxc_cmd_fd_cleanup(fd, handler, descr, req.cmd);
724e753c
MN
1449 goto out;
1450}
1451
84c92abd
DE
1452static int lxc_cmd_accept(int fd, uint32_t events, void *data,
1453 struct lxc_epoll_descr *descr)
724e753c 1454{
4c2effce 1455 __do_close_prot_errno int connection = -EBADF;
fe84a562 1456 int opt = 1, ret = -1;
724e753c
MN
1457
1458 connection = accept(fd, NULL, 0);
6c6497ea
CB
1459 if (connection < 0)
1460 return log_error_errno(LXC_MAINLOOP_ERROR, errno, "Failed to accept connection to run command");
724e753c 1461
fe84a562 1462 ret = fcntl(connection, F_SETFD, FD_CLOEXEC);
6c6497ea
CB
1463 if (ret < 0)
1464 return log_error_errno(ret, errno, "Failed to set close-on-exec on incoming command connection");
9ccb2dbc 1465
fe84a562 1466 ret = setsockopt(connection, SOL_SOCKET, SO_PASSCRED, &opt, sizeof(opt));
6c6497ea
CB
1467 if (ret < 0)
1468 return log_error_errno(ret, errno, "Failed to enable necessary credentials on command socket");
724e753c 1469
ef6e34ee 1470 ret = lxc_mainloop_add_handler(descr, connection, lxc_cmd_handler, data);
6c6497ea
CB
1471 if (ret)
1472 return log_error(ret, "Failed to add command handler");
724e753c 1473
ea2a070b 1474 TRACE("Accepted new client as fd %d on command server fd %d", connection, fd);
240fecd0 1475 move_fd(connection);
724e753c 1476 return ret;
724e753c
MN
1477}
1478
9dfa4041 1479int lxc_cmd_init(const char *name, const char *lxcpath, const char *suffix)
724e753c 1480{
c13e7111
CB
1481 __do_close_prot_errno int fd = -EBADF;
1482 int ret;
b1234129 1483 char path[LXC_AUDS_ADDR_LEN] = {0};
724e753c 1484
5b46db1a 1485 ret = lxc_make_abstract_socket_name(path, sizeof(path), name, lxcpath, NULL, suffix);
fe84a562 1486 if (ret < 0)
9ba8130c 1487 return -1;
724e753c 1488
aae93dd3 1489 fd = lxc_abstract_unix_open(path, SOCK_STREAM, 0);
724e753c 1490 if (fd < 0) {
08aa08fe 1491 if (errno == EADDRINUSE)
fe84a562 1492 ERROR("Container \"%s\" appears to be already running", name);
6d1400b5 1493
6c6497ea 1494 return log_error_errno(-1, errno, "Failed to create command socket %s", &path[1]);
724e753c
MN
1495 }
1496
fe84a562 1497 ret = fcntl(fd, F_SETFD, FD_CLOEXEC);
6c6497ea
CB
1498 if (ret < 0)
1499 return log_error_errno(-1, errno, "Failed to set FD_CLOEXEC on command socket file descriptor");
91480a0f 1500
6c6497ea 1501 return log_trace(move_fd(fd), "Created abstract unix socket \"%s\"", &path[1]);
d2e30e99
DE
1502}
1503
fe84a562 1504int lxc_cmd_mainloop_add(const char *name, struct lxc_epoll_descr *descr,
ef6e34ee 1505 struct lxc_handler *handler)
d2e30e99 1506{
fe84a562 1507 int ret;
d2e30e99 1508
ea2a070b 1509 ret = lxc_mainloop_add_handler(descr, handler->conf->maincmd_fd, lxc_cmd_accept, handler);
6c6497ea 1510 if (ret < 0)
ea2a070b 1511 return log_error(ret, "Failed to add handler for command socket fd %d", handler->conf->maincmd_fd);
724e753c
MN
1512
1513 return ret;
1514}