diff options
Diffstat (limited to 'xlators/mgmt/glusterd/src/glusterd-snapshot.c')
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-snapshot.c | 154 |
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", |