summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libglusterfs/src/common-utils.c62
-rw-r--r--libglusterfs/src/common-utils.h2
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-rebalance.c18
3 files changed, 69 insertions, 13 deletions
diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c
index 7e7eb461409..4b8807be1eb 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 d5880291250..69d57c8d431 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
diff --git a/xlators/mgmt/glusterd/src/glusterd-rebalance.c b/xlators/mgmt/glusterd/src/glusterd-rebalance.c
index 010ff599cf9..686b9b36db3 100644
--- a/xlators/mgmt/glusterd/src/glusterd-rebalance.c
+++ b/xlators/mgmt/glusterd/src/glusterd-rebalance.c
@@ -224,7 +224,6 @@ glusterd_handle_defrag_start (glusterd_volinfo_t *volinfo, char *op_errstr,
runner_t runner = {0,};
glusterd_conf_t *priv = NULL;
char defrag_path[PATH_MAX];
- struct stat buf = {0,};
char sockfile[PATH_MAX] = {0,};
char pidfile[PATH_MAX] = {0,};
char logfile[PATH_MAX] = {0,};
@@ -263,18 +262,11 @@ glusterd_handle_defrag_start (glusterd_volinfo_t *volinfo, char *op_errstr,
glusterd_store_perform_node_state_store (volinfo);
GLUSTERD_GET_DEFRAG_DIR (defrag_path, volinfo, priv);
- ret = stat (defrag_path, &buf);
- if (ret && (errno == ENOENT)) {
- runinit (&runner);
- runner_add_args (&runner, "mkdir", "-p", defrag_path, NULL);
- ret = runner_run_reuse (&runner);
- if (ret) {
- runner_log (&runner, "glusterd", GF_LOG_DEBUG,
- "command failed");
- runner_end (&runner);
- goto out;
- }
- runner_end (&runner);
+ ret = mkdir_p (defrag_path, 0777, 0, NULL);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR, "Failed to create "
+ "directory %s", defrag_path);
+ goto out;
}
GLUSTERD_GET_DEFRAG_SOCK_FILE (sockfile, volinfo, priv);