2 * lxc: linux Container library
4 * (C) Copyright IBM Corp. 2007, 2009
7 * Daniel Lezcano <daniel.lezcano at free.fr>
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.
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.
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
35 #include <sys/param.h>
36 #include <sys/socket.h>
42 #include "commands_utils.h"
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).
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
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.
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.
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
79 lxc_log_define(lxc_commands
, lxc
);
81 static const char *lxc_cmd_str(lxc_cmd_t cmd
)
83 static const char *const cmdname
[LXC_CMD_MAX
] = {
84 [LXC_CMD_CONSOLE
] = "console",
85 [LXC_CMD_CONSOLE_WINCH
] = "console_winch",
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_SET_CONFIG_ITEM
] = "set_config_item",
96 [LXC_CMD_CONSOLE_LOG
] = "console_log",
99 if (cmd
>= LXC_CMD_MAX
)
100 return "Unknown cmd";
106 * lxc_cmd_rsp_recv: Receive a response to a command
108 * @sock : the socket connected to the container
109 * @cmd : command to put response in
111 * Returns the size of the response message or < 0 on failure
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.
118 * As a special case, the response for LXC_CMD_CONSOLE is created
119 * here as it contains an fd for the master pty passed through the
122 static int lxc_cmd_rsp_recv(int sock
, struct lxc_cmd_rr
*cmd
)
125 struct lxc_cmd_rsp
*rsp
= &cmd
->rsp
;
127 ret
= lxc_abstract_unix_recv_fds(sock
, &rspfd
, 1, rsp
, sizeof(*rsp
));
129 WARN("%s - Failed to receive response for command \"%s\"",
130 strerror(errno
), lxc_cmd_str(cmd
->req
.cmd
));
133 TRACE("Command \"%s\" received response", lxc_cmd_str(cmd
->req
.cmd
));
135 if (cmd
->req
.cmd
== LXC_CMD_CONSOLE
) {
136 struct lxc_cmd_console_rsp_data
*rspdata
;
138 /* recv() returns 0 bytes when a tty cannot be allocated,
139 * rsp->ret is < 0 when the peer permission check failed
141 if (ret
== 0 || rsp
->ret
< 0)
144 rspdata
= malloc(sizeof(*rspdata
));
146 ERROR("Failed to allocate response buffer for command \"%s\"",
147 lxc_cmd_str(cmd
->req
.cmd
));
150 rspdata
->masterfd
= rspfd
;
151 rspdata
->ttynum
= PTR_TO_INT(rsp
->data
);
155 if (rsp
->datalen
== 0) {
156 DEBUG("Response data length for command \"%s\" is 0",
157 lxc_cmd_str(cmd
->req
.cmd
));
161 if ((rsp
->datalen
> LXC_CMD_DATA_MAX
) &&
162 (cmd
->req
.cmd
!= LXC_CMD_CONSOLE_LOG
)) {
164 ERROR("%s - Response data for command \"%s\" is too long: %d "
165 "bytes > %d", strerror(errno
), lxc_cmd_str(cmd
->req
.cmd
),
166 rsp
->datalen
, LXC_CMD_DATA_MAX
);
170 if (cmd
->req
.cmd
== LXC_CMD_CONSOLE_LOG
) {
171 rsp
->data
= malloc(rsp
->datalen
+ 1);
172 ((char *)rsp
->data
)[rsp
->datalen
] = '\0';
174 rsp
->data
= malloc(rsp
->datalen
);
178 ERROR("%s - Failed to allocate response buffer for command "
179 "\"%s\"", strerror(errno
), lxc_cmd_str(cmd
->req
.cmd
));
183 ret
= recv(sock
, rsp
->data
, rsp
->datalen
, 0);
184 if (ret
!= rsp
->datalen
) {
185 ERROR("%s - Failed to receive response data for command \"%s\"",
186 lxc_cmd_str(cmd
->req
.cmd
), strerror(errno
));
195 * lxc_cmd_rsp_send: Send a command response
197 * @fd : file descriptor of socket to send response on
198 * @rsp : response to send
200 * Returns 0 on success, < 0 on failure
202 static int lxc_cmd_rsp_send(int fd
, struct lxc_cmd_rsp
*rsp
)
206 ret
= send(fd
, rsp
, sizeof(*rsp
), 0);
207 if (ret
< 0 || (size_t)ret
!= sizeof(*rsp
)) {
208 ERROR("%s - Failed to send command response %zd",
209 strerror(errno
), ret
);
213 if (rsp
->datalen
<= 0)
216 ret
= send(fd
, rsp
->data
, rsp
->datalen
, 0);
217 if (ret
< 0 || ret
!= (ssize_t
)rsp
->datalen
) {
218 WARN("%s - Failed to send command response data %zd",
219 strerror(errno
), ret
);
226 static int lxc_cmd_send(const char *name
, struct lxc_cmd_rr
*cmd
,
227 const char *lxcpath
, const char *hashed_sock_name
)
232 client_fd
= lxc_cmd_connect(name
, lxcpath
, hashed_sock_name
, "command");
234 if (client_fd
== -ECONNREFUSED
)
235 return -ECONNREFUSED
;
240 ret
= lxc_abstract_unix_send_credential(client_fd
, &cmd
->req
,
242 if (ret
< 0 || (size_t)ret
!= sizeof(cmd
->req
)) {
254 if (cmd
->req
.datalen
<= 0)
257 ret
= send(client_fd
, cmd
->req
.data
, cmd
->req
.datalen
, MSG_NOSIGNAL
);
258 if (ret
< 0 || ret
!= (ssize_t
)cmd
->req
.datalen
) {
274 * lxc_cmd: Connect to the specified running container, send it a command
275 * request and collect the response
277 * @name : name of container to connect to
278 * @cmd : command with initialized request to send
279 * @stopped : output indicator if the container was not running
280 * @lxcpath : the lxcpath in which the container is running
282 * Returns the size of the response message on success, < 0 on failure
284 * Note that there is a special case for LXC_CMD_CONSOLE. For this command
285 * the fd cannot be closed because it is used as a placeholder to indicate
286 * that a particular tty slot is in use. The fd is also used as a signal to
287 * the container that when the caller dies or closes the fd, the container
288 * will notice the fd on its side of the socket in its mainloop select and
289 * then free the slot with lxc_cmd_fd_cleanup(). The socket fd will be
290 * returned in the cmd response structure.
292 static int lxc_cmd(const char *name
, struct lxc_cmd_rr
*cmd
, int *stopped
,
293 const char *lxcpath
, const char *hashed_sock_name
)
297 bool stay_connected
= false;
299 if (cmd
->req
.cmd
== LXC_CMD_CONSOLE
||
300 cmd
->req
.cmd
== LXC_CMD_ADD_STATE_CLIENT
)
301 stay_connected
= true;
305 client_fd
= lxc_cmd_send(name
, cmd
, lxcpath
, hashed_sock_name
);
307 TRACE("%s - Command \"%s\" failed to connect command socket",
308 strerror(errno
), lxc_cmd_str(cmd
->req
.cmd
));
309 if (client_fd
== -ECONNREFUSED
) {
314 if (client_fd
== -EPIPE
)
320 ret
= lxc_cmd_rsp_recv(client_fd
, cmd
);
322 if (!stay_connected
|| ret
<= 0)
325 if (stay_connected
&& ret
> 0)
326 cmd
->rsp
.ret
= client_fd
;
335 int lxc_try_cmd(const char *name
, const char *lxcpath
)
338 struct lxc_cmd_rr cmd
= {
339 .req
= { .cmd
= LXC_CMD_GET_INIT_PID
},
342 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
345 if (ret
> 0 && cmd
.rsp
.ret
< 0) {
352 /* At this point we weren't denied access, and the container *was*
353 * started. There was some inexplicable error in the protocol. I'm not
354 * clear on whether we should return -1 here, but we didn't receive a
355 * -EACCES, so technically it's not that we're not allowed to control
356 * the container - it's just not behaving.
361 /* Implentations of the commands and their callbacks */
364 * lxc_cmd_get_init_pid: Get pid of the container's init process
366 * @name : name of container to connect to
367 * @lxcpath : the lxcpath in which the container is running
369 * Returns the pid on success, < 0 on failure
371 pid_t
lxc_cmd_get_init_pid(const char *name
, const char *lxcpath
)
374 struct lxc_cmd_rr cmd
= {
375 .req
= { .cmd
= LXC_CMD_GET_INIT_PID
},
378 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
382 return PTR_TO_INT(cmd
.rsp
.data
);
385 static int lxc_cmd_get_init_pid_callback(int fd
, struct lxc_cmd_req
*req
,
386 struct lxc_handler
*handler
)
388 struct lxc_cmd_rsp rsp
= { .data
= INT_TO_PTR(handler
->pid
) };
390 return lxc_cmd_rsp_send(fd
, &rsp
);
394 * lxc_cmd_get_clone_flags: Get clone flags container was spawned with
396 * @name : name of container to connect to
397 * @lxcpath : the lxcpath in which the container is running
399 * Returns the clone flags on success, < 0 on failure
401 int lxc_cmd_get_clone_flags(const char *name
, const char *lxcpath
)
404 struct lxc_cmd_rr cmd
= {
405 .req
= { .cmd
= LXC_CMD_GET_CLONE_FLAGS
},
408 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
412 return PTR_TO_INT(cmd
.rsp
.data
);
415 static int lxc_cmd_get_clone_flags_callback(int fd
, struct lxc_cmd_req
*req
,
416 struct lxc_handler
*handler
)
418 struct lxc_cmd_rsp rsp
= { .data
= INT_TO_PTR(handler
->clone_flags
) };
420 return lxc_cmd_rsp_send(fd
, &rsp
);
424 * lxc_cmd_get_cgroup_path: Calculate a container's cgroup path for a
425 * particular subsystem. This is the cgroup path relative to the root
426 * of the cgroup filesystem.
428 * @name : name of container to connect to
429 * @lxcpath : the lxcpath in which the container is running
430 * @subsystem : the subsystem being asked about
432 * Returns the path on success, NULL on failure. The caller must free() the
435 char *lxc_cmd_get_cgroup_path(const char *name
, const char *lxcpath
,
436 const char *subsystem
)
439 struct lxc_cmd_rr cmd
= {
441 .cmd
= LXC_CMD_GET_CGROUP
,
442 .datalen
= strlen(subsystem
) + 1,
447 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
454 if (cmd
.rsp
.ret
< 0 || cmd
.rsp
.datalen
< 0)
460 static int lxc_cmd_get_cgroup_callback(int fd
, struct lxc_cmd_req
*req
,
461 struct lxc_handler
*handler
)
464 struct lxc_cmd_rsp rsp
;
466 if (req
->datalen
< 1)
469 path
= cgroup_get_cgroup(handler
, req
->data
);
474 rsp
.datalen
= strlen(path
) + 1;
475 rsp
.data
= (char *)path
;
477 return lxc_cmd_rsp_send(fd
, &rsp
);
481 * lxc_cmd_get_config_item: Get config item the running container
483 * @name : name of container to connect to
484 * @item : the configuration item to retrieve (ex: lxc.net.0.veth.pair)
485 * @lxcpath : the lxcpath in which the container is running
487 * Returns the item on success, NULL on failure. The caller must free() the
490 char *lxc_cmd_get_config_item(const char *name
, const char *item
,
494 struct lxc_cmd_rr cmd
= {
495 .req
= { .cmd
= LXC_CMD_GET_CONFIG_ITEM
,
497 .datalen
= strlen(item
) + 1,
501 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
505 if (cmd
.rsp
.ret
== 0)
511 static int lxc_cmd_get_config_item_callback(int fd
, struct lxc_cmd_req
*req
,
512 struct lxc_handler
*handler
)
516 struct lxc_config_t
*item
;
517 struct lxc_cmd_rsp rsp
;
519 memset(&rsp
, 0, sizeof(rsp
));
520 item
= lxc_get_config(req
->data
);
524 cilen
= item
->get(req
->data
, NULL
, 0, handler
->conf
, NULL
);
528 cidata
= alloca(cilen
+ 1);
529 if (item
->get(req
->data
, cidata
, cilen
+ 1, handler
->conf
, NULL
) != cilen
)
532 cidata
[cilen
] = '\0';
534 rsp
.datalen
= cilen
+ 1;
541 return lxc_cmd_rsp_send(fd
, &rsp
);
545 * lxc_cmd_set_config_item: Get config item the running container
547 * @name : name of container to connect to
548 * @item : the configuration item to set (ex: lxc.net.0.veth.pair)
549 * @value : the value to set (ex: "eth0")
550 * @lxcpath : the lxcpath in which the container is running
552 * Returns 0 on success, negative errno on failure.
554 int lxc_cmd_set_config_item(const char *name
, const char *item
,
555 const char *value
, const char *lxcpath
)
558 struct lxc_cmd_set_config_item_req_data data
;
559 struct lxc_cmd_rr cmd
;
561 /* pre-validate request
562 Currently we only support live-patching network configurations.
564 if (strncmp(item
, "lxc.net.", 8))
568 data
.value
= (void *)value
;
570 cmd
.req
.cmd
= LXC_CMD_SET_CONFIG_ITEM
;
571 cmd
.req
.data
= &data
;
572 cmd
.req
.datalen
= sizeof(data
);
574 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
581 static int lxc_cmd_set_config_item_callback(int fd
, struct lxc_cmd_req
*req
,
582 struct lxc_handler
*handler
)
584 const char *key
, *value
;
585 struct lxc_cmd_rsp rsp
;
586 const struct lxc_cmd_set_config_item_req_data
*data
;
592 memset(&rsp
, 0, sizeof(rsp
));
593 rsp
.ret
= lxc_set_config_item_locked(handler
->conf
, key
, value
);
595 return lxc_cmd_rsp_send(fd
, &rsp
);
599 * lxc_cmd_get_state: Get current state of the container
601 * @name : name of container to connect to
602 * @lxcpath : the lxcpath in which the container is running
604 * Returns the state on success, < 0 on failure
606 int lxc_cmd_get_state(const char *name
, const char *lxcpath
)
609 struct lxc_cmd_rr cmd
= {
610 .req
= { .cmd
= LXC_CMD_GET_STATE
}
613 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
614 if (ret
< 0 && stopped
)
621 WARN("Container \"%s\" has stopped before sending its state", name
);
625 DEBUG("Container \"%s\" is in \"%s\" state", name
,
626 lxc_state2str(PTR_TO_INT(cmd
.rsp
.data
)));
628 return PTR_TO_INT(cmd
.rsp
.data
);
631 static int lxc_cmd_get_state_callback(int fd
, struct lxc_cmd_req
*req
,
632 struct lxc_handler
*handler
)
634 struct lxc_cmd_rsp rsp
= { .data
= INT_TO_PTR(handler
->state
) };
636 return lxc_cmd_rsp_send(fd
, &rsp
);
640 * lxc_cmd_stop: Stop the container previously started with lxc_start. All
641 * the processes running inside this container will be killed.
643 * @name : name of container to connect to
644 * @lxcpath : the lxcpath in which the container is running
646 * Returns 0 on success, < 0 on failure
648 int lxc_cmd_stop(const char *name
, const char *lxcpath
)
651 struct lxc_cmd_rr cmd
= {
652 .req
= { .cmd
= LXC_CMD_STOP
},
655 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
658 INFO("Container \"%s\" is already stopped", name
);
665 /* We do not expect any answer, because we wait for the connection to be
669 ERROR("%s - Failed to stop container \"%s\"",
670 strerror(-cmd
.rsp
.ret
), name
);
674 INFO("Container \"%s\" has stopped", name
);
678 static int lxc_cmd_stop_callback(int fd
, struct lxc_cmd_req
*req
,
679 struct lxc_handler
*handler
)
681 struct lxc_cmd_rsp rsp
;
682 int stopsignal
= SIGKILL
;
684 if (handler
->conf
->stopsignal
)
685 stopsignal
= handler
->conf
->stopsignal
;
686 memset(&rsp
, 0, sizeof(rsp
));
687 rsp
.ret
= kill(handler
->pid
, stopsignal
);
689 /* We can't just use lxc_unfreeze() since we are already in the
690 * context of handling the STOP cmd in lxc-start, and calling
691 * lxc_unfreeze() would do another cmd (GET_CGROUP) which would
694 if (cgroup_unfreeze(handler
))
697 ERROR("Failed to unfreeze container \"%s\"", handler
->name
);
701 return lxc_cmd_rsp_send(fd
, &rsp
);
705 * lxc_cmd_console_winch: To process as if a SIGWINCH were received
707 * @name : name of container to connect to
708 * @lxcpath : the lxcpath in which the container is running
710 * Returns 0 on success, < 0 on failure
712 int lxc_cmd_console_winch(const char *name
, const char *lxcpath
)
715 struct lxc_cmd_rr cmd
= {
716 .req
= { .cmd
= LXC_CMD_CONSOLE_WINCH
},
719 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
726 static int lxc_cmd_console_winch_callback(int fd
, struct lxc_cmd_req
*req
,
727 struct lxc_handler
*handler
)
729 struct lxc_cmd_rsp rsp
= { .data
= 0 };
731 lxc_console_sigwinch(SIGWINCH
);
733 return lxc_cmd_rsp_send(fd
, &rsp
);
737 * lxc_cmd_console: Open an fd to a tty in the container
739 * @name : name of container to connect to
740 * @ttynum : in: the tty to open or -1 for next available
741 * : out: the tty allocated
742 * @fd : out: file descriptor for master side of pty
743 * @lxcpath : the lxcpath in which the container is running
745 * Returns fd holding tty allocated on success, < 0 on failure
747 int lxc_cmd_console(const char *name
, int *ttynum
, int *fd
, const char *lxcpath
)
750 struct lxc_cmd_console_rsp_data
*rspdata
;
751 struct lxc_cmd_rr cmd
= {
752 .req
= { .cmd
= LXC_CMD_CONSOLE
, .data
= INT_TO_PTR(*ttynum
) },
755 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
759 if (cmd
.rsp
.ret
< 0) {
760 ERROR("%s - Denied access to tty", strerror(-cmd
.rsp
.ret
));
766 ERROR("tty number %d invalid, busy or all ttys busy", *ttynum
);
771 rspdata
= cmd
.rsp
.data
;
772 if (rspdata
->masterfd
< 0) {
773 ERROR("Unable to allocate fd for tty %d", rspdata
->ttynum
);
777 ret
= cmd
.rsp
.ret
; /* socket fd */
778 *fd
= rspdata
->masterfd
;
779 *ttynum
= rspdata
->ttynum
;
780 INFO("Alloced fd %d for tty %d via socket %d", *fd
, rspdata
->ttynum
, ret
);
787 static int lxc_cmd_console_callback(int fd
, struct lxc_cmd_req
*req
,
788 struct lxc_handler
*handler
)
791 struct lxc_cmd_rsp rsp
;
792 int ttynum
= PTR_TO_INT(req
->data
);
794 masterfd
= lxc_console_allocate(handler
->conf
, fd
, &ttynum
);
798 memset(&rsp
, 0, sizeof(rsp
));
799 rsp
.data
= INT_TO_PTR(ttynum
);
800 ret
= lxc_abstract_unix_send_fds(fd
, &masterfd
, 1, &rsp
, sizeof(rsp
));
802 ERROR("Failed to send tty to client");
803 lxc_console_free(handler
->conf
, fd
);
810 /* Special indicator to lxc_cmd_handler() to close the fd and do
817 * lxc_cmd_get_name: Returns the name of the container
819 * @hashed_sock_name: hashed socket name
821 * Returns the name on success, NULL on failure.
823 char *lxc_cmd_get_name(const char *hashed_sock_name
)
826 struct lxc_cmd_rr cmd
= {
827 .req
= { .cmd
= LXC_CMD_GET_NAME
},
830 ret
= lxc_cmd(NULL
, &cmd
, &stopped
, NULL
, hashed_sock_name
);
834 if (cmd
.rsp
.ret
== 0)
840 static int lxc_cmd_get_name_callback(int fd
, struct lxc_cmd_req
*req
,
841 struct lxc_handler
*handler
)
843 struct lxc_cmd_rsp rsp
;
845 memset(&rsp
, 0, sizeof(rsp
));
847 rsp
.data
= (char *)handler
->name
;
848 rsp
.datalen
= strlen(handler
->name
) + 1;
851 return lxc_cmd_rsp_send(fd
, &rsp
);
855 * lxc_cmd_get_lxcpath: Returns the lxcpath of the container
857 * @hashed_sock_name: hashed socket name
859 * Returns the lxcpath on success, NULL on failure.
861 char *lxc_cmd_get_lxcpath(const char *hashed_sock_name
)
864 struct lxc_cmd_rr cmd
= {
865 .req
= { .cmd
= LXC_CMD_GET_LXCPATH
},
868 ret
= lxc_cmd(NULL
, &cmd
, &stopped
, NULL
, hashed_sock_name
);
872 if (cmd
.rsp
.ret
== 0)
878 static int lxc_cmd_get_lxcpath_callback(int fd
, struct lxc_cmd_req
*req
,
879 struct lxc_handler
*handler
)
881 struct lxc_cmd_rsp rsp
;
883 memset(&rsp
, 0, sizeof(rsp
));
886 rsp
.data
= (char *)handler
->lxcpath
;
887 rsp
.datalen
= strlen(handler
->lxcpath
) + 1;
889 return lxc_cmd_rsp_send(fd
, &rsp
);
892 int lxc_cmd_add_state_client(const char *name
, const char *lxcpath
,
893 lxc_state_t states
[MAX_STATE
],
894 int *state_client_fd
)
899 struct lxc_cmd_rr cmd
= {
901 .cmd
= LXC_CMD_ADD_STATE_CLIENT
,
903 .datalen
= (sizeof(lxc_state_t
) * MAX_STATE
)
907 /* Lock the whole lxc_cmd_add_state_client_callback() call to ensure
908 * that lxc_set_state() doesn't cause us to miss a state.
911 /* Check if already in requested state. */
912 state
= lxc_getstate(name
, lxcpath
);
915 TRACE("%s - Failed to retrieve state of container", strerror(errno
));
917 } else if (states
[state
]) {
919 TRACE("Container is %s state", lxc_state2str(state
));
923 if ((state
== STARTING
) && !states
[RUNNING
] && !states
[STOPPING
] && !states
[STOPPED
]) {
925 TRACE("Container is in %s state and caller requested to be "
926 "informed about a previous state", lxc_state2str(state
));
928 } else if ((state
== RUNNING
) && !states
[STOPPING
] && !states
[STOPPED
]) {
930 TRACE("Container is in %s state and caller requested to be "
931 "informed about a previous state", lxc_state2str(state
));
933 } else if ((state
== STOPPING
) && !states
[STOPPED
]) {
935 TRACE("Container is in %s state and caller requested to be "
936 "informed about a previous state", lxc_state2str(state
));
938 } else if ((state
== STOPPED
) || (state
== ABORTING
)) {
940 TRACE("Container is in %s state and caller requested to be "
941 "informed about a previous state", lxc_state2str(state
));
945 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
948 ERROR("%s - Failed to execute command", strerror(errno
));
952 /* We should now be guaranteed to get an answer from the state sending
956 if (cmd
.rsp
.ret
< 0) {
957 ERROR("Failed to receive socket fd");
961 *state_client_fd
= cmd
.rsp
.ret
;
965 static int lxc_cmd_add_state_client_callback(int fd
, struct lxc_cmd_req
*req
,
966 struct lxc_handler
*handler
)
968 struct lxc_cmd_rsp rsp
= {0};
970 if (req
->datalen
< 0)
973 if (req
->datalen
> (sizeof(lxc_state_t
) * MAX_STATE
))
979 rsp
.ret
= lxc_add_state_client(fd
, handler
, (lxc_state_t
*)req
->data
);
981 ERROR("Failed to add state client %d to state client list", fd
);
983 TRACE("Added state client %d to state client list", fd
);
985 return lxc_cmd_rsp_send(fd
, &rsp
);
988 int lxc_cmd_console_log(const char *name
, const char *lxcpath
,
989 struct lxc_console_log
*log
)
992 struct lxc_cmd_console_log data
;
993 struct lxc_cmd_rr cmd
;
995 data
.clear
= log
->clear
;
996 data
.read
= log
->read
;
997 data
.read_max
= *log
->read_max
;
998 data
.write_logfile
= log
->write_logfile
;
1000 cmd
.req
.cmd
= LXC_CMD_CONSOLE_LOG
;
1001 cmd
.req
.data
= &data
;
1002 cmd
.req
.datalen
= sizeof(struct lxc_cmd_console_log
);
1004 ret
= lxc_cmd(name
, &cmd
, &stopped
, lxcpath
, NULL
);
1008 /* There is nothing to be read from the buffer. So clear any values we
1009 * where passed to clearly indicate to the user that nothing went wrong.
1011 if (cmd
.rsp
.ret
== -ENODATA
|| cmd
.rsp
.ret
== -EFAULT
|| cmd
.rsp
.ret
== -ENOENT
) {
1016 /* This is a proper error so don't touch any values we were passed. */
1017 if (cmd
.rsp
.ret
< 0)
1020 *log
->read_max
= cmd
.rsp
.datalen
;
1021 log
->data
= cmd
.rsp
.data
;
1026 static int lxc_cmd_console_log_callback(int fd
, struct lxc_cmd_req
*req
,
1027 struct lxc_handler
*handler
)
1029 struct lxc_cmd_rsp rsp
;
1030 uint64_t buffer_size
= handler
->conf
->console
.buffer_size
;
1031 const struct lxc_cmd_console_log
*log
= req
->data
;
1032 struct lxc_console
*console
= &handler
->conf
->console
;
1033 struct lxc_ringbuf
*buf
= &handler
->conf
->console
.ringbuf
;
1038 if (buffer_size
<= 0)
1041 if (log
->read
|| log
->write_logfile
)
1042 rsp
.datalen
= lxc_ringbuf_used(buf
);
1045 rsp
.data
= lxc_ringbuf_get_read_addr(buf
);
1047 if (log
->read_max
> 0 && (log
->read_max
<= rsp
.datalen
))
1048 rsp
.datalen
= log
->read_max
;
1050 /* there's nothing to read */
1052 if (log
->read
&& (buf
->r_off
== buf
->w_off
))
1055 if (log
->write_logfile
&& rsp
.datalen
> 0) {
1057 if (!console
->buffer_log_file
)
1060 rsp
.ret
= lxc_console_write_ringbuffer(console
);
1071 /* clear the ringbuffer */
1072 lxc_ringbuf_clear(buf
);
1074 /* truncate the ringbuffer log file */
1075 if (console
->buffer_log_file
) {
1077 if (!file_exists(console
->buffer_log_file
))
1080 /* be very certain things are kosher */
1082 if (console
->buffer_log_file_fd
< 0)
1085 rsp
.ret
= lxc_unpriv(ftruncate(console
->buffer_log_file_fd
, 0));
1087 ERROR("%s - Failed to truncate console "
1088 "ringbuffer log file \"%s\"",
1089 strerror(errno
), console
->buffer_log_file
);
1094 /* rotate the console log file */
1095 if (!console
->log_path
|| console
->log_rotate
== 0)
1098 /* be very certain things are kosher */
1100 if (console
->log_fd
< 0)
1103 len
= strlen(console
->log_path
) + sizeof(".1");
1107 ret
= snprintf(tmp
, len
, "%s.1", console
->log_path
);
1108 if (ret
< 0 || (size_t)ret
>= len
)
1111 close(console
->log_fd
);
1112 console
->log_fd
= -1;
1113 rsp
.ret
= lxc_unpriv(rename(console
->log_path
, tmp
));
1117 rsp
.ret
= lxc_console_create_log_file(console
);
1118 } else if (rsp
.datalen
> 0) {
1119 lxc_ringbuf_move_read_addr(buf
, rsp
.datalen
);
1123 return lxc_cmd_rsp_send(fd
, &rsp
);
1126 static int lxc_cmd_process(int fd
, struct lxc_cmd_req
*req
,
1127 struct lxc_handler
*handler
)
1129 typedef int (*callback
)(int, struct lxc_cmd_req
*, struct lxc_handler
*);
1131 callback cb
[LXC_CMD_MAX
] = {
1132 [LXC_CMD_CONSOLE
] = lxc_cmd_console_callback
,
1133 [LXC_CMD_CONSOLE_WINCH
] = lxc_cmd_console_winch_callback
,
1134 [LXC_CMD_STOP
] = lxc_cmd_stop_callback
,
1135 [LXC_CMD_GET_STATE
] = lxc_cmd_get_state_callback
,
1136 [LXC_CMD_GET_INIT_PID
] = lxc_cmd_get_init_pid_callback
,
1137 [LXC_CMD_GET_CLONE_FLAGS
] = lxc_cmd_get_clone_flags_callback
,
1138 [LXC_CMD_GET_CGROUP
] = lxc_cmd_get_cgroup_callback
,
1139 [LXC_CMD_GET_CONFIG_ITEM
] = lxc_cmd_get_config_item_callback
,
1140 [LXC_CMD_GET_NAME
] = lxc_cmd_get_name_callback
,
1141 [LXC_CMD_GET_LXCPATH
] = lxc_cmd_get_lxcpath_callback
,
1142 [LXC_CMD_ADD_STATE_CLIENT
] = lxc_cmd_add_state_client_callback
,
1143 [LXC_CMD_SET_CONFIG_ITEM
] = lxc_cmd_set_config_item_callback
,
1144 [LXC_CMD_CONSOLE_LOG
] = lxc_cmd_console_log_callback
,
1147 if (req
->cmd
>= LXC_CMD_MAX
) {
1148 ERROR("Undefined command id %d", req
->cmd
);
1151 return cb
[req
->cmd
](fd
, req
, handler
);
1154 static void lxc_cmd_fd_cleanup(int fd
, struct lxc_handler
*handler
,
1155 struct lxc_epoll_descr
*descr
)
1157 lxc_console_free(handler
->conf
, fd
);
1158 lxc_mainloop_del_handler(descr
, fd
);
1162 static int lxc_cmd_handler(int fd
, uint32_t events
, void *data
,
1163 struct lxc_epoll_descr
*descr
)
1166 struct lxc_cmd_req req
;
1167 void *reqdata
= NULL
;
1168 struct lxc_handler
*handler
= data
;
1170 ret
= lxc_abstract_unix_rcv_credential(fd
, &req
, sizeof(req
));
1171 if (ret
== -EACCES
) {
1172 /* We don't care for the peer, just send and close. */
1173 struct lxc_cmd_rsp rsp
= {.ret
= ret
};
1175 lxc_cmd_rsp_send(fd
, &rsp
);
1180 SYSERROR("Failed to receive data on command socket for command "
1181 "\"%s\"", lxc_cmd_str(req
.cmd
));
1188 if (ret
!= sizeof(req
)) {
1189 WARN("Failed to receive full command request. Ignoring request "
1190 "for \"%s\"", lxc_cmd_str(req
.cmd
));
1195 if ((req
.datalen
> LXC_CMD_DATA_MAX
) &&
1196 (req
.cmd
!= LXC_CMD_CONSOLE_LOG
)) {
1197 ERROR("Received command data length %d is too large for "
1198 "command \"%s\"", req
.datalen
, lxc_cmd_str(req
.cmd
));
1204 if (req
.datalen
> 0) {
1205 /* LXC_CMD_CONSOLE_LOG needs to be able to allocate data
1206 * that exceeds LXC_CMD_DATA_MAX: use malloc() for that.
1208 if (req
.cmd
== LXC_CMD_CONSOLE_LOG
)
1209 reqdata
= malloc(req
.datalen
);
1211 reqdata
= alloca(req
.datalen
);
1213 ERROR("Failed to allocate memory for \"%s\" command",
1214 lxc_cmd_str(req
.cmd
));
1220 ret
= recv(fd
, reqdata
, req
.datalen
, 0);
1221 if (ret
!= req
.datalen
) {
1222 WARN("Failed to receive full command request. Ignoring "
1223 "request for \"%s\"", lxc_cmd_str(req
.cmd
));
1231 ret
= lxc_cmd_process(fd
, &req
, handler
);
1233 /* This is not an error, but only a request to close fd. */
1239 if (req
.cmd
== LXC_CMD_CONSOLE_LOG
&& reqdata
)
1245 lxc_cmd_fd_cleanup(fd
, handler
, descr
);
1249 static int lxc_cmd_accept(int fd
, uint32_t events
, void *data
,
1250 struct lxc_epoll_descr
*descr
)
1253 int opt
= 1, ret
= -1;
1255 connection
= accept(fd
, NULL
, 0);
1256 if (connection
< 0) {
1257 SYSERROR("Failed to accept connection to run command.");
1261 ret
= fcntl(connection
, F_SETFD
, FD_CLOEXEC
);
1263 SYSERROR("Failed to set close-on-exec on incoming command connection");
1267 ret
= setsockopt(connection
, SOL_SOCKET
, SO_PASSCRED
, &opt
, sizeof(opt
));
1269 SYSERROR("Failed to enable necessary credentials on command socket");
1273 ret
= lxc_mainloop_add_handler(descr
, connection
, lxc_cmd_handler
, data
);
1275 ERROR("Failed to add command handler");
1287 int lxc_cmd_init(const char *name
, const char *lxcpath
, const char *suffix
)
1290 char path
[sizeof(((struct sockaddr_un
*)0)->sun_path
)] = {0};
1291 char *offset
= &path
[1];
1293 /* -2 here because this is an abstract unix socket so it needs a
1294 * leading \0, and we null terminate, so it needs a trailing \0.
1295 * Although null termination isn't required by the API, we do it anyway
1296 * because we print the sockname out sometimes.
1298 len
= sizeof(path
) - 2;
1299 ret
= lxc_make_abstract_socket_name(offset
, len
, name
, lxcpath
, NULL
, suffix
);
1302 TRACE("Creating abstract unix socket \"%s\"", offset
);
1304 fd
= lxc_abstract_unix_open(path
, SOCK_STREAM
, 0);
1306 ERROR("%s - Failed to create command socket %s",
1307 strerror(errno
), offset
);
1308 if (errno
== EADDRINUSE
)
1309 ERROR("Container \"%s\" appears to be already running", name
);
1313 ret
= fcntl(fd
, F_SETFD
, FD_CLOEXEC
);
1315 SYSERROR("Failed to set FD_CLOEXEC on command socket file descriptor");
1323 int lxc_cmd_mainloop_add(const char *name
, struct lxc_epoll_descr
*descr
,
1324 struct lxc_handler
*handler
)
1327 int fd
= handler
->conf
->maincmd_fd
;
1329 ret
= lxc_mainloop_add_handler(descr
, fd
, lxc_cmd_accept
, handler
);
1331 ERROR("Failed to add handler for command socket");