]> git.proxmox.com Git - mirror_lxc.git/commitdiff
fix multithreaded create()
authorDwight Engen <dwight.engen@oracle.com>
Tue, 12 Nov 2013 19:04:45 +0000 (14:04 -0500)
committerSerge Hallyn <serge.hallyn@ubuntu.com>
Tue, 12 Nov 2013 20:43:31 +0000 (14:43 -0600)
We were calling save_config() twice within the create() flow, each
from a different process. Depending on order of scheduling, sometimes
the data from the first save_config() (which was just the stuff from
LXC_DEFAULT_CONFIG) would overwrite the config we wanted (the full
config), causing a truncated config file which would then cause lxc
to segfault once it read it back in because no rootfs.path was set.

This fixes it by only calling save_config() once in the create()
flow. A rejected alternative was to call fsync(fileno(fout)) before
the fclose in save_config.

Signed-off-by: Dwight Engen <dwight.engen@oracle.com>
Acked-by: S.Çağlar Onur <caglar@10ur.org>
Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
src/lxc/lxccontainer.c

index ede011324ac916adf14606b108607a6aa27964f5..0a94f5e6b9e9eed21b421d27ed11ca2e0a4840f9 100644 (file)
@@ -1192,16 +1192,19 @@ static bool lxcapi_create(struct lxc_container *c, const char *t,
        if (lxcapi_is_defined(c) && c->lxc_conf && c->lxc_conf->rootfs.path &&
                        access(c->lxc_conf->rootfs.path, F_OK) == 0 && tpath) {
                ERROR("Container %s:%s already exists", c->config_path, c->name);
-               free(tpath);
-               return false;
+               goto free_tpath;
        }
 
-       /* Save the loaded configuration to disk */
-       if (!c->save_config(c, NULL)) {
-               ERROR("failed to save starting configuration for %s\n", c->name);
-               goto out;
+       if (!c->lxc_conf) {
+               if (!c->load_config(c, LXC_DEFAULT_CONFIG)) {
+                       ERROR("Error loading default configuration file %s\n", LXC_DEFAULT_CONFIG);
+                       goto free_tpath;
+               }
        }
 
+       if (!create_container_dir(c))
+               goto free_tpath;
+
        /*
         * either template or rootfs.path should be set.
         * if both template and rootfs.path are set, template is setup as rootfs.path.
@@ -1290,10 +1293,11 @@ out_unlock:
        if (partial_fd >= 0)
                remove_partial(c, partial_fd);
 out:
-       if (tpath)
-               free(tpath);
        if (!ret && c)
                lxcapi_destroy(c);
+free_tpath:
+       if (tpath)
+               free(tpath);
        return ret;
 }