mirror of
https://git.proxmox.com/git/mirror_lxc
synced 2025-07-27 05:03:17 +00:00
cgfsng: avoid tiny race window
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
This commit is contained in:
parent
ee455be41c
commit
17e5599174
@ -1257,13 +1257,50 @@ on_error:
|
|||||||
return bret;
|
return bret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int mkdir_eexist_on_last(const char *dir, mode_t mode)
|
||||||
|
{
|
||||||
|
const char *tmp = dir;
|
||||||
|
const char *orig = dir;
|
||||||
|
size_t orig_len;
|
||||||
|
|
||||||
|
orig_len = strlen(dir);
|
||||||
|
do {
|
||||||
|
int ret;
|
||||||
|
size_t cur_len;
|
||||||
|
char *makeme;
|
||||||
|
|
||||||
|
dir = tmp + strspn(tmp, "/");
|
||||||
|
tmp = dir + strcspn(dir, "/");
|
||||||
|
|
||||||
|
errno = ENOMEM;
|
||||||
|
cur_len = dir - orig;
|
||||||
|
makeme = strndup(orig, cur_len);
|
||||||
|
if (!makeme)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
ret = mkdir(makeme, mode);
|
||||||
|
if (ret < 0) {
|
||||||
|
if ((errno != EEXIST) || (orig_len == cur_len)) {
|
||||||
|
SYSERROR("Failed to create directory \"%s\"", makeme);
|
||||||
|
free(makeme);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(makeme);
|
||||||
|
|
||||||
|
} while (tmp != dir);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static bool monitor_create_path_for_hierarchy(struct hierarchy *h, char *cgname)
|
static bool monitor_create_path_for_hierarchy(struct hierarchy *h, char *cgname)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
h->monitor_full_path = must_make_path(h->mountpoint, h->container_base_path, cgname, NULL);
|
h->monitor_full_path = must_make_path(h->mountpoint, h->container_base_path, cgname, NULL);
|
||||||
if (dir_exists(h->monitor_full_path)) {
|
ret = mkdir_eexist_on_last(h->monitor_full_path, 0755);
|
||||||
ERROR("The cgroup \"%s\" already existed", h->monitor_full_path);
|
if (ret < 0) {
|
||||||
|
ERROR("Failed to create cgroup \"%s\"", h->monitor_full_path);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1272,12 +1309,6 @@ static bool monitor_create_path_for_hierarchy(struct hierarchy *h, char *cgname)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = mkdir_p(h->monitor_full_path, 0755);
|
|
||||||
if (ret < 0) {
|
|
||||||
ERROR("Failed to create cgroup \"%s\"", h->monitor_full_path);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return cg_unified_create_cgroup(h, cgname);
|
return cg_unified_create_cgroup(h, cgname);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1286,8 +1317,9 @@ static bool container_create_path_for_hierarchy(struct hierarchy *h, char *cgnam
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
h->container_full_path = must_make_path(h->mountpoint, h->container_base_path, cgname, NULL);
|
h->container_full_path = must_make_path(h->mountpoint, h->container_base_path, cgname, NULL);
|
||||||
if (dir_exists(h->container_full_path)) {
|
ret = mkdir_eexist_on_last(h->container_full_path, 0755);
|
||||||
ERROR("The cgroup \"%s\" already existed", h->container_full_path);
|
if (ret < 0) {
|
||||||
|
ERROR("Failed to create cgroup \"%s\"", h->container_full_path);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1296,12 +1328,6 @@ static bool container_create_path_for_hierarchy(struct hierarchy *h, char *cgnam
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = mkdir_p(h->container_full_path, 0755);
|
|
||||||
if (ret < 0) {
|
|
||||||
ERROR("Failed to create cgroup \"%s\"", h->container_full_path);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return cg_unified_create_cgroup(h, cgname);
|
return cg_unified_create_cgroup(h, cgname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,25 +221,30 @@ extern int get_u16(unsigned short *val, const char *arg, int base)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern int mkdir_p(const char *dir, mode_t mode)
|
int mkdir_p(const char *dir, mode_t mode)
|
||||||
{
|
{
|
||||||
const char *tmp = dir;
|
const char *tmp = dir;
|
||||||
const char *orig = dir;
|
const char *orig = dir;
|
||||||
|
do {
|
||||||
|
int ret;
|
||||||
char *makeme;
|
char *makeme;
|
||||||
|
|
||||||
do {
|
|
||||||
dir = tmp + strspn(tmp, "/");
|
dir = tmp + strspn(tmp, "/");
|
||||||
tmp = dir + strcspn(dir, "/");
|
tmp = dir + strcspn(dir, "/");
|
||||||
|
|
||||||
|
errno = ENOMEM;
|
||||||
makeme = strndup(orig, dir - orig);
|
makeme = strndup(orig, dir - orig);
|
||||||
if (*makeme) {
|
if (!makeme)
|
||||||
if (mkdir(makeme, mode) && errno != EEXIST) {
|
return -1;
|
||||||
SYSERROR("failed to create directory '%s'", makeme);
|
|
||||||
|
ret = mkdir(makeme, mode);
|
||||||
|
if (ret < 0 && errno != EEXIST) {
|
||||||
|
SYSERROR("Failed to create directory \"%s\"", makeme);
|
||||||
free(makeme);
|
free(makeme);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
free(makeme);
|
free(makeme);
|
||||||
|
|
||||||
} while (tmp != dir);
|
} while (tmp != dir);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user