mirror of
https://git.proxmox.com/git/mirror_lxc
synced 2025-08-14 17:12:14 +00:00
api: convert lxc_start
Normal lxc-start usage tends to be "lxc-start -n name [-P lxcpath]". This causes $lxcpath/$name/config to be the configuration for the container. However, lxc-start is more flexible than that. You can specify a custom configuration file, in which case $lxcpath/$name/config is not used. You can also (in addition or in place of either of these) specify configuration entries one-by-one using "-s lxc.utsname=xxx". To support this using the API, if we are not using $lxcpath/$name/config then we put ourselves into a custom lxcpath called (configurable using LXCPATH) /var/lib/lxc_anon. To stop a container so created, then, you would use lxc-stop -P /var/lib/lxc_anon -n name TODO: we should walk over the list of &defines by hand and set them using c->set_config_item. I haven't done that in this patch. Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
This commit is contained in:
parent
cb0c6c0203
commit
79622932f2
@ -43,6 +43,7 @@
|
|||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "caps.h"
|
#include "caps.h"
|
||||||
#include "lxc.h"
|
#include "lxc.h"
|
||||||
|
#include "lxccontainer.h"
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
#include "cgroup.h"
|
#include "cgroup.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
@ -151,6 +152,8 @@ int main(int argc, char *argv[])
|
|||||||
'\0',
|
'\0',
|
||||||
};
|
};
|
||||||
FILE *pid_fp = NULL;
|
FILE *pid_fp = NULL;
|
||||||
|
struct lxc_container *c;
|
||||||
|
char *anonpath;
|
||||||
|
|
||||||
lxc_list_init(&defines);
|
lxc_list_init(&defines);
|
||||||
|
|
||||||
@ -169,13 +172,32 @@ int main(int argc, char *argv[])
|
|||||||
my_args.progname, my_args.quiet, my_args.lxcpath[0]))
|
my_args.progname, my_args.quiet, my_args.lxcpath[0]))
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
anonpath = alloca(strlen(LXCPATH) + 6);
|
||||||
|
sprintf(anonpath, "%s_anon", LXCPATH);
|
||||||
|
/*
|
||||||
|
* rcfile possibilities:
|
||||||
|
* 1. rcfile from random path specified in cli option
|
||||||
|
* 2. rcfile not specified, use $lxcpath/$lxcname/config
|
||||||
|
* 3. rcfile not specified and does not exist.
|
||||||
|
*/
|
||||||
/* rcfile is specified in the cli option */
|
/* rcfile is specified in the cli option */
|
||||||
if (my_args.rcfile)
|
if (my_args.rcfile) {
|
||||||
rcfile = (char *)my_args.rcfile;
|
rcfile = (char *)my_args.rcfile;
|
||||||
else {
|
c = lxc_container_new(my_args.name, anonpath);
|
||||||
|
if (!c) {
|
||||||
|
ERROR("Failed to create lxc_container");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
if (!c->load_config(c, rcfile)) {
|
||||||
|
ERROR("Failed to load rcfile");
|
||||||
|
lxc_container_put(c);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
int rc;
|
int rc;
|
||||||
|
const char *lxcpath = my_args.lxcpath[0];
|
||||||
|
|
||||||
rc = asprintf(&rcfile, "%s/%s/config", my_args.lxcpath[0], my_args.name);
|
rc = asprintf(&rcfile, "%s/%s/config", lxcpath, my_args.name);
|
||||||
if (rc == -1) {
|
if (rc == -1) {
|
||||||
SYSERROR("failed to allocate memory");
|
SYSERROR("failed to allocate memory");
|
||||||
return err;
|
return err;
|
||||||
@ -186,25 +208,28 @@ int main(int argc, char *argv[])
|
|||||||
if (access(rcfile, F_OK)) {
|
if (access(rcfile, F_OK)) {
|
||||||
free(rcfile);
|
free(rcfile);
|
||||||
rcfile = NULL;
|
rcfile = NULL;
|
||||||
|
lxcpath = anonpath;
|
||||||
}
|
}
|
||||||
}
|
c = lxc_container_new(my_args.name, lxcpath);
|
||||||
|
if (!c) {
|
||||||
conf = lxc_conf_init();
|
ERROR("Failed to create lxc_container");
|
||||||
if (!conf) {
|
|
||||||
ERROR("failed to initialize configuration");
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rcfile && lxc_config_read(rcfile, conf)) {
|
|
||||||
ERROR("failed to read configuration file");
|
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We should use set_config_item() over &defines, which would handle
|
||||||
|
* unset c->lxc_conf for us and let us not use lxc_config_define_load()
|
||||||
|
*/
|
||||||
|
if (!c->lxc_conf)
|
||||||
|
c->lxc_conf = lxc_conf_init();
|
||||||
|
conf = c->lxc_conf;
|
||||||
|
|
||||||
if (lxc_config_define_load(&defines, conf))
|
if (lxc_config_define_load(&defines, conf))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (!rcfile && !strcmp("/sbin/init", args[0])) {
|
if (!rcfile && !strcmp("/sbin/init", args[0])) {
|
||||||
ERROR("no configuration file for '/sbin/init' (may crash the host)");
|
ERROR("Executing '/sbin/init' with no configuration file may crash the host");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,10 +253,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (my_args.daemonize) {
|
if (my_args.daemonize) {
|
||||||
if (daemon(0, 0)) {
|
c->want_daemonize(c);
|
||||||
SYSERROR("failed to daemonize '%s'", my_args.name);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pid_fp != NULL) {
|
if (pid_fp != NULL) {
|
||||||
@ -245,23 +267,13 @@ int main(int argc, char *argv[])
|
|||||||
if (my_args.close_all_fds)
|
if (my_args.close_all_fds)
|
||||||
conf->close_all_fds = 1;
|
conf->close_all_fds = 1;
|
||||||
|
|
||||||
err = lxc_start(my_args.name, args, conf, my_args.lxcpath[0]);
|
err = c->start(c, 0, args) ? 0 : -1;
|
||||||
|
|
||||||
/*
|
|
||||||
* exec ourself, that requires to have all opened fd
|
|
||||||
* with the close-on-exec flag set
|
|
||||||
*/
|
|
||||||
if (conf->reboot) {
|
|
||||||
INFO("rebooting container");
|
|
||||||
execvp(argv[0], argv);
|
|
||||||
SYSERROR("failed to exec");
|
|
||||||
err = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (my_args.pidfile)
|
if (my_args.pidfile)
|
||||||
unlink(my_args.pidfile);
|
unlink(my_args.pidfile);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
lxc_conf_free(conf);
|
lxc_container_put(c);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user