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