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