summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKrutika Dhananjay <kdhananj@redhat.com>2013-02-12 17:26:35 +0530
committerAnand Avati <avati@redhat.com>2013-11-26 21:39:16 -0800
commit5b91bef50d834e597f8c62b83419f26d146e631f (patch)
tree64772c0f7dae11d1b3e5045ec4b817ccd496d5f0
parentf73373f1244829d65d001fa3af8fdade192418c9 (diff)
glusterd: changes in 'volume create' behaviour
Backport of http://review.gluster.org/4740 Note: This patch is needed by oVirt's Gluster Integration Project BUG: 948729 Change-Id: I7a9d7c36b7e15269f95637cd9061abac6f8a97de Signed-off-by: Krutika Dhananjay <kdhananj@redhat.com> Reviewed-on: http://review.gluster.org/6355 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Anand Avati <avati@redhat.com>
-rw-r--r--cli/src/cli-cmd-parser.c40
-rw-r--r--cli/src/cli-cmd-volume.c37
-rw-r--r--tests/bugs/bug-948729/bug-948729-force.t85
-rw-r--r--tests/bugs/bug-948729/bug-948729-mode-script.t85
-rw-r--r--tests/bugs/bug-948729/bug-948729.t68
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-brick-ops.c12
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-replace-brick.c11
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.c109
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.h9
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volume-ops.c16
10 files changed, 445 insertions, 27 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c
index 8725b79f6f7..0533b96c3a8 100644
--- a/cli/src/cli-cmd-parser.c
+++ b/cli/src/cli-cmd-parser.c
@@ -174,6 +174,8 @@ cli_cmd_volume_create_parse (const char **words, int wordcount, dict_t **options
#ifdef HAVE_BD_XLATOR
char *dev_type = NULL;
#endif
+ gf_boolean_t is_force = _gf_false;
+ int wc = wordcount;
GF_ASSERT (words);
GF_ASSERT (options);
@@ -350,7 +352,12 @@ cli_cmd_volume_create_parse (const char **words, int wordcount, dict_t **options
brick_index = index;
- ret = cli_cmd_bricks_parse (words, wordcount, brick_index, &bricks,
+ if (strcmp (words[wordcount - 1], "force") == 0) {
+ is_force = _gf_true;
+ wc = wordcount - 1;
+ }
+
+ ret = cli_cmd_bricks_parse (words, wc, brick_index, &bricks,
&brick_count);
if (ret)
goto out;
@@ -421,6 +428,10 @@ cli_cmd_volume_create_parse (const char **words, int wordcount, dict_t **options
if (ret)
goto out;
+ ret = dict_set_int32 (dict, "force", is_force);
+ if (ret)
+ goto out;
+
*options = dict;
out:
@@ -909,6 +920,8 @@ cli_cmd_volume_add_brick_parse (const char **words, int wordcount,
int count = 1;
char *w = NULL;
int index;
+ gf_boolean_t is_force = _gf_false;
+ int wc = wordcount;
GF_ASSERT (words);
GF_ASSERT (options);
@@ -986,7 +999,13 @@ cli_cmd_volume_add_brick_parse (const char **words, int wordcount,
brick_index = index;
parse_bricks:
- ret = cli_cmd_bricks_parse (words, wordcount, brick_index, &bricks,
+
+ if (strcmp (words[wordcount - 1], "force") == 0) {
+ is_force = _gf_true;
+ wc = wordcount - 1;
+ }
+
+ ret = cli_cmd_bricks_parse (words, wc, brick_index, &bricks,
&brick_count);
if (ret)
goto out;
@@ -1000,6 +1019,10 @@ parse_bricks:
if (ret)
goto out;
+ ret = dict_set_int32 (dict, "force", is_force);
+ if (ret)
+ goto out;
+
*options = dict;
out:
@@ -1202,6 +1225,7 @@ cli_cmd_volume_replace_brick_parse (const char **words, int wordcount,
char *opwords[] = { "start", "commit", "pause", "abort", "status",
NULL };
char *w = NULL;
+ gf_boolean_t is_force = _gf_false;
GF_ASSERT (words);
GF_ASSERT (options);
@@ -1299,12 +1323,17 @@ cli_cmd_volume_replace_brick_parse (const char **words, int wordcount,
}
if (wordcount == (op_index + 1)) {
- if (replace_op != GF_REPLACE_OP_COMMIT) {
+ if ((replace_op != GF_REPLACE_OP_COMMIT) &&
+ (replace_op != GF_REPLACE_OP_START)) {
ret = -1;
goto out;
}
if (!strcmp ("force", words[op_index])) {
- replace_op = GF_REPLACE_OP_COMMIT_FORCE;
+ if (replace_op == GF_REPLACE_OP_COMMIT)
+ replace_op = GF_REPLACE_OP_COMMIT_FORCE;
+
+ else if (replace_op == GF_REPLACE_OP_START)
+ is_force = _gf_true;
}
}
@@ -1318,6 +1347,9 @@ cli_cmd_volume_replace_brick_parse (const char **words, int wordcount,
if (ret)
goto out;
+ ret = dict_set_int32 (dict, "force", is_force);
+ if (ret)
+ goto out;
*options = dict;
diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c
index 4dcb99ce26e..216a2b6bfd9 100644
--- a/cli/src/cli-cmd-volume.c
+++ b/cli/src/cli-cmd-volume.c
@@ -392,6 +392,15 @@ cli_cmd_volume_create_cbk (struct cli_state *state, struct cli_cmd_word *word,
}
}
+ if (state->mode & GLUSTER_MODE_SCRIPT) {
+ ret = dict_set_int32 (options, "force", _gf_true);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Failed to set force "
+ "option");
+ goto out;
+ }
+ }
+
CLI_LOCAL_INIT (local, words, frame, options);
if (proc->fn) {
@@ -963,6 +972,15 @@ cli_cmd_volume_add_brick_cbk (struct cli_state *state,
}
}
+ if (state->mode & GLUSTER_MODE_SCRIPT) {
+ ret = dict_set_int32 (options, "force", _gf_true);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Failed to set force "
+ "option");
+ goto out;
+ }
+ }
+
proc = &cli_rpc_prog->proctable[GLUSTER_CLI_ADD_BRICK];
CLI_LOCAL_INIT (local, words, frame, options);
@@ -1131,6 +1149,15 @@ cli_cmd_volume_replace_brick_cbk (struct cli_state *state,
goto out;
}
+ if (state->mode & GLUSTER_MODE_SCRIPT) {
+ ret = dict_set_int32 (options, "force", _gf_true);
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR, "Failed to set force"
+ "option");
+ goto out;
+ }
+ }
+
CLI_LOCAL_INIT (local, words, frame, options);
if (proc->fn) {
@@ -1795,7 +1822,11 @@ struct cli_cmd volume_cmds[] = {
cli_cmd_volume_info_cbk,
"list information of all volumes"},
- { "volume create <NEW-VOLNAME> [stripe <COUNT>] [replica <COUNT>] [device vg] [transport <tcp|rdma|tcp,rdma>] <NEW-BRICK> ...",
+ { "volume create <NEW-VOLNAME> [stripe <COUNT>] [replica <COUNT>] "
+#ifdef HAVE_BD_XLATOR
+ "[device vg] "
+#endif
+ "[transport <tcp|rdma|tcp,rdma>] <NEW-BRICK> ... [force]",
cli_cmd_volume_create_cbk,
"create a new volume of specified type with mentioned bricks"},
@@ -1815,7 +1846,7 @@ struct cli_cmd volume_cmds[] = {
cli_cmd_volume_rename_cbk,
"rename volume <VOLNAME> to <NEW-VOLNAME>"},*/
- { "volume add-brick <VOLNAME> [<stripe|replica> <COUNT>] <NEW-BRICK> ...",
+ { "volume add-brick <VOLNAME> [<stripe|replica> <COUNT>] <NEW-BRICK> ... [force]",
cli_cmd_volume_add_brick_cbk,
"add brick to volume <VOLNAME>"},
@@ -1827,7 +1858,7 @@ struct cli_cmd volume_cmds[] = {
cli_cmd_volume_defrag_cbk,
"rebalance operations"},
- { "volume replace-brick <VOLNAME> <BRICK> <NEW-BRICK> {start|pause|abort|status|commit [force]}",
+ { "volume replace-brick <VOLNAME> <BRICK> <NEW-BRICK> {start [force]|pause|abort|status|commit [force]}",
cli_cmd_volume_replace_brick_cbk,
"replace-brick operations"},
diff --git a/tests/bugs/bug-948729/bug-948729-force.t b/tests/bugs/bug-948729/bug-948729-force.t
new file mode 100644
index 00000000000..3a5df791606
--- /dev/null
+++ b/tests/bugs/bug-948729/bug-948729-force.t
@@ -0,0 +1,85 @@
+#!/bin/bash
+
+. $(dirname $0)/../../include.rc
+. $(dirname $0)/../../cluster.rc
+
+function check_peers {
+ $CLI_1 peer status | grep 'Peer in Cluster (Connected)' | wc -l
+}
+
+cleanup;
+uuid1=`uuidgen`;
+uuid2=`uuidgen`;
+uuid3=`uuidgen`;
+
+V1=patchy1
+V2=patchy2
+
+TEST launch_cluster 2;
+cli1="gluster --remote-host=$H1"
+
+TEST $CLI_1 peer probe $H2;
+
+EXPECT_WITHIN 20 1 check_peers;
+
+B3=/d/backends/3
+B4=/d/backends/4
+B5=/d/backends/5
+B6=/d/backends/6
+
+mkdir -p $B3 $B4 $B5 $B6
+
+TEST truncate -s 16M $B1/brick1
+TEST truncate -s 16M $B2/brick2
+TEST truncate -s 16M $B3/brick3
+TEST truncate -s 16M $B4/brick4
+TEST truncate -s 16M $B5/brick5
+TEST truncate -s 16M $B6/brick6
+
+TEST LD1=`losetup --find --show $B1/brick1`
+TEST mkfs.xfs $LD1
+TEST LD2=`losetup --find --show $B2/brick2`
+TEST mkfs.xfs $LD2
+TEST LD3=`losetup --find --show $B3/brick3`
+TEST mkfs.xfs $LD3
+TEST LD4=`losetup --find --show $B4/brick4`
+TEST mkfs.xfs $LD4
+TEST LD5=`losetup --find --show $B5/brick5`
+TEST mkfs.xfs $LD5
+TEST LD6=`losetup --find --show $B6/brick6`
+TEST mkfs.xfs $LD6
+
+mkdir -p $B1/$V0 $B2/$V0 $B3/$V0 $B4/$V0 $B5/$V0 $B6/$V0
+
+TEST mount -t xfs $LD1 $B1/$V0
+TEST mount -t xfs $LD2 $B2/$V0
+TEST mount -t xfs $LD3 $B3/$V0
+TEST mount -t xfs $LD4 $B4/$V0
+TEST mount -t xfs $LD5 $B5/$V0
+TEST mount -t xfs $LD6 $B6/$V0
+
+#Case 0: Parent directory of the brick is absent
+TEST ! $cli1 volume create $V0 $H1:$B1/$V0/nonexistent/b1 $H2:$B2/$V0/nonexistent/b2 force
+
+#Case 1: File system root is being used as brick directory
+TEST $cli1 volume create $V0 $H1:$B5/$V0 $H2:$B6/$V0 force
+
+#Case 2: Brick directory contains only one component
+TEST $cli1 volume create $V1 $H1:/$uuid1 $H2:/$uuid2 force
+
+#Case 3: Sub-directories of the backend FS being used as brick directory
+TEST $cli1 volume create $V2 $H1:$B1/$V0/brick1 $H2:$B2/$V0/brick2 force
+
+#add-brick tests
+TEST ! $cli1 volume add-brick $V0 $H1:$B3/$V0/nonexistent/brick3 force
+TEST $cli1 volume add-brick $V0 $H1:$B3/$V0 force
+TEST $cli1 volume add-brick $V1 $H1:/$uuid3 force
+TEST $cli1 volume add-brick $V2 $H1:$B4/$V0/brick3 force
+
+#####replace-brick tests
+#FIX-ME: replace-brick does not work with the newly introduced cluster test
+#####framework
+
+rmdir /$uuid1 /$uuid2 /$uuid3;
+
+cleanup;
diff --git a/tests/bugs/bug-948729/bug-948729-mode-script.t b/tests/bugs/bug-948729/bug-948729-mode-script.t
new file mode 100644
index 00000000000..541ca897d5f
--- /dev/null
+++ b/tests/bugs/bug-948729/bug-948729-mode-script.t
@@ -0,0 +1,85 @@
+#!/bin/bash
+
+. $(dirname $0)/../../include.rc
+. $(dirname $0)/../../cluster.rc
+
+function check_peers {
+ $CLI_1 peer status | grep 'Peer in Cluster (Connected)' | wc -l
+}
+
+cleanup;
+
+uuid1=`uuidgen`;
+uuid2=`uuidgen`;
+uuid3=`uuidgen`;
+
+V1=patchy1
+V2=patchy2
+V3=patchy3
+
+TEST launch_cluster 2;
+
+TEST $CLI_1 peer probe $H2;
+
+EXPECT_WITHIN 20 1 check_peers;
+
+B3=/d/backends/3
+B4=/d/backends/4
+B5=/d/backends/5
+B6=/d/backends/6
+mkdir -p $B3 $B4 $B5 $B6
+
+TEST truncate -s 16M $B1/brick1
+TEST truncate -s 16M $B2/brick2
+TEST truncate -s 16M $B3/brick3
+TEST truncate -s 16M $B4/brick4
+TEST truncate -s 16M $B5/brick5
+TEST truncate -s 16M $B6/brick6
+
+TEST LD1=`losetup --find --show $B1/brick1`
+TEST mkfs.xfs $LD1
+TEST LD2=`losetup --find --show $B2/brick2`
+TEST mkfs.xfs $LD2
+TEST LD3=`losetup --find --show $B3/brick3`
+TEST mkfs.xfs $LD3
+TEST LD4=`losetup --find --show $B4/brick4`
+TEST mkfs.xfs $LD4
+TEST LD5=`losetup --find --show $B5/brick5`
+TEST mkfs.xfs $LD5
+TEST LD6=`losetup --find --show $B6/brick6`
+TEST mkfs.xfs $LD6
+
+mkdir -p $B1/$V0 $B2/$V0 $B3/$V0 $B4/$V0 $B5/$V0 $B6/$V0
+
+TEST mount -t xfs $LD1 $B1/$V0
+TEST mount -t xfs $LD2 $B2/$V0
+TEST mount -t xfs $LD3 $B3/$V0
+TEST mount -t xfs $LD4 $B4/$V0
+TEST mount -t xfs $LD5 $B5/$V0
+TEST mount -t xfs $LD6 $B6/$V0
+
+#Case 0: Parent directory of the brick is absent
+TEST ! $CLI_1 volume create $V0 $H1:$B1/$V0/nonexistent/b1 $H2:$B2/$V0/nonexistent/b2
+
+#Case 1: File system root being used as brick directory
+TEST $CLI_1 volume create $V0 $H1:$B5/$V0 $H2:$B6/$V0
+
+#Case 2: Brick directory contains only one component
+TEST $CLI_1 volume create $V1 $H1:/$uuid1 $H2:/$uuid2
+
+#Case 3: Sub-directories of the backend FS being used as brick directory
+TEST $CLI_1 volume create $V2 $H1:$B1/$V0/brick1 $H2:$B2/$V0/brick2
+
+#add-brick tests
+TEST ! $CLI_1 volume add-brick $V0 $H1:$B3/$V0/nonexistent/brick3
+TEST $CLI_1 volume add-brick $V0 $H1:$B3/$V0
+TEST $CLI_1 volume add-brick $V1 $H1:/$uuid3
+TEST $CLI_1 volume add-brick $V2 $H1:$B4/$V0/brick3
+
+#####replace-brick tests
+#FIX-ME : replace-brick does not currently work in the newly introduced
+#####cluster test framework
+
+rmdir /$uuid1 /$uuid2 /$uuid3
+
+cleanup;
diff --git a/tests/bugs/bug-948729/bug-948729.t b/tests/bugs/bug-948729/bug-948729.t
new file mode 100644
index 00000000000..288ae2bef51
--- /dev/null
+++ b/tests/bugs/bug-948729/bug-948729.t
@@ -0,0 +1,68 @@
+#!/bin/bash
+
+. $(dirname $0)/../../include.rc
+. $(dirname $0)/../../cluster.rc
+
+function check_peers {
+ $CLI_1 peer status | grep 'Peer in Cluster (Connected)' | wc -l
+}
+
+cleanup;
+
+uuid1=`uuidgen`;
+uuid2=`uuidgen`;
+uuid3=`uuidgen`;
+
+TEST launch_cluster 2;
+cli1="gluster --remote-host=$H1"
+
+TEST $CLI_1 peer probe $H2;
+
+EXPECT_WITHIN 20 1 check_peers;
+
+B3=/d/backends/3
+
+mkdir -p $B3
+
+TEST truncate -s 16M $B1/brick1
+TEST truncate -s 16M $B2/brick2
+TEST truncate -s 16M $B3/brick3
+
+TEST LD1=`losetup --find --show $B1/brick1`
+TEST mkfs.xfs $LD1
+TEST LD2=`losetup --find --show $B2/brick2`
+TEST mkfs.xfs $LD2
+TEST LD3=`losetup --find --show $B3/brick3`
+TEST mkfs.xfs $LD3
+
+mkdir -p $B1/$V0 $B2/$V0 $B3/$V0
+
+TEST mount -t xfs $LD1 $B1/$V0
+TEST mount -t xfs $LD2 $B2/$V0
+TEST mount -t xfs $LD3 $B3/$V0
+
+#Tests without --mode=script option
+
+#Case 0: Parent directory of the brick is absent
+TEST ! $cli1 volume create $V0 $H1:$B1/$V0/nonexistent/b1 $H2:$B2/$V0/nonexistent/b2
+
+#Case 1: File system root being used as brick directory
+TEST ! $cli1 volume create $V0 $H1:$B1/$V0 $H2:$B2/$V0
+
+#Case 2: Brick directory contains only one component
+TEST ! $cli1 volume create $V0 $H1:/$uuid1 $H2:/$uuid2
+
+#Case 3: Sub-directories of the backend FS being used as brick directory
+TEST $cli1 volume create $V0 $H1:$B1/$V0/brick1 $H2:$B2/$V0/brick2
+
+#add-brick tests
+TEST ! $cli1 volume add-brick $V0 $H1:$B3/$V0/nonexistent/b3
+TEST ! $cli1 volume add-brick $V0 $H1:$B3/$V0
+TEST ! $cli1 volume add-brick $V0 $H1:/$uuid3
+TEST $cli1 volume add-brick $V0 $H1:$B3/$V0/brick3
+
+#####replace-brick tests
+#FIX-ME: Replace-brick does not work currently in the newly introduced cluster
+#####test framework.
+
+cleanup;
diff --git a/xlators/mgmt/glusterd/src/glusterd-brick-ops.c b/xlators/mgmt/glusterd/src/glusterd-brick-ops.c
index 0167992ba56..bfa716b638a 100644
--- a/xlators/mgmt/glusterd/src/glusterd-brick-ops.c
+++ b/xlators/mgmt/glusterd/src/glusterd-brick-ops.c
@@ -423,6 +423,10 @@ __glusterd_handle_add_brick (rpcsvc_request_t *req)
stripe_count);
}
+ if (!dict_get (dict, "force")) {
+ gf_log (this->name, GF_LOG_ERROR, "Failed to get flag");
+ goto out;
+ }
ret = glusterd_volinfo_find (volname, &volinfo);
if (ret) {
@@ -1043,6 +1047,7 @@ glusterd_op_stage_add_brick (dict_t *dict, char **op_errstr)
gf_boolean_t brick_alloc = _gf_false;
char *all_bricks = NULL;
char *str_ret = NULL;
+ gf_boolean_t is_force = _gf_false;
priv = THIS->private;
if (!priv)
@@ -1105,6 +1110,8 @@ glusterd_op_stage_add_brick (dict_t *dict, char **op_errstr)
goto out;
}
+ is_force = dict_get_str_boolean (dict, "force", _gf_false);
+
if (bricks) {
brick_list = gf_strdup (bricks);
all_bricks = gf_strdup (bricks);
@@ -1146,10 +1153,9 @@ glusterd_op_stage_add_brick (dict_t *dict, char **op_errstr)
}
if (!uuid_compare (brickinfo->uuid, MY_UUID)) {
- ret = glusterd_brick_create_path (brickinfo->hostname,
- brickinfo->path,
+ ret = glusterd_validate_and_create_brickpath (brickinfo,
volinfo->volume_id,
- op_errstr);
+ op_errstr, is_force);
if (ret)
goto out;
}
diff --git a/xlators/mgmt/glusterd/src/glusterd-replace-brick.c b/xlators/mgmt/glusterd/src/glusterd-replace-brick.c
index 928d2ee2190..5f299a7eff5 100644
--- a/xlators/mgmt/glusterd/src/glusterd-replace-brick.c
+++ b/xlators/mgmt/glusterd/src/glusterd-replace-brick.c
@@ -221,6 +221,7 @@ glusterd_op_stage_replace_brick (dict_t *dict, char **op_errstr,
char pidfile[PATH_MAX] = {0};
char *task_id_str = NULL;
xlator_t *this = NULL;
+ gf_boolean_t is_force = _gf_false;
this = THIS;
GF_ASSERT (this);
@@ -357,6 +358,8 @@ glusterd_op_stage_replace_brick (dict_t *dict, char **op_errstr,
ret = 0;
}
}
+ is_force = dict_get_str_boolean (dict, "force", _gf_false);
+
break;
case GF_REPLACE_OP_PAUSE:
@@ -391,7 +394,9 @@ glusterd_op_stage_replace_brick (dict_t *dict, char **op_errstr,
}
break;
- case GF_REPLACE_OP_COMMIT_FORCE: break;
+ case GF_REPLACE_OP_COMMIT_FORCE:
+ is_force = _gf_true;
+ break;
case GF_REPLACE_OP_STATUS:
@@ -517,9 +522,9 @@ glusterd_op_stage_replace_brick (dict_t *dict, char **op_errstr,
if (!glusterd_is_rb_ongoing (volinfo) &&
glusterd_is_local_addr (host)) {
- ret = glusterd_brick_create_path (host, path,
+ ret = glusterd_validate_and_create_brickpath (dst_brickinfo,
volinfo->volume_id,
- op_errstr);
+ op_errstr, is_force);
if (ret)
goto out;
}
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
index 53b3937d462..b0a2ac31651 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
@@ -925,6 +925,105 @@ out:
return available;
}
+int
+glusterd_validate_and_create_brickpath (glusterd_brickinfo_t *brickinfo,
+ uuid_t volume_id, char **op_errstr,
+ gf_boolean_t is_force)
+{
+ int ret = -1;
+ char parentdir[PATH_MAX] = {0,};
+ struct stat parent_st = {0,};
+ struct stat brick_st = {0,};
+ struct stat root_st = {0,};
+ char msg[2048] = {0,};
+ gf_boolean_t is_created = _gf_false;
+
+ ret = mkdir (brickinfo->path, 0777);
+ if (ret) {
+ if (errno != EEXIST) {
+ snprintf (msg, sizeof (msg), "Failed to create brick "
+ "directory for brick %s:%s. Reason : %s ",
+ brickinfo->hostname, brickinfo->path,
+ strerror (errno));
+ goto out;
+ }
+ } else {
+ is_created = _gf_true;
+ }
+
+ ret = lstat (brickinfo->path, &brick_st);
+ if (ret) {
+ snprintf (msg, sizeof (msg), "lstat failed on %s. Reason : %s",
+ brickinfo->path, strerror (errno));
+ goto out;
+ }
+
+ if ((!is_created) && (!S_ISDIR (brick_st.st_mode))) {
+ snprintf (msg, sizeof (msg), "The provided path %s which is "
+ "already present, is not a directory",
+ brickinfo->path);
+ ret = -1;
+ goto out;
+ }
+
+ snprintf (parentdir, sizeof (parentdir), "%s/..", brickinfo->path);
+
+ ret = lstat ("/", &root_st);
+ if (ret) {
+ snprintf (msg, sizeof (msg), "lstat failed on /. Reason : %s",
+ strerror (errno));
+ goto out;
+ }
+
+ ret = lstat (parentdir, &parent_st);
+ if (ret) {
+ snprintf (msg, sizeof (msg), "lstat failed on %s. Reason : %s",
+ parentdir, strerror (errno));
+ goto out;
+ }
+
+ if (!is_force) {
+ if (brick_st.st_dev != parent_st.st_dev) {
+ snprintf (msg, sizeof (msg), "The brick %s:%s is a "
+ "mount point. Please create a sub-directory "
+ "under the mount point and use that as the "
+ "brick directory. Or use 'force' at the end "
+ "of the command if you want to override this "
+ "behavior.", brickinfo->hostname,
+ brickinfo->path);
+ ret = -1;
+ goto out;
+ }
+ else if (parent_st.st_dev == root_st.st_dev) {
+ snprintf (msg, sizeof (msg), "The brick %s:%s is "
+ "is being created in the root partition. It "
+ "is recommended that you don't use the "
+ "system's root partition for storage backend."
+ " Or use 'force' at the end of the command if"
+ " you want to override this behavior.",
+ brickinfo->hostname, brickinfo->path);
+ ret = -1;
+ goto out;
+ }
+ }
+
+ ret = glusterd_check_and_set_brick_xattr (brickinfo->hostname,
+ brickinfo->path, volume_id,
+ op_errstr);
+ if (ret)
+ goto out;
+
+ ret = 0;
+
+out:
+ if (ret && is_created)
+ rmdir (brickinfo->path);
+ if (ret && !*op_errstr && msg[0] != '\0')
+ *op_errstr = gf_strdup (msg);
+
+ return ret;
+}
+
int32_t
glusterd_volume_brickinfo_get (uuid_t uuid, char *hostname, char *path,
glusterd_volinfo_t *volinfo,
@@ -5257,17 +5356,13 @@ out:
}
int
-glusterd_brick_create_path (char *host, char *path, uuid_t uuid,
- char **op_errstr)
+glusterd_check_and_set_brick_xattr (char *host, char *path, uuid_t uuid,
+ char **op_errstr)
{
int ret = -1;
char msg[2048] = {0,};
gf_boolean_t in_use = _gf_false;
- ret = mkdir_p (path, 0777, _gf_true);
- if (ret)
- goto out;
-
/* Check for xattr support in backend fs */
ret = sys_lsetxattr (path, "trusted.glusterfs.test",
"working", 8, 0);
@@ -5280,7 +5375,6 @@ glusterd_brick_create_path (char *host, char *path, uuid_t uuid,
} else {
sys_lremovexattr (path, "trusted.glusterfs.test");
-
}
ret = glusterd_is_path_in_use (path, &in_use, op_errstr);
@@ -5307,7 +5401,6 @@ out:
*op_errstr = gf_strdup (msg);
return ret;
-
}
int
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h
index 06f85e8d35d..687b48bf3ab 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.h
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.h
@@ -320,8 +320,13 @@ glusterd_rb_check_bricks (glusterd_volinfo_t *volinfo,
glusterd_brickinfo_t *dst_brick);
int
-glusterd_brick_create_path (char *host, char *path, uuid_t uuid,
- char **op_errstr);
+glusterd_check_and_set_brick_xattr (char *host, char *path, uuid_t uuid,
+ char **op_errstr);
+
+int
+glusterd_validate_and_create_brickpath (glusterd_brickinfo_t *brickinfo,
+ uuid_t volume_id, char **op_errstr,
+ gf_boolean_t is_force);
int
glusterd_sm_tr_log_transition_add (glusterd_sm_tr_log_t *log,
int old_state, int new_state,
diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c
index 1cbe0c8acf9..28cecb9891e 100644
--- a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c
+++ b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c
@@ -134,6 +134,11 @@ __glusterd_handle_create_volume (rpcsvc_request_t *req)
goto out;
}
+ if (!dict_get (dict, "force")) {
+ gf_log (this->name, GF_LOG_ERROR, "Failed to get 'force' flag");
+ goto out;
+ }
+
uuid_generate (volume_id);
free_ptr = gf_strdup (uuid_utoa (volume_id));
ret = dict_set_dynstr (dict, "volume-id", free_ptr);
@@ -655,6 +660,8 @@ glusterd_op_stage_create_volume (dict_t *dict, char **op_errstr)
#ifdef HAVE_BD_XLATOR
char *dev_type = NULL;
#endif
+ gf_boolean_t is_force = _gf_false;
+
this = THIS;
GF_ASSERT (this);
priv = this->private;
@@ -708,6 +715,8 @@ glusterd_op_stage_create_volume (dict_t *dict, char **op_errstr)
goto out;
}
+ is_force = dict_get_str_boolean (dict, "force", _gf_false);
+
if (bricks) {
brick_list = gf_strdup (bricks);
if (!brick_list) {
@@ -760,10 +769,9 @@ glusterd_op_stage_create_volume (dict_t *dict, char **op_errstr)
} else
#endif
if (!uuid_compare (brick_info->uuid, MY_UUID)) {
- ret = glusterd_brick_create_path (brick_info->hostname,
- brick_info->path,
- volume_uuid,
- op_errstr);
+ ret = glusterd_validate_and_create_brickpath (brick_info,
+ volume_uuid, op_errstr,
+ is_force);
if (ret)
goto out;
brick_list = tmpptr;