]>
git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/tools/lxc_start.c
b1b3ca5da2a5359c2111d386c5914b80677ec40f
1 /* SPDX-License-Identifier: LGPL-2.1+ */
10 #include <netinet/in.h>
15 #include <sys/param.h>
16 #include <sys/socket.h>
18 #include <sys/types.h>
19 #include <sys/utsname.h>
24 #include "arguments.h"
29 lxc_log_define(lxc_start
, lxc
);
31 static int my_parser(struct lxc_arguments
*args
, int c
, char *arg
);
32 static int ensure_path(char **confpath
, const char *path
);
34 static struct lxc_list defines
;
36 static const struct option my_longopts
[] = {
37 {"daemon", no_argument
, 0, 'd'},
38 {"foreground", no_argument
, 0, 'F'},
39 {"rcfile", required_argument
, 0, 'f'},
40 {"define", required_argument
, 0, 's'},
41 {"console", required_argument
, 0, 'c'},
42 {"console-log", required_argument
, 0, 'L'},
43 {"close-all-fds", no_argument
, 0, 'C'},
44 {"pidfile", required_argument
, 0, 'p'},
45 {"share-net", required_argument
, 0, OPT_SHARE_NET
},
46 {"share-ipc", required_argument
, 0, OPT_SHARE_IPC
},
47 {"share-uts", required_argument
, 0, OPT_SHARE_UTS
},
48 {"share-pid", required_argument
, 0, OPT_SHARE_PID
},
52 static struct lxc_arguments my_args
= {
53 .progname
= "lxc-start",
55 --name=NAME -- COMMAND\n\
57 lxc-start start COMMAND in specified container NAME\n\
60 -n, --name=NAME NAME of the container\n\
61 -d, --daemon Daemonize the container (default)\n\
62 -F, --foreground Start with the current tty attached to /dev/console\n\
63 -p, --pidfile=FILE Create a file with the process id\n\
64 -f, --rcfile=FILE Load configuration file FILE\n\
65 -c, --console=FILE Use specified FILE for the container console\n\
66 -L, --console-log=FILE Log container console output to FILE\n\
67 -C, --close-all-fds If any fds are inherited, close them\n\
68 Note: --daemon implies --close-all-fds\n\
69 -s, --define KEY=VAL Assign VAL to configuration variable KEY\n\
70 --share-[net|ipc|uts|pid]=NAME Share a namespace with another container or pid\n\
72 .options
= my_longopts
,
75 .log_priority
= "ERROR",
81 static int my_parser(struct lxc_arguments
*args
, int c
, char *arg
)
88 args
->console_log
= arg
;
100 args
->close_all_fds
= true;
103 return lxc_config_define_add(&defines
, arg
);
108 args
->share_ns
[LXC_NS_NET
] = arg
;
111 args
->share_ns
[LXC_NS_IPC
] = arg
;
114 args
->share_ns
[LXC_NS_UTS
] = arg
;
117 args
->share_ns
[LXC_NS_PID
] = arg
;
123 static int ensure_path(char **confpath
, const char *path
)
126 char *fullpath
= NULL
;
129 if (access(path
, W_OK
)) {
130 fd
= creat(path
, 0600);
131 if (fd
< 0 && errno
!= EEXIST
) {
132 ERROR("Failed to create '%s'", path
);
140 fullpath
= realpath(path
, NULL
);
142 ERROR("Failed to get the real path of '%s'", path
);
146 *confpath
= fullpath
;
152 int __attribute__((weak
, alias("lxc_start_main"))) main(int argc
, char *argv
[]);
153 int lxc_start_main(int argc
, char *argv
[])
157 struct lxc_container
*c
;
159 int err
= EXIT_FAILURE
;
161 char *const default_args
[] = {
166 lxc_list_init(&defines
);
171 if (lxc_arguments_parse(&my_args
, argc
, argv
))
179 log
.name
= my_args
.name
;
180 log
.file
= my_args
.log_file
;
181 log
.level
= my_args
.log_priority
;
182 log
.prefix
= my_args
.progname
;
183 log
.quiet
= my_args
.quiet
;
184 log
.lxcpath
= my_args
.lxcpath
[0];
186 if (lxc_log_init(&log
))
189 lxcpath
= my_args
.lxcpath
[0];
190 if (access(lxcpath
, O_RDONLY
) < 0) {
191 ERROR("You lack access to %s", lxcpath
);
196 * rcfile possibilities:
197 * 1. rcfile from random path specified in cli option
198 * 2. rcfile not specified, use $lxcpath/$lxcname/config
199 * 3. rcfile not specified and does not exist.
201 /* rcfile is specified in the cli option */
202 if (my_args
.rcfile
) {
203 rcfile
= (char *)my_args
.rcfile
;
205 c
= lxc_container_new(my_args
.name
, lxcpath
);
207 ERROR("Failed to create lxc_container");
213 if (!c
->load_config(c
, rcfile
)) {
214 ERROR("Failed to load rcfile");
215 lxc_container_put(c
);
219 c
->configfile
= strdup(my_args
.rcfile
);
220 if (!c
->configfile
) {
221 ERROR("Out of memory setting new config filename");
227 rc
= asprintf(&rcfile
, "%s/%s/config", lxcpath
, my_args
.name
);
229 ERROR("Failed to allocate memory");
233 /* container configuration does not exist */
234 if (access(rcfile
, F_OK
)) {
239 c
= lxc_container_new(my_args
.name
, lxcpath
);
241 ERROR("Failed to create lxc_container");
246 /* We do not check here whether the container is defined, because we
247 * support volatile containers. Which means the container does not need
248 * to be created for it to be started. You can just pass a configuration
249 * file as argument and start the container right away.
251 if (!c
->may_control(c
)) {
252 ERROR("Insufficent privileges to control %s", c
->name
);
256 if (c
->is_running(c
)) {
257 ERROR("Container is already running");
263 * We should use set_config_item() over &defines, which would handle
264 * unset c->lxc_conf for us and let us not use lxc_config_define_load()
267 ERROR("No container config specified");
271 if (!lxc_config_define_load(&defines
, c
))
274 if (!rcfile
&& !strcmp("/sbin/init", args
[0])) {
275 ERROR("Executing '/sbin/init' with no configuration file may crash the host");
280 if (ensure_path(&c
->pidfile
, my_args
.pidfile
) < 0) {
281 ERROR("Failed to ensure pidfile '%s'", my_args
.pidfile
);
286 if (!c
->set_config_item(c
, "lxc.console.path", my_args
.console
))
289 if (my_args
.console_log
)
290 if (!c
->set_config_item(c
, "lxc.console.logfile", my_args
.console_log
))
293 if (!lxc_setup_shared_ns(&my_args
, c
))
296 if (!my_args
.daemonize
)
297 c
->want_daemonize(c
, false);
299 if (my_args
.close_all_fds
)
300 c
->want_close_all_fds(c
, true);
302 if (args
== default_args
)
303 err
= c
->start(c
, 0, NULL
) ? EXIT_SUCCESS
: EXIT_FAILURE
;
305 err
= c
->start(c
, 0, args
) ? EXIT_SUCCESS
: EXIT_FAILURE
;
307 ERROR("The container failed to start");
309 if (my_args
.daemonize
)
310 ERROR("To get more details, run the container in foreground mode");
312 ERROR("Additional information can be obtained by setting the "
313 "--logfile and --logpriority options");
316 lxc_container_put(c
);
321 lxc_container_put(c
);