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