mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2025-04-06 17:49:11 +03:00
Replace zed_file_create_dirs() with mkdirp()
When processing directory components starting from the root dir, zed_file_create_dirs() contained a bug in checking the return value of mkdir(). A typo was made, and the test for (mkdir_errno != EEXIST) was erroneously written as (mkdir_errno == EEXIST). If some of the leading directory components already existed, this bug would cause the routine to exit before creating the remaining directory components. Instead of fixing the above mkdir_errno test, this commit replaces zed_file_create_dirs() with mkdirp(). This cleanup was already planned, and zed_file_create_dirs() only existed because I didn't realize mkdirp() was already in tree at the time. Signed-off-by: Chris Dunlap <cdunlap@llnl.gov> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #2248
This commit is contained in:
parent
7368eb621e
commit
6ac770b196
@ -29,6 +29,7 @@
|
|||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <libgen.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -435,6 +436,7 @@ int
|
|||||||
zed_conf_write_pid(struct zed_conf *zcp)
|
zed_conf_write_pid(struct zed_conf *zcp)
|
||||||
{
|
{
|
||||||
char dirbuf[PATH_MAX];
|
char dirbuf[PATH_MAX];
|
||||||
|
mode_t dirmode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
|
||||||
int n;
|
int n;
|
||||||
char *p;
|
char *p;
|
||||||
mode_t mask;
|
mode_t mask;
|
||||||
@ -457,10 +459,12 @@ zed_conf_write_pid(struct zed_conf *zcp)
|
|||||||
if (p)
|
if (p)
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
|
|
||||||
/* FIXME: Replace with mkdirp()? (lib/libspl/mkdirp.c) */
|
if ((mkdirp(dirbuf, dirmode) < 0) && (errno != EEXIST)) {
|
||||||
if (zed_file_create_dirs(dirbuf) < 0)
|
zed_log_msg(LOG_WARNING,
|
||||||
|
"Failed to create directory \"%s\": %s",
|
||||||
|
dirbuf, strerror(errno));
|
||||||
return (-1);
|
return (-1);
|
||||||
|
}
|
||||||
(void) unlink(zcp->pid_file);
|
(void) unlink(zcp->pid_file);
|
||||||
|
|
||||||
mask = umask(0);
|
mask = umask(0);
|
||||||
@ -494,6 +498,7 @@ int
|
|||||||
zed_conf_open_state(struct zed_conf *zcp)
|
zed_conf_open_state(struct zed_conf *zcp)
|
||||||
{
|
{
|
||||||
char dirbuf[PATH_MAX];
|
char dirbuf[PATH_MAX];
|
||||||
|
mode_t dirmode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
|
||||||
int n;
|
int n;
|
||||||
char *p;
|
char *p;
|
||||||
int rv;
|
int rv;
|
||||||
@ -515,10 +520,12 @@ zed_conf_open_state(struct zed_conf *zcp)
|
|||||||
if (p)
|
if (p)
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
|
|
||||||
/* FIXME: Replace with mkdirp()? (lib/libspl/mkdirp.c) */
|
if ((mkdirp(dirbuf, dirmode) < 0) && (errno != EEXIST)) {
|
||||||
if (zed_file_create_dirs(dirbuf) < 0)
|
zed_log_msg(LOG_WARNING,
|
||||||
|
"Failed to create directory \"%s\": %s",
|
||||||
|
dirbuf, strerror(errno));
|
||||||
return (-1);
|
return (-1);
|
||||||
|
}
|
||||||
if (zcp->state_fd >= 0) {
|
if (zcp->state_fd >= 0) {
|
||||||
if (close(zcp->state_fd) < 0) {
|
if (close(zcp->state_fd) < 0) {
|
||||||
zed_log_msg(LOG_WARNING,
|
zed_log_msg(LOG_WARNING,
|
||||||
|
@ -225,92 +225,3 @@ zed_file_close_on_exec(int fd)
|
|||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Create the directory [dir_name] and any missing parent directories.
|
|
||||||
* Directories will be created with permissions 0755 modified by the umask.
|
|
||||||
* Return 0 on success, or -1 on error.
|
|
||||||
* FIXME: Deprecate in favor of mkdirp(). (lib/libspl/mkdirp.c)
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
zed_file_create_dirs(const char *dir_name)
|
|
||||||
{
|
|
||||||
struct stat st;
|
|
||||||
char dir_buf[PATH_MAX];
|
|
||||||
mode_t dir_mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
|
|
||||||
char *p;
|
|
||||||
|
|
||||||
if ((dir_name == NULL) || (dir_name[0] == '\0')) {
|
|
||||||
zed_log_msg(LOG_WARNING,
|
|
||||||
"Failed to create directory: no directory specified");
|
|
||||||
errno = EINVAL;
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
if (dir_name[0] != '/') {
|
|
||||||
zed_log_msg(LOG_WARNING,
|
|
||||||
"Failed to create directory \"%s\": not absolute path",
|
|
||||||
dir_name);
|
|
||||||
errno = EINVAL;
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
/* Check if directory already exists. */
|
|
||||||
if (stat(dir_name, &st) == 0) {
|
|
||||||
if (S_ISDIR(st.st_mode))
|
|
||||||
return (0);
|
|
||||||
|
|
||||||
errno = EEXIST;
|
|
||||||
zed_log_msg(LOG_WARNING,
|
|
||||||
"Failed to create directory \"%s\": %s",
|
|
||||||
dir_name, strerror(errno));
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
/* Create copy for modification. */
|
|
||||||
if (strlen(dir_name) >= sizeof (dir_buf)) {
|
|
||||||
errno = ENAMETOOLONG;
|
|
||||||
zed_log_msg(LOG_WARNING,
|
|
||||||
"Failed to create directory \"%s\": %s",
|
|
||||||
dir_name, strerror(errno));
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
strncpy(dir_buf, dir_name, sizeof (dir_buf));
|
|
||||||
|
|
||||||
/* Remove trailing slashes. */
|
|
||||||
p = dir_buf + strlen(dir_buf) - 1;
|
|
||||||
while ((p > dir_buf) && (*p == '/'))
|
|
||||||
*p-- = '\0';
|
|
||||||
|
|
||||||
/* Process directory components starting from the root dir. */
|
|
||||||
p = dir_buf;
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
|
|
||||||
/* Skip over adjacent slashes. */
|
|
||||||
while (*p == '/')
|
|
||||||
p++;
|
|
||||||
|
|
||||||
/* Advance to the next path component. */
|
|
||||||
p = strchr(p, '/');
|
|
||||||
if (p != NULL)
|
|
||||||
*p = '\0';
|
|
||||||
|
|
||||||
/* Create directory. */
|
|
||||||
if (mkdir(dir_buf, dir_mode) < 0) {
|
|
||||||
|
|
||||||
int mkdir_errno = errno;
|
|
||||||
|
|
||||||
if ((mkdir_errno == EEXIST) ||
|
|
||||||
(stat(dir_buf, &st) < 0) ||
|
|
||||||
(!S_ISDIR(st.st_mode))) {
|
|
||||||
zed_log_msg(LOG_WARNING,
|
|
||||||
"Failed to create directory \"%s\": %s",
|
|
||||||
dir_buf, strerror(mkdir_errno));
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (p == NULL)
|
|
||||||
break;
|
|
||||||
|
|
||||||
*p++ = '/';
|
|
||||||
}
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
@ -44,6 +44,4 @@ void zed_file_close_from(int fd);
|
|||||||
|
|
||||||
int zed_file_close_on_exec(int fd);
|
int zed_file_close_on_exec(int fd);
|
||||||
|
|
||||||
int zed_file_create_dirs(const char *dir_name);
|
|
||||||
|
|
||||||
#endif /* !ZED_FILE_H */
|
#endif /* !ZED_FILE_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user