]> git.proxmox.com Git - mirror_lxc.git/blame - src/lxc/commands.c
coverity: #1425890
[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 "console.h"
46#include "log.h"
47#include "lxc.h"
dbc9832d 48#include "lxclock.h"
724e753c 49#include "mainloop.h"
dbc9832d 50#include "monitor.h"
fe84a562
CB
51#include "start.h"
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
724e753c
MN
79lxc_log_define(lxc_commands, lxc);
80
ef6e34ee 81static const char *lxc_cmd_str(lxc_cmd_t cmd)
724e753c 82{
fe84a562 83 static const char *const cmdname[LXC_CMD_MAX] = {
54446942 84 [LXC_CMD_CONSOLE] = "console",
86a78f17 85 [LXC_CMD_CONSOLE_WINCH] = "console_winch",
54446942
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",
0d9cd9c3 95 [LXC_CMD_SET_CONFIG_ITEM] = "set_config_item",
191d43cc 96 [LXC_CMD_CONSOLE_LOG] = "console_log",
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) {
fe84a562
CB
129 WARN("%s - Failed to receive response for command \"%s\"",
130 strerror(errno), lxc_cmd_str(cmd->req.cmd));
6b7f85cb
CB
131 if (errno == ECONNRESET)
132 return -ECONNRESET;
133
ef6e34ee
DE
134 return -1;
135 }
fe84a562 136 TRACE("Command \"%s\" received response", lxc_cmd_str(cmd->req.cmd));
ef6e34ee
DE
137
138 if (cmd->req.cmd == LXC_CMD_CONSOLE) {
139 struct lxc_cmd_console_rsp_data *rspdata;
140
0115f8fd
DE
141 /* recv() returns 0 bytes when a tty cannot be allocated,
142 * rsp->ret is < 0 when the peer permission check failed
143 */
144 if (ret == 0 || rsp->ret < 0)
145 return 0;
146
ef6e34ee
DE
147 rspdata = malloc(sizeof(*rspdata));
148 if (!rspdata) {
fe84a562 149 ERROR("Failed to allocate response buffer for command \"%s\"",
ef6e34ee 150 lxc_cmd_str(cmd->req.cmd));
fe84a562 151 return -ENOMEM;
ef6e34ee 152 }
0115f8fd 153 rspdata->masterfd = rspfd;
ef6e34ee
DE
154 rspdata->ttynum = PTR_TO_INT(rsp->data);
155 rsp->data = rspdata;
156 }
157
860e7c43 158 if (rsp->datalen == 0) {
fe84a562 159 DEBUG("Response data length for command \"%s\" is 0",
860e7c43 160 lxc_cmd_str(cmd->req.cmd));
ae5c8b8e 161 return ret;
860e7c43 162 }
fe84a562 163
191d43cc
CB
164 if ((rsp->datalen > LXC_CMD_DATA_MAX) &&
165 (cmd->req.cmd != LXC_CMD_CONSOLE_LOG)) {
ef6e34ee 166 errno = EFBIG;
fe84a562
CB
167 ERROR("%s - Response data for command \"%s\" is too long: %d "
168 "bytes > %d", strerror(errno), lxc_cmd_str(cmd->req.cmd),
169 rsp->datalen, LXC_CMD_DATA_MAX);
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
CB
180 errno = ENOMEM;
181 ERROR("%s - Failed to allocate response buffer for command "
182 "\"%s\"", strerror(errno), lxc_cmd_str(cmd->req.cmd));
183 return -ENOMEM;
ef6e34ee 184 }
fe84a562 185
ef6e34ee
DE
186 ret = recv(sock, rsp->data, rsp->datalen, 0);
187 if (ret != rsp->datalen) {
fe84a562 188 ERROR("%s - Failed to receive response data for command \"%s\"",
08aa08fe 189 lxc_cmd_str(cmd->req.cmd), strerror(errno));
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
DE
208
209 ret = send(fd, rsp, sizeof(*rsp), 0);
fe84a562
CB
210 if (ret < 0 || (size_t)ret != sizeof(*rsp)) {
211 ERROR("%s - Failed to send command response %zd",
212 strerror(errno), ret);
ef6e34ee
DE
213 return -1;
214 }
215
fe84a562
CB
216 if (rsp->datalen <= 0)
217 return 0;
218
219 ret = send(fd, rsp->data, rsp->datalen, 0);
220 if (ret < 0 || ret != (ssize_t)rsp->datalen) {
221 WARN("%s - Failed to send command response data %zd",
222 strerror(errno), ret);
223 return -1;
ef6e34ee 224 }
fe84a562 225
ef6e34ee
DE
226 return 0;
227}
228
c01c2be6 229static int lxc_cmd_send(const char *name, struct lxc_cmd_rr *cmd,
fe84a562 230 const char *lxcpath, const char *hashed_sock_name)
c01c2be6
CB
231{
232 int client_fd;
fe84a562 233 ssize_t ret = -1;
c01c2be6 234
9dfa4041 235 client_fd = lxc_cmd_connect(name, lxcpath, hashed_sock_name, "command");
fe84a562
CB
236 if (client_fd < 0) {
237 if (client_fd == -ECONNREFUSED)
238 return -ECONNREFUSED;
c01c2be6 239
fe84a562
CB
240 return -1;
241 }
c01c2be6 242
fe84a562
CB
243 ret = lxc_abstract_unix_send_credential(client_fd, &cmd->req,
244 sizeof(cmd->req));
245 if (ret < 0 || (size_t)ret != sizeof(cmd->req)) {
c01c2be6
CB
246 close(client_fd);
247
248 if (errno == EPIPE)
249 return -EPIPE;
250
251 if (ret >= 0)
252 return -EMSGSIZE;
253
254 return -1;
255 }
256
fe84a562
CB
257 if (cmd->req.datalen <= 0)
258 return client_fd;
c01c2be6 259
fe84a562
CB
260 ret = send(client_fd, cmd->req.data, cmd->req.datalen, MSG_NOSIGNAL);
261 if (ret < 0 || ret != (ssize_t)cmd->req.datalen) {
262 close(client_fd);
c01c2be6 263
fe84a562
CB
264 if (errno == EPIPE)
265 return -EPIPE;
c01c2be6 266
fe84a562
CB
267 if (ret >= 0)
268 return -EMSGSIZE;
c01c2be6 269
fe84a562 270 return -1;
c01c2be6
CB
271 }
272
273 return client_fd;
274}
275
ef6e34ee
DE
276/*
277 * lxc_cmd: Connect to the specified running container, send it a command
278 * request and collect the response
279 *
280 * @name : name of container to connect to
1e8cfdf6 281 * @cmd : command with initialized request to send
ef6e34ee
DE
282 * @stopped : output indicator if the container was not running
283 * @lxcpath : the lxcpath in which the container is running
284 *
285 * Returns the size of the response message on success, < 0 on failure
286 *
287 * Note that there is a special case for LXC_CMD_CONSOLE. For this command
288 * the fd cannot be closed because it is used as a placeholder to indicate
289 * that a particular tty slot is in use. The fd is also used as a signal to
290 * the container that when the caller dies or closes the fd, the container
0115f8fd
DE
291 * will notice the fd on its side of the socket in its mainloop select and
292 * then free the slot with lxc_cmd_fd_cleanup(). The socket fd will be
293 * returned in the cmd response structure.
ef6e34ee
DE
294 */
295static int lxc_cmd(const char *name, struct lxc_cmd_rr *cmd, int *stopped,
88556fd7 296 const char *lxcpath, const char *hashed_sock_name)
724e753c 297{
fe84a562
CB
298 int client_fd;
299 int ret = -1;
dbc9832d
CB
300 bool stay_connected = false;
301
302 if (cmd->req.cmd == LXC_CMD_CONSOLE ||
54446942 303 cmd->req.cmd == LXC_CMD_ADD_STATE_CLIENT)
dbc9832d 304 stay_connected = true;
724e753c 305
0ecf64b5
SH
306 *stopped = 0;
307
c01c2be6
CB
308 client_fd = lxc_cmd_send(name, cmd, lxcpath, hashed_sock_name);
309 if (client_fd < 0) {
fe84a562
CB
310 TRACE("%s - Command \"%s\" failed to connect command socket",
311 strerror(errno), lxc_cmd_str(cmd->req.cmd));
c01c2be6 312 if (client_fd == -ECONNREFUSED) {
ef6e34ee 313 *stopped = 1;
c01c2be6 314 return -1;
3f903c04
CB
315 }
316
c01c2be6 317 if (client_fd == -EPIPE)
6168ff15 318 goto epipe;
724e753c 319
c01c2be6 320 goto out;
724e753c
MN
321 }
322
c01c2be6 323 ret = lxc_cmd_rsp_recv(client_fd, cmd);
6b7f85cb
CB
324 if (ret == -ECONNRESET)
325 *stopped = 1;
724e753c 326out:
4575a9f9 327 if (!stay_connected || ret <= 0)
c01c2be6 328 close(client_fd);
fe84a562 329
0115f8fd 330 if (stay_connected && ret > 0)
c01c2be6 331 cmd->rsp.ret = client_fd;
43eb6f29 332
1362f2eb 333 return ret;
6168ff15
SH
334
335epipe:
6168ff15
SH
336 *stopped = 1;
337 return 0;
724e753c
MN
338}
339
b494d2dd
SH
340int lxc_try_cmd(const char *name, const char *lxcpath)
341{
0ecf64b5 342 int stopped, ret;
b494d2dd
SH
343 struct lxc_cmd_rr cmd = {
344 .req = { .cmd = LXC_CMD_GET_INIT_PID },
345 };
346
88556fd7 347 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
b494d2dd
SH
348 if (stopped)
349 return 0;
350 if (ret > 0 && cmd.rsp.ret < 0) {
351 errno = cmd.rsp.ret;
352 return -1;
353 }
354 if (ret > 0)
355 return 0;
356
fe84a562
CB
357 /* At this point we weren't denied access, and the container *was*
358 * started. There was some inexplicable error in the protocol. I'm not
359 * clear on whether we should return -1 here, but we didn't receive a
360 * -EACCES, so technically it's not that we're not allowed to control
361 * the container - it's just not behaving.
b494d2dd
SH
362 */
363 return 0;
364}
365
ef6e34ee
DE
366/* Implentations of the commands and their callbacks */
367
368/*
369 * lxc_cmd_get_init_pid: Get pid of the container's init process
370 *
371 * @name : name of container to connect to
372 * @lxcpath : the lxcpath in which the container is running
373 *
374 * Returns the pid on success, < 0 on failure
375 */
376pid_t lxc_cmd_get_init_pid(const char *name, const char *lxcpath)
43eb6f29 377{
0ecf64b5 378 int ret, stopped;
ef6e34ee
DE
379 struct lxc_cmd_rr cmd = {
380 .req = { .cmd = LXC_CMD_GET_INIT_PID },
381 };
382
88556fd7 383 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
ef6e34ee
DE
384 if (ret < 0)
385 return ret;
386
387 return PTR_TO_INT(cmd.rsp.data);
43eb6f29
DL
388}
389
ef6e34ee
DE
390static int lxc_cmd_get_init_pid_callback(int fd, struct lxc_cmd_req *req,
391 struct lxc_handler *handler)
43eb6f29 392{
ef6e34ee
DE
393 struct lxc_cmd_rsp rsp = { .data = INT_TO_PTR(handler->pid) };
394
395 return lxc_cmd_rsp_send(fd, &rsp);
43eb6f29
DL
396}
397
ef6e34ee
DE
398/*
399 * lxc_cmd_get_clone_flags: Get clone flags container was spawned with
400 *
401 * @name : name of container to connect to
402 * @lxcpath : the lxcpath in which the container is running
403 *
404 * Returns the clone flags on success, < 0 on failure
405 */
406int lxc_cmd_get_clone_flags(const char *name, const char *lxcpath)
407{
0ecf64b5 408 int ret, stopped;
ef6e34ee
DE
409 struct lxc_cmd_rr cmd = {
410 .req = { .cmd = LXC_CMD_GET_CLONE_FLAGS },
411 };
412
88556fd7 413 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
ef6e34ee
DE
414 if (ret < 0)
415 return ret;
43eb6f29 416
ef6e34ee
DE
417 return PTR_TO_INT(cmd.rsp.data);
418}
419
420static int lxc_cmd_get_clone_flags_callback(int fd, struct lxc_cmd_req *req,
421 struct lxc_handler *handler)
26b2d152 422{
ef6e34ee
DE
423 struct lxc_cmd_rsp rsp = { .data = INT_TO_PTR(handler->clone_flags) };
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,
fe84a562 447 .datalen = strlen(subsystem) + 1,
b98f7d6e
SH
448 .data = subsystem,
449 },
26b2d152
MN
450 };
451
88556fd7 452 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
fe84a562 453 if (ret < 0)
ef6e34ee
DE
454 return NULL;
455
fe84a562 456 if (ret == 0)
ef6e34ee 457 return NULL;
ef6e34ee 458
fe84a562 459 if (cmd.rsp.ret < 0 || cmd.rsp.datalen < 0)
ef6e34ee 460 return NULL;
3f903c04 461
ef6e34ee
DE
462 return cmd.rsp.data;
463}
464
465static int lxc_cmd_get_cgroup_callback(int fd, struct lxc_cmd_req *req,
466 struct lxc_handler *handler)
467{
4fb3cba5 468 const char *path;
fe84a562 469 struct lxc_cmd_rsp rsp;
b98f7d6e
SH
470
471 if (req->datalen < 1)
472 return -1;
8900b9eb 473
d4ef7c50 474 path = cgroup_get_cgroup(handler, req->data);
b98f7d6e
SH
475 if (!path)
476 return -1;
fe84a562 477
4f17323e 478 rsp.ret = 0;
fe84a562
CB
479 rsp.datalen = strlen(path) + 1;
480 rsp.data = (char *)path;
ef6e34ee
DE
481
482 return lxc_cmd_rsp_send(fd, &rsp);
483}
484
485/*
486 * lxc_cmd_get_config_item: Get config item the running container
487 *
488 * @name : name of container to connect to
7fa3f2e9 489 * @item : the configuration item to retrieve (ex: lxc.net.0.veth.pair)
ef6e34ee
DE
490 * @lxcpath : the lxcpath in which the container is running
491 *
492 * Returns the item on success, NULL on failure. The caller must free() the
493 * returned item.
494 */
495char *lxc_cmd_get_config_item(const char *name, const char *item,
496 const char *lxcpath)
497{
0ecf64b5 498 int ret, stopped;
ef6e34ee
DE
499 struct lxc_cmd_rr cmd = {
500 .req = { .cmd = LXC_CMD_GET_CONFIG_ITEM,
501 .data = item,
fe84a562 502 .datalen = strlen(item) + 1,
ef6e34ee
DE
503 },
504 };
505
88556fd7 506 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
ef6e34ee
DE
507 if (ret < 0)
508 return NULL;
509
510 if (cmd.rsp.ret == 0)
511 return cmd.rsp.data;
fe84a562 512
ef6e34ee
DE
513 return NULL;
514}
515
516static int lxc_cmd_get_config_item_callback(int fd, struct lxc_cmd_req *req,
517 struct lxc_handler *handler)
518{
519 int cilen;
ef6e34ee 520 char *cidata;
30aec088 521 struct lxc_config_t *item;
fe84a562 522 struct lxc_cmd_rsp rsp;
ef6e34ee
DE
523
524 memset(&rsp, 0, sizeof(rsp));
300df83e 525 item = lxc_get_config(req->data);
30aec088
CB
526 if (!item)
527 goto err1;
fe84a562 528
cccd2219 529 cilen = item->get(req->data, NULL, 0, handler->conf, NULL);
ef6e34ee
DE
530 if (cilen <= 0)
531 goto err1;
532
533 cidata = alloca(cilen + 1);
cccd2219 534 if (item->get(req->data, cidata, cilen + 1, handler->conf, NULL) != cilen)
ef6e34ee 535 goto err1;
fe84a562 536
ef6e34ee
DE
537 cidata[cilen] = '\0';
538 rsp.data = cidata;
539 rsp.datalen = cilen + 1;
540 rsp.ret = 0;
541 goto out;
542
543err1:
544 rsp.ret = -1;
545out:
546 return lxc_cmd_rsp_send(fd, &rsp);
547}
548
0d9cd9c3
CB
549/*
550 * lxc_cmd_set_config_item: Get config item the running container
551 *
552 * @name : name of container to connect to
553 * @item : the configuration item to set (ex: lxc.net.0.veth.pair)
554 * @value : the value to set (ex: "eth0")
555 * @lxcpath : the lxcpath in which the container is running
556 *
557 * Returns 0 on success, negative errno on failure.
558 */
559int lxc_cmd_set_config_item(const char *name, const char *item,
560 const char *value, const char *lxcpath)
561{
562 int ret, stopped;
563 struct lxc_cmd_set_config_item_req_data data;
564 struct lxc_cmd_rr cmd;
565
566 /* pre-validate request
567 Currently we only support live-patching network configurations.
568 */
569 if (strncmp(item, "lxc.net.", 8))
570 return -EINVAL;
571
572 data.item = item;
573 data.value = (void *)value;
574
575 cmd.req.cmd = LXC_CMD_SET_CONFIG_ITEM;
576 cmd.req.data = &data;
577 cmd.req.datalen = sizeof(data);
578
579 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
580 if (ret < 0)
581 return ret;
582
583 return cmd.rsp.ret;
584}
585
586static int lxc_cmd_set_config_item_callback(int fd, struct lxc_cmd_req *req,
587 struct lxc_handler *handler)
588{
589 const char *key, *value;
590 struct lxc_cmd_rsp rsp;
591 const struct lxc_cmd_set_config_item_req_data *data;
592
593 data = req->data;
594 key = data->item;
595 value = data->value;
596
597 memset(&rsp, 0, sizeof(rsp));
598 rsp.ret = lxc_set_config_item_locked(handler->conf, key, value);
fe84a562 599
0d9cd9c3
CB
600 return lxc_cmd_rsp_send(fd, &rsp);
601}
602
ef6e34ee
DE
603/*
604 * lxc_cmd_get_state: Get current state of the container
605 *
606 * @name : name of container to connect to
607 * @lxcpath : the lxcpath in which the container is running
608 *
609 * Returns the state on success, < 0 on failure
610 */
dbc9832d 611int lxc_cmd_get_state(const char *name, const char *lxcpath)
ef6e34ee 612{
0ecf64b5 613 int ret, stopped;
ef6e34ee
DE
614 struct lxc_cmd_rr cmd = {
615 .req = { .cmd = LXC_CMD_GET_STATE }
616 };
26b2d152 617
88556fd7 618 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
ebdd307d 619 if (ret < 0 && stopped)
ef6e34ee
DE
620 return STOPPED;
621
622 if (ret < 0)
26b2d152 623 return -1;
26b2d152 624
ef6e34ee 625 if (!ret) {
fe84a562 626 WARN("Container \"%s\" has stopped before sending its state", name);
ef6e34ee
DE
627 return -1;
628 }
629
fe84a562 630 DEBUG("Container \"%s\" is in \"%s\" state", name,
ef6e34ee 631 lxc_state2str(PTR_TO_INT(cmd.rsp.data)));
fe84a562 632
ef6e34ee
DE
633 return PTR_TO_INT(cmd.rsp.data);
634}
635
636static int lxc_cmd_get_state_callback(int fd, struct lxc_cmd_req *req,
637 struct lxc_handler *handler)
638{
639 struct lxc_cmd_rsp rsp = { .data = INT_TO_PTR(handler->state) };
640
641 return lxc_cmd_rsp_send(fd, &rsp);
642}
643
644/*
645 * lxc_cmd_stop: Stop the container previously started with lxc_start. All
646 * the processes running inside this container will be killed.
647 *
648 * @name : name of container to connect to
649 * @lxcpath : the lxcpath in which the container is running
650 *
651 * Returns 0 on success, < 0 on failure
652 */
653int lxc_cmd_stop(const char *name, const char *lxcpath)
654{
0ecf64b5 655 int ret, stopped;
ef6e34ee
DE
656 struct lxc_cmd_rr cmd = {
657 .req = { .cmd = LXC_CMD_STOP },
658 };
659
88556fd7 660 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
26b2d152 661 if (ret < 0) {
ef6e34ee 662 if (stopped) {
fe84a562 663 INFO("Container \"%s\" is already stopped", name);
ef6e34ee
DE
664 return 0;
665 }
fe84a562 666
26b2d152
MN
667 return -1;
668 }
669
fe84a562
CB
670 /* We do not expect any answer, because we wait for the connection to be
671 * closed.
95d5b147
SH
672 */
673 if (ret > 0) {
fe84a562
CB
674 ERROR("%s - Failed to stop container \"%s\"",
675 strerror(-cmd.rsp.ret), name);
26b2d152
MN
676 return -1;
677 }
678
fe84a562 679 INFO("Container \"%s\" has stopped", name);
ef6e34ee 680 return 0;
26b2d152
MN
681}
682
ef6e34ee
DE
683static int lxc_cmd_stop_callback(int fd, struct lxc_cmd_req *req,
684 struct lxc_handler *handler)
d5088cf2 685{
ef6e34ee 686 struct lxc_cmd_rsp rsp;
ef6e34ee
DE
687 int stopsignal = SIGKILL;
688
689 if (handler->conf->stopsignal)
690 stopsignal = handler->conf->stopsignal;
691 memset(&rsp, 0, sizeof(rsp));
692 rsp.ret = kill(handler->pid, stopsignal);
693 if (!rsp.ret) {
fe84a562 694 /* We can't just use lxc_unfreeze() since we are already in the
4fb3cba5
DE
695 * context of handling the STOP cmd in lxc-start, and calling
696 * lxc_unfreeze() would do another cmd (GET_CGROUP) which would
fe84a562 697 * deadlock us.
4fb3cba5
DE
698 */
699 if (cgroup_unfreeze(handler))
95d5b147 700 return 0;
fe84a562
CB
701
702 ERROR("Failed to unfreeze container \"%s\"", handler->name);
ecfcb3f0 703 rsp.ret = -1;
ef6e34ee
DE
704 }
705
706 return lxc_cmd_rsp_send(fd, &rsp);
707}
d5088cf2 708
b5159817
DE
709/*
710 * lxc_cmd_console_winch: To process as if a SIGWINCH were received
711 *
712 * @name : name of container to connect to
713 * @lxcpath : the lxcpath in which the container is running
714 *
715 * Returns 0 on success, < 0 on failure
716 */
717int lxc_cmd_console_winch(const char *name, const char *lxcpath)
718{
0ecf64b5 719 int ret, stopped;
b5159817
DE
720 struct lxc_cmd_rr cmd = {
721 .req = { .cmd = LXC_CMD_CONSOLE_WINCH },
722 };
723
88556fd7 724 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
b5159817
DE
725 if (ret < 0)
726 return ret;
727
728 return 0;
729}
730
731static int lxc_cmd_console_winch_callback(int fd, struct lxc_cmd_req *req,
732 struct lxc_handler *handler)
733{
734 struct lxc_cmd_rsp rsp = { .data = 0 };
735
736 lxc_console_sigwinch(SIGWINCH);
fe84a562 737
b5159817
DE
738 return lxc_cmd_rsp_send(fd, &rsp);
739}
740
ef6e34ee
DE
741/*
742 * lxc_cmd_console: Open an fd to a tty in the container
743 *
744 * @name : name of container to connect to
745 * @ttynum : in: the tty to open or -1 for next available
746 * : out: the tty allocated
747 * @fd : out: file descriptor for master side of pty
748 * @lxcpath : the lxcpath in which the container is running
749 *
0115f8fd 750 * Returns fd holding tty allocated on success, < 0 on failure
ef6e34ee
DE
751 */
752int lxc_cmd_console(const char *name, int *ttynum, int *fd, const char *lxcpath)
753{
0ecf64b5 754 int ret, stopped;
ef6e34ee
DE
755 struct lxc_cmd_console_rsp_data *rspdata;
756 struct lxc_cmd_rr cmd = {
757 .req = { .cmd = LXC_CMD_CONSOLE, .data = INT_TO_PTR(*ttynum) },
758 };
d5088cf2 759
88556fd7 760 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
ef6e34ee
DE
761 if (ret < 0)
762 return ret;
0115f8fd
DE
763
764 if (cmd.rsp.ret < 0) {
fe84a562 765 ERROR("%s - Denied access to tty", strerror(-cmd.rsp.ret));
ef6e34ee
DE
766 ret = -1;
767 goto out;
768 }
d5088cf2 769
0115f8fd 770 if (ret == 0) {
fe84a562 771 ERROR("tty number %d invalid, busy or all ttys busy", *ttynum);
0115f8fd 772 ret = -1;
ef6e34ee
DE
773 goto out;
774 }
ef6e34ee
DE
775
776 rspdata = cmd.rsp.data;
0115f8fd 777 if (rspdata->masterfd < 0) {
fe84a562 778 ERROR("Unable to allocate fd for tty %d", rspdata->ttynum);
ef6e34ee
DE
779 goto out;
780 }
781
fe84a562 782 ret = cmd.rsp.ret; /* socket fd */
0115f8fd 783 *fd = rspdata->masterfd;
ef6e34ee 784 *ttynum = rspdata->ttynum;
fe84a562
CB
785 INFO("Alloced fd %d for tty %d via socket %d", *fd, rspdata->ttynum, ret);
786
ef6e34ee
DE
787out:
788 free(cmd.rsp.data);
789 return ret;
790}
791
792static int lxc_cmd_console_callback(int fd, struct lxc_cmd_req *req,
793 struct lxc_handler *handler)
794{
fe84a562 795 int masterfd, ret;
ef6e34ee 796 struct lxc_cmd_rsp rsp;
fe84a562 797 int ttynum = PTR_TO_INT(req->data);
ef6e34ee 798
b5159817
DE
799 masterfd = lxc_console_allocate(handler->conf, fd, &ttynum);
800 if (masterfd < 0)
ef6e34ee
DE
801 goto out_close;
802
ef6e34ee
DE
803 memset(&rsp, 0, sizeof(rsp));
804 rsp.data = INT_TO_PTR(ttynum);
fe84a562
CB
805 ret = lxc_abstract_unix_send_fds(fd, &masterfd, 1, &rsp, sizeof(rsp));
806 if (ret < 0) {
807 ERROR("Failed to send tty to client");
b5159817 808 lxc_console_free(handler->conf, fd);
ef6e34ee
DE
809 goto out_close;
810 }
811
ef6e34ee
DE
812 return 0;
813
814out_close:
fe84a562
CB
815 /* Special indicator to lxc_cmd_handler() to close the fd and do
816 * related cleanup.
ef6e34ee
DE
817 */
818 return 1;
d5088cf2
CS
819}
820
88556fd7
ÇO
821/*
822 * lxc_cmd_get_name: Returns the name of the container
823 *
824 * @hashed_sock_name: hashed socket name
825 *
826 * Returns the name on success, NULL on failure.
827 */
828char *lxc_cmd_get_name(const char *hashed_sock_name)
829{
830 int ret, stopped;
831 struct lxc_cmd_rr cmd = {
832 .req = { .cmd = LXC_CMD_GET_NAME},
833 };
834
835 ret = lxc_cmd(NULL, &cmd, &stopped, NULL, hashed_sock_name);
fe84a562 836 if (ret < 0)
88556fd7 837 return NULL;
88556fd7
ÇO
838
839 if (cmd.rsp.ret == 0)
840 return cmd.rsp.data;
fe84a562 841
88556fd7
ÇO
842 return NULL;
843}
844
845static int lxc_cmd_get_name_callback(int fd, struct lxc_cmd_req *req,
fe84a562 846 struct lxc_handler *handler)
88556fd7
ÇO
847{
848 struct lxc_cmd_rsp rsp;
849
850 memset(&rsp, 0, sizeof(rsp));
851
f0ecc19d 852 rsp.data = (char *)handler->name;
88556fd7
ÇO
853 rsp.datalen = strlen(handler->name) + 1;
854 rsp.ret = 0;
855
856 return lxc_cmd_rsp_send(fd, &rsp);
857}
858
859/*
860 * lxc_cmd_get_lxcpath: Returns the lxcpath of the container
861 *
862 * @hashed_sock_name: hashed socket name
863 *
864 * Returns the lxcpath on success, NULL on failure.
865 */
866char *lxc_cmd_get_lxcpath(const char *hashed_sock_name)
867{
868 int ret, stopped;
869 struct lxc_cmd_rr cmd = {
870 .req = { .cmd = LXC_CMD_GET_LXCPATH},
871 };
724e753c 872
88556fd7 873 ret = lxc_cmd(NULL, &cmd, &stopped, NULL, hashed_sock_name);
fe84a562 874 if (ret < 0)
88556fd7 875 return NULL;
88556fd7
ÇO
876
877 if (cmd.rsp.ret == 0)
878 return cmd.rsp.data;
fe84a562 879
88556fd7
ÇO
880 return NULL;
881}
882
883static int lxc_cmd_get_lxcpath_callback(int fd, struct lxc_cmd_req *req,
884 struct lxc_handler *handler)
885{
886 struct lxc_cmd_rsp rsp;
887
888 memset(&rsp, 0, sizeof(rsp));
889
fe84a562 890 rsp.ret = 0;
88556fd7
ÇO
891 rsp.data = (char *)handler->lxcpath;
892 rsp.datalen = strlen(handler->lxcpath) + 1;
88556fd7
ÇO
893
894 return lxc_cmd_rsp_send(fd, &rsp);
895}
ef6e34ee 896
54446942 897int lxc_cmd_add_state_client(const char *name, const char *lxcpath,
92e35018
CB
898 lxc_state_t states[MAX_STATE],
899 int *state_client_fd)
dbc9832d 900{
bc631984 901 int state, stopped;
dbc9832d 902 ssize_t ret;
dbc9832d
CB
903 struct lxc_cmd_rr cmd = {
904 .req = {
54446942 905 .cmd = LXC_CMD_ADD_STATE_CLIENT,
dbc9832d
CB
906 .data = states,
907 .datalen = (sizeof(lxc_state_t) * MAX_STATE)
908 },
909 };
910
dbc9832d 911 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
bc631984
CB
912 if (states[STOPPED] != 0 && stopped != 0)
913 return STOPPED;
914
dbc9832d 915 if (ret < 0) {
fe84a562 916 ERROR("%s - Failed to execute command", strerror(errno));
dbc9832d
CB
917 return -1;
918 }
fe84a562 919
dbc9832d
CB
920 /* We should now be guaranteed to get an answer from the state sending
921 * function.
922 */
dbc9832d 923 if (cmd.rsp.ret < 0) {
bc631984 924 ERROR("%s - Failed to receive socket fd", strerror(-cmd.rsp.ret));
dbc9832d
CB
925 return -1;
926 }
927
bc631984
CB
928 state = PTR_TO_INT(cmd.rsp.data);
929 if (state < MAX_STATE) {
44552fb2
CB
930 TRACE("Container is already in requested state %s", lxc_state2str(state));
931 close(cmd.rsp.ret);
bc631984
CB
932 return state;
933 }
934
92e35018 935 *state_client_fd = cmd.rsp.ret;
bc631984 936 TRACE("Added state client %d to state client list", cmd.rsp.ret);
92e35018 937 return MAX_STATE;
dbc9832d
CB
938}
939
54446942
CB
940static int lxc_cmd_add_state_client_callback(int fd, struct lxc_cmd_req *req,
941 struct lxc_handler *handler)
dbc9832d 942{
44552fb2 943 int ret;
dbc9832d 944 struct lxc_cmd_rsp rsp = {0};
dbc9832d 945
fe84a562 946 if (req->datalen < 0)
44552fb2 947 goto reap_client_fd;
dbc9832d 948
fe84a562 949 if (req->datalen > (sizeof(lxc_state_t) * MAX_STATE))
44552fb2 950 goto reap_client_fd;
dbc9832d 951
fe84a562 952 if (!req->data)
44552fb2 953 goto reap_client_fd;
dbc9832d 954
c01c2be6 955 rsp.ret = lxc_add_state_client(fd, handler, (lxc_state_t *)req->data);
44552fb2
CB
956 if (rsp.ret < 0)
957 goto reap_client_fd;
958
bc631984 959 rsp.data = INT_TO_PTR(rsp.ret);
dbc9832d 960
44552fb2
CB
961 ret = lxc_cmd_rsp_send(fd, &rsp);
962 if (ret < 0)
963 goto reap_client_fd;
964
965 return 0;
966
967reap_client_fd:
968 /* Special indicator to lxc_cmd_handler() to close the fd and do related
969 * cleanup.
970 */
971 return 1;
dbc9832d
CB
972}
973
191d43cc
CB
974int lxc_cmd_console_log(const char *name, const char *lxcpath,
975 struct lxc_console_log *log)
976{
977 int ret, stopped;
978 struct lxc_cmd_console_log data;
979 struct lxc_cmd_rr cmd;
980
981 data.clear = log->clear;
982 data.read = log->read;
983 data.read_max = *log->read_max;
63b74cda 984 data.write_logfile = log->write_logfile;
191d43cc
CB
985
986 cmd.req.cmd = LXC_CMD_CONSOLE_LOG;
987 cmd.req.data = &data;
988 cmd.req.datalen = sizeof(struct lxc_cmd_console_log);
989
990 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
991 if (ret < 0)
992 return ret;
993
994 /* There is nothing to be read from the buffer. So clear any values we
995 * where passed to clearly indicate to the user that nothing went wrong.
996 */
63b74cda 997 if (cmd.rsp.ret == -ENODATA || cmd.rsp.ret == -EFAULT || cmd.rsp.ret == -ENOENT) {
191d43cc
CB
998 *log->read_max = 0;
999 log->data = NULL;
1000 }
1001
1002 /* This is a proper error so don't touch any values we were passed. */
1003 if (cmd.rsp.ret < 0)
1004 return cmd.rsp.ret;
1005
1006 *log->read_max = cmd.rsp.datalen;
1007 log->data = cmd.rsp.data;
1008
1009 return 0;
1010}
1011
1012static int lxc_cmd_console_log_callback(int fd, struct lxc_cmd_req *req,
1013 struct lxc_handler *handler)
1014{
1015 struct lxc_cmd_rsp rsp;
28f3b1cd 1016 uint64_t buffer_size = handler->conf->console.buffer_size;
191d43cc 1017 const struct lxc_cmd_console_log *log = req->data;
63b74cda 1018 struct lxc_console *console = &handler->conf->console;
191d43cc
CB
1019 struct lxc_ringbuf *buf = &handler->conf->console.ringbuf;
1020
1021 rsp.ret = -EFAULT;
1022 rsp.datalen = 0;
1023 rsp.data = NULL;
28f3b1cd 1024 if (buffer_size <= 0)
191d43cc
CB
1025 goto out;
1026
5928191e
CB
1027 if (log->read || log->write_logfile)
1028 rsp.datalen = lxc_ringbuf_used(buf);
1029
191d43cc
CB
1030 if (log->read)
1031 rsp.data = lxc_ringbuf_get_read_addr(buf);
1032
1033 if (log->read_max > 0 && (log->read_max <= rsp.datalen))
1034 rsp.datalen = log->read_max;
1035
1036 /* there's nothing to read */
63b74cda 1037 rsp.ret = -ENODATA;
191d43cc 1038 if (log->read && (buf->r_off == buf->w_off))
63b74cda
CB
1039 goto out;
1040
1041 if (log->write_logfile && rsp.datalen > 0) {
1042 rsp.ret = -ENOENT;
3a784510 1043 if (!console->buffer_log_file)
63b74cda
CB
1044 goto out;
1045
1046 rsp.ret = lxc_console_write_ringbuffer(console);
1047 if (rsp.ret < 0)
1048 goto out;
1049 }
1050
1051 rsp.ret = 0;
cf685555 1052 if (log->clear) {
966b9ecd
CB
1053 int ret;
1054 size_t len;
1055 char *tmp;
1056
cf685555 1057 /* clear the ringbuffer */
191d43cc 1058 lxc_ringbuf_clear(buf);
cf685555
CB
1059
1060 /* truncate the ringbuffer log file */
1061 if (console->buffer_log_file) {
1062 rsp.ret = -ENOENT;
1063 if (!file_exists(console->buffer_log_file))
1064 goto out;
1065
1066 /* be very certain things are kosher */
1067 rsp.ret = -EBADF;
1068 if (console->buffer_log_file_fd < 0)
1069 goto out;
1070
1071 rsp.ret = lxc_unpriv(ftruncate(console->buffer_log_file_fd, 0));
1072 if (rsp.ret < 0) {
1073 ERROR("%s - Failed to truncate console "
1074 "ringbuffer log file \"%s\"",
1075 strerror(errno), console->buffer_log_file);
1076 goto out;
1077 }
1078 }
966b9ecd
CB
1079
1080 /* rotate the console log file */
1081 if (!console->log_path || console->log_rotate == 0)
1082 goto out;
1083
1084 /* be very certain things are kosher */
1085 rsp.ret = -EBADF;
1086 if (console->log_fd < 0)
1087 goto out;
1088
1089 len = strlen(console->log_path) + sizeof(".1");
1090 tmp = alloca(len);
1091
1092 rsp.ret = -EFBIG;
1093 ret = snprintf(tmp, len, "%s.1", console->log_path);
1094 if (ret < 0 || (size_t)ret >= len)
1095 goto out;
1096
1097 close(console->log_fd);
1098 console->log_fd = -1;
1099 rsp.ret = lxc_unpriv(rename(console->log_path, tmp));
1100 if (rsp.ret < 0)
1101 goto out;
1102
1103 rsp.ret = lxc_console_create_log_file(console);
cf685555 1104 } else if (rsp.datalen > 0) {
191d43cc 1105 lxc_ringbuf_move_read_addr(buf, rsp.datalen);
cf685555 1106 }
191d43cc
CB
1107
1108out:
1109 return lxc_cmd_rsp_send(fd, &rsp);
1110}
1111
ef6e34ee 1112static int lxc_cmd_process(int fd, struct lxc_cmd_req *req,
ded1d23f 1113 struct lxc_handler *handler)
724e753c 1114{
ef6e34ee
DE
1115 typedef int (*callback)(int, struct lxc_cmd_req *, struct lxc_handler *);
1116
1117 callback cb[LXC_CMD_MAX] = {
54446942
CB
1118 [LXC_CMD_CONSOLE] = lxc_cmd_console_callback,
1119 [LXC_CMD_CONSOLE_WINCH] = lxc_cmd_console_winch_callback,
1120 [LXC_CMD_STOP] = lxc_cmd_stop_callback,
1121 [LXC_CMD_GET_STATE] = lxc_cmd_get_state_callback,
1122 [LXC_CMD_GET_INIT_PID] = lxc_cmd_get_init_pid_callback,
1123 [LXC_CMD_GET_CLONE_FLAGS] = lxc_cmd_get_clone_flags_callback,
1124 [LXC_CMD_GET_CGROUP] = lxc_cmd_get_cgroup_callback,
1125 [LXC_CMD_GET_CONFIG_ITEM] = lxc_cmd_get_config_item_callback,
1126 [LXC_CMD_GET_NAME] = lxc_cmd_get_name_callback,
1127 [LXC_CMD_GET_LXCPATH] = lxc_cmd_get_lxcpath_callback,
1128 [LXC_CMD_ADD_STATE_CLIENT] = lxc_cmd_add_state_client_callback,
0d9cd9c3 1129 [LXC_CMD_SET_CONFIG_ITEM] = lxc_cmd_set_config_item_callback,
191d43cc 1130 [LXC_CMD_CONSOLE_LOG] = lxc_cmd_console_log_callback,
724e753c
MN
1131 };
1132
f371aca9 1133 if (req->cmd >= LXC_CMD_MAX) {
fe84a562 1134 ERROR("Undefined command id %d", req->cmd);
724e753c 1135 return -1;
ef6e34ee
DE
1136 }
1137 return cb[req->cmd](fd, req, handler);
724e753c
MN
1138}
1139
ef6e34ee 1140static void lxc_cmd_fd_cleanup(int fd, struct lxc_handler *handler,
f6fc1565
CB
1141 struct lxc_epoll_descr *descr,
1142 const lxc_cmd_t cmd)
724e753c 1143{
d39b10eb 1144 struct lxc_state_client *client;
f6fc1565
CB
1145 struct lxc_list *cur, *next;
1146
b5159817 1147 lxc_console_free(handler->conf, fd);
724e753c 1148 lxc_mainloop_del_handler(descr, fd);
f6fc1565
CB
1149 if (cmd != LXC_CMD_ADD_STATE_CLIENT) {
1150 close(fd);
1151 return;
1152 }
1153
1154 process_lock();
d39b10eb 1155 lxc_list_for_each_safe(cur, &handler->conf->state_clients, next) {
f6fc1565
CB
1156 client = cur->elem;
1157 if (client->clientfd != fd)
1158 continue;
1159
1160 /* kick client from list */
1161 close(client->clientfd);
1162 lxc_list_del(cur);
1163 free(cur->elem);
1164 free(cur);
b1ca434a
CB
1165 /* No need to walk the whole list. If we found the state client
1166 * fd there can't be a second one.
1167 */
1168 break;
f6fc1565
CB
1169 }
1170 process_unlock();
724e753c
MN
1171}
1172
84c92abd
DE
1173static int lxc_cmd_handler(int fd, uint32_t events, void *data,
1174 struct lxc_epoll_descr *descr)
724e753c
MN
1175{
1176 int ret;
ef6e34ee 1177 struct lxc_cmd_req req;
191d43cc 1178 void *reqdata = NULL;
724e753c
MN
1179 struct lxc_handler *handler = data;
1180
aae93dd3 1181 ret = lxc_abstract_unix_rcv_credential(fd, &req, sizeof(req));
0a3ec350 1182 if (ret == -EACCES) {
fe84a562
CB
1183 /* We don't care for the peer, just send and close. */
1184 struct lxc_cmd_rsp rsp = {.ret = ret};
ef6e34ee
DE
1185
1186 lxc_cmd_rsp_send(fd, &rsp);
3cc5de36 1187 goto out_close;
ded1d23f
DL
1188 }
1189
1190 if (ret < 0) {
fe84a562
CB
1191 SYSERROR("Failed to receive data on command socket for command "
1192 "\"%s\"", lxc_cmd_str(req.cmd));
724e753c
MN
1193 goto out_close;
1194 }
1195
fe84a562 1196 if (ret == 0)
724e753c 1197 goto out_close;
724e753c 1198
ef6e34ee 1199 if (ret != sizeof(req)) {
c01c2be6 1200 WARN("Failed to receive full command request. Ignoring request "
fe84a562 1201 "for \"%s\"", lxc_cmd_str(req.cmd));
ef6e34ee
DE
1202 ret = -1;
1203 goto out_close;
1204 }
1205
191d43cc
CB
1206 if ((req.datalen > LXC_CMD_DATA_MAX) &&
1207 (req.cmd != LXC_CMD_CONSOLE_LOG)) {
c01c2be6 1208 ERROR("Received command data length %d is too large for "
fe84a562
CB
1209 "command \"%s\"", req.datalen, lxc_cmd_str(req.cmd));
1210 errno = EFBIG;
1211 ret = -EFBIG;
724e753c
MN
1212 goto out_close;
1213 }
1214
ef6e34ee 1215 if (req.datalen > 0) {
191d43cc
CB
1216 /* LXC_CMD_CONSOLE_LOG needs to be able to allocate data
1217 * that exceeds LXC_CMD_DATA_MAX: use malloc() for that.
1218 */
1219 if (req.cmd == LXC_CMD_CONSOLE_LOG)
1220 reqdata = malloc(req.datalen);
1221 else
1222 reqdata = alloca(req.datalen);
1223 if (!reqdata) {
1224 ERROR("Failed to allocate memory for \"%s\" command",
1225 lxc_cmd_str(req.cmd));
1226 errno = ENOMEM;
1227 ret = -ENOMEM;
1228 goto out_close;
1229 }
ef6e34ee 1230
ef6e34ee
DE
1231 ret = recv(fd, reqdata, req.datalen, 0);
1232 if (ret != req.datalen) {
c01c2be6 1233 WARN("Failed to receive full command request. Ignoring "
fe84a562 1234 "request for \"%s\"", lxc_cmd_str(req.cmd));
ef6e34ee
DE
1235 ret = -1;
1236 goto out_close;
1237 }
fe84a562 1238
ef6e34ee
DE
1239 req.data = reqdata;
1240 }
1241
1242 ret = lxc_cmd_process(fd, &req, handler);
724e753c 1243 if (ret) {
fe84a562 1244 /* This is not an error, but only a request to close fd. */
724e753c
MN
1245 ret = 0;
1246 goto out_close;
1247 }
1248
1249out:
191d43cc
CB
1250 if (req.cmd == LXC_CMD_CONSOLE_LOG && reqdata)
1251 free(reqdata);
1252
724e753c 1253 return ret;
fe84a562 1254
724e753c 1255out_close:
f6fc1565 1256 lxc_cmd_fd_cleanup(fd, handler, descr, req.cmd);
724e753c
MN
1257 goto out;
1258}
1259
84c92abd
DE
1260static int lxc_cmd_accept(int fd, uint32_t events, void *data,
1261 struct lxc_epoll_descr *descr)
724e753c 1262{
fe84a562
CB
1263 int connection;
1264 int opt = 1, ret = -1;
724e753c
MN
1265
1266 connection = accept(fd, NULL, 0);
1267 if (connection < 0) {
08aa08fe 1268 SYSERROR("Failed to accept connection to run command.");
724e753c
MN
1269 return -1;
1270 }
1271
fe84a562
CB
1272 ret = fcntl(connection, F_SETFD, FD_CLOEXEC);
1273 if (ret < 0) {
1274 SYSERROR("Failed to set close-on-exec on incoming command connection");
9ccb2dbc
DL
1275 goto out_close;
1276 }
1277
fe84a562
CB
1278 ret = setsockopt(connection, SOL_SOCKET, SO_PASSCRED, &opt, sizeof(opt));
1279 if (ret < 0) {
1280 SYSERROR("Failed to enable necessary credentials on command socket");
724e753c
MN
1281 goto out_close;
1282 }
1283
ef6e34ee 1284 ret = lxc_mainloop_add_handler(descr, connection, lxc_cmd_handler, data);
724e753c 1285 if (ret) {
fe84a562 1286 ERROR("Failed to add command handler");
724e753c
MN
1287 goto out_close;
1288 }
1289
1290out:
1291 return ret;
1292
1293out_close:
1294 close(connection);
1295 goto out;
1296}
1297
9dfa4041 1298int lxc_cmd_init(const char *name, const char *lxcpath, const char *suffix)
724e753c 1299{
fe84a562
CB
1300 int fd, len, ret;
1301 char path[sizeof(((struct sockaddr_un *)0)->sun_path)] = {0};
46968ea3 1302 char *offset = &path[1];
724e753c 1303
6f2944c1
TA
1304 /* -2 here because this is an abstract unix socket so it needs a
1305 * leading \0, and we null terminate, so it needs a trailing \0.
1306 * Although null termination isn't required by the API, we do it anyway
1307 * because we print the sockname out sometimes.
1308 */
860e7c43 1309 len = sizeof(path) - 2;
9dfa4041 1310 ret = lxc_make_abstract_socket_name(offset, len, name, lxcpath, NULL, suffix);
fe84a562 1311 if (ret < 0)
9ba8130c 1312 return -1;
9dfa4041 1313 TRACE("Creating abstract unix socket \"%s\"", offset);
724e753c 1314
aae93dd3 1315 fd = lxc_abstract_unix_open(path, SOCK_STREAM, 0);
724e753c 1316 if (fd < 0) {
fe84a562
CB
1317 ERROR("%s - Failed to create command socket %s",
1318 strerror(errno), offset);
08aa08fe 1319 if (errno == EADDRINUSE)
fe84a562 1320 ERROR("Container \"%s\" appears to be already running", name);
724e753c
MN
1321 return -1;
1322 }
1323
fe84a562
CB
1324 ret = fcntl(fd, F_SETFD, FD_CLOEXEC);
1325 if (ret < 0) {
1326 SYSERROR("Failed to set FD_CLOEXEC on command socket file descriptor");
91480a0f
DL
1327 close(fd);
1328 return -1;
1329 }
1330
9dfa4041 1331 return fd;
d2e30e99
DE
1332}
1333
fe84a562 1334int lxc_cmd_mainloop_add(const char *name, struct lxc_epoll_descr *descr,
ef6e34ee 1335 struct lxc_handler *handler)
d2e30e99 1336{
fe84a562
CB
1337 int ret;
1338 int fd = handler->conf->maincmd_fd;
d2e30e99 1339
ef6e34ee 1340 ret = lxc_mainloop_add_handler(descr, fd, lxc_cmd_accept, handler);
fe84a562
CB
1341 if (ret < 0) {
1342 ERROR("Failed to add handler for command socket");
724e753c
MN
1343 close(fd);
1344 }
1345
1346 return ret;
1347}