summaryrefslogtreecommitdiffstats
path: root/xlators/mgmt
diff options
context:
space:
mode:
authorVijaikumar M <vmallika@redhat.com>2014-02-13 16:32:12 +0530
committerRajesh Joseph <rjoseph@redhat.com>2014-02-13 06:18:15 -0800
commit96f6c5159da92500e8ddb21a487d2848a2b1f7db (patch)
tree173aadb72ff76d27ef6589a2ed1eed5c5220abff /xlators/mgmt
parenta6351ee1c823a295f592f4adf5876a6166d47afe (diff)
glusterd/snapshot: Use snap uuid to create lvm snapshot
Using snap uuid to create lvm snapshot will solve the problem of having '-' in the snap name or snap name is too long. Change-Id: If204f02a8f5de599fb409d06c7893ef3542a6300 BUG: 1045333 Signed-off-by: Vijaikumar M <vmallika@redhat.com> Reviewed-on: http://review.gluster.org/6709 Reviewed-by: Rajesh Joseph <rjoseph@redhat.com> Tested-by: Rajesh Joseph <rjoseph@redhat.com>
Diffstat (limited to 'xlators/mgmt')
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-handler.c1
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-handshake.c102
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-snapshot.c154
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-store.c10
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.h14
5 files changed, 188 insertions, 93 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c
index d109e11..ec13c85 100644
--- a/xlators/mgmt/glusterd/src/glusterd-handler.c
+++ b/xlators/mgmt/glusterd/src/glusterd-handler.c
@@ -338,7 +338,6 @@ glusterd_add_volume_detail_to_dict (glusterd_volinfo_t *volinfo,
char *volume_id_str = NULL;
struct args_pack pack = {0,};
xlator_t *this = NULL;
- int caps = 0;
GF_ASSERT (volinfo);
GF_ASSERT (volumes);
diff --git a/xlators/mgmt/glusterd/src/glusterd-handshake.c b/xlators/mgmt/glusterd/src/glusterd-handshake.c
index dbf342c..a1368e2 100644
--- a/xlators/mgmt/glusterd/src/glusterd-handshake.c
+++ b/xlators/mgmt/glusterd/src/glusterd-handshake.c
@@ -42,19 +42,21 @@ static size_t
build_volfile_path (const char *volname, char *path,
size_t path_len, char *trusted_str)
{
- struct stat stbuf = {0,};
- int32_t ret = -1;
- glusterd_conf_t *priv = NULL;
- char *vol = NULL;
- char *dup_volname = NULL;
- char *free_ptr = NULL;
- char *tmp = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- char *server = NULL;
- gf_boolean_t snap_volume = _gf_false;
- char *str = NULL;
- char *tmp_volname = NULL;
- char *input_vol = NULL;
+ struct stat stbuf = {0,};
+ int32_t ret = -1;
+ glusterd_conf_t *priv = NULL;
+ char *vol = NULL;
+ char *dup_volname = NULL;
+ char *free_ptr = NULL;
+ char *tmp = NULL;
+ glusterd_volinfo_t *volinfo = NULL;
+ glusterd_volinfo_t *parent_volinfo = NULL;
+ glusterd_snap_t *snap = NULL;
+ char *server = NULL;
+ gf_boolean_t snap_volume = _gf_false;
+ char *str = NULL;
+ char *parent_volname = NULL;
+ char *input_vol = NULL;
priv = THIS->private;
@@ -64,17 +66,53 @@ build_volfile_path (const char *volname, char *path,
path, path_len);
ret = 1;
goto out;
- } else if (strstr (volname, "/snaps/")) {
- input_vol = gf_strdup (volname);
+ } else if ((tmp = strstr (volname, "/snaps/"))) {
+ /* Input volname will have below formats:
+ <parent_volname>/snaps/<uuid>/<brick_path>
+ or
+ <parent_volname>/snaps/snapname
+
+ We need to extract snap uuid from the input volname */
+
snap_volume = _gf_true;
+ input_vol = gf_strdup (volname);
+ if (!input_vol)
+ goto out;
+ parent_volname = strtok_r (input_vol, "/", &str);
+ if (!parent_volname)
+ goto out;
+
str = strrchr (volname, '/');
if (str)
str++;
- dup_volname = gf_strdup (str);
+
+ tmp = strstr (tmp+1, "/");
+ while(*tmp && *tmp == '/')
+ tmp++;
+
+ /* User has provided snapname from the mountpoint.
+ Map the snapname to uuid to find the volfile */
+ if (tmp == str) {
+ ret = glusterd_volinfo_find (parent_volname,
+ &parent_volinfo);
+ if (ret) {
+ gf_log(THIS->name, GF_LOG_ERROR, "Failed to "
+ "find parent volinfo for snap %s", str);
+ goto out;
+ }
+ snap = glusterd_find_snap_by_name (parent_volinfo, str);
+ if (!snap) {
+ gf_log(THIS->name, GF_LOG_ERROR, "Failed to "
+ "fetch snap %s", str);
+ ret = -1;
+ goto out;
+ }
+ dup_volname = gf_strdup (snap->snap_volume->volname);
+ } else {
+ dup_volname = gf_strdup (str);
+ }
str = NULL;
- tmp_volname = strtok_r (input_vol, "/", &str);
- if (!tmp_volname)
- goto out;
+
} else if (volname[0] != '/') {
/* Normal behavior */
dup_volname = gf_strdup (volname);
@@ -85,9 +123,23 @@ build_volfile_path (const char *volname, char *path,
dup_volname = gf_strdup (&volname[1]);
}
+ if (!dup_volname) {
+ gf_log(THIS->name, GF_LOG_ERROR, "strdup failed");
+ ret = -1;
+ goto out;
+ }
free_ptr = dup_volname;
- ret = glusterd_volinfo_find (dup_volname, &volinfo);
+ if (!snap_volume) {
+ ret = glusterd_volinfo_find (dup_volname, &volinfo);
+ } else {
+ ret = 0;
+ if (snap)
+ volinfo = snap->snap_volume;
+ else
+ ret = glusterd_snap_volinfo_find (dup_volname,&volinfo);
+ }
+
if (ret) {
/* Split the volume name */
vol = strtok_r (dup_volname, ".", &tmp);
@@ -125,9 +177,9 @@ build_volfile_path (const char *volname, char *path,
dup_volname);
else
snprintf (path, path_len,
- "%s/vols/%s/snaps/%s/%s%s-fuse.vol",
- priv->workdir, tmp_volname, volinfo->volname,
- (trusted_str ? trusted_str:""), dup_volname);
+ "%s/vols/%s/snaps/%s/%s%s-fuse.vol",
+ priv->workdir, parent_volname, volinfo->volname,
+ (trusted_str ? trusted_str:""), dup_volname);
ret = stat (path, &stbuf);
}
@@ -139,8 +191,8 @@ build_volfile_path (const char *volname, char *path,
else
snprintf (path, path_len,
"%s/vols/%s/snaps/%s/%s-tcp.vol",
- priv->workdir, tmp_volname, volinfo->volname,
- volname);
+ priv->workdir, parent_volname,
+ volinfo->volname, volname);
}
ret = 1;
diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot.c b/xlators/mgmt/glusterd/src/glusterd-snapshot.c
index b33be09..e886f4b 100644
--- a/xlators/mgmt/glusterd/src/glusterd-snapshot.c
+++ b/xlators/mgmt/glusterd/src/glusterd-snapshot.c
@@ -585,6 +585,7 @@ glusterd_snapshot_create_prevalidate (dict_t *dict, char **op_errstr,
char snapmntname[PATH_MAX] = "";
char snapbrckcnt[PATH_MAX] = "";
char snapbrckord[PATH_MAX] = "";
+ char snap_volname[64] = "";
int ret = -1;
int64_t i = 0;
int64_t volume_count = 0;
@@ -594,6 +595,7 @@ glusterd_snapshot_create_prevalidate (dict_t *dict, char **op_errstr,
glusterd_volinfo_t *volinfo = NULL;
gf_boolean_t is_cg = _gf_false;
xlator_t *this = NULL;
+ uuid_t *snap_volid = NULL;
this = THIS;
@@ -653,10 +655,24 @@ glusterd_snapshot_create_prevalidate (dict_t *dict, char **op_errstr,
goto out;
}
+ snprintf (key, sizeof(key) - 1, "vol%ld_volid", i+1);
+ ret = dict_get_bin (dict, key, (void **)&snap_volid);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Unable to fetch snap_volid");
+ goto out;
+ }
+
+ /* snap uuid is used as lvm snapshot name.
+ This will avoid restrictions on snapshot names
+ provided by user */
+ GLUSTERD_GET_UUID_NOHYPHEN (snap_volname, *snap_volid);
+
if (is_cg) {
memset(snapname, '\0', sizeof (snapname));
snprintf (tmp, sizeof (tmp), "%s_snap", volinfo->volname);
snprintf (snapname, sizeof (snapname), "%s_%s", name, tmp);
+ strcpy(snap_volname, snapname);
}
//Also check whether geo replication is running
@@ -683,7 +699,8 @@ glusterd_snapshot_create_prevalidate (dict_t *dict, char **op_errstr,
goto out;
}
- device = glusterd_build_snap_device_path (device, snapname);
+ device = glusterd_build_snap_device_path (device,
+ snap_volname);
if (!device) {
gf_log (this->name, GF_LOG_WARNING, "cannot copy the "
"snapshot device name (volname: %s, "
@@ -699,7 +716,7 @@ glusterd_snapshot_create_prevalidate (dict_t *dict, char **op_errstr,
ret = snprintf (snap_mount, sizeof(snap_mount) - 1,
"%s/%s%s-brick",
GLUSTERD_DEFAULT_SNAPS_BRICK_DIR,
- snapname, device);
+ snap_volname, device);
snap_mount[ret] = '\0';
ret = glusterd_get_brick_root (brickinfo->path, &mnt_pt);
@@ -2642,7 +2659,7 @@ out:
*/
int32_t
glusterd_snap_create (glusterd_volinfo_t *volinfo,
- glusterd_volinfo_t *snap_volinfo,
+ glusterd_volinfo_t *snap_volinfo, char *snapname,
char *description, uuid_t *cg_id,
glusterd_snap_cg_t *cg, char *cg_name)
{
@@ -2655,6 +2672,7 @@ glusterd_snap_create (glusterd_volinfo_t *volinfo,
priv = this->private;
GF_ASSERT (snap_volinfo);
+ GF_ASSERT (snapname);
if (cg_id)
GF_ASSERT (cg_name);
@@ -2667,7 +2685,7 @@ glusterd_snap_create (glusterd_volinfo_t *volinfo,
if (!snap) {
gf_log (this->name, GF_LOG_ERROR, "could not create "
"the snap object fot the volume %s (snap: %s)",
- volinfo->volname, snap_volinfo->volname);
+ volinfo->volname, snapname);
goto out;
}
@@ -2701,8 +2719,7 @@ glusterd_snap_create (glusterd_volinfo_t *volinfo,
sizeof (snap->cg_name) - 1);
}
snap->snap_volume = snap_volinfo;
- strcpy (snap->snap_name, snap_volinfo->volname);
- //TODO: replace strcpy with strncpy
+ strcpy (snap->snap_name, snapname);
ret = glusterd_add_snap (volinfo, snap);
if (ret) {
@@ -2729,22 +2746,21 @@ out:
}
/* This function is called to get the device path of the snap lvm. Usually
- if /dev/<group-name>/<group-name>-<lvm-name> is the device for the lvm,
- then the snap device will be /dev/<group-name>/<group-name>-<snap-name>.
+ if /dev/mapper/<group-name>-<lvm-name> is the device for the lvm,
+ then the snap device will be /dev/<group-name>/<snap-name>.
This function takes care of building the path for the snap device.
*/
char *
glusterd_build_snap_device_path (char *device, char *snapname)
{
- char *tmp = NULL;
- char snap[PATH_MAX] = {0, };
- char msg[1024] = {0, };
- char *str = NULL;
- int device_len = 0;
- int tmp_len = 0;
- int var = 0;
- char *snap_device = NULL;
- xlator_t *this = NULL;
+ char snap[PATH_MAX] = "";
+ char msg[1024] = "";
+ char volgroup[PATH_MAX] = "";
+ char *snap_device = NULL;
+ xlator_t *this = NULL;
+ runner_t runner = {0,};
+ char *ptr = NULL;
+ int ret = -1;
this = THIS;
GF_ASSERT (this);
@@ -2752,42 +2768,47 @@ glusterd_build_snap_device_path (char *device, char *snapname)
gf_log (this->name, GF_LOG_ERROR, "device is NULL");
goto out;
}
+ if (!snapname) {
+ gf_log (this->name, GF_LOG_ERROR, "snapname is NULL");
+ goto out;
+ }
- device_len = strlen (device);
-
- tmp = strrchr (device, '/');
- if (tmp)
- tmp++;
- str = gf_strdup (tmp);
- if (!str) {
+ runinit (&runner);
+ runner_add_args (&runner, "/sbin/lvs", "--noheadings", "-o", "vg_name",
+ device, NULL);
+ runner_redir (&runner, STDOUT_FILENO, RUN_PIPE);
+ snprintf (msg, sizeof (msg), "Get volume group for device %s", device);
+ runner_log (&runner, this->name, GF_LOG_DEBUG, msg);
+ ret = runner_start (&runner);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_ERROR, "Failed to get volume group "
+ "for device %s", device);
+ runner_end (&runner);
+ goto out;
+ }
+ ptr = fgets(volgroup, sizeof(volgroup),
+ runner_chio (&runner, STDOUT_FILENO));
+ if (!ptr || !strlen(volgroup)) {
+ gf_log (this->name, GF_LOG_ERROR, "Failed to get volume group "
+ "for snap %s", snapname);
+ runner_end (&runner);
+ ret = -1;
goto out;
}
+ runner_end (&runner);
+
+ strcpy(snap, "/dev/");
+ strcat(snap, gf_trim(volgroup));
+ strcat(snap, "/");
+ strcat(snap, snapname);
- tmp_len = strlen (str);
- var = device_len - tmp_len;
- device[var] = '\0';
- tmp = strchr (str, '-');
- if (tmp)
- tmp++;
- device_len = tmp_len;
- tmp_len = strlen (tmp);
- var = device_len - tmp_len;
- str[var] = '\0';
- msg[0] = '\0';
- strcpy (msg, str);
- strcat (msg, snapname);
- strcpy (snap, device);
- strcat (snap, msg);
snap_device = gf_strdup (snap);
if (!snap_device) {
- gf_log (this->name, GF_LOG_WARNING, "cannot copy the "
- "snapshot device name "
- "snapname: %s)", snapname);
- goto out;
+ gf_log (this->name, GF_LOG_WARNING, "Cannot copy the "
+ "snapshot device name for snapname: %s)", snapname);
}
out:
- GF_FREE (str);
return snap_device;
}
@@ -2898,20 +2919,19 @@ int32_t
glusterd_snap_brick_create (char *device, glusterd_volinfo_t *snap_volinfo,
glusterd_brickinfo_t *original_brickinfo)
{
- int32_t ret = -1;
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
- char snap_brick_mount_path[PATH_MAX] = {0, };
- char *tmp = NULL;
- char *mnt_pt = NULL;
- struct mntent *entry = NULL;
- FILE *mtab = NULL;
- char *snap_brick_dir = NULL;
- char snap_brick_path[PATH_MAX] = {0, };
- struct stat statbuf = {0, };
- runner_t runner = {0, };
- char msg[1024] = {0, };
-
+ int32_t ret = -1;
+ xlator_t *this = NULL;
+ glusterd_conf_t *priv = NULL;
+ char *snap_brick_dir = NULL;
+ char snap_brick_mount_path[PATH_MAX] = "";
+ char *tmp = NULL;
+ char snap_brick_path[PATH_MAX] = "";
+ char msg[1024] = "";
+ char *mnt_pt = NULL;
+ struct mntent *entry = NULL;
+ FILE *mtab = NULL;
+ struct stat statbuf = {0, };
+ runner_t runner = {0, };
this = THIS;
priv = this->private;
@@ -3077,8 +3097,16 @@ glusterd_do_snap (glusterd_volinfo_t *volinfo, char *snapname, dict_t *dict,
GF_ASSERT (cg_name);
ret = glusterd_volinfo_dup (volinfo, &snap_volume);
- strncpy (snap_volume->volname, snapname,
- sizeof(snap_volume->volname) - 1);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Failed to duplicate volinfo "
+ "for the snapshot %s", snapname);
+ goto out;
+ }
+
+ /* snap uuid is used as lvm snapshot name.
+ This will avoid restrictions on snapshot names provided by user */
+ GLUSTERD_GET_UUID_NOHYPHEN (snap_volume->volname, snap_volid);
+
snap_volume->is_snap_volume = _gf_true;
strncpy (snap_volume->parent_volname, volinfo->volname,
sizeof(snap_volume->parent_volname) - 1);
@@ -3158,7 +3186,7 @@ glusterd_do_snap (glusterd_volinfo_t *volinfo, char *snapname, dict_t *dict,
ret = glusterd_take_snapshot (brickinfo,
volinfo->volname,
- snapname, &device);
+ snap_volume->volname, &device);
/* Fail the snapshot even though snapshot on one of
the bricks fails. At the end when we check whether
the snapshot volume meets quorum or not, then the
@@ -3190,8 +3218,8 @@ glusterd_do_snap (glusterd_volinfo_t *volinfo, char *snapname, dict_t *dict,
ret = dict_get_str (dict, "snap-description", &description);
// for now continue the snap, if getting description fails.
- ret = glusterd_snap_create (volinfo, snap_volume, description, cg_id,
- cg, cg_name);
+ ret = glusterd_snap_create (volinfo, snap_volume, snapname,
+ description, cg_id, cg, cg_name);
if (ret) {
gf_log (this->name, GF_LOG_ERROR, "creating the"
"snap object failed for the volume %s",
diff --git a/xlators/mgmt/glusterd/src/glusterd-store.c b/xlators/mgmt/glusterd/src/glusterd-store.c
index 56a6414..c02c2c6 100644
--- a/xlators/mgmt/glusterd/src/glusterd-store.c
+++ b/xlators/mgmt/glusterd/src/glusterd-store.c
@@ -1444,7 +1444,7 @@ glusterd_store_snap_volume (glusterd_volinfo_t *volinfo, glusterd_snap_t *snap)
goto unlock;
ret = glusterd_store_create_snap_vol_dir (volinfo,
- snap->snap_name);
+ snap_volinfo->volname);
if (ret) {
gf_log (THIS->name, GF_LOG_ERROR,
"Failed create snapshot dir (%s) for volume "
@@ -2843,7 +2843,7 @@ glusterd_store_update_volinfo (glusterd_volinfo_t *volinfo,
goto out;
}
- GLUSTERD_GET_SNAP_DIR (volpath, parent_vol, snap->snap_name,
+ GLUSTERD_GET_SNAP_DIR (volpath, parent_vol, volinfo->volname,
conf);
} else {
GLUSTERD_GET_VOLUME_DIR(volpath, volinfo, conf);
@@ -3075,8 +3075,10 @@ glusterd_store_retrieve_volume (char *volname, glusterd_snap_t *snap)
ret = glusterd_volinfo_find (volname, &parent_vol);
if (ret)
goto out;
- strncpy (volinfo->volname, snap->snap_name, GLUSTERD_MAX_VOLUME_NAME);
- GLUSTERD_GET_SNAP_DIR (volpath, parent_vol, snap->snap_name, priv);
+ GLUSTERD_GET_UUID_NOHYPHEN(volinfo->volname,
+ snap->snap_id);
+ GLUSTERD_GET_SNAP_DIR (volpath, parent_vol, volinfo->volname,
+ priv);
strncpy (volinfo->parent_volname, volname, GLUSTERD_MAX_VOLUME_NAME);
} else {
strncpy (volinfo->volname, volname, GLUSTERD_MAX_VOLUME_NAME);
diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h
index 8997e75..27ebbbb 100644
--- a/xlators/mgmt/glusterd/src/glusterd.h
+++ b/xlators/mgmt/glusterd/src/glusterd.h
@@ -528,6 +528,20 @@ typedef ssize_t (*gd_serialize_t) (struct iovec outmsg, void *args);
uuid_utoa(MY_UUID)); \
} while (0)
+#define GLUSTERD_GET_UUID_NOHYPHEN(ret_string, uuid) do { \
+ char *snap_volname_ptr = ret_string; \
+ char *snap_volid_ptr = uuid_utoa(uuid); \
+ while (*snap_volid_ptr) { \
+ if (*snap_volid_ptr == '-') { \
+ snap_volid_ptr++; \
+ } else { \
+ (*snap_volname_ptr++) = \
+ (*snap_volid_ptr++); \
+ } \
+ } \
+ *snap_volname_ptr = '\0'; \
+ } while (0)
+
int glusterd_uuid_init();
int glusterd_uuid_generate_save ();