]> git.proxmox.com Git - mirror_lxc.git/blame - src/lxc/commands.c
Merge pull request #3059 from brauner/2019-06-21/seccomp_notify
[mirror_lxc.git] / src / lxc / commands.c
CommitLineData
724e753c
MN
1/*
2 * lxc: linux Container library
3 *
4 * (C) Copyright IBM Corp. 2007, 2009
5 *
6 * Authors:
9afe19d6 7 * Daniel Lezcano <daniel.lezcano at free.fr>
724e753c
MN
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
250b1eec 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
724e753c
MN
22 */
23
d38dd64a
CB
24#ifndef _GNU_SOURCE
25#define _GNU_SOURCE 1
26#endif
cf685555 27#include <caps.h>
724e753c 28#include <errno.h>
91480a0f 29#include <fcntl.h>
fe84a562 30#include <malloc.h>
37515ebd 31#include <poll.h>
fe84a562
CB
32#include <signal.h>
33#include <stdio.h>
34#include <stdlib.h>
fe84a562 35#include <sys/param.h>
724e753c
MN
36#include <sys/socket.h>
37#include <sys/un.h>
d38dd64a 38#include <unistd.h>
724e753c 39
fe84a562 40#include "af_unix.h"
f2363e38 41#include "cgroup.h"
724e753c 42#include "commands.h"
bbf5cf35 43#include "commands_utils.h"
fe84a562 44#include "conf.h"
d38dd64a 45#include "config.h"
ef6e34ee 46#include "confile.h"
fe84a562
CB
47#include "log.h"
48#include "lxc.h"
dbc9832d 49#include "lxclock.h"
cdb2a47f 50#include "lxcseccomp.h"
724e753c 51#include "mainloop.h"
5265a60c 52#include "memory_utils.h"
dbc9832d 53#include "monitor.h"
fe84a562 54#include "start.h"
0ed9b1bc 55#include "terminal.h"
fe84a562 56#include "utils.h"
724e753c 57
ded1d23f 58/*
fe84a562
CB
59 * This file provides the different functions for clients to query/command the
60 * server. The client is typically some lxc tool and the server is typically the
61 * container (ie. lxc-start).
ded1d23f 62 *
fe84a562
CB
63 * Each command is transactional, the clients send a request to the server and
64 * the server answers the request with a message giving the request's status
65 * (zero or a negative errno value). Both the request and response may contain
66 * additional data.
ded1d23f 67 *
fe84a562
CB
68 * Each command is wrapped in a ancillary message in order to pass a credential
69 * making possible to the server to check if the client is allowed to ask for
70 * this command or not.
80bcb053 71 *
fe84a562
CB
72 * IMPORTANTLY: Note that semantics for current commands are fixed. If you wish
73 * to make any changes to how, say, LXC_CMD_GET_CONFIG_ITEM works by adding
74 * information to the end of cmd.data, then you must introduce a new
75 * LXC_CMD_GET_CONFIG_ITEM_V2 define with a new number. You may wish to also
76 * mark LXC_CMD_GET_CONFIG_ITEM deprecated in commands.h.
80bcb053
SH
77 *
78 * This is necessary in order to avoid having a newly compiled lxc command
79 * communicating with a running (old) monitor from crashing the running
80 * container.
ded1d23f
DL
81 */
82
ac2cecc4 83lxc_log_define(commands, lxc);
724e753c 84
ef6e34ee 85static const char *lxc_cmd_str(lxc_cmd_t cmd)
724e753c 86{
fe84a562 87 static const char *const cmdname[LXC_CMD_MAX] = {
974a8aba 88 [LXC_CMD_CONSOLE] = "console",
8ccbbf94 89 [LXC_CMD_TERMINAL_WINCH] = "terminal_winch",
974a8aba
CB
90 [LXC_CMD_STOP] = "stop",
91 [LXC_CMD_GET_STATE] = "get_state",
92 [LXC_CMD_GET_INIT_PID] = "get_init_pid",
93 [LXC_CMD_GET_CLONE_FLAGS] = "get_clone_flags",
94 [LXC_CMD_GET_CGROUP] = "get_cgroup",
95 [LXC_CMD_GET_CONFIG_ITEM] = "get_config_item",
96 [LXC_CMD_GET_NAME] = "get_name",
97 [LXC_CMD_GET_LXCPATH] = "get_lxcpath",
98 [LXC_CMD_ADD_STATE_CLIENT] = "add_state_client",
99 [LXC_CMD_CONSOLE_LOG] = "console_log",
100 [LXC_CMD_SERVE_STATE_CLIENTS] = "serve_state_clients",
cdb2a47f 101 [LXC_CMD_SECCOMP_NOTIFY_ADD_LISTENER] = "seccomp_notify_add_listener",
ef6e34ee 102 };
724e753c 103
f371aca9 104 if (cmd >= LXC_CMD_MAX)
a8007512 105 return "Invalid request";
fe84a562 106
ef6e34ee
DE
107 return cmdname[cmd];
108}
109
110/*
111 * lxc_cmd_rsp_recv: Receive a response to a command
112 *
113 * @sock : the socket connected to the container
114 * @cmd : command to put response in
115 *
116 * Returns the size of the response message or < 0 on failure
117 *
118 * Note that if the command response datalen > 0, then data is
119 * a malloc()ed buffer and should be free()ed by the caller. If
120 * the response data is <= a void * worth of data, it will be
121 * stored directly in data and datalen will be 0.
122 *
123 * As a special case, the response for LXC_CMD_CONSOLE is created
0115f8fd
DE
124 * here as it contains an fd for the master pty passed through the
125 * unix socket.
ef6e34ee
DE
126 */
127static int lxc_cmd_rsp_recv(int sock, struct lxc_cmd_rr *cmd)
128{
2945ea97 129 int ret, rspfd;
ef6e34ee
DE
130 struct lxc_cmd_rsp *rsp = &cmd->rsp;
131
ae467c54 132 ret = lxc_abstract_unix_recv_fds(sock, &rspfd, 1, rsp, sizeof(*rsp));
ef6e34ee 133 if (ret < 0) {
a24c5678 134 SYSWARN("Failed to receive response for command \"%s\"",
135 lxc_cmd_str(cmd->req.cmd));
136
6b7f85cb 137 if (errno == ECONNRESET)
2a850b2c 138 return -1;
6b7f85cb 139
ef6e34ee
DE
140 return -1;
141 }
fe84a562 142 TRACE("Command \"%s\" received response", lxc_cmd_str(cmd->req.cmd));
ef6e34ee
DE
143
144 if (cmd->req.cmd == LXC_CMD_CONSOLE) {
145 struct lxc_cmd_console_rsp_data *rspdata;
146
0115f8fd
DE
147 /* recv() returns 0 bytes when a tty cannot be allocated,
148 * rsp->ret is < 0 when the peer permission check failed
149 */
150 if (ret == 0 || rsp->ret < 0)
151 return 0;
152
ef6e34ee
DE
153 rspdata = malloc(sizeof(*rspdata));
154 if (!rspdata) {
2a850b2c 155 errno = ENOMEM;
fe84a562 156 ERROR("Failed to allocate response buffer for command \"%s\"",
ef6e34ee 157 lxc_cmd_str(cmd->req.cmd));
2a850b2c 158 return -1;
ef6e34ee 159 }
2a850b2c 160
0115f8fd 161 rspdata->masterfd = rspfd;
ef6e34ee
DE
162 rspdata->ttynum = PTR_TO_INT(rsp->data);
163 rsp->data = rspdata;
164 }
165
860e7c43 166 if (rsp->datalen == 0) {
fe84a562 167 DEBUG("Response data length for command \"%s\" is 0",
860e7c43 168 lxc_cmd_str(cmd->req.cmd));
ae5c8b8e 169 return ret;
860e7c43 170 }
fe84a562 171
191d43cc
CB
172 if ((rsp->datalen > LXC_CMD_DATA_MAX) &&
173 (cmd->req.cmd != LXC_CMD_CONSOLE_LOG)) {
2a850b2c
CB
174 ERROR("Response data for command \"%s\" is too long: %d bytes > %d",
175 lxc_cmd_str(cmd->req.cmd), rsp->datalen, LXC_CMD_DATA_MAX);
176 return -1;
2ac9aafc 177 }
ef6e34ee 178
191d43cc
CB
179 if (cmd->req.cmd == LXC_CMD_CONSOLE_LOG) {
180 rsp->data = malloc(rsp->datalen + 1);
181 ((char *)rsp->data)[rsp->datalen] = '\0';
182 } else {
183 rsp->data = malloc(rsp->datalen);
184 }
ef6e34ee 185 if (!rsp->data) {
fe84a562 186 errno = ENOMEM;
2a850b2c
CB
187 ERROR("Failed to allocate response buffer for command \"%s\"",
188 lxc_cmd_str(cmd->req.cmd));
189 return -1;
ef6e34ee 190 }
fe84a562 191
2a850b2c 192 ret = lxc_recv_nointr(sock, rsp->data, rsp->datalen, 0);
ef6e34ee 193 if (ret != rsp->datalen) {
6d1400b5 194 SYSERROR("Failed to receive response data for command \"%s\"",
195 lxc_cmd_str(cmd->req.cmd));
2a850b2c 196 return -1;
ef6e34ee 197 }
724e753c
MN
198
199 return ret;
200}
201
ef6e34ee
DE
202/*
203 * lxc_cmd_rsp_send: Send a command response
204 *
205 * @fd : file descriptor of socket to send response on
206 * @rsp : response to send
207 *
208 * Returns 0 on success, < 0 on failure
209 */
210static int lxc_cmd_rsp_send(int fd, struct lxc_cmd_rsp *rsp)
211{
fe84a562 212 ssize_t ret;
ef6e34ee 213
7fbb15ec
CB
214 errno = EMSGSIZE;
215 ret = lxc_send_nointr(fd, rsp, sizeof(*rsp), MSG_NOSIGNAL);
fe84a562 216 if (ret < 0 || (size_t)ret != sizeof(*rsp)) {
6d1400b5 217 SYSERROR("Failed to send command response %zd", ret);
ef6e34ee
DE
218 return -1;
219 }
220
a674dfe1 221 if (!rsp->data || rsp->datalen <= 0)
fe84a562
CB
222 return 0;
223
7fbb15ec
CB
224 errno = EMSGSIZE;
225 ret = lxc_send_nointr(fd, rsp->data, rsp->datalen, MSG_NOSIGNAL);
fe84a562 226 if (ret < 0 || ret != (ssize_t)rsp->datalen) {
a24c5678 227 SYSWARN("Failed to send command response data %zd", ret);
fe84a562 228 return -1;
ef6e34ee 229 }
fe84a562 230
ef6e34ee
DE
231 return 0;
232}
233
c01c2be6 234static int lxc_cmd_send(const char *name, struct lxc_cmd_rr *cmd,
fe84a562 235 const char *lxcpath, const char *hashed_sock_name)
c01c2be6 236{
e96f9291 237 __do_close_prot_errno int client_fd = -EBADF;
fe84a562 238 ssize_t ret = -1;
c01c2be6 239
9dfa4041 240 client_fd = lxc_cmd_connect(name, lxcpath, hashed_sock_name, "command");
2a850b2c 241 if (client_fd < 0)
fe84a562 242 return -1;
c01c2be6 243
fe84a562
CB
244 ret = lxc_abstract_unix_send_credential(client_fd, &cmd->req,
245 sizeof(cmd->req));
2a850b2c 246 if (ret < 0 || (size_t)ret != sizeof(cmd->req))
e96f9291 247 return -1;
9044b79e 248
cdb2a47f
CB
249 if (cmd->req.cmd == LXC_CMD_SECCOMP_NOTIFY_ADD_LISTENER) {
250 int notify_fd = PTR_TO_INT(cmd->req.data);
251 ret = lxc_abstract_unix_send_fds(client_fd, &notify_fd, 1, NULL, 0);
252 if (ret <= 0)
253 return -1;
254 } else {
255 if (cmd->req.datalen <= 0)
256 return move_fd(client_fd);
c01c2be6 257
cdb2a47f
CB
258 errno = EMSGSIZE;
259 ret = lxc_send_nointr(client_fd, (void *)cmd->req.data,
260 cmd->req.datalen, MSG_NOSIGNAL);
261 if (ret < 0 || ret != (ssize_t)cmd->req.datalen)
262 return -1;
263 }
c01c2be6 264
240fecd0 265 return move_fd(client_fd);
c01c2be6
CB
266}
267
ef6e34ee
DE
268/*
269 * lxc_cmd: Connect to the specified running container, send it a command
270 * request and collect the response
271 *
272 * @name : name of container to connect to
1e8cfdf6 273 * @cmd : command with initialized request to send
ef6e34ee
DE
274 * @stopped : output indicator if the container was not running
275 * @lxcpath : the lxcpath in which the container is running
276 *
277 * Returns the size of the response message on success, < 0 on failure
278 *
279 * Note that there is a special case for LXC_CMD_CONSOLE. For this command
280 * the fd cannot be closed because it is used as a placeholder to indicate
281 * that a particular tty slot is in use. The fd is also used as a signal to
282 * the container that when the caller dies or closes the fd, the container
0115f8fd
DE
283 * will notice the fd on its side of the socket in its mainloop select and
284 * then free the slot with lxc_cmd_fd_cleanup(). The socket fd will be
285 * returned in the cmd response structure.
ef6e34ee
DE
286 */
287static int lxc_cmd(const char *name, struct lxc_cmd_rr *cmd, int *stopped,
88556fd7 288 const char *lxcpath, const char *hashed_sock_name)
724e753c 289{
c34ff119 290 __do_close_prot_errno int client_fd = -EBADF;
fe84a562 291 int ret = -1;
dbc9832d
CB
292 bool stay_connected = false;
293
294 if (cmd->req.cmd == LXC_CMD_CONSOLE ||
54446942 295 cmd->req.cmd == LXC_CMD_ADD_STATE_CLIENT)
dbc9832d 296 stay_connected = true;
724e753c 297
0ecf64b5
SH
298 *stopped = 0;
299
c01c2be6
CB
300 client_fd = lxc_cmd_send(name, cmd, lxcpath, hashed_sock_name);
301 if (client_fd < 0) {
7874d81a 302 SYSTRACE("Command \"%s\" failed to connect command socket",
303 lxc_cmd_str(cmd->req.cmd));
6a93ae77 304
00e5ca13 305 if (errno == ECONNREFUSED || errno == EPIPE)
ef6e34ee 306 *stopped = 1;
3f903c04 307
2a850b2c 308 return -1;
724e753c
MN
309 }
310
c01c2be6 311 ret = lxc_cmd_rsp_recv(client_fd, cmd);
2a850b2c 312 if (ret < 0 && errno == ECONNRESET)
6b7f85cb 313 *stopped = 1;
6a93ae77 314
c34ff119 315 if (stay_connected && ret > 0)
240fecd0 316 cmd->rsp.ret = move_fd(client_fd);
43eb6f29 317
1362f2eb 318 return ret;
724e753c
MN
319}
320
b494d2dd
SH
321int lxc_try_cmd(const char *name, const char *lxcpath)
322{
0ecf64b5 323 int stopped, ret;
b494d2dd
SH
324 struct lxc_cmd_rr cmd = {
325 .req = { .cmd = LXC_CMD_GET_INIT_PID },
326 };
327
88556fd7 328 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
b494d2dd
SH
329 if (stopped)
330 return 0;
331 if (ret > 0 && cmd.rsp.ret < 0) {
332 errno = cmd.rsp.ret;
333 return -1;
334 }
335 if (ret > 0)
336 return 0;
337
fe84a562
CB
338 /* At this point we weren't denied access, and the container *was*
339 * started. There was some inexplicable error in the protocol. I'm not
340 * clear on whether we should return -1 here, but we didn't receive a
341 * -EACCES, so technically it's not that we're not allowed to control
342 * the container - it's just not behaving.
b494d2dd
SH
343 */
344 return 0;
345}
346
cc4c0832 347/* Implementations of the commands and their callbacks */
ef6e34ee
DE
348
349/*
350 * lxc_cmd_get_init_pid: Get pid of the container's init process
351 *
352 * @name : name of container to connect to
353 * @lxcpath : the lxcpath in which the container is running
354 *
355 * Returns the pid on success, < 0 on failure
356 */
357pid_t lxc_cmd_get_init_pid(const char *name, const char *lxcpath)
43eb6f29 358{
0ecf64b5 359 int ret, stopped;
9234406b 360 intmax_t pid;
ef6e34ee 361 struct lxc_cmd_rr cmd = {
e8cd1208
CB
362 .req = {
363 .cmd = LXC_CMD_GET_INIT_PID
364 },
365 .rsp = {
9234406b 366 .data = INTMAX_TO_PTR((intmax_t){-1})
e8cd1208 367 }
ef6e34ee
DE
368 };
369
88556fd7 370 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
ef6e34ee 371 if (ret < 0)
8ed8a626 372 return -1;
ef6e34ee 373
9234406b
CB
374 pid = PTR_TO_INTMAX(cmd.rsp.data);
375 if (pid < 0)
376 return -1;
377
378 /* We need to assume that pid_t can actually hold any pid given to us
379 * by the kernel. If it can't it's a libc bug.
380 */
381 return (pid_t)pid;
43eb6f29
DL
382}
383
ef6e34ee 384static int lxc_cmd_get_init_pid_callback(int fd, struct lxc_cmd_req *req,
cdb2a47f
CB
385 struct lxc_handler *handler,
386 struct lxc_epoll_descr *descr)
43eb6f29 387{
54dcfd81
CB
388 intmax_t pid = handler->pid;
389
9234406b 390 struct lxc_cmd_rsp rsp = {
54dcfd81 391 .data = INTMAX_TO_PTR(pid)
9234406b 392 };
ef6e34ee
DE
393
394 return lxc_cmd_rsp_send(fd, &rsp);
43eb6f29
DL
395}
396
ef6e34ee
DE
397/*
398 * lxc_cmd_get_clone_flags: Get clone flags container was spawned with
399 *
400 * @name : name of container to connect to
401 * @lxcpath : the lxcpath in which the container is running
402 *
403 * Returns the clone flags on success, < 0 on failure
404 */
405int lxc_cmd_get_clone_flags(const char *name, const char *lxcpath)
406{
0ecf64b5 407 int ret, stopped;
ef6e34ee
DE
408 struct lxc_cmd_rr cmd = {
409 .req = { .cmd = LXC_CMD_GET_CLONE_FLAGS },
410 };
411
88556fd7 412 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
ef6e34ee
DE
413 if (ret < 0)
414 return ret;
43eb6f29 415
ef6e34ee
DE
416 return PTR_TO_INT(cmd.rsp.data);
417}
418
419static int lxc_cmd_get_clone_flags_callback(int fd, struct lxc_cmd_req *req,
cdb2a47f
CB
420 struct lxc_handler *handler,
421 struct lxc_epoll_descr *descr)
26b2d152 422{
becad0ec 423 struct lxc_cmd_rsp rsp = { .data = INT_TO_PTR(handler->ns_clone_flags) };
ef6e34ee
DE
424
425 return lxc_cmd_rsp_send(fd, &rsp);
426}
427
428/*
429 * lxc_cmd_get_cgroup_path: Calculate a container's cgroup path for a
430 * particular subsystem. This is the cgroup path relative to the root
431 * of the cgroup filesystem.
432 *
ef6e34ee
DE
433 * @name : name of container to connect to
434 * @lxcpath : the lxcpath in which the container is running
b98f7d6e 435 * @subsystem : the subsystem being asked about
ef6e34ee
DE
436 *
437 * Returns the path on success, NULL on failure. The caller must free() the
438 * returned path.
439 */
b98f7d6e 440char *lxc_cmd_get_cgroup_path(const char *name, const char *lxcpath,
fe84a562 441 const char *subsystem)
ef6e34ee 442{
0ecf64b5 443 int ret, stopped;
ef6e34ee 444 struct lxc_cmd_rr cmd = {
b98f7d6e
SH
445 .req = {
446 .cmd = LXC_CMD_GET_CGROUP,
b98f7d6e 447 .data = subsystem,
c2aed66d 448 .datalen = 0,
b98f7d6e 449 },
26b2d152
MN
450 };
451
c2aed66d
CB
452 cmd.req.data = subsystem;
453 cmd.req.datalen = 0;
454 if (subsystem)
455 cmd.req.datalen = strlen(subsystem) + 1;
456
88556fd7 457 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
fe84a562 458 if (ret < 0)
ef6e34ee
DE
459 return NULL;
460
fe84a562 461 if (ret == 0)
ef6e34ee 462 return NULL;
ef6e34ee 463
fe84a562 464 if (cmd.rsp.ret < 0 || cmd.rsp.datalen < 0)
ef6e34ee 465 return NULL;
3f903c04 466
ef6e34ee
DE
467 return cmd.rsp.data;
468}
469
470static int lxc_cmd_get_cgroup_callback(int fd, struct lxc_cmd_req *req,
cdb2a47f
CB
471 struct lxc_handler *handler,
472 struct lxc_epoll_descr *descr)
ef6e34ee 473{
4fb3cba5 474 const char *path;
fe84a562 475 struct lxc_cmd_rsp rsp;
2202afc9 476 struct cgroup_ops *cgroup_ops = handler->cgroup_ops;
b98f7d6e 477
c2aed66d 478 if (req->datalen > 0)
2202afc9 479 path = cgroup_ops->get_cgroup(cgroup_ops, req->data);
c2aed66d 480 else
2202afc9 481 path = cgroup_ops->get_cgroup(cgroup_ops, NULL);
b98f7d6e
SH
482 if (!path)
483 return -1;
fe84a562 484
4f17323e 485 rsp.ret = 0;
fe84a562
CB
486 rsp.datalen = strlen(path) + 1;
487 rsp.data = (char *)path;
ef6e34ee
DE
488
489 return lxc_cmd_rsp_send(fd, &rsp);
490}
491
492/*
493 * lxc_cmd_get_config_item: Get config item the running container
494 *
495 * @name : name of container to connect to
7fa3f2e9 496 * @item : the configuration item to retrieve (ex: lxc.net.0.veth.pair)
ef6e34ee
DE
497 * @lxcpath : the lxcpath in which the container is running
498 *
499 * Returns the item on success, NULL on failure. The caller must free() the
500 * returned item.
501 */
502char *lxc_cmd_get_config_item(const char *name, const char *item,
503 const char *lxcpath)
504{
0ecf64b5 505 int ret, stopped;
ef6e34ee
DE
506 struct lxc_cmd_rr cmd = {
507 .req = { .cmd = LXC_CMD_GET_CONFIG_ITEM,
508 .data = item,
fe84a562 509 .datalen = strlen(item) + 1,
ef6e34ee
DE
510 },
511 };
512
88556fd7 513 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
ef6e34ee
DE
514 if (ret < 0)
515 return NULL;
516
517 if (cmd.rsp.ret == 0)
518 return cmd.rsp.data;
fe84a562 519
ef6e34ee
DE
520 return NULL;
521}
522
523static int lxc_cmd_get_config_item_callback(int fd, struct lxc_cmd_req *req,
cdb2a47f
CB
524 struct lxc_handler *handler,
525 struct lxc_epoll_descr *descr)
ef6e34ee 526{
5265a60c 527 __do_free char *cidata = NULL;
ef6e34ee 528 int cilen;
30aec088 529 struct lxc_config_t *item;
fe84a562 530 struct lxc_cmd_rsp rsp;
ef6e34ee
DE
531
532 memset(&rsp, 0, sizeof(rsp));
300df83e 533 item = lxc_get_config(req->data);
30aec088
CB
534 if (!item)
535 goto err1;
fe84a562 536
cccd2219 537 cilen = item->get(req->data, NULL, 0, handler->conf, NULL);
ef6e34ee
DE
538 if (cilen <= 0)
539 goto err1;
540
5265a60c 541 cidata = must_realloc(NULL, cilen + 1);
cccd2219 542 if (item->get(req->data, cidata, cilen + 1, handler->conf, NULL) != cilen)
ef6e34ee 543 goto err1;
fe84a562 544
ef6e34ee
DE
545 cidata[cilen] = '\0';
546 rsp.data = cidata;
547 rsp.datalen = cilen + 1;
548 rsp.ret = 0;
549 goto out;
550
551err1:
552 rsp.ret = -1;
553out:
554 return lxc_cmd_rsp_send(fd, &rsp);
555}
556
557/*
558 * lxc_cmd_get_state: Get current state of the container
559 *
560 * @name : name of container to connect to
561 * @lxcpath : the lxcpath in which the container is running
562 *
563 * Returns the state on success, < 0 on failure
564 */
dbc9832d 565int lxc_cmd_get_state(const char *name, const char *lxcpath)
ef6e34ee 566{
0ecf64b5 567 int ret, stopped;
ef6e34ee
DE
568 struct lxc_cmd_rr cmd = {
569 .req = { .cmd = LXC_CMD_GET_STATE }
570 };
26b2d152 571
88556fd7 572 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
ebdd307d 573 if (ret < 0 && stopped)
ef6e34ee
DE
574 return STOPPED;
575
576 if (ret < 0)
26b2d152 577 return -1;
26b2d152 578
ef6e34ee 579 if (!ret) {
fe84a562 580 WARN("Container \"%s\" has stopped before sending its state", name);
ef6e34ee
DE
581 return -1;
582 }
583
fe84a562 584 DEBUG("Container \"%s\" is in \"%s\" state", name,
ef6e34ee 585 lxc_state2str(PTR_TO_INT(cmd.rsp.data)));
fe84a562 586
ef6e34ee
DE
587 return PTR_TO_INT(cmd.rsp.data);
588}
589
590static int lxc_cmd_get_state_callback(int fd, struct lxc_cmd_req *req,
cdb2a47f
CB
591 struct lxc_handler *handler,
592 struct lxc_epoll_descr *descr)
ef6e34ee
DE
593{
594 struct lxc_cmd_rsp rsp = { .data = INT_TO_PTR(handler->state) };
595
596 return lxc_cmd_rsp_send(fd, &rsp);
597}
598
599/*
600 * lxc_cmd_stop: Stop the container previously started with lxc_start. All
601 * the processes running inside this container will be killed.
602 *
603 * @name : name of container to connect to
604 * @lxcpath : the lxcpath in which the container is running
605 *
606 * Returns 0 on success, < 0 on failure
607 */
608int lxc_cmd_stop(const char *name, const char *lxcpath)
609{
0ecf64b5 610 int ret, stopped;
ef6e34ee
DE
611 struct lxc_cmd_rr cmd = {
612 .req = { .cmd = LXC_CMD_STOP },
613 };
614
88556fd7 615 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
26b2d152 616 if (ret < 0) {
ef6e34ee 617 if (stopped) {
fe84a562 618 INFO("Container \"%s\" is already stopped", name);
ef6e34ee
DE
619 return 0;
620 }
fe84a562 621
26b2d152
MN
622 return -1;
623 }
624
fe84a562
CB
625 /* We do not expect any answer, because we wait for the connection to be
626 * closed.
95d5b147
SH
627 */
628 if (ret > 0) {
6d1400b5 629 errno = -cmd.rsp.ret;
630 SYSERROR("Failed to stop container \"%s\"", name);
26b2d152
MN
631 return -1;
632 }
633
fe84a562 634 INFO("Container \"%s\" has stopped", name);
ef6e34ee 635 return 0;
26b2d152
MN
636}
637
ef6e34ee 638static int lxc_cmd_stop_callback(int fd, struct lxc_cmd_req *req,
cdb2a47f
CB
639 struct lxc_handler *handler,
640 struct lxc_epoll_descr *descr)
d5088cf2 641{
ef6e34ee 642 struct lxc_cmd_rsp rsp;
ef6e34ee 643 int stopsignal = SIGKILL;
2202afc9 644 struct cgroup_ops *cgroup_ops = handler->cgroup_ops;
ef6e34ee
DE
645
646 if (handler->conf->stopsignal)
647 stopsignal = handler->conf->stopsignal;
648 memset(&rsp, 0, sizeof(rsp));
649 rsp.ret = kill(handler->pid, stopsignal);
650 if (!rsp.ret) {
fe84a562 651 /* We can't just use lxc_unfreeze() since we are already in the
4fb3cba5
DE
652 * context of handling the STOP cmd in lxc-start, and calling
653 * lxc_unfreeze() would do another cmd (GET_CGROUP) which would
fe84a562 654 * deadlock us.
4fb3cba5 655 */
27a5132c 656 if (!cgroup_ops->get_cgroup(cgroup_ops, "freezer"))
d18d43da
SG
657 return 0;
658
2202afc9 659 if (cgroup_ops->unfreeze(cgroup_ops))
95d5b147 660 return 0;
fe84a562
CB
661
662 ERROR("Failed to unfreeze container \"%s\"", handler->name);
ecfcb3f0 663 rsp.ret = -1;
ef6e34ee
DE
664 }
665
666 return lxc_cmd_rsp_send(fd, &rsp);
667}
d5088cf2 668
b5159817 669/*
2bd158cc 670 * lxc_cmd_terminal_winch: noop
b5159817
DE
671 *
672 * @name : name of container to connect to
673 * @lxcpath : the lxcpath in which the container is running
674 *
675 * Returns 0 on success, < 0 on failure
676 */
8ccbbf94 677int lxc_cmd_terminal_winch(const char *name, const char *lxcpath)
b5159817 678{
b5159817
DE
679 return 0;
680}
681
8ccbbf94 682static int lxc_cmd_terminal_winch_callback(int fd, struct lxc_cmd_req *req,
cdb2a47f
CB
683 struct lxc_handler *handler,
684 struct lxc_epoll_descr *descr)
b5159817 685{
2bd158cc
CB
686 /* should never be called */
687 return -1;
b5159817
DE
688}
689
ef6e34ee
DE
690/*
691 * lxc_cmd_console: Open an fd to a tty in the container
692 *
693 * @name : name of container to connect to
694 * @ttynum : in: the tty to open or -1 for next available
695 * : out: the tty allocated
696 * @fd : out: file descriptor for master side of pty
697 * @lxcpath : the lxcpath in which the container is running
698 *
0115f8fd 699 * Returns fd holding tty allocated on success, < 0 on failure
ef6e34ee
DE
700 */
701int lxc_cmd_console(const char *name, int *ttynum, int *fd, const char *lxcpath)
702{
8259d86d 703 __do_free struct lxc_cmd_console_rsp_data *rspdata = NULL;
0ecf64b5 704 int ret, stopped;
ef6e34ee
DE
705 struct lxc_cmd_rr cmd = {
706 .req = { .cmd = LXC_CMD_CONSOLE, .data = INT_TO_PTR(*ttynum) },
707 };
d5088cf2 708
88556fd7 709 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
ef6e34ee
DE
710 if (ret < 0)
711 return ret;
0115f8fd 712
8259d86d 713 rspdata = cmd.rsp.data;
0115f8fd 714 if (cmd.rsp.ret < 0) {
6d1400b5 715 errno = -cmd.rsp.ret;
716 SYSERROR("Denied access to tty");
8259d86d 717 return -1;
ef6e34ee 718 }
d5088cf2 719
0115f8fd 720 if (ret == 0) {
fe84a562 721 ERROR("tty number %d invalid, busy or all ttys busy", *ttynum);
8259d86d 722 return -1;
ef6e34ee 723 }
ef6e34ee 724
0115f8fd 725 if (rspdata->masterfd < 0) {
fe84a562 726 ERROR("Unable to allocate fd for tty %d", rspdata->ttynum);
8259d86d 727 return -1;
ef6e34ee
DE
728 }
729
fe84a562 730 ret = cmd.rsp.ret; /* socket fd */
0115f8fd 731 *fd = rspdata->masterfd;
ef6e34ee 732 *ttynum = rspdata->ttynum;
fe84a562
CB
733 INFO("Alloced fd %d for tty %d via socket %d", *fd, rspdata->ttynum, ret);
734
ef6e34ee
DE
735 return ret;
736}
737
738static int lxc_cmd_console_callback(int fd, struct lxc_cmd_req *req,
cdb2a47f
CB
739 struct lxc_handler *handler,
740 struct lxc_epoll_descr *descr)
ef6e34ee 741{
fe84a562 742 int masterfd, ret;
ef6e34ee 743 struct lxc_cmd_rsp rsp;
fe84a562 744 int ttynum = PTR_TO_INT(req->data);
ef6e34ee 745
c1ee47cd 746 masterfd = lxc_terminal_allocate(handler->conf, fd, &ttynum);
b5159817 747 if (masterfd < 0)
ef6e34ee
DE
748 goto out_close;
749
ef6e34ee
DE
750 memset(&rsp, 0, sizeof(rsp));
751 rsp.data = INT_TO_PTR(ttynum);
fe84a562
CB
752 ret = lxc_abstract_unix_send_fds(fd, &masterfd, 1, &rsp, sizeof(rsp));
753 if (ret < 0) {
9044b79e 754 SYSERROR("Failed to send tty to client");
3dfe6f8d 755 lxc_terminal_free(handler->conf, fd);
ef6e34ee
DE
756 goto out_close;
757 }
758
ef6e34ee
DE
759 return 0;
760
761out_close:
fe84a562
CB
762 /* Special indicator to lxc_cmd_handler() to close the fd and do
763 * related cleanup.
ef6e34ee
DE
764 */
765 return 1;
d5088cf2
CS
766}
767
88556fd7
ÇO
768/*
769 * lxc_cmd_get_name: Returns the name of the container
770 *
771 * @hashed_sock_name: hashed socket name
772 *
773 * Returns the name on success, NULL on failure.
774 */
775char *lxc_cmd_get_name(const char *hashed_sock_name)
776{
777 int ret, stopped;
778 struct lxc_cmd_rr cmd = {
779 .req = { .cmd = LXC_CMD_GET_NAME},
780 };
781
782 ret = lxc_cmd(NULL, &cmd, &stopped, NULL, hashed_sock_name);
fe84a562 783 if (ret < 0)
88556fd7 784 return NULL;
88556fd7
ÇO
785
786 if (cmd.rsp.ret == 0)
787 return cmd.rsp.data;
fe84a562 788
88556fd7
ÇO
789 return NULL;
790}
791
792static int lxc_cmd_get_name_callback(int fd, struct lxc_cmd_req *req,
cdb2a47f
CB
793 struct lxc_handler *handler,
794 struct lxc_epoll_descr *descr)
88556fd7
ÇO
795{
796 struct lxc_cmd_rsp rsp;
797
798 memset(&rsp, 0, sizeof(rsp));
799
f0ecc19d 800 rsp.data = (char *)handler->name;
88556fd7
ÇO
801 rsp.datalen = strlen(handler->name) + 1;
802 rsp.ret = 0;
803
804 return lxc_cmd_rsp_send(fd, &rsp);
805}
806
807/*
808 * lxc_cmd_get_lxcpath: Returns the lxcpath of the container
809 *
810 * @hashed_sock_name: hashed socket name
811 *
812 * Returns the lxcpath on success, NULL on failure.
813 */
814char *lxc_cmd_get_lxcpath(const char *hashed_sock_name)
815{
816 int ret, stopped;
817 struct lxc_cmd_rr cmd = {
818 .req = { .cmd = LXC_CMD_GET_LXCPATH},
819 };
724e753c 820
88556fd7 821 ret = lxc_cmd(NULL, &cmd, &stopped, NULL, hashed_sock_name);
fe84a562 822 if (ret < 0)
88556fd7 823 return NULL;
88556fd7
ÇO
824
825 if (cmd.rsp.ret == 0)
826 return cmd.rsp.data;
fe84a562 827
88556fd7
ÇO
828 return NULL;
829}
830
831static int lxc_cmd_get_lxcpath_callback(int fd, struct lxc_cmd_req *req,
cdb2a47f
CB
832 struct lxc_handler *handler,
833 struct lxc_epoll_descr *descr)
88556fd7
ÇO
834{
835 struct lxc_cmd_rsp rsp;
836
837 memset(&rsp, 0, sizeof(rsp));
838
fe84a562 839 rsp.ret = 0;
88556fd7
ÇO
840 rsp.data = (char *)handler->lxcpath;
841 rsp.datalen = strlen(handler->lxcpath) + 1;
88556fd7
ÇO
842
843 return lxc_cmd_rsp_send(fd, &rsp);
844}
ef6e34ee 845
54446942 846int lxc_cmd_add_state_client(const char *name, const char *lxcpath,
92e35018
CB
847 lxc_state_t states[MAX_STATE],
848 int *state_client_fd)
dbc9832d 849{
cd889e57 850 __do_close_prot_errno int clientfd = -EBADF;
bc631984 851 int state, stopped;
dbc9832d 852 ssize_t ret;
dbc9832d
CB
853 struct lxc_cmd_rr cmd = {
854 .req = {
54446942 855 .cmd = LXC_CMD_ADD_STATE_CLIENT,
dbc9832d
CB
856 .data = states,
857 .datalen = (sizeof(lxc_state_t) * MAX_STATE)
858 },
859 };
860
dbc9832d 861 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
bc631984
CB
862 if (states[STOPPED] != 0 && stopped != 0)
863 return STOPPED;
864
dbc9832d 865 if (ret < 0) {
f577e061 866 if (errno != ECONNREFUSED)
6d1400b5 867 SYSERROR("Failed to execute command");
868
dbc9832d
CB
869 return -1;
870 }
fe84a562 871
dbc9832d
CB
872 /* We should now be guaranteed to get an answer from the state sending
873 * function.
874 */
cd889e57
CB
875 clientfd = cmd.rsp.ret;
876 if (clientfd < 0) {
877 errno = -clientfd;
6d1400b5 878 SYSERROR("Failed to receive socket fd");
dbc9832d
CB
879 return -1;
880 }
881
bc631984
CB
882 state = PTR_TO_INT(cmd.rsp.data);
883 if (state < MAX_STATE) {
44552fb2 884 TRACE("Container is already in requested state %s", lxc_state2str(state));
bc631984
CB
885 return state;
886 }
887
240fecd0 888 *state_client_fd = move_fd(clientfd);
cd889e57 889 TRACE("Added state client %d to state client list", *state_client_fd);
92e35018 890 return MAX_STATE;
dbc9832d
CB
891}
892
54446942 893static int lxc_cmd_add_state_client_callback(int fd, struct lxc_cmd_req *req,
cdb2a47f
CB
894 struct lxc_handler *handler,
895 struct lxc_epoll_descr *descr)
dbc9832d 896{
44552fb2 897 int ret;
dbc9832d 898 struct lxc_cmd_rsp rsp = {0};
dbc9832d 899
fe84a562 900 if (req->datalen < 0)
44552fb2 901 goto reap_client_fd;
dbc9832d 902
71fc9c04 903 if (req->datalen != (sizeof(lxc_state_t) * MAX_STATE))
44552fb2 904 goto reap_client_fd;
dbc9832d 905
fe84a562 906 if (!req->data)
44552fb2 907 goto reap_client_fd;
dbc9832d 908
c01c2be6 909 rsp.ret = lxc_add_state_client(fd, handler, (lxc_state_t *)req->data);
44552fb2
CB
910 if (rsp.ret < 0)
911 goto reap_client_fd;
912
bc631984 913 rsp.data = INT_TO_PTR(rsp.ret);
dbc9832d 914
44552fb2
CB
915 ret = lxc_cmd_rsp_send(fd, &rsp);
916 if (ret < 0)
917 goto reap_client_fd;
918
919 return 0;
920
921reap_client_fd:
922 /* Special indicator to lxc_cmd_handler() to close the fd and do related
923 * cleanup.
924 */
925 return 1;
dbc9832d
CB
926}
927
191d43cc
CB
928int lxc_cmd_console_log(const char *name, const char *lxcpath,
929 struct lxc_console_log *log)
930{
931 int ret, stopped;
932 struct lxc_cmd_console_log data;
933 struct lxc_cmd_rr cmd;
934
935 data.clear = log->clear;
936 data.read = log->read;
937 data.read_max = *log->read_max;
938
939 cmd.req.cmd = LXC_CMD_CONSOLE_LOG;
940 cmd.req.data = &data;
941 cmd.req.datalen = sizeof(struct lxc_cmd_console_log);
942
943 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
944 if (ret < 0)
945 return ret;
946
947 /* There is nothing to be read from the buffer. So clear any values we
948 * where passed to clearly indicate to the user that nothing went wrong.
949 */
63b74cda 950 if (cmd.rsp.ret == -ENODATA || cmd.rsp.ret == -EFAULT || cmd.rsp.ret == -ENOENT) {
191d43cc
CB
951 *log->read_max = 0;
952 log->data = NULL;
953 }
954
955 /* This is a proper error so don't touch any values we were passed. */
956 if (cmd.rsp.ret < 0)
957 return cmd.rsp.ret;
958
959 *log->read_max = cmd.rsp.datalen;
960 log->data = cmd.rsp.data;
961
962 return 0;
963}
964
965static int lxc_cmd_console_log_callback(int fd, struct lxc_cmd_req *req,
cdb2a47f
CB
966 struct lxc_handler *handler,
967 struct lxc_epoll_descr *descr)
191d43cc
CB
968{
969 struct lxc_cmd_rsp rsp;
28f3b1cd 970 uint64_t buffer_size = handler->conf->console.buffer_size;
191d43cc
CB
971 const struct lxc_cmd_console_log *log = req->data;
972 struct lxc_ringbuf *buf = &handler->conf->console.ringbuf;
973
974 rsp.ret = -EFAULT;
975 rsp.datalen = 0;
976 rsp.data = NULL;
28f3b1cd 977 if (buffer_size <= 0)
191d43cc
CB
978 goto out;
979
5928191e
CB
980 if (log->read || log->write_logfile)
981 rsp.datalen = lxc_ringbuf_used(buf);
982
191d43cc
CB
983 if (log->read)
984 rsp.data = lxc_ringbuf_get_read_addr(buf);
985
986 if (log->read_max > 0 && (log->read_max <= rsp.datalen))
987 rsp.datalen = log->read_max;
988
989 /* there's nothing to read */
63b74cda 990 rsp.ret = -ENODATA;
191d43cc 991 if (log->read && (buf->r_off == buf->w_off))
63b74cda
CB
992 goto out;
993
63b74cda 994 rsp.ret = 0;
23e0d9af 995 if (log->clear)
43366ca2 996 lxc_ringbuf_clear(buf); /* clear the ringbuffer */
23e0d9af 997 else if (rsp.datalen > 0)
191d43cc
CB
998 lxc_ringbuf_move_read_addr(buf, rsp.datalen);
999
1000out:
1001 return lxc_cmd_rsp_send(fd, &rsp);
1002}
1003
974a8aba
CB
1004int lxc_cmd_serve_state_clients(const char *name, const char *lxcpath,
1005 lxc_state_t state)
1006{
1007 int stopped;
1008 ssize_t ret;
1009 struct lxc_cmd_rr cmd = {
1010 .req = {
1011 .cmd = LXC_CMD_SERVE_STATE_CLIENTS,
1012 .data = INT_TO_PTR(state)
1013 },
1014 };
1015
1016 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
1017 if (ret < 0) {
6d1400b5 1018 SYSERROR("Failed to execute command");
974a8aba
CB
1019 return -1;
1020 }
1021
1022 return 0;
1023}
1024
1025static int lxc_cmd_serve_state_clients_callback(int fd, struct lxc_cmd_req *req,
cdb2a47f
CB
1026 struct lxc_handler *handler,
1027 struct lxc_epoll_descr *descr)
974a8aba
CB
1028{
1029 int ret;
1030 lxc_state_t state = PTR_TO_INT(req->data);
1031 struct lxc_cmd_rsp rsp = {0};
1032
1033 ret = lxc_serve_state_clients(handler->name, handler, state);
1034 if (ret < 0)
1035 goto reap_client_fd;
1036
1037 ret = lxc_cmd_rsp_send(fd, &rsp);
1038 if (ret < 0)
1039 goto reap_client_fd;
1040
1041 return 0;
1042
1043reap_client_fd:
1044 /* Special indicator to lxc_cmd_handler() to close the fd and do related
1045 * cleanup.
1046 */
1047 return 1;
1048}
1049
cdb2a47f
CB
1050int lxc_cmd_seccomp_notify_add_listener(const char *name, const char *lxcpath,
1051 int fd,
1052 /* unused */ unsigned int command,
1053 /* unused */ unsigned int flags)
1054{
1055
c3e3c21a 1056#ifdef HAVE_SECCOMP_NOTIFY
cdb2a47f
CB
1057 int ret, stopped;
1058 struct lxc_cmd_rr cmd = {
1059 .req = {
1060 .cmd = LXC_CMD_SECCOMP_NOTIFY_ADD_LISTENER,
1061 .data = INT_TO_PTR(fd),
1062 },
1063 };
1064
1065 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
1066 if (ret < 0) {
1067 SYSERROR("Failed to execute command");
1068 return -1;
1069 }
1070
1071 return cmd.rsp.ret;
1072#else
1073 return minus_one_set_errno(ENOSYS);
1074#endif
1075}
1076
1077static int lxc_cmd_seccomp_notify_add_listener_callback(int fd,
1078 struct lxc_cmd_req *req,
1079 struct lxc_handler *handler,
1080 struct lxc_epoll_descr *descr)
1081{
1082 struct lxc_cmd_rsp rsp = {0};
cdb2a47f 1083
c3e3c21a
CB
1084#ifdef HAVE_SECCOMP_NOTIFY
1085 int ret;
cdb2a47f
CB
1086 __do_close_prot_errno int recv_fd = -EBADF;
1087 int notify_fd = -EBADF;
1088
c3e3c21a
CB
1089 ret = lxc_abstract_unix_recv_fds(fd, &recv_fd, 1, NULL, 0);
1090 if (ret <= 0) {
1091 rsp.ret = -errno;
1092 goto out;
cdb2a47f
CB
1093 }
1094
c3e3c21a
CB
1095 if (!handler->conf->seccomp.notifier.wants_supervision ||
1096 handler->conf->seccomp.notifier.proxy_fd < 0) {
1097 SYSERROR("No seccomp proxy fd specified");
1098 rsp.ret = -EINVAL;
1099 goto out;
1100 }
cdb2a47f 1101
c3e3c21a 1102 ret = lxc_mainloop_add_handler(descr, recv_fd, seccomp_notify_handler,
cdb2a47f 1103 handler);
c3e3c21a
CB
1104 if (ret < 0) {
1105 rsp.ret = -errno;
1106 goto out;
1107 }
cdb2a47f 1108 notify_fd = move_fd(recv_fd);
cdb2a47f 1109
c3e3c21a 1110out:
cdb2a47f
CB
1111#else
1112 rsp.ret = -ENOSYS;
cdb2a47f 1113
c3e3c21a
CB
1114#endif
1115 return lxc_cmd_rsp_send(fd, &rsp);
cdb2a47f
CB
1116}
1117
ef6e34ee 1118static int lxc_cmd_process(int fd, struct lxc_cmd_req *req,
cdb2a47f
CB
1119 struct lxc_handler *handler,
1120 struct lxc_epoll_descr *descr)
724e753c 1121{
cdb2a47f
CB
1122 typedef int (*callback)(int, struct lxc_cmd_req *, struct lxc_handler *,
1123 struct lxc_epoll_descr *);
ef6e34ee
DE
1124
1125 callback cb[LXC_CMD_MAX] = {
cdb2a47f
CB
1126 [LXC_CMD_CONSOLE] = lxc_cmd_console_callback,
1127 [LXC_CMD_TERMINAL_WINCH] = lxc_cmd_terminal_winch_callback,
1128 [LXC_CMD_STOP] = lxc_cmd_stop_callback,
1129 [LXC_CMD_GET_STATE] = lxc_cmd_get_state_callback,
1130 [LXC_CMD_GET_INIT_PID] = lxc_cmd_get_init_pid_callback,
1131 [LXC_CMD_GET_CLONE_FLAGS] = lxc_cmd_get_clone_flags_callback,
1132 [LXC_CMD_GET_CGROUP] = lxc_cmd_get_cgroup_callback,
1133 [LXC_CMD_GET_CONFIG_ITEM] = lxc_cmd_get_config_item_callback,
1134 [LXC_CMD_GET_NAME] = lxc_cmd_get_name_callback,
1135 [LXC_CMD_GET_LXCPATH] = lxc_cmd_get_lxcpath_callback,
1136 [LXC_CMD_ADD_STATE_CLIENT] = lxc_cmd_add_state_client_callback,
1137 [LXC_CMD_CONSOLE_LOG] = lxc_cmd_console_log_callback,
1138 [LXC_CMD_SERVE_STATE_CLIENTS] = lxc_cmd_serve_state_clients_callback,
1139 [LXC_CMD_SECCOMP_NOTIFY_ADD_LISTENER] = lxc_cmd_seccomp_notify_add_listener_callback,
724e753c
MN
1140 };
1141
f371aca9 1142 if (req->cmd >= LXC_CMD_MAX) {
fe84a562 1143 ERROR("Undefined command id %d", req->cmd);
724e753c 1144 return -1;
ef6e34ee 1145 }
cdb2a47f 1146 return cb[req->cmd](fd, req, handler, descr);
724e753c
MN
1147}
1148
ef6e34ee 1149static void lxc_cmd_fd_cleanup(int fd, struct lxc_handler *handler,
cdb2a47f 1150 struct lxc_epoll_descr *descr, const lxc_cmd_t cmd)
724e753c 1151{
f6fc1565
CB
1152 struct lxc_list *cur, *next;
1153
3dfe6f8d 1154 lxc_terminal_free(handler->conf, fd);
724e753c 1155 lxc_mainloop_del_handler(descr, fd);
f6fc1565 1156
cdb2a47f
CB
1157 switch (cmd) {
1158 case LXC_CMD_ADD_STATE_CLIENT:
1159 lxc_list_for_each_safe(cur, &handler->conf->state_clients, next) {
1160 struct lxc_state_client *client = cur->elem;
1161
1162 if (client->clientfd != fd)
1163 continue;
1164
1165 /* kick client from list */
1166 lxc_list_del(cur);
1167 close(client->clientfd);
1168 free(cur->elem);
1169 free(cur);
1170 /* No need to walk the whole list. If we found the state
1171 * client fd there can't be a second one.
1172 */
1173 break;
1174 }
b1ca434a 1175 break;
cdb2a47f
CB
1176 default:
1177 close(fd);
f6fc1565 1178 }
724e753c
MN
1179}
1180
84c92abd
DE
1181static int lxc_cmd_handler(int fd, uint32_t events, void *data,
1182 struct lxc_epoll_descr *descr)
724e753c 1183{
5265a60c 1184 __do_free void *reqdata = NULL;
724e753c 1185 int ret;
ef6e34ee 1186 struct lxc_cmd_req req;
724e753c
MN
1187 struct lxc_handler *handler = data;
1188
aae93dd3 1189 ret = lxc_abstract_unix_rcv_credential(fd, &req, sizeof(req));
ded1d23f 1190 if (ret < 0) {
fe84a562 1191 SYSERROR("Failed to receive data on command socket for command "
9044b79e 1192 "\"%s\"", lxc_cmd_str(req.cmd));
1193
1194 if (errno == EACCES) {
1195 /* We don't care for the peer, just send and close. */
1196 struct lxc_cmd_rsp rsp = {.ret = ret};
1197
1198 lxc_cmd_rsp_send(fd, &rsp);
1199 }
1200
724e753c
MN
1201 goto out_close;
1202 }
1203
fe84a562 1204 if (ret == 0)
724e753c 1205 goto out_close;
724e753c 1206
ef6e34ee 1207 if (ret != sizeof(req)) {
c01c2be6 1208 WARN("Failed to receive full command request. Ignoring request "
fe84a562 1209 "for \"%s\"", lxc_cmd_str(req.cmd));
ef6e34ee
DE
1210 ret = -1;
1211 goto out_close;
1212 }
1213
191d43cc
CB
1214 if ((req.datalen > LXC_CMD_DATA_MAX) &&
1215 (req.cmd != LXC_CMD_CONSOLE_LOG)) {
c01c2be6 1216 ERROR("Received command data length %d is too large for "
fe84a562
CB
1217 "command \"%s\"", req.datalen, lxc_cmd_str(req.cmd));
1218 errno = EFBIG;
1219 ret = -EFBIG;
724e753c
MN
1220 goto out_close;
1221 }
1222
ef6e34ee 1223 if (req.datalen > 0) {
5265a60c 1224 reqdata = must_realloc(NULL, req.datalen);
e3233f26 1225 ret = lxc_recv_nointr(fd, reqdata, req.datalen, 0);
ef6e34ee 1226 if (ret != req.datalen) {
c01c2be6 1227 WARN("Failed to receive full command request. Ignoring "
fe84a562 1228 "request for \"%s\"", lxc_cmd_str(req.cmd));
b2a48508 1229 ret = LXC_MAINLOOP_ERROR;
ef6e34ee
DE
1230 goto out_close;
1231 }
fe84a562 1232
ef6e34ee
DE
1233 req.data = reqdata;
1234 }
1235
cdb2a47f 1236 ret = lxc_cmd_process(fd, &req, handler, descr);
724e753c 1237 if (ret) {
fe84a562 1238 /* This is not an error, but only a request to close fd. */
b2a48508 1239 ret = LXC_MAINLOOP_CONTINUE;
724e753c
MN
1240 goto out_close;
1241 }
1242
1243out:
1244 return ret;
fe84a562 1245
724e753c 1246out_close:
f6fc1565 1247 lxc_cmd_fd_cleanup(fd, handler, descr, req.cmd);
724e753c
MN
1248 goto out;
1249}
1250
84c92abd
DE
1251static int lxc_cmd_accept(int fd, uint32_t events, void *data,
1252 struct lxc_epoll_descr *descr)
724e753c 1253{
4c2effce 1254 __do_close_prot_errno int connection = -EBADF;
fe84a562 1255 int opt = 1, ret = -1;
724e753c
MN
1256
1257 connection = accept(fd, NULL, 0);
1258 if (connection < 0) {
47903908 1259 SYSERROR("Failed to accept connection to run command");
b2a48508 1260 return LXC_MAINLOOP_ERROR;
724e753c
MN
1261 }
1262
fe84a562
CB
1263 ret = fcntl(connection, F_SETFD, FD_CLOEXEC);
1264 if (ret < 0) {
1265 SYSERROR("Failed to set close-on-exec on incoming command connection");
4c2effce 1266 return ret;
9ccb2dbc
DL
1267 }
1268
fe84a562
CB
1269 ret = setsockopt(connection, SOL_SOCKET, SO_PASSCRED, &opt, sizeof(opt));
1270 if (ret < 0) {
1271 SYSERROR("Failed to enable necessary credentials on command socket");
4c2effce 1272 return ret;
724e753c
MN
1273 }
1274
ef6e34ee 1275 ret = lxc_mainloop_add_handler(descr, connection, lxc_cmd_handler, data);
724e753c 1276 if (ret) {
fe84a562 1277 ERROR("Failed to add command handler");
4c2effce 1278 return ret;
724e753c
MN
1279 }
1280
240fecd0 1281 move_fd(connection);
724e753c 1282 return ret;
724e753c
MN
1283}
1284
9dfa4041 1285int lxc_cmd_init(const char *name, const char *lxcpath, const char *suffix)
724e753c 1286{
c13e7111
CB
1287 __do_close_prot_errno int fd = -EBADF;
1288 int ret;
b1234129 1289 char path[LXC_AUDS_ADDR_LEN] = {0};
724e753c 1290
5b46db1a 1291 ret = lxc_make_abstract_socket_name(path, sizeof(path), name, lxcpath, NULL, suffix);
fe84a562 1292 if (ret < 0)
9ba8130c 1293 return -1;
724e753c 1294
aae93dd3 1295 fd = lxc_abstract_unix_open(path, SOCK_STREAM, 0);
724e753c 1296 if (fd < 0) {
5b46db1a 1297 SYSERROR("Failed to create command socket %s", &path[1]);
08aa08fe 1298 if (errno == EADDRINUSE)
fe84a562 1299 ERROR("Container \"%s\" appears to be already running", name);
6d1400b5 1300
724e753c
MN
1301 return -1;
1302 }
1303
fe84a562
CB
1304 ret = fcntl(fd, F_SETFD, FD_CLOEXEC);
1305 if (ret < 0) {
1306 SYSERROR("Failed to set FD_CLOEXEC on command socket file descriptor");
91480a0f
DL
1307 return -1;
1308 }
1309
c13e7111 1310 TRACE("Created abstract unix socket \"%s\"", &path[1]);
240fecd0 1311 return move_fd(fd);
d2e30e99
DE
1312}
1313
fe84a562 1314int lxc_cmd_mainloop_add(const char *name, struct lxc_epoll_descr *descr,
ef6e34ee 1315 struct lxc_handler *handler)
d2e30e99 1316{
2a30bdea 1317 __do_close_prot_errno int fd = handler->conf->maincmd_fd;
fe84a562 1318 int ret;
d2e30e99 1319
ef6e34ee 1320 ret = lxc_mainloop_add_handler(descr, fd, lxc_cmd_accept, handler);
fe84a562
CB
1321 if (ret < 0) {
1322 ERROR("Failed to add handler for command socket");
2a30bdea 1323 return ret;
724e753c
MN
1324 }
1325
240fecd0 1326 move_fd(fd);
724e753c
MN
1327 return ret;
1328}