diff options
author | Krutika Dhananjay <kdhananj@redhat.com> | 2013-02-12 17:26:35 +0530 |
---|---|---|
committer | Anand Avati <avati@redhat.com> | 2013-11-26 21:39:16 -0800 |
commit | 5b91bef50d834e597f8c62b83419f26d146e631f (patch) | |
tree | 64772c0f7dae11d1b3e5045ec4b817ccd496d5f0 | |
parent | f73373f1244829d65d001fa3af8fdade192418c9 (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.c | 40 | ||||
-rw-r--r-- | cli/src/cli-cmd-volume.c | 37 | ||||
-rw-r--r-- | tests/bugs/bug-948729/bug-948729-force.t | 85 | ||||
-rw-r--r-- | tests/bugs/bug-948729/bug-948729-mode-script.t | 85 | ||||
-rw-r--r-- | tests/bugs/bug-948729/bug-948729.t | 68 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-brick-ops.c | 12 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-replace-brick.c | 11 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.c | 109 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.h | 9 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-volume-ops.c | 16 |
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; |