From 43ff1680d9135bbc85dad24f51f02996d22580df Mon Sep 17 00:00:00 2001 From: Krishnan Parthasarathi Date: Wed, 16 May 2012 18:22:35 +0530 Subject: common-utils: Added C wrapper to mkdir(1) -p functionality. - Modified glusterd-rebalance to use mkdir_p C wrapper. Change-Id: If9a00b8c0e00af644b9c3e64a5fc94cf6201827c Signed-off-by: Krishnan Parthasarathi Reviewed-on: http://review.gluster.com/3347 Tested-by: Gluster Build System Reviewed-by: Anand Avati --- libglusterfs/src/common-utils.c | 62 +++++++++++++++++++++++++++++++++++++++++ libglusterfs/src/common-utils.h | 2 ++ 2 files changed, 64 insertions(+) (limited to 'libglusterfs') diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c index 7e7eb4614..4b8807be1 100644 --- a/libglusterfs/src/common-utils.c +++ b/libglusterfs/src/common-utils.c @@ -58,6 +58,68 @@ struct dnscache6 { }; +/* works similar to mkdir(1) -p. + * @start returns the point in path from which components were created + * @start is -1 if the entire path existed before. + */ +int +mkdir_p (char *path, mode_t mode, gf_boolean_t allow_symlinks, int *start) +{ + int i = 0; + int ret = -1; + char dir[PATH_MAX] = {0,}; + struct stat stbuf = {0,}; + int created = -1; + + strcpy (dir, path); + i = (dir[0] == '/')? 1: 0; + do { + if (path[i] != '/' && path[i] != '\0') + continue; + + dir[i] = '\0'; + ret = mkdir (dir, mode); + if (ret && errno != EEXIST) { + gf_log ("", GF_LOG_ERROR, "Failed due to reason %s", + strerror (errno)); + goto out; + } + + if (ret && errno == EEXIST) + created = i; + + if (ret && errno == EEXIST && !allow_symlinks) { + ret = lstat (dir, &stbuf); + if (ret) + goto out; + + if (S_ISLNK (stbuf.st_mode)) { + ret = -1; + gf_log ("", GF_LOG_ERROR, "%s is a symlink", + dir); + goto out; + } + } + dir[i] = '/'; + + } while (path[i++] != '\0'); + + ret = stat (dir, &stbuf); + if (ret || !S_ISDIR (stbuf.st_mode)) { + ret = -1; + gf_log ("", GF_LOG_ERROR, "Failed to create directory, " + "possibly some of the components were not directories"); + goto out; + } + + ret = 0; + if (start) + *start = created; +out: + + return ret; +} + int log_base2 (unsigned long x) { diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h index d58802912..69d57c8d4 100644 --- a/libglusterfs/src/common-utils.h +++ b/libglusterfs/src/common-utils.h @@ -392,6 +392,8 @@ memdup (const void *ptr, size_t size) return newptr; } +int +mkdir_p (char *path, mode_t mode, gf_boolean_t allow_symlinks, int *start); /* * rounds up nr to power of two. If nr is already a power of two, just returns * nr -- cgit