Add the ability to automatically create the container fs. We use OpenVZ precreated template for this - these are just regular tarballs with all the files required for container work. So in this patch we just untar it into a specified root dir (and destroy one after container destruction). Signed-off-by: Sergey Krasnov <krasnov@xxxxxxxxxx> Reviewed-by: Pavel Emelyanov <xemul@xxxxxxxxxx> Acked-by: Dmitry Mishin <dim@xxxxxxxxxx> --- --- ./src/lxc/lxc_conf.c.cache 2008-10-08 18:15:58.000000000 +0400 +++ ./src/lxc/lxc_conf.c 2008-10-29 13:04:23.000000000 +0300 @@ -419,27 +419,69 @@ return 0; } -static int configure_rootfs(const char *name, const char *rootfs) +static int configure_cache(const char *name, struct lxc_conf *conf) { + int rc; + char cmd[BUFSIZ]; char path[MAXPATHLEN]; - char absrootfs[MAXPATHLEN]; - char *pwd; - snprintf(path, MAXPATHLEN, LXCPATH "/%s/rootfs", name); + if (strlen(conf->cachefile) == 0) + return 0; - pwd = get_current_dir_name(); + if (strlen(conf->rootfs) == 0) { + /* special case : rootfs in container home dir */ + snprintf(conf->rootfs, sizeof(conf->rootfs), + LXCPATH "/%s/root", name); + if (mkdir(conf->rootfs, 0755)) { + lxc_log_syserror("mkdir(%s, 0755)", conf->rootfs); + return -1; + } + } - snprintf(absrootfs, MAXPATHLEN, "%s/%s", pwd, rootfs); + if (access(conf->rootfs, F_OK)) { + lxc_log_syserror("'%s' is not accessible", conf->rootfs); + return -1; + } - free(pwd); + snprintf(path, MAXPATHLEN, LXCPATH "/%s/cachefile", name); + if (symlink(conf->cachefile, path)) { + lxc_log_syserror("symlink(%s,%s)", conf->cachefile, path); + return -1; + } - if (access(absrootfs, F_OK)) { - lxc_log_syserror("'%s' is not accessible", absrootfs); + snprintf(cmd, sizeof(cmd), "tar -C %s -xzf %s", conf->rootfs, path); + lxc_log_debug("system(%s)", cmd); + rc = system(cmd); + if (rc == -1) { + lxc_log_error("system(%s) error : %m", cmd); + return -1; + } + if (!WIFEXITED(rc)) { + lxc_log_error("\"%s\" failed", cmd); return -1; } + if (WEXITSTATUS(rc)) { + lxc_log_error("\"%s\" return %d", cmd, WEXITSTATUS(rc)); + return -1; + } + return 0; +} + +static int configure_rootfs(const char *name, const char *rootfs) +{ + char path[MAXPATHLEN]; - return symlink(absrootfs, path); + if (access(rootfs, F_OK)) { + lxc_log_syserror("'%s' is not accessible", rootfs); + return -1; + } + snprintf(path, MAXPATHLEN, LXCPATH "/%s/rootfs", name); + if (symlink(rootfs, path)) { + lxc_log_syserror("symlink(%s,%s) : %m", rootfs, path); + return -1; + } + return 0; } static int configure_mount(const char *name, const char *fstab) @@ -574,6 +616,27 @@ return 0; } +static int unconfigure_cache(const char *name) +{ + char buf[BUFSIZ]; + char path[MAXPATHLEN+1]; + + snprintf(path, sizeof(path), LXCPATH "/%s/rootfs", name); + if (readlink(path, buf, sizeof(buf)) == -1) { + lxc_log_syserror("readlink(%s)", path); + return -1; + } + strncpy(path, buf, sizeof(path)); + + snprintf(buf, sizeof(buf), "rm -rf %s/*", path); + system(buf); + snprintf(path, sizeof(path), LXCPATH "/%s/root", name); + rmdir(path); + snprintf(path, sizeof(path), LXCPATH "/%s", name); + delete_info(path, "cachefile"); + return 0; +} + static int unconfigure_rootfs(const char *name) { char path[MAXPATHLEN]; @@ -950,9 +1013,18 @@ return -1; } - if (conf->rootfs && configure_rootfs(name, conf->rootfs)) { - lxc_log_error("failed to configure the rootfs"); - return -1; + if (strlen(conf->cachefile)) { + if (configure_cache(name, conf)) { + lxc_log_error("failed to configure the cache"); + return -1; + } + } + + if (strlen(conf->rootfs)) { + if (configure_rootfs(name, conf->rootfs)) { + lxc_log_error("failed to configure the rootfs"); + return -1; + } } if (conf->fstab && configure_mount(name, conf->fstab)) { @@ -974,6 +1046,9 @@ if (conf_has_cgroup(name) && unconfigure_cgroup(name)) lxc_log_error("failed to cleanup cgroup"); + if (conf_has_cachefile(name) && unconfigure_cache(name)) + lxc_log_error("failed to cleanup rootfs"); + if (conf_has_rootfs(name) && unconfigure_rootfs(name)) lxc_log_error("failed to cleanup rootfs"); --- ./src/lxc/lxc_conf.h.cache 2008-10-06 22:47:19.000000000 +0400 +++ ./src/lxc/lxc_conf.h 2008-10-29 13:04:23.000000000 +0300 @@ -24,6 +24,7 @@ #define _conf_h #include <netinet/in.h> +#include <sys/param.h> enum { EMPTY, @@ -115,7 +116,8 @@ * @utsname : the container utsname */ struct lxc_conf { - char *rootfs; + char rootfs[MAXPATHLEN+1]; + char cachefile[MAXPATHLEN+1]; char *fstab; struct utsname *utsname; struct lxc_list cgroup; @@ -145,6 +147,7 @@ #define conf_has_fstab(__name) conf_has(__name, "fstab") #define conf_has_rootfs(__name) conf_has(__name, "rootfs") +#define conf_has_cachefile(__name) conf_has(__name, "cachefile") #define conf_has_utsname(__name) conf_has(__name, "utsname") #define conf_has_network(__name) conf_has(__name, "network") #define conf_has_cgroup(__name) conf_has(__name, "cgroup") --- ./src/lxc/lxc_config.c.cache 2008-10-06 22:47:19.000000000 +0400 +++ ./src/lxc/lxc_config.c 2008-10-29 13:04:23.000000000 +0300 @@ -40,6 +40,7 @@ static int config_cgroup(const char *, char *, struct lxc_conf *); static int config_mount(const char *, char *, struct lxc_conf *); static int config_rootfs(const char *, char *, struct lxc_conf *); +static int config_cachefile(const char *, char *, struct lxc_conf *); static int config_utsname(const char *, char *, struct lxc_conf *); static int config_network_type(const char *, char *, struct lxc_conf *); static int config_network_flags(const char *, char *, struct lxc_conf *); @@ -59,6 +60,7 @@ { "lxc.cgroup", config_cgroup }, { "lxc.mount", config_mount }, { "lxc.rootfs", config_rootfs }, + { "lxc.cachefile", config_cachefile }, { "lxc.utsname", config_utsname }, { "lxc.network.type", config_network_type }, { "lxc.network.flags", config_network_flags }, @@ -478,12 +480,43 @@ lxc_log_error("%s path is too long", value); return -1; } + /* if rootfs is relative path, add it on current dir */ + if (value[0] != '/') { + char path[MAXPATHLEN+1]; + if (getcwd(path, sizeof(path)) == NULL) { + lxc_log_error("getcwd() error : %m"); + return -1; + } + snprintf(lxc_conf->rootfs, sizeof(lxc_conf->rootfs), + "%s/%s", path, value); + } else { + strncpy(lxc_conf->rootfs, value, sizeof(lxc_conf->rootfs)); + } - lxc_conf->rootfs = strdup(value); - if (!lxc_conf->rootfs) { - lxc_log_syserror("failed to duplicate string %s", value); + return 0; +} + +static int config_cachefile( + const char *key, + char *value, + struct lxc_conf *lxc_conf) +{ + if (strlen(value) >= MAXPATHLEN) { + lxc_log_error("%s path is too long", value); return -1; } + /* if cachefile is relative path, add it on current dir */ + if (value[0] != '/') { + char path[MAXPATHLEN+1]; + if (getcwd(path, sizeof(path)) == NULL) { + lxc_log_error("getcwd() error : %m"); + return -1; + } + snprintf(lxc_conf->cachefile, sizeof(lxc_conf->cachefile), + "%s/%s", path, value); + } else { + strncpy(lxc_conf->cachefile, value, sizeof(lxc_conf->cachefile)); + } return 0; } @@ -577,7 +610,8 @@ int lxc_config_init(struct lxc_conf *conf) { - conf->rootfs = NULL; + conf->rootfs[0] = '\0'; + conf->cachefile[0] = '\0'; conf->fstab = NULL; conf->utsname = NULL; lxc_list_init(&conf->cgroup); --- ./src/lxc/start.c.cache 2008-10-08 18:15:17.000000000 +0400 +++ ./src/lxc/start.c 2008-10-29 13:04:23.000000000 +0300 @@ -126,9 +126,11 @@ return -1; } - if (mount(ttyname, "/dev/console", "none", MS_BIND, 0)) { - lxc_log_syserror("failed to mount '/dev/console'"); - return -1; + if (access("/dev/console", F_OK)) { + if (mount(ttyname, "/dev/console", "none", MS_BIND, 0)) { + lxc_log_syserror("failed to mount '/dev/console'"); + return -1; + } } /* If a callback has been passed, call it before doing exec */ --- ./README.cache 2008-10-15 11:30:09.000000000 +0400 +++ ./README 2008-10-29 13:04:23.000000000 +0300 @@ -150,6 +150,10 @@ # the rootfs if needed for the running application lxc.rootfs = /mnt/root +# OpenVZ precreated OS template cache (see http://wiki.openvz.org , +# http://wiki.openvz.org/Download/template/precreated) +lxc.cachefiles = /var/tmp/ubuntu-8.04-x86.tar.gz + # The network has several of kind of configuration: # # * veth : the network will use the veth virtual device, the -- Thanks, Dmitry. _______________________________________________ Containers mailing list Containers@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linux-foundation.org/mailman/listinfo/containers