diff options
| -rw-r--r-- | cli/src/cli-cmd-parser.c | 40 | ||||
| -rw-r--r-- | cli/src/cli-cmd-volume.c | 33 | ||||
| -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, 441 insertions, 27 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index c09aa6260fa..484c4a34b47 100644 --- a/cli/src/cli-cmd-parser.c +++ b/cli/src/cli-cmd-parser.c @@ -175,6 +175,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); @@ -351,7 +353,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; @@ -422,6 +429,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: @@ -910,6 +921,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); @@ -987,7 +1000,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; @@ -1001,6 +1020,10 @@ parse_bricks:          if (ret)                  goto out; +        ret = dict_set_int32 (dict, "force", is_force); +        if (ret) +                goto out; +          *options = dict;  out: @@ -1203,6 +1226,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); @@ -1300,12 +1324,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;                  }          } @@ -1319,6 +1348,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 de7adfe8fec..aa1c77553b4 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) { @@ -1799,7 +1826,7 @@ struct cli_cmd volume_cmds[] = {  #ifdef HAVE_BD_XLATOR            "[device vg] "  #endif -          "[transport <tcp|rdma|tcp,rdma>] <NEW-BRICK> ...", +          "[transport <tcp|rdma|tcp,rdma>] <NEW-BRICK> ... [force]",            cli_cmd_volume_create_cbk,            "create a new volume of specified type with mentioned bricks"}, @@ -1819,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>"}, @@ -1831,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 2ac2699cfc2..d21facb0ad0 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) { @@ -1034,6 +1038,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) @@ -1096,6 +1101,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); @@ -1137,10 +1144,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 36f0b10dc6f..0afe2203c85 100644 --- a/xlators/mgmt/glusterd/src/glusterd-replace-brick.c +++ b/xlators/mgmt/glusterd/src/glusterd-replace-brick.c @@ -213,6 +213,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); @@ -349,6 +350,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: @@ -383,7 +386,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: @@ -507,9 +512,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 09aeb737067..6c5d0e2f074 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c @@ -924,6 +924,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, @@ -5045,17 +5144,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); @@ -5068,7 +5163,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); @@ -5095,7 +5189,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 c7fbe447e31..28182d6ba5b 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.h +++ b/xlators/mgmt/glusterd/src/glusterd-utils.h @@ -317,8 +317,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 bc5f8f2a749..fd4e0268a57 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); @@ -610,6 +615,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; @@ -663,6 +670,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) { @@ -715,10 +724,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;  | 
