diff --git a/lib/device/online.c b/lib/device/online.c index db2234a1f..15972de94 100644 --- a/lib/device/online.c +++ b/lib/device/online.c @@ -457,55 +457,12 @@ bad: void online_dir_setup(struct cmd_context *cmd) { - struct stat st; - int rv; - - if (!stat(DEFAULT_RUN_DIR, &st)) - goto do_pvs; - - log_debug("Creating run_dir."); - dm_prepare_selinux_context(DEFAULT_RUN_DIR, S_IFDIR); - rv = mkdir(DEFAULT_RUN_DIR, 0755); - dm_prepare_selinux_context(NULL, 0); - - if ((rv < 0) && stat(DEFAULT_RUN_DIR, &st)) - log_error_pvscan(cmd, "Failed to create %s %d", DEFAULT_RUN_DIR, errno); - -do_pvs: - if (!stat(PVS_ONLINE_DIR, &st)) - goto do_vgs; - - log_debug("Creating pvs_online_dir."); - dm_prepare_selinux_context(PVS_ONLINE_DIR, S_IFDIR); - rv = mkdir(PVS_ONLINE_DIR, 0755); - dm_prepare_selinux_context(NULL, 0); - - if ((rv < 0) && stat(PVS_ONLINE_DIR, &st)) - log_error_pvscan(cmd, "Failed to create %s %d", PVS_ONLINE_DIR, errno); - -do_vgs: - if (!stat(VGS_ONLINE_DIR, &st)) - goto do_lookup; - - log_debug("Creating vgs_online_dir."); - dm_prepare_selinux_context(VGS_ONLINE_DIR, S_IFDIR); - rv = mkdir(VGS_ONLINE_DIR, 0755); - dm_prepare_selinux_context(NULL, 0); - - if ((rv < 0) && stat(VGS_ONLINE_DIR, &st)) - log_error_pvscan(cmd, "Failed to create %s %d", VGS_ONLINE_DIR, errno); - -do_lookup: - if (!stat(PVS_LOOKUP_DIR, &st)) - return; - - log_debug("Creating pvs_lookup_dir."); - dm_prepare_selinux_context(PVS_LOOKUP_DIR, S_IFDIR); - rv = mkdir(PVS_LOOKUP_DIR, 0755); - dm_prepare_selinux_context(NULL, 0); - - if ((rv < 0) && stat(PVS_LOOKUP_DIR, &st)) - log_error_pvscan(cmd, "Failed to create %s %d", PVS_LOOKUP_DIR, errno); + if (!dir_create_recursive(PVS_ONLINE_DIR, 0755)) + stack; + if (!dir_create_recursive(VGS_ONLINE_DIR, 0755)) + stack; + if (!dir_create_recursive(PVS_LOOKUP_DIR, 0755)) + stack; } void online_lookup_file_remove(const char *vgname) diff --git a/lib/misc/lvm-file.c b/lib/misc/lvm-file.c index 4a3479a5a..2ec00f1d5 100644 --- a/lib/misc/lvm-file.c +++ b/lib/misc/lvm-file.c @@ -141,6 +141,57 @@ int dir_exists(const char *path) return 1; } +int dir_create(const char *path, int mode) +{ + int r; + + log_debug("Creating directory %s.", path); + + dm_prepare_selinux_context(path, S_IFDIR); + r = mkdir(path, mode); + dm_prepare_selinux_context(NULL, 0); + + if (r == 0) + return 1; + + if (errno == EEXIST) { + if (dir_exists(path)) + return 1; + + log_error("Path %s is not a directory.", path); + } else + log_sys_error("mkdir", path); + + return 0; +} + +int dir_create_recursive(const char *path, int mode) +{ + int r = 0; + char *orig, *s; + + orig = s = strdup(path); + if (!s) { + log_error("Failed to duplicate directory path %s.", path); + return 0; + } + + while ((s = strchr(s, '/')) != NULL) { + *s = '\0'; + if (*orig && !dir_exists(orig) && !dir_create(orig, mode)) + goto_out; + *s++ = '/'; + } + + if (!dir_exists(path) && !dir_create(path, mode)) + goto_out; + r = 1; +out: + free(orig); + + return r; +} + void sync_dir(const char *file) { int fd; diff --git a/lib/misc/lvm-file.h b/lib/misc/lvm-file.h index 4c405e683..32999ecf9 100644 --- a/lib/misc/lvm-file.h +++ b/lib/misc/lvm-file.h @@ -40,6 +40,8 @@ int lvm_rename(const char *old, const char *new); */ int path_exists(const char *path); int dir_exists(const char *path); +int dir_create(const char *path, int mode); +int dir_create_recursive(const char *path, int mode); /* Sync directory changes */ void sync_dir(const char *file);