mirror of
https://git.proxmox.com/git/mirror_lxc
synced 2025-06-15 16:07:46 +00:00
fix multithreaded create()
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>
This commit is contained in:
parent
bdb3f44147
commit
6c6892b5c5
@ -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 &&
|
if (lxcapi_is_defined(c) && c->lxc_conf && c->lxc_conf->rootfs.path &&
|
||||||
access(c->lxc_conf->rootfs.path, F_OK) == 0 && tpath) {
|
access(c->lxc_conf->rootfs.path, F_OK) == 0 && tpath) {
|
||||||
ERROR("Container %s:%s already exists", c->config_path, c->name);
|
ERROR("Container %s:%s already exists", c->config_path, c->name);
|
||||||
free(tpath);
|
goto free_tpath;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save the loaded configuration to disk */
|
if (!c->lxc_conf) {
|
||||||
if (!c->save_config(c, NULL)) {
|
if (!c->load_config(c, LXC_DEFAULT_CONFIG)) {
|
||||||
ERROR("failed to save starting configuration for %s\n", c->name);
|
ERROR("Error loading default configuration file %s\n", LXC_DEFAULT_CONFIG);
|
||||||
goto out;
|
goto free_tpath;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!create_container_dir(c))
|
||||||
|
goto free_tpath;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* either template or rootfs.path should be set.
|
* either template or rootfs.path should be set.
|
||||||
* if both template and rootfs.path are set, template is setup as rootfs.path.
|
* if both template and rootfs.path are set, template is setup as rootfs.path.
|
||||||
@ -1290,10 +1293,11 @@ out_unlock:
|
|||||||
if (partial_fd >= 0)
|
if (partial_fd >= 0)
|
||||||
remove_partial(c, partial_fd);
|
remove_partial(c, partial_fd);
|
||||||
out:
|
out:
|
||||||
if (tpath)
|
|
||||||
free(tpath);
|
|
||||||
if (!ret && c)
|
if (!ret && c)
|
||||||
lxcapi_destroy(c);
|
lxcapi_destroy(c);
|
||||||
|
free_tpath:
|
||||||
|
if (tpath)
|
||||||
|
free(tpath);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user