mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
libdm: file: add proper checks for directory components in dm_create_dir
Also make error messages more consistent: Before this patch: (/run/lock exists and is not a directory) $ pvs /run/lock/lvm: mkdir failed: Not a directory File-based locking initialisation failed. (/run/lock/lvm exists and is not a directory) $ pvs Directory "/run/lock/lvm" not found File-based locking initialisation failed. With this patch applied: (/run/lock exists and is not a directory) $ pvs Existing path /run/lock is not a directory. Failed to create directory /run/lock/lvm. File-based locking initialisation failed (/run/lock/lvm exists and is not a directory) $ pvs Existing path /run/lock/lvm is not a directory. Failed to create directory /run/lock/lvm. File-based locking initialisation failed.
This commit is contained in:
parent
afdae26c71
commit
6c0b4a2769
@ -19,6 +19,24 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
|
||||||
|
static int _is_dir(const char *path)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
if (stat(path, &st) < 0) {
|
||||||
|
log_sys_error("stat", path);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!S_ISDIR(st.st_mode)) {
|
||||||
|
log_error("Existing path %s is not "
|
||||||
|
"a directory.", path);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int _create_dir_recursive(const char *dir)
|
static int _create_dir_recursive(const char *dir)
|
||||||
{
|
{
|
||||||
char *orig, *s;
|
char *orig, *s;
|
||||||
@ -36,22 +54,32 @@ static int _create_dir_recursive(const char *dir)
|
|||||||
*s = '\0';
|
*s = '\0';
|
||||||
if (*orig) {
|
if (*orig) {
|
||||||
rc = mkdir(orig, 0777);
|
rc = mkdir(orig, 0777);
|
||||||
if (rc < 0 && errno != EEXIST) {
|
if (rc < 0) {
|
||||||
|
if (errno == EEXIST) {
|
||||||
|
if (!_is_dir(orig))
|
||||||
|
goto_out;
|
||||||
|
} else {
|
||||||
if (errno != EROFS)
|
if (errno != EROFS)
|
||||||
log_sys_error("mkdir", orig);
|
log_sys_error("mkdir", orig);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
*s++ = '/';
|
*s++ = '/';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create final directory */
|
/* Create final directory */
|
||||||
rc = mkdir(dir, 0777);
|
rc = mkdir(dir, 0777);
|
||||||
if (rc < 0 && errno != EEXIST) {
|
if (rc < 0) {
|
||||||
|
if (errno == EEXIST) {
|
||||||
|
if (!_is_dir(dir))
|
||||||
|
goto_out;
|
||||||
|
} else {
|
||||||
if (errno != EROFS)
|
if (errno != EROFS)
|
||||||
log_sys_error("mkdir", orig);
|
log_sys_error("mkdir", orig);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
r = 1;
|
r = 1;
|
||||||
out:
|
out:
|
||||||
@ -66,16 +94,17 @@ int dm_create_dir(const char *dir)
|
|||||||
if (!*dir)
|
if (!*dir)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (stat(dir, &info) < 0)
|
if (stat(dir, &info) == 0 && S_ISDIR(info.st_mode))
|
||||||
return _create_dir_recursive(dir);
|
|
||||||
|
|
||||||
if (S_ISDIR(info.st_mode))
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
log_error("Directory \"%s\" not found", dir);
|
if (!_create_dir_recursive(dir)) {
|
||||||
|
log_error("Failed to create directory %s.", dir);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int dm_is_empty_dir(const char *dir)
|
int dm_is_empty_dir(const char *dir)
|
||||||
{
|
{
|
||||||
struct dirent *dirent;
|
struct dirent *dirent;
|
||||||
|
Loading…
Reference in New Issue
Block a user