Blob Blame History Raw
From b872be92b66d608b2fdeb788cdd5eb0a323307a9 Mon Sep 17 00:00:00 2001
From: Avra Sengupta <asengupt@redhat.com>
Date: Thu, 20 Oct 2016 12:58:16 +0530
Subject: [PATCH 345/361] snapshot: Fix the failure to recreate clones with
 same name

The brick path of snapshot clones contained the clonename,
thereby failing to create newer clones with the same name
after the original clone had been deleted.

This fix creates the brick path with the clone's vol id
instead of the clones name. Hence future clones with the
same name will not have the namespace clash.

mainline:
> BUG: 1387160
> Reviewed-on: http://review.gluster.org/15683
> Smoke: Gluster Build System <jenkins@build.gluster.org>
> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
> CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
> Reviewed-by: Rajesh Joseph <rjoseph@redhat.com>
(cherry picked from commit 88c8720f3b200bce9b008e8200adbd11431d3fe7)

BUG: 1309209
Change-Id: I262712adc576122f051b5d1ce171d020efaefd1a
Signed-off-by: Avra Sengupta <asengupt@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/101285
Tested-by: Milind Changire <mchangir@redhat.com>
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
---
 tests/basic/volume-snapshot-clone.t                | 13 ++++++
 xlators/mgmt/glusterd/src/glusterd-handshake.c     |  2 +-
 .../mgmt/glusterd/src/glusterd-snapshot-utils.h    |  2 +-
 xlators/mgmt/glusterd/src/glusterd-snapshot.c      | 54 ++++++++++++++++------
 xlators/mgmt/glusterd/src/glusterd.h               |  3 +-
 5 files changed, 57 insertions(+), 17 deletions(-)

diff --git a/tests/basic/volume-snapshot-clone.t b/tests/basic/volume-snapshot-clone.t
index cf68911..e6da9d7 100755
--- a/tests/basic/volume-snapshot-clone.t
+++ b/tests/basic/volume-snapshot-clone.t
@@ -98,6 +98,19 @@ EXPECT_WITHIN $PROBE_TIMEOUT 2 peer_count;
 
 EXPECT_WITHIN $PROCESS_UP_TIMEOUT 'Started' volinfo_field ${V0}_clone 'Status';
 EXPECT_WITHIN $PROCESS_UP_TIMEOUT 'Started' volinfo_field ${V1}_clone 'Status';
+
+TEST $CLI_1 volume stop ${V0}_clone
+TEST $CLI_1 volume stop ${V1}_clone
+
+TEST $CLI_1 volume delete ${V0}_clone
+TEST $CLI_1 volume delete ${V1}_clone
+
+TEST $CLI_1 snapshot clone ${V0}_clone ${V0}_snap
+TEST $CLI_1 snapshot clone ${V1}_clone ${V1}_snap
+
+EXPECT 'Created' volinfo_field ${V0}_clone 'Status';
+EXPECT 'Created' volinfo_field ${V1}_clone 'Status';
+
 #Clean up
 stop_force_volumes 2
 EXPECT_WITHIN $CONFIG_UPDATE_TIMEOUT 'Stopped' volinfo_field $V0 'Status';
diff --git a/xlators/mgmt/glusterd/src/glusterd-handshake.c b/xlators/mgmt/glusterd/src/glusterd-handshake.c
index 4e5dd01..0cd1a29 100644
--- a/xlators/mgmt/glusterd/src/glusterd-handshake.c
+++ b/xlators/mgmt/glusterd/src/glusterd-handshake.c
@@ -615,7 +615,7 @@ glusterd_create_missed_snap (glusterd_missed_snap_info *missed_snapinfo,
 
         /* Create and mount the snap brick */
         ret = glusterd_snap_brick_create (snap_vol, brickinfo,
-                                          snap_opinfo->brick_num - 1);
+                                          snap_opinfo->brick_num - 1, 0);
         if (ret) {
                 gf_msg (this->name, GF_LOG_ERROR, 0,
                         GD_MSG_BRICK_CREATION_FAIL, "Failed to "
diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.h b/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.h
index b964a43..e050166 100644
--- a/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.h
+++ b/xlators/mgmt/glusterd/src/glusterd-snapshot-utils.h
@@ -137,7 +137,7 @@ glusterd_snap_quorum_check (dict_t *dict, gf_boolean_t snap_volume,
 int32_t
 glusterd_snap_brick_create (glusterd_volinfo_t *snap_volinfo,
                             glusterd_brickinfo_t *brickinfo,
-                            int32_t brick_count);
+                            int32_t brick_count, int32_t clone);
 
 int
 glusterd_snapshot_restore_cleanup (dict_t *rsp_dict,
diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot.c b/xlators/mgmt/glusterd/src/glusterd-snapshot.c
index 2c0a192..d3e9b99 100644
--- a/xlators/mgmt/glusterd/src/glusterd-snapshot.c
+++ b/xlators/mgmt/glusterd/src/glusterd-snapshot.c
@@ -2378,6 +2378,7 @@ glusterd_snapshot_clone_prevalidate (dict_t *dict, char **op_errstr,
 {
         char                  *clonename         = NULL;
         char                  *snapname          = NULL;
+        char                   device_name[64]   = "";
         char                   key[PATH_MAX]     = "";
         glusterd_snap_t       *snap              = NULL;
         char                   err_str[PATH_MAX] = "";
@@ -2443,10 +2444,12 @@ glusterd_snapshot_clone_prevalidate (dict_t *dict, char **op_errstr,
                 goto out;
         }
 
+        GLUSTERD_GET_UUID_NOHYPHEN (device_name, *snap_volid);
+
         /* Adding snap bricks mount paths to the dict */
         ret = glusterd_snap_create_clone_common_prevalidate (rsp_dict, 0,
                                                              snapname, err_str,
-                                                             clonename, 1,
+                                                             device_name, 1,
                                                              snap_vol,
                                                              &loglevel,
                                                              1, op_errno);
@@ -4812,12 +4815,13 @@ out:
 int32_t
 glusterd_snap_brick_create (glusterd_volinfo_t *snap_volinfo,
                             glusterd_brickinfo_t *brickinfo,
-                            int32_t brick_count)
+                            int32_t brick_count, int32_t clone)
 {
         int32_t          ret                             = -1;
         xlator_t        *this                            = NULL;
         glusterd_conf_t *priv                            = NULL;
         char             snap_brick_mount_path[PATH_MAX] = "";
+        char             clone_uuid[64]                  = "";
         struct stat      statbuf                         = {0, };
 
         this = THIS;
@@ -4826,9 +4830,16 @@ glusterd_snap_brick_create (glusterd_volinfo_t *snap_volinfo,
         GF_ASSERT (snap_volinfo);
         GF_ASSERT (brickinfo);
 
-        snprintf (snap_brick_mount_path, sizeof (snap_brick_mount_path),
-                  "%s/%s/brick%d",  snap_mount_dir, snap_volinfo->volname,
-                  brick_count + 1);
+        if (clone) {
+                GLUSTERD_GET_UUID_NOHYPHEN(clone_uuid, snap_volinfo->volume_id);
+                snprintf (snap_brick_mount_path, sizeof (snap_brick_mount_path),
+                          "%s/%s/brick%d",  snap_mount_dir,
+                          clone_uuid, brick_count + 1);
+        } else {
+                snprintf (snap_brick_mount_path, sizeof (snap_brick_mount_path),
+                          "%s/%s/brick%d",  snap_mount_dir,
+                          snap_volinfo->volname, brick_count + 1);
+        }
 
         ret = mkdir_p (snap_brick_mount_path, 0777, _gf_true);
         if (ret) {
@@ -4903,6 +4914,7 @@ glusterd_add_brick_to_snap_volume (dict_t *dict, dict_t *rsp_dict,
         char                   *value                           = NULL;
         char                   *snap_brick_dir                  = NULL;
         char                    snap_brick_path[PATH_MAX]       = "";
+        char                    clone_uuid[64]                  = "";
         char                   *snap_device                     = NULL;
         glusterd_brickinfo_t   *snap_brickinfo                  = NULL;
         gf_boolean_t            add_missed_snap                 = _gf_false;
@@ -5018,10 +5030,18 @@ glusterd_add_brick_to_snap_volume (dict_t *dict, dict_t *rsp_dict,
         /* Create brick-path in the format /var/run/gluster/snaps/ *
          * <snap-uuid>/<original-brick#>/snap-brick-dir *
          */
-        snprintf (snap_brick_path, sizeof(snap_brick_path),
-                  "%s/%s/brick%d%s", snap_mount_dir,
-                  snap_vol->volname, brick_count+1,
-                  snap_brick_dir);
+        if (clone) {
+                GLUSTERD_GET_UUID_NOHYPHEN(clone_uuid, snap_vol->volume_id);
+                snprintf (snap_brick_path, sizeof(snap_brick_path),
+                          "%s/%s/brick%d%s", snap_mount_dir,
+                          clone_uuid, brick_count+1,
+                          snap_brick_dir);
+        } else {
+                snprintf (snap_brick_path, sizeof(snap_brick_path),
+                          "%s/%s/brick%d%s", snap_mount_dir,
+                          snap_vol->volname, brick_count+1,
+                          snap_brick_dir);
+        }
 
         snprintf (key, sizeof(key), "vol%"PRId64".brick_snapdevice%d",
                   volcount, brick_count);
@@ -5163,7 +5183,8 @@ out:
 static int32_t
 glusterd_take_brick_snapshot (dict_t *dict, glusterd_volinfo_t *snap_vol,
                               glusterd_brickinfo_t *brickinfo,
-                              int32_t volcount, int32_t brick_count)
+                              int32_t volcount, int32_t brick_count,
+                              int32_t clone)
 {
         char                   *origin_brick_path   = NULL;
         char                    key[PATH_MAX]       = "";
@@ -5219,7 +5240,8 @@ glusterd_take_brick_snapshot (dict_t *dict, glusterd_volinfo_t *snap_vol,
         }
 
         /* create the complete brick here */
-        ret = glusterd_snap_brick_create (snap_vol, brickinfo, brick_count);
+        ret = glusterd_snap_brick_create (snap_vol, brickinfo,
+                                          brick_count, clone);
         if (ret) {
                 gf_msg (this->name, GF_LOG_ERROR, 0,
                         GD_MSG_BRICK_CREATION_FAIL, "not able to"
@@ -6515,7 +6537,8 @@ out:
 int
 glusterd_take_brick_snapshot_task (void *opaque)
 {
-        int ret                             = 0;
+        int                  ret            = 0;
+        int32_t              clone          = 0;
         snap_create_args_t  *snap_args      = NULL;
         char                *clonename      = NULL;
         char                 key[PATH_MAX]  = "";
@@ -6531,15 +6554,18 @@ glusterd_take_brick_snapshot_task (void *opaque)
         if (ret) {
                 snprintf (key, sizeof (key), "snap-vol%d.brick%d.status",
                           snap_args->volcount, snap_args->brickorder);
-        } else
+        } else {
                 snprintf (key, sizeof (key), "clone%d.brick%d.status",
                           snap_args->volcount, snap_args->brickorder);
+                clone = 1;
+        }
 
         ret = glusterd_take_brick_snapshot (snap_args->dict,
                                             snap_args->snap_vol,
                                             snap_args->brickinfo,
                                             snap_args->volcount,
-                                            snap_args->brickorder);
+                                            snap_args->brickorder,
+                                            clone);
 
         if (ret) {
                 gf_msg (THIS->name, GF_LOG_ERROR, 0,
diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h
index 857c455..d80ad20 100644
--- a/xlators/mgmt/glusterd/src/glusterd.h
+++ b/xlators/mgmt/glusterd/src/glusterd.h
@@ -696,7 +696,8 @@ typedef ssize_t (*gd_serialize_t) (struct iovec outmsg, void *args);
 
 #define GLUSTERD_GET_UUID_NOHYPHEN(ret_string, uuid) do {               \
                 char *snap_volname_ptr = ret_string;                    \
-                char *snap_volid_ptr = uuid_utoa(uuid);                 \
+                char  tmp_uuid[64];                                     \
+                char *snap_volid_ptr = uuid_utoa_r(uuid, tmp_uuid);     \
                 while (*snap_volid_ptr) {                               \
                         if (*snap_volid_ptr == '-') {                   \
                                 snap_volid_ptr++;                       \
-- 
1.8.3.1