summaryrefslogtreecommitdiffstats
path: root/xlators/mgmt/glusterd/src/glusterd-snapshot.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/mgmt/glusterd/src/glusterd-snapshot.c')
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-snapshot.c154
1 files changed, 91 insertions, 63 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot.c b/xlators/mgmt/glusterd/src/glusterd-snapshot.c
index b33be0982..e886f4b55 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",