]> git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/commands.c
ovl_rsync: make sure to umount
[mirror_lxc.git] / src / lxc / commands.c
1 /*
2 * lxc: linux Container library
3 *
4 * (C) Copyright IBM Corp. 2007, 2009
5 *
6 * Authors:
7 * Daniel Lezcano <daniel.lezcano at free.fr>
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
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 #include <stdio.h>
25 #include <errno.h>
26 #include <unistd.h>
27 #include <signal.h>
28 #include <fcntl.h>
29 #include <poll.h>
30 #include <sys/socket.h>
31 #include <inttypes.h>
32 #include <sys/un.h>
33 #include <sys/param.h>
34 #include <malloc.h>
35 #include <stdlib.h>
36
37 #include "log.h"
38 #include "lxc.h"
39 #include "conf.h"
40 #include "start.h" /* for struct lxc_handler */
41 #include "utils.h"
42 #include "cgroup.h"
43 #include "commands.h"
44 #include "console.h"
45 #include "confile.h"
46 #include "mainloop.h"
47 #include "af_unix.h"
48 #include "config.h"
49
50 /*
51 * This file provides the different functions for clients to
52 * query/command the server. The client is typically some lxc
53 * tool and the server is typically the container (ie. lxc-start).
54 *
55 * Each command is transactional, the clients send a request to
56 * the server and the server answers the request with a message
57 * giving the request's status (zero or a negative errno value).
58 * Both the request and response may contain additional data.
59 *
60 * Each command is wrapped in a ancillary message in order to pass
61 * a credential making possible to the server to check if the client
62 * is allowed to ask for this command or not.
63 *
64 * IMPORTANTLY: Note that semantics for current commands are fixed. If you
65 * wish to make any changes to how, say, LXC_CMD_GET_CONFIG_ITEM works by
66 * adding information to the end of cmd.data, then you must introduce a new
67 * LXC_CMD_GET_CONFIG_ITEM_V2 define with a new number. You may wish to
68 * also mark LXC_CMD_GET_CONFIG_ITEM deprecated in commands.h.
69 *
70 * This is necessary in order to avoid having a newly compiled lxc command
71 * communicating with a running (old) monitor from crashing the running
72 * container.
73 */
74
75 lxc_log_define(lxc_commands, lxc);
76
77 static int fill_sock_name(char *path, int len, const char *name,
78 const char *lxcpath, const char *hashed_sock_name)
79 {
80 char *tmppath;
81 size_t tmplen;
82 uint64_t hash;
83 int ret;
84
85 if (hashed_sock_name != NULL) {
86 ret = snprintf(path, len, "lxc/%s/command", hashed_sock_name);
87 if (ret < 0 || ret >= len) {
88 ERROR("Error writing to command sock path");
89 return -1;
90 }
91 return 0;
92 }
93
94 if (!lxcpath) {
95 lxcpath = lxc_global_config_value("lxc.lxcpath");
96 if (!lxcpath) {
97 ERROR("Out of memory getting lxcpath");
98 return -1;
99 }
100 }
101
102 ret = snprintf(path, len, "%s/%s/command", lxcpath, name);
103 if (ret < 0) {
104 ERROR("Error writing to command sock path");
105 return -1;
106 }
107 if (ret < len)
108 return 0;
109
110 /* ret >= len; lxcpath or name is too long. hash both */
111 tmplen = strlen(name) + strlen(lxcpath) + 2;
112 tmppath = alloca(tmplen);
113 ret = snprintf(tmppath, tmplen, "%s/%s", lxcpath, name);
114 if (ret < 0 || ret >= tmplen) {
115 ERROR("memory error");
116 return -1;
117 }
118 hash = fnv_64a_buf(tmppath, ret, FNV1A_64_INIT);
119 ret = snprintf(path, len, "lxc/%016" PRIx64 "/command", hash);
120 if (ret < 0 || ret >= len) {
121 ERROR("Command socket name too long");
122 return -1;
123 }
124
125 return 0;
126 }
127
128 static const char *lxc_cmd_str(lxc_cmd_t cmd)
129 {
130 static const char * const cmdname[LXC_CMD_MAX] = {
131 [LXC_CMD_CONSOLE] = "console",
132 [LXC_CMD_STOP] = "stop",
133 [LXC_CMD_GET_STATE] = "get_state",
134 [LXC_CMD_GET_INIT_PID] = "get_init_pid",
135 [LXC_CMD_GET_CLONE_FLAGS] = "get_clone_flags",
136 [LXC_CMD_GET_CGROUP] = "get_cgroup",
137 [LXC_CMD_GET_CONFIG_ITEM] = "get_config_item",
138 [LXC_CMD_GET_NAME] = "get_name",
139 [LXC_CMD_GET_LXCPATH] = "get_lxcpath",
140 };
141
142 if (cmd >= LXC_CMD_MAX)
143 return "Unknown cmd";
144 return cmdname[cmd];
145 }
146
147 /*
148 * lxc_cmd_rsp_recv: Receive a response to a command
149 *
150 * @sock : the socket connected to the container
151 * @cmd : command to put response in
152 *
153 * Returns the size of the response message or < 0 on failure
154 *
155 * Note that if the command response datalen > 0, then data is
156 * a malloc()ed buffer and should be free()ed by the caller. If
157 * the response data is <= a void * worth of data, it will be
158 * stored directly in data and datalen will be 0.
159 *
160 * As a special case, the response for LXC_CMD_CONSOLE is created
161 * here as it contains an fd for the master pty passed through the
162 * unix socket.
163 */
164 static int lxc_cmd_rsp_recv(int sock, struct lxc_cmd_rr *cmd)
165 {
166 int ret,rspfd;
167 struct lxc_cmd_rsp *rsp = &cmd->rsp;
168
169 ret = lxc_abstract_unix_recv_fd(sock, &rspfd, rsp, sizeof(*rsp));
170 if (ret < 0) {
171 WARN("command %s failed to receive response",
172 lxc_cmd_str(cmd->req.cmd));
173 return -1;
174 }
175
176 if (cmd->req.cmd == LXC_CMD_CONSOLE) {
177 struct lxc_cmd_console_rsp_data *rspdata;
178
179 /* recv() returns 0 bytes when a tty cannot be allocated,
180 * rsp->ret is < 0 when the peer permission check failed
181 */
182 if (ret == 0 || rsp->ret < 0)
183 return 0;
184
185 rspdata = malloc(sizeof(*rspdata));
186 if (!rspdata) {
187 ERROR("command %s couldn't allocate response buffer",
188 lxc_cmd_str(cmd->req.cmd));
189 return -1;
190 }
191 rspdata->masterfd = rspfd;
192 rspdata->ttynum = PTR_TO_INT(rsp->data);
193 rsp->data = rspdata;
194 }
195
196 if (rsp->datalen == 0)
197 return ret;
198 if (rsp->datalen > LXC_CMD_DATA_MAX) {
199 ERROR("command %s response data %d too long",
200 lxc_cmd_str(cmd->req.cmd), rsp->datalen);
201 errno = EFBIG;
202 return -1;
203 }
204
205 rsp->data = malloc(rsp->datalen);
206 if (!rsp->data) {
207 ERROR("command %s unable to allocate response buffer",
208 lxc_cmd_str(cmd->req.cmd));
209 return -1;
210 }
211 ret = recv(sock, rsp->data, rsp->datalen, 0);
212 if (ret != rsp->datalen) {
213 ERROR("command %s failed to receive response data",
214 lxc_cmd_str(cmd->req.cmd));
215 if (ret >= 0)
216 ret = -1;
217 }
218
219 return ret;
220 }
221
222 /*
223 * lxc_cmd_rsp_send: Send a command response
224 *
225 * @fd : file descriptor of socket to send response on
226 * @rsp : response to send
227 *
228 * Returns 0 on success, < 0 on failure
229 */
230 static int lxc_cmd_rsp_send(int fd, struct lxc_cmd_rsp *rsp)
231 {
232 int ret;
233
234 ret = send(fd, rsp, sizeof(*rsp), 0);
235 if (ret != sizeof(*rsp)) {
236 ERROR("failed to send command response %d %s", ret,
237 strerror(errno));
238 return -1;
239 }
240
241 if (rsp->datalen > 0) {
242 ret = send(fd, rsp->data, rsp->datalen, 0);
243 if (ret != rsp->datalen) {
244 WARN("failed to send command response data %d %s", ret,
245 strerror(errno));
246 return -1;
247 }
248 }
249 return 0;
250 }
251
252 /*
253 * lxc_cmd: Connect to the specified running container, send it a command
254 * request and collect the response
255 *
256 * @name : name of container to connect to
257 * @cmd : command with initialized reqest to send
258 * @stopped : output indicator if the container was not running
259 * @lxcpath : the lxcpath in which the container is running
260 *
261 * Returns the size of the response message on success, < 0 on failure
262 *
263 * Note that there is a special case for LXC_CMD_CONSOLE. For this command
264 * the fd cannot be closed because it is used as a placeholder to indicate
265 * that a particular tty slot is in use. The fd is also used as a signal to
266 * the container that when the caller dies or closes the fd, the container
267 * will notice the fd on its side of the socket in its mainloop select and
268 * then free the slot with lxc_cmd_fd_cleanup(). The socket fd will be
269 * returned in the cmd response structure.
270 */
271 static int lxc_cmd(const char *name, struct lxc_cmd_rr *cmd, int *stopped,
272 const char *lxcpath, const char *hashed_sock_name)
273 {
274 int sock, ret = -1;
275 char path[sizeof(((struct sockaddr_un *)0)->sun_path)] = { 0 };
276 char *offset = &path[1];
277 int len;
278 int stay_connected = cmd->req.cmd == LXC_CMD_CONSOLE;
279
280 *stopped = 0;
281
282 len = sizeof(path)-1;
283 if (fill_sock_name(offset, len, name, lxcpath, hashed_sock_name))
284 return -1;
285
286 sock = lxc_abstract_unix_connect(path);
287 if (sock < 0) {
288 if (errno == ECONNREFUSED)
289 *stopped = 1;
290 else
291 SYSERROR("command %s failed to connect to '@%s'",
292 lxc_cmd_str(cmd->req.cmd), offset);
293 return -1;
294 }
295
296 ret = lxc_abstract_unix_send_credential(sock, &cmd->req, sizeof(cmd->req));
297 if (ret != sizeof(cmd->req)) {
298 if (errno == EPIPE)
299 goto epipe;
300 SYSERROR("command %s failed to send req to '@%s' %d",
301 lxc_cmd_str(cmd->req.cmd), offset, ret);
302 if (ret >=0)
303 ret = -1;
304 goto out;
305 }
306
307 if (cmd->req.datalen > 0) {
308 ret = send(sock, cmd->req.data, cmd->req.datalen, MSG_NOSIGNAL);
309 if (ret != cmd->req.datalen) {
310 if (errno == EPIPE)
311 goto epipe;
312 SYSERROR("command %s failed to send request data to '@%s' %d",
313 lxc_cmd_str(cmd->req.cmd), offset, ret);
314 if (ret >=0)
315 ret = -1;
316 goto out;
317 }
318 }
319
320 ret = lxc_cmd_rsp_recv(sock, cmd);
321 out:
322 if (!stay_connected || ret <= 0)
323 close(sock);
324 if (stay_connected && ret > 0)
325 cmd->rsp.ret = sock;
326
327 return ret;
328
329 epipe:
330 close(sock);
331 *stopped = 1;
332 return 0;
333 }
334
335 int lxc_try_cmd(const char *name, const char *lxcpath)
336 {
337 int stopped, ret;
338 struct lxc_cmd_rr cmd = {
339 .req = { .cmd = LXC_CMD_GET_INIT_PID },
340 };
341
342 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
343
344 if (stopped)
345 return 0;
346 if (ret > 0 && cmd.rsp.ret < 0) {
347 errno = cmd.rsp.ret;
348 return -1;
349 }
350 if (ret > 0)
351 return 0;
352
353 /*
354 * At this point we weren't denied access, and the
355 * container *was* started. There was some inexplicable
356 * error in the protocol.
357 * I'm not clear on whether we should return -1 here, but
358 * we didn't receive a -EACCES, so technically it's not that
359 * we're not allowed to control the container - it's just not
360 * behaving.
361 */
362 return 0;
363 }
364
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 */
375 pid_t lxc_cmd_get_init_pid(const char *name, const char *lxcpath)
376 {
377 int ret, stopped;
378 struct lxc_cmd_rr cmd = {
379 .req = { .cmd = LXC_CMD_GET_INIT_PID },
380 };
381
382 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
383 if (ret < 0)
384 return ret;
385
386 return PTR_TO_INT(cmd.rsp.data);
387 }
388
389 static int lxc_cmd_get_init_pid_callback(int fd, struct lxc_cmd_req *req,
390 struct lxc_handler *handler)
391 {
392 struct lxc_cmd_rsp rsp = { .data = INT_TO_PTR(handler->pid) };
393
394 return lxc_cmd_rsp_send(fd, &rsp);
395 }
396
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 */
405 int lxc_cmd_get_clone_flags(const char *name, const char *lxcpath)
406 {
407 int ret, stopped;
408 struct lxc_cmd_rr cmd = {
409 .req = { .cmd = LXC_CMD_GET_CLONE_FLAGS },
410 };
411
412 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
413 if (ret < 0)
414 return ret;
415
416 return PTR_TO_INT(cmd.rsp.data);
417 }
418
419 static int lxc_cmd_get_clone_flags_callback(int fd, struct lxc_cmd_req *req,
420 struct lxc_handler *handler)
421 {
422 struct lxc_cmd_rsp rsp = { .data = INT_TO_PTR(handler->clone_flags) };
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 *
432 * @name : name of container to connect to
433 * @lxcpath : the lxcpath in which the container is running
434 * @subsystem : the subsystem being asked about
435 *
436 * Returns the path on success, NULL on failure. The caller must free() the
437 * returned path.
438 */
439 char *lxc_cmd_get_cgroup_path(const char *name, const char *lxcpath,
440 const char *subsystem)
441 {
442 int ret, stopped;
443 struct lxc_cmd_rr cmd = {
444 .req = {
445 .cmd = LXC_CMD_GET_CGROUP,
446 .datalen = strlen(subsystem)+1,
447 .data = subsystem,
448 },
449 };
450
451 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
452 if (ret < 0)
453 return NULL;
454
455 if (!ret) {
456 WARN("'%s' has stopped before sending its state", name);
457 return NULL;
458 }
459
460 if (cmd.rsp.ret < 0 || cmd.rsp.datalen < 0) {
461 ERROR("command %s failed for '%s': %s",
462 lxc_cmd_str(cmd.req.cmd), name,
463 strerror(-cmd.rsp.ret));
464 return NULL;
465 }
466
467 return cmd.rsp.data;
468 }
469
470 static int lxc_cmd_get_cgroup_callback(int fd, struct lxc_cmd_req *req,
471 struct lxc_handler *handler)
472 {
473 struct lxc_cmd_rsp rsp;
474 const char *path;
475
476 if (req->datalen < 1)
477 return -1;
478
479 path = cgroup_get_cgroup(handler, req->data);
480 if (!path)
481 return -1;
482 rsp.datalen = strlen(path) + 1,
483 rsp.data = (char *)path;
484 rsp.ret = 0;
485
486 return lxc_cmd_rsp_send(fd, &rsp);
487 }
488
489 /*
490 * lxc_cmd_get_config_item: Get config item the running container
491 *
492 * @name : name of container to connect to
493 * @item : the configuration item to retrieve (ex: lxc.network.0.veth.pair)
494 * @lxcpath : the lxcpath in which the container is running
495 *
496 * Returns the item on success, NULL on failure. The caller must free() the
497 * returned item.
498 */
499 char *lxc_cmd_get_config_item(const char *name, const char *item,
500 const char *lxcpath)
501 {
502 int ret, stopped;
503 struct lxc_cmd_rr cmd = {
504 .req = { .cmd = LXC_CMD_GET_CONFIG_ITEM,
505 .data = item,
506 .datalen = strlen(item)+1,
507 },
508 };
509
510 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
511 if (ret < 0)
512 return NULL;
513
514 if (cmd.rsp.ret == 0)
515 return cmd.rsp.data;
516 return NULL;
517 }
518
519 static int lxc_cmd_get_config_item_callback(int fd, struct lxc_cmd_req *req,
520 struct lxc_handler *handler)
521 {
522 int cilen;
523 struct lxc_cmd_rsp rsp;
524 char *cidata;
525
526 memset(&rsp, 0, sizeof(rsp));
527 cilen = lxc_get_config_item(handler->conf, req->data, NULL, 0);
528 if (cilen <= 0)
529 goto err1;
530
531 cidata = alloca(cilen + 1);
532 if (lxc_get_config_item(handler->conf, req->data, cidata, cilen + 1) != cilen)
533 goto err1;
534 cidata[cilen] = '\0';
535 rsp.data = cidata;
536 rsp.datalen = cilen + 1;
537 rsp.ret = 0;
538 goto out;
539
540 err1:
541 rsp.ret = -1;
542 out:
543 return lxc_cmd_rsp_send(fd, &rsp);
544 }
545
546 /*
547 * lxc_cmd_get_state: Get current state of the container
548 *
549 * @name : name of container to connect to
550 * @lxcpath : the lxcpath in which the container is running
551 *
552 * Returns the state on success, < 0 on failure
553 */
554 lxc_state_t lxc_cmd_get_state(const char *name, const char *lxcpath)
555 {
556 int ret, stopped;
557 struct lxc_cmd_rr cmd = {
558 .req = { .cmd = LXC_CMD_GET_STATE }
559 };
560
561 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
562 if (ret < 0 && stopped)
563 return STOPPED;
564
565 if (ret < 0)
566 return -1;
567
568 if (!ret) {
569 WARN("'%s' has stopped before sending its state", name);
570 return -1;
571 }
572
573 DEBUG("'%s' is in '%s' state", name,
574 lxc_state2str(PTR_TO_INT(cmd.rsp.data)));
575 return PTR_TO_INT(cmd.rsp.data);
576 }
577
578 static int lxc_cmd_get_state_callback(int fd, struct lxc_cmd_req *req,
579 struct lxc_handler *handler)
580 {
581 struct lxc_cmd_rsp rsp = { .data = INT_TO_PTR(handler->state) };
582
583 return lxc_cmd_rsp_send(fd, &rsp);
584 }
585
586 /*
587 * lxc_cmd_stop: Stop the container previously started with lxc_start. All
588 * the processes running inside this container will be killed.
589 *
590 * @name : name of container to connect to
591 * @lxcpath : the lxcpath in which the container is running
592 *
593 * Returns 0 on success, < 0 on failure
594 */
595 int lxc_cmd_stop(const char *name, const char *lxcpath)
596 {
597 int ret, stopped;
598 struct lxc_cmd_rr cmd = {
599 .req = { .cmd = LXC_CMD_STOP },
600 };
601
602 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
603 if (ret < 0) {
604 if (stopped) {
605 INFO("'%s' is already stopped", name);
606 return 0;
607 }
608 return -1;
609 }
610
611 /* we do not expect any answer, because we wait for the connection to be
612 * closed
613 */
614 if (ret > 0) {
615 ERROR("failed to stop '%s': %s", name, strerror(-cmd.rsp.ret));
616 return -1;
617 }
618
619 INFO("'%s' has stopped", name);
620 return 0;
621 }
622
623 static int lxc_cmd_stop_callback(int fd, struct lxc_cmd_req *req,
624 struct lxc_handler *handler)
625 {
626 struct lxc_cmd_rsp rsp;
627 int stopsignal = SIGKILL;
628
629 if (handler->conf->stopsignal)
630 stopsignal = handler->conf->stopsignal;
631 memset(&rsp, 0, sizeof(rsp));
632 rsp.ret = kill(handler->pid, stopsignal);
633 if (!rsp.ret) {
634 /* we can't just use lxc_unfreeze() since we are already in the
635 * context of handling the STOP cmd in lxc-start, and calling
636 * lxc_unfreeze() would do another cmd (GET_CGROUP) which would
637 * deadlock us
638 */
639 if (cgroup_unfreeze(handler))
640 return 0;
641 ERROR("Failed to unfreeze %s:%s", handler->lxcpath, handler->name);
642 rsp.ret = -1;
643 }
644
645 return lxc_cmd_rsp_send(fd, &rsp);
646 }
647
648 /*
649 * lxc_cmd_console_winch: To process as if a SIGWINCH were received
650 *
651 * @name : name of container to connect to
652 * @lxcpath : the lxcpath in which the container is running
653 *
654 * Returns 0 on success, < 0 on failure
655 */
656 int lxc_cmd_console_winch(const char *name, const char *lxcpath)
657 {
658 int ret, stopped;
659 struct lxc_cmd_rr cmd = {
660 .req = { .cmd = LXC_CMD_CONSOLE_WINCH },
661 };
662
663 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
664 if (ret < 0)
665 return ret;
666
667 return 0;
668 }
669
670 static int lxc_cmd_console_winch_callback(int fd, struct lxc_cmd_req *req,
671 struct lxc_handler *handler)
672 {
673 struct lxc_cmd_rsp rsp = { .data = 0 };
674
675 lxc_console_sigwinch(SIGWINCH);
676 return lxc_cmd_rsp_send(fd, &rsp);
677 }
678
679 /*
680 * lxc_cmd_console: Open an fd to a tty in the container
681 *
682 * @name : name of container to connect to
683 * @ttynum : in: the tty to open or -1 for next available
684 * : out: the tty allocated
685 * @fd : out: file descriptor for master side of pty
686 * @lxcpath : the lxcpath in which the container is running
687 *
688 * Returns fd holding tty allocated on success, < 0 on failure
689 */
690 int lxc_cmd_console(const char *name, int *ttynum, int *fd, const char *lxcpath)
691 {
692 int ret, stopped;
693 struct lxc_cmd_console_rsp_data *rspdata;
694 struct lxc_cmd_rr cmd = {
695 .req = { .cmd = LXC_CMD_CONSOLE, .data = INT_TO_PTR(*ttynum) },
696 };
697
698 ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL);
699 if (ret < 0)
700 return ret;
701
702 if (cmd.rsp.ret < 0) {
703 ERROR("console access denied: %s", strerror(-cmd.rsp.ret));
704 ret = -1;
705 goto out;
706 }
707
708 if (ret == 0) {
709 ERROR("console %d invalid,busy or all consoles busy", *ttynum);
710 ret = -1;
711 goto out;
712 }
713
714 rspdata = cmd.rsp.data;
715 if (rspdata->masterfd < 0) {
716 ERROR("unable to allocate fd for tty %d", rspdata->ttynum);
717 goto out;
718 }
719
720 ret = cmd.rsp.ret; /* sock fd */
721 *fd = rspdata->masterfd;
722 *ttynum = rspdata->ttynum;
723 INFO("tty %d allocated fd %d sock %d", rspdata->ttynum, *fd, ret);
724 out:
725 free(cmd.rsp.data);
726 return ret;
727 }
728
729 static int lxc_cmd_console_callback(int fd, struct lxc_cmd_req *req,
730 struct lxc_handler *handler)
731 {
732 int ttynum = PTR_TO_INT(req->data);
733 int masterfd;
734 struct lxc_cmd_rsp rsp;
735
736 masterfd = lxc_console_allocate(handler->conf, fd, &ttynum);
737 if (masterfd < 0)
738 goto out_close;
739
740 memset(&rsp, 0, sizeof(rsp));
741 rsp.data = INT_TO_PTR(ttynum);
742 if (lxc_abstract_unix_send_fd(fd, masterfd, &rsp, sizeof(rsp)) < 0) {
743 ERROR("failed to send tty to client");
744 lxc_console_free(handler->conf, fd);
745 goto out_close;
746 }
747
748 return 0;
749
750 out_close:
751 /* special indicator to lxc_cmd_handler() to close the fd and do
752 * related cleanup
753 */
754 return 1;
755 }
756
757 /*
758 * lxc_cmd_get_name: Returns the name of the container
759 *
760 * @hashed_sock_name: hashed socket name
761 *
762 * Returns the name on success, NULL on failure.
763 */
764 char *lxc_cmd_get_name(const char *hashed_sock_name)
765 {
766 int ret, stopped;
767 struct lxc_cmd_rr cmd = {
768 .req = { .cmd = LXC_CMD_GET_NAME},
769 };
770
771 ret = lxc_cmd(NULL, &cmd, &stopped, NULL, hashed_sock_name);
772 if (ret < 0) {
773 return NULL;
774 }
775
776 if (cmd.rsp.ret == 0)
777 return cmd.rsp.data;
778 return NULL;
779 }
780
781 static int lxc_cmd_get_name_callback(int fd, struct lxc_cmd_req *req,
782 struct lxc_handler *handler)
783 {
784 struct lxc_cmd_rsp rsp;
785
786 memset(&rsp, 0, sizeof(rsp));
787
788 rsp.data = handler->name;
789 rsp.datalen = strlen(handler->name) + 1;
790 rsp.ret = 0;
791
792 return lxc_cmd_rsp_send(fd, &rsp);
793 }
794
795 /*
796 * lxc_cmd_get_lxcpath: Returns the lxcpath of the container
797 *
798 * @hashed_sock_name: hashed socket name
799 *
800 * Returns the lxcpath on success, NULL on failure.
801 */
802 char *lxc_cmd_get_lxcpath(const char *hashed_sock_name)
803 {
804 int ret, stopped;
805 struct lxc_cmd_rr cmd = {
806 .req = { .cmd = LXC_CMD_GET_LXCPATH},
807 };
808
809 ret = lxc_cmd(NULL, &cmd, &stopped, NULL, hashed_sock_name);
810 if (ret < 0) {
811 return NULL;
812 }
813
814 if (cmd.rsp.ret == 0)
815 return cmd.rsp.data;
816 return NULL;
817 }
818
819 static int lxc_cmd_get_lxcpath_callback(int fd, struct lxc_cmd_req *req,
820 struct lxc_handler *handler)
821 {
822 struct lxc_cmd_rsp rsp;
823
824 memset(&rsp, 0, sizeof(rsp));
825
826 rsp.data = (char *)handler->lxcpath;
827 rsp.datalen = strlen(handler->lxcpath) + 1;
828 rsp.ret = 0;
829
830 return lxc_cmd_rsp_send(fd, &rsp);
831 }
832
833 static int lxc_cmd_process(int fd, struct lxc_cmd_req *req,
834 struct lxc_handler *handler)
835 {
836 typedef int (*callback)(int, struct lxc_cmd_req *, struct lxc_handler *);
837
838 callback cb[LXC_CMD_MAX] = {
839 [LXC_CMD_CONSOLE] = lxc_cmd_console_callback,
840 [LXC_CMD_CONSOLE_WINCH] = lxc_cmd_console_winch_callback,
841 [LXC_CMD_STOP] = lxc_cmd_stop_callback,
842 [LXC_CMD_GET_STATE] = lxc_cmd_get_state_callback,
843 [LXC_CMD_GET_INIT_PID] = lxc_cmd_get_init_pid_callback,
844 [LXC_CMD_GET_CLONE_FLAGS] = lxc_cmd_get_clone_flags_callback,
845 [LXC_CMD_GET_CGROUP] = lxc_cmd_get_cgroup_callback,
846 [LXC_CMD_GET_CONFIG_ITEM] = lxc_cmd_get_config_item_callback,
847 [LXC_CMD_GET_NAME] = lxc_cmd_get_name_callback,
848 [LXC_CMD_GET_LXCPATH] = lxc_cmd_get_lxcpath_callback,
849 };
850
851 if (req->cmd >= LXC_CMD_MAX) {
852 ERROR("bad cmd %d received", req->cmd);
853 return -1;
854 }
855 return cb[req->cmd](fd, req, handler);
856 }
857
858 static void lxc_cmd_fd_cleanup(int fd, struct lxc_handler *handler,
859 struct lxc_epoll_descr *descr)
860 {
861 lxc_console_free(handler->conf, fd);
862 lxc_mainloop_del_handler(descr, fd);
863 close(fd);
864 }
865
866 static int lxc_cmd_handler(int fd, uint32_t events, void *data,
867 struct lxc_epoll_descr *descr)
868 {
869 int ret;
870 struct lxc_cmd_req req;
871 struct lxc_handler *handler = data;
872
873 ret = lxc_abstract_unix_rcv_credential(fd, &req, sizeof(req));
874 if (ret == -EACCES) {
875 /* we don't care for the peer, just send and close */
876 struct lxc_cmd_rsp rsp = { .ret = ret };
877
878 lxc_cmd_rsp_send(fd, &rsp);
879 goto out_close;
880 }
881
882 if (ret < 0) {
883 SYSERROR("failed to receive data on command socket");
884 goto out_close;
885 }
886
887 if (!ret) {
888 DEBUG("peer has disconnected");
889 goto out_close;
890 }
891
892 if (ret != sizeof(req)) {
893 WARN("partial request, ignored");
894 ret = -1;
895 goto out_close;
896 }
897
898 if (req.datalen > LXC_CMD_DATA_MAX) {
899 ERROR("cmd data length %d too large", req.datalen);
900 ret = -1;
901 goto out_close;
902 }
903
904 if (req.datalen > 0) {
905 void *reqdata;
906
907 reqdata = alloca(req.datalen);
908 ret = recv(fd, reqdata, req.datalen, 0);
909 if (ret != req.datalen) {
910 WARN("partial request, ignored");
911 ret = -1;
912 goto out_close;
913 }
914 req.data = reqdata;
915 }
916
917 ret = lxc_cmd_process(fd, &req, handler);
918 if (ret) {
919 /* this is not an error, but only a request to close fd */
920 ret = 0;
921 goto out_close;
922 }
923
924 out:
925 return ret;
926 out_close:
927 lxc_cmd_fd_cleanup(fd, handler, descr);
928 goto out;
929 }
930
931 static int lxc_cmd_accept(int fd, uint32_t events, void *data,
932 struct lxc_epoll_descr *descr)
933 {
934 int opt = 1, ret = -1, connection;
935
936 connection = accept(fd, NULL, 0);
937 if (connection < 0) {
938 SYSERROR("failed to accept connection");
939 return -1;
940 }
941
942 if (fcntl(connection, F_SETFD, FD_CLOEXEC)) {
943 SYSERROR("failed to set close-on-exec on incoming connection");
944 goto out_close;
945 }
946
947 if (setsockopt(connection, SOL_SOCKET,
948 SO_PASSCRED, &opt, sizeof(opt))) {
949 SYSERROR("failed to enable credential on socket");
950 goto out_close;
951 }
952
953 ret = lxc_mainloop_add_handler(descr, connection, lxc_cmd_handler, data);
954 if (ret) {
955 ERROR("failed to add handler");
956 goto out_close;
957 }
958
959 out:
960 return ret;
961
962 out_close:
963 close(connection);
964 goto out;
965 }
966
967 int lxc_cmd_init(const char *name, struct lxc_handler *handler,
968 const char *lxcpath)
969 {
970 int fd;
971 char path[sizeof(((struct sockaddr_un *)0)->sun_path)] = { 0 };
972 char *offset = &path[1];
973 int len;
974
975 len = sizeof(path)-1;
976 if (fill_sock_name(offset, len, name, lxcpath, NULL))
977 return -1;
978
979 fd = lxc_abstract_unix_open(path, SOCK_STREAM, 0);
980 if (fd < 0) {
981 ERROR("failed (%d) to create the command service point %s", errno, offset);
982 if (errno == EADDRINUSE) {
983 ERROR("##");
984 ERROR("# The container appears to be already running!");
985 ERROR("##");
986 }
987 return -1;
988 }
989
990 if (fcntl(fd, F_SETFD, FD_CLOEXEC)) {
991 SYSERROR("failed to set sigfd to close-on-exec");
992 close(fd);
993 return -1;
994 }
995
996 handler->conf->maincmd_fd = fd;
997 return 0;
998 }
999
1000 int lxc_cmd_mainloop_add(const char *name,
1001 struct lxc_epoll_descr *descr,
1002 struct lxc_handler *handler)
1003 {
1004 int ret, fd = handler->conf->maincmd_fd;
1005
1006 ret = lxc_mainloop_add_handler(descr, fd, lxc_cmd_accept, handler);
1007 if (ret) {
1008 ERROR("failed to add handler for command socket");
1009 close(fd);
1010 }
1011
1012 return ret;
1013 }