Skip to content

Commit

Permalink
Replace zed_file_create_dirs() with mkdirp()
Browse files Browse the repository at this point in the history
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
  • Loading branch information
dun authored and behlendorf committed Apr 9, 2014
1 parent 7368eb6 commit 6ac770b
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 97 deletions.
19 changes: 13 additions & 6 deletions cmd/zed/zed_conf.c
Expand Up @@ -29,6 +29,7 @@
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <libgen.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
Expand Down Expand Up @@ -435,6 +436,7 @@ int
zed_conf_write_pid(struct zed_conf *zcp)
{
char dirbuf[PATH_MAX];
mode_t dirmode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
int n;
char *p;
mode_t mask;
Expand All @@ -457,10 +459,12 @@ zed_conf_write_pid(struct zed_conf *zcp)
if (p)
*p = '\0';

/* FIXME: Replace with mkdirp()? (lib/libspl/mkdirp.c) */
if (zed_file_create_dirs(dirbuf) < 0)
if ((mkdirp(dirbuf, dirmode) < 0) && (errno != EEXIST)) {
zed_log_msg(LOG_WARNING,
"Failed to create directory \"%s\": %s",
dirbuf, strerror(errno));
return (-1);

}
(void) unlink(zcp->pid_file);

mask = umask(0);
Expand Down Expand Up @@ -494,6 +498,7 @@ int
zed_conf_open_state(struct zed_conf *zcp)
{
char dirbuf[PATH_MAX];
mode_t dirmode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
int n;
char *p;
int rv;
Expand All @@ -515,10 +520,12 @@ zed_conf_open_state(struct zed_conf *zcp)
if (p)
*p = '\0';

/* FIXME: Replace with mkdirp()? (lib/libspl/mkdirp.c) */
if (zed_file_create_dirs(dirbuf) < 0)
if ((mkdirp(dirbuf, dirmode) < 0) && (errno != EEXIST)) {
zed_log_msg(LOG_WARNING,
"Failed to create directory \"%s\": %s",
dirbuf, strerror(errno));
return (-1);

}
if (zcp->state_fd >= 0) {
if (close(zcp->state_fd) < 0) {
zed_log_msg(LOG_WARNING,
Expand Down
89 changes: 0 additions & 89 deletions cmd/zed/zed_file.c
Expand Up @@ -225,92 +225,3 @@ zed_file_close_on_exec(int fd)

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);
}
2 changes: 0 additions & 2 deletions cmd/zed/zed_file.h
Expand Up @@ -44,6 +44,4 @@ void zed_file_close_from(int fd);

int zed_file_close_on_exec(int fd);

int zed_file_create_dirs(const char *dir_name);

#endif /* !ZED_FILE_H */

0 comments on commit 6ac770b

Please sign in to comment.