summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRajesh Joseph <rjoseph@redhat.com>2014-07-01 20:25:04 +0530
committerVijay Bellur <vbellur@redhat.com>2014-07-03 06:53:12 -0700
commitdedef037d64fef59d74b9861562aa7f93857a53e (patch)
treee3ed0c288cfac75f0ece3f10a64bfa63bbb9a431
parent3df72ddcdb371c441b5535ad802fc59a794e3ac9 (diff)
glusterd/snapshot: Change file-system uuid to file-system label
Problem: In XFS changing file-system UUID with xfs_admin is causing too much delay with large file-system. The time taken by xfs_admin tool to change UUID is directly proportional to the size of the file system. Cause: In XFS file-system UUID is stored in file-system superblock. Therefore for chaning UUID all the superblock needs to be changed. Fix: Instead of using file-system UUID use file-system label. Change-Id: Ifb4c668fb29cfc1c89d9b221abc8d09dc09589ec BUG: 1115107 Signed-off-by: Rajesh Joseph <rjoseph@redhat.com> Reviewed-on: http://review.gluster.org/8215 Reviewed-by: Atin Mukherjee <amukherj@redhat.com> Reviewed-by: Avra Sengupta <asengupt@redhat.com> Reviewed-by: Vijay Bellur <vbellur@redhat.com> Tested-by: Vijay Bellur <vbellur@redhat.com>
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-handshake.c12
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-snapshot.c140
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-store.c23
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-store.h1
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.c44
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.h5
6 files changed, 129 insertions, 96 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-handshake.c b/xlators/mgmt/glusterd/src/glusterd-handshake.c
index 0fd60806da2..7d582d443f4 100644
--- a/xlators/mgmt/glusterd/src/glusterd-handshake.c
+++ b/xlators/mgmt/glusterd/src/glusterd-handshake.c
@@ -454,16 +454,16 @@ glusterd_create_missed_snap (glusterd_missed_snap_info *missed_snapinfo,
}
/* After the snapshot both the origin brick (LVM brick) and
- * the snapshot brick will have the same file-system UUID. This
+ * the snapshot brick will have the same file-system label. This
* will cause lot of problems at mount time. Therefore we must
- * generate a new UUID for the snapshot brick
+ * generate a new label for the snapshot brick
*/
- ret = glusterd_update_fs_uuid (brickinfo);
+ ret = glusterd_update_fs_label (brickinfo);
if (ret) {
gf_log (this->name, GF_LOG_ERROR, "Failed to update "
- "file-system uuid for %s brick", brickinfo->path);
- /* Failing to update UUID should not cause snapshot failure.
- * Currently UUID is updated only for XFS and ext2/ext3/ext4
+ "file-system label for %s brick", brickinfo->path);
+ /* Failing to update label should not cause snapshot failure.
+ * Currently label is updated only for XFS and ext2/ext3/ext4
* file-system.
*/
}
diff --git a/xlators/mgmt/glusterd/src/glusterd-snapshot.c b/xlators/mgmt/glusterd/src/glusterd-snapshot.c
index c1ddc0849cc..7678d77b3d5 100644
--- a/xlators/mgmt/glusterd/src/glusterd-snapshot.c
+++ b/xlators/mgmt/glusterd/src/glusterd-snapshot.c
@@ -971,6 +971,17 @@ glusterd_snapshot_restore_prevalidate (dict_t *dict, char **op_errstr,
"Failed to set %s", key);
goto out;
}
+
+ snprintf (key, sizeof (key),
+ "snap%d.brick%d.fs_type",
+ volcount, brick_count);
+ ret = dict_set_str (rsp_dict, key,
+ brickinfo->fstype);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to set %s", key);
+ goto out;
+ }
}
snprintf (key, sizeof (key), "snap%d.brick_count", volcount);
@@ -1466,6 +1477,21 @@ glusterd_snap_restore_use_rsp_dict (dict_t *dst, dict_t *src)
"Failed to set %s", key);
goto out;
}
+
+ snprintf (key, sizeof (key),
+ "snap%d.brick%d.fs_type", i, j);
+ ret = dict_get_str (src, key, &strvalue);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to get %s", key);
+ goto out;
+ }
+ ret = dict_set_dynstr_with_alloc (dst, key, strvalue);
+ if (ret) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Failed to set %s", key);
+ goto out;
+ }
}
}
@@ -3725,7 +3751,8 @@ glusterd_snap_brick_create (glusterd_volinfo_t *snap_volinfo,
But for now, mounting using runner apis.
*/
ret = glusterd_mount_lvm_snapshot (brickinfo->device_path,
- snap_brick_mount_path);
+ snap_brick_mount_path,
+ brickinfo->fstype);
if (ret) {
gf_log (this->name, GF_LOG_ERROR,
"Failed to mount lvm snapshot.");
@@ -3978,7 +4005,7 @@ out:
return ret;
}
-/* This function will update the file-system UUID of the
+/* This function will update the file-system label of the
* backend snapshot brick.
*
* @param brickinfo brickinfo of the snap volume
@@ -3986,14 +4013,11 @@ out:
* @return 0 on success and -1 on failure
*/
int
-glusterd_update_fs_uuid (glusterd_brickinfo_t *brickinfo)
+glusterd_update_fs_label (glusterd_brickinfo_t *brickinfo)
{
int32_t ret = -1;
char msg [PATH_MAX] = "";
- char uuid_str [NAME_MAX] = "";
- char template [] = "/tmp/xfsmountXXXXXX";
- char *mount_path = NULL;
- char *cmd = NULL;
+ char label [NAME_MAX] = "";
uuid_t uuid = {0,};
runner_t runner = {0,};
xlator_t *this = NULL;
@@ -4005,82 +4029,39 @@ glusterd_update_fs_uuid (glusterd_brickinfo_t *brickinfo)
/* Generate a new UUID */
uuid_generate (uuid);
- if (NULL == uuid_utoa_r (uuid, uuid_str)) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to convert "
- "uuid to string for %s brick", brickinfo->path);
- goto out;
- }
+ GLUSTERD_GET_UUID_NOHYPHEN (label, uuid);
runinit (&runner);
- snprintf (msg, sizeof (msg), "Changing filesystem uuid of %s brick to "
- "%s", brickinfo->path, uuid_str);
/* Call the file-system specific tools to update the file-system
- * UUID. Currently we are only supporting xfs and ext2/ext3/ext4
+ * label. Currently we are only supporting xfs and ext2/ext3/ext4
* file-system.
*/
if (0 == strcmp (brickinfo->fstype, "xfs")) {
- /* TODO: xfs_admin tool is used to replace the file-system
- * UUID. As of now the tool is failing with error when trying
- * to replace the UUID. Therefore as a workaround we mount
- * the file-system to a temporary location and then unmount
- * it.
- * After this xfs_admin tool works fine.
- */
- mount_path = mkdtemp (template);
- if (NULL == mount_path) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to create "
- "temporary folder. Error: %s",
- strerror (errno));
- runner_end (&runner);
- goto out;
- }
-
- /* First we mount the brick to a temporary path. Please
- * note that we are using "nouuid" option here because
- * both the origin volume brick and this brick will have
- * the same UUID. And XFS does not allow us to mount a
- * file-system which is sharing the UUID with any other
- * file-system on the system.
- */
-#ifdef GF_LINUX_HOST_OS
- ret = mount (brickinfo->device_path, mount_path,
- brickinfo->fstype, 0, "nouuid");
-#else
- ret = -1;
-#endif
-
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to mount "
- "%s at %s", brickinfo->device_path,
- mount_path);
- runner_end (&runner);
- goto out;
- }
-
- /* Now unmount the brick. */
- ret = glusterd_umount (mount_path);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to unmount "
- "%s from %s", brickinfo->device_path,
- mount_path);
- runner_end (&runner);
- goto out;
- }
-
- /* Now we are ready to run xfs_admin tool */
- runner_add_args (&runner, "xfs_admin", "-U", uuid_str,
+ /* XFS label is of size 12. Therefore we should truncate the
+ * label to 12 bytes*/
+ label [12] = '\0';
+ snprintf (msg, sizeof (msg), "Changing filesystem label of "
+ "%s brick to %s", brickinfo->path, label);
+ /* Run the run xfs_admin tool to change the label
+ * of the file-system */
+ runner_add_args (&runner, "xfs_admin", "-L", label,
brickinfo->device_path, NULL);
} else if (0 == strcmp (brickinfo->fstype, "ext4") ||
0 == strcmp (brickinfo->fstype, "ext3") ||
0 == strcmp (brickinfo->fstype, "ext2")) {
+ /* Ext2/Ext3/Ext4 label is of size 16. Therefore we should
+ * truncate the label to 16 bytes*/
+ label [16] = '\0';
+ snprintf (msg, sizeof (msg), "Changing filesystem label of "
+ "%s brick to %s", brickinfo->path, label);
/* For ext2/ext3/ext4 run tune2fs to change the
- * file-system UUID */
- runner_add_args (&runner, "tune2fs", "-U", uuid_str,
+ * file-system label */
+ runner_add_args (&runner, "tune2fs", "-L", label,
brickinfo->device_path, NULL);
} else {
gf_log (this->name, GF_LOG_WARNING, "Changing file-system "
- "UUID of %s file-system is not supported as of now",
+ "label of %s file-system is not supported as of now",
brickinfo->fstype);
runner_end (&runner);
ret = -1;
@@ -4091,20 +4072,13 @@ glusterd_update_fs_uuid (glusterd_brickinfo_t *brickinfo)
ret = runner_run (&runner);
if (ret) {
gf_log (this->name, GF_LOG_ERROR, "Failed to change "
- "filesystem uuid of %s brick to %s",
- brickinfo->path, uuid_str);
+ "filesystem label of %s brick to %s",
+ brickinfo->path, label);
goto out;
}
ret = 0;
out:
- if (NULL != mount_path) {
- if (rmdir (mount_path)) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to remove "
- "temporary folder %s. Error: %s",
- mount_path, strerror (errno));
- }
- }
return ret;
}
@@ -4148,16 +4122,16 @@ glusterd_take_brick_snapshot (dict_t *dict, glusterd_volinfo_t *snap_vol,
}
/* After the snapshot both the origin brick (LVM brick) and
- * the snapshot brick will have the same file-system UUID. This
+ * the snapshot brick will have the same file-system label. This
* will cause lot of problems at mount time. Therefore we must
- * generate a new UUID for the snapshot brick
+ * generate a new label for the snapshot brick
*/
- ret = glusterd_update_fs_uuid (brickinfo);
+ ret = glusterd_update_fs_label (brickinfo);
if (ret) {
gf_log (this->name, GF_LOG_ERROR, "Failed to update "
- "file-system uuid for %s brick", brickinfo->path);
- /* Failing to update UUID should not cause snapshot failure.
- * Currently UUID is updated only for XFS and ext2/ext3/ext4
+ "file-system label for %s brick", brickinfo->path);
+ /* Failing to update label should not cause snapshot failure.
+ * Currently label is updated only for XFS and ext2/ext3/ext4
* file-system.
*/
}
diff --git a/xlators/mgmt/glusterd/src/glusterd-store.c b/xlators/mgmt/glusterd/src/glusterd-store.c
index e03ec7af9f5..c31d8a8ad71 100644
--- a/xlators/mgmt/glusterd/src/glusterd-store.c
+++ b/xlators/mgmt/glusterd/src/glusterd-store.c
@@ -325,6 +325,17 @@ gd_store_brick_snap_details_write (int fd, glusterd_brickinfo_t *brickinfo)
goto out;
}
+ if (strlen (brickinfo->fstype) > 0) {
+ snprintf (value, sizeof (value), "%s", brickinfo->fstype);
+ ret = gf_store_save_value (fd,
+ GLUSTERD_STORE_KEY_BRICK_FSTYPE, value);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Failed to save "
+ "brick fs type of brick %s", brickinfo->path);
+ goto out;
+ }
+ }
+
memset (value, 0, sizeof (value));
snprintf (value, sizeof(value), "%d", brickinfo->snap_status);
ret = gf_store_save_value (fd, GLUSTERD_STORE_KEY_BRICK_SNAP_STATUS,
@@ -2272,6 +2283,10 @@ glusterd_store_retrieve_bricks (glusterd_volinfo_t *volinfo)
} else if (!strncmp (key, GLUSTERD_STORE_KEY_BRICK_SNAP_STATUS,
strlen (GLUSTERD_STORE_KEY_BRICK_SNAP_STATUS))) {
gf_string2int (value, &brickinfo->snap_status);
+ } else if (!strncmp (key, GLUSTERD_STORE_KEY_BRICK_FSTYPE,
+ strlen (GLUSTERD_STORE_KEY_BRICK_FSTYPE))) {
+ strncpy (brickinfo->fstype, value,
+ sizeof (brickinfo->fstype));
} else if (!strncmp (key,
GLUSTERD_STORE_KEY_BRICK_VGNAME,
strlen (GLUSTERD_STORE_KEY_BRICK_VGNAME))) {
@@ -3086,7 +3101,8 @@ out:
* at the brick_mount_path
*/
int32_t
-glusterd_mount_brick_paths (char *brick_mount_path, char *device_path)
+glusterd_mount_brick_paths (char *brick_mount_path, char *device_path,
+ const char *fstype)
{
int32_t ret = -1;
runner_t runner = {0, };
@@ -3134,7 +3150,8 @@ glusterd_mount_brick_paths (char *brick_mount_path, char *device_path)
"Activating %s successful", device_path);
/* Mount the snapshot */
- ret = glusterd_mount_lvm_snapshot (device_path, brick_mount_path);
+ ret = glusterd_mount_lvm_snapshot (device_path, brick_mount_path,
+ fstype);
if (ret) {
gf_log (this->name, GF_LOG_ERROR,
"Failed to mount lvm snapshot.");
@@ -3208,7 +3225,7 @@ glusterd_recreate_vol_brick_mounts (xlator_t *this,
/* Check if brick_mount_path is already mounted.
* If not, mount the device_path at the brick_mount_path */
ret = glusterd_mount_brick_paths (brick_mount_path,
- brickinfo->device_path);
+ brickinfo->device_path, brickinfo->fstype);
if (ret) {
gf_log (this->name, GF_LOG_ERROR,
"Failed to mount brick_mount_path");
diff --git a/xlators/mgmt/glusterd/src/glusterd-store.h b/xlators/mgmt/glusterd/src/glusterd-store.h
index 4c0f0d42321..89cf24de789 100644
--- a/xlators/mgmt/glusterd/src/glusterd-store.h
+++ b/xlators/mgmt/glusterd/src/glusterd-store.h
@@ -82,6 +82,7 @@ typedef enum glusterd_store_ver_ac_{
#define GLUSTERD_STORE_KEY_BRICK_DEVICE_PATH "device_path"
#define GLUSTERD_STORE_KEY_BRICK_MOUNT_DIR "mount_dir"
#define GLUSTERD_STORE_KEY_BRICK_SNAP_STATUS "snap-status"
+#define GLUSTERD_STORE_KEY_BRICK_FSTYPE "fs-type"
#define GLUSTERD_STORE_KEY_BRICK_ID "brick-id"
#define GLUSTERD_STORE_KEY_PEER_UUID "uuid"
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
index 6b973a3638d..02b2ba923e5 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
@@ -612,6 +612,7 @@ glusterd_brickinfo_dup (glusterd_brickinfo_t *brickinfo,
strcpy (dup_brickinfo->hostname, brickinfo->hostname);
strcpy (dup_brickinfo->path, brickinfo->path);
strcpy (dup_brickinfo->device_path, brickinfo->device_path);
+ strcpy (dup_brickinfo->fstype, brickinfo->fstype);
ret = gf_canonicalize_path (dup_brickinfo->path);
if (ret) {
gf_log (THIS->name, GF_LOG_ERROR, "Failed to canonicalize "
@@ -710,6 +711,13 @@ glusterd_snap_volinfo_restore (dict_t *dict, dict_t *rsp_dict,
strncpy (new_brickinfo->device_path, value,
sizeof(new_brickinfo->device_path));
+ snprintf (key, sizeof (key), "snap%d.brick%d.fs_type",
+ volcount, brick_count);
+ ret = dict_get_str (dict, key, &value);
+ if (!ret)
+ strncpy (new_brickinfo->fstype, value,
+ sizeof(new_brickinfo->fstype));
+
/* If the brick is not of this peer, or snapshot is missed *
* for the brick do not replace the xattr for it */
if ((!uuid_compare (brickinfo->uuid, MY_UUID)) &&
@@ -2363,6 +2371,15 @@ gd_add_brick_snap_details_to_dict (dict_t *dict, char *prefix,
goto out;
}
+ snprintf (key, sizeof (key), "%s.fs_type", prefix);
+ ret = dict_set_str (dict, key, brickinfo->fstype);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to set fstype for %s:%s",
+ brickinfo->hostname, brickinfo->path);
+ goto out;
+ }
+
memset (key, 0, sizeof (key));
snprintf (key, sizeof (key), "%s.mount_dir", prefix);
ret = dict_set_str (dict, key, brickinfo->mount_dir);
@@ -3695,6 +3712,7 @@ gd_import_new_brick_snap_details (dict_t *dict, char *prefix,
glusterd_conf_t *conf = NULL;
char key[512] = {0,};
char *snap_device = NULL;
+ char *fs_type = NULL;
char *mount_dir = NULL;
this = THIS;
@@ -3727,6 +3745,14 @@ gd_import_new_brick_snap_details (dict_t *dict, char *prefix,
}
strcpy (brickinfo->device_path, snap_device);
+ snprintf (key, sizeof (key), "%s.fs_type", prefix);
+ ret = dict_get_str (dict, key, &fs_type);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "%s missing in payload", key);
+ goto out;
+ }
+ strcpy (brickinfo->fstype, fs_type);
+
memset (key, 0, sizeof (key));
snprintf (key, sizeof (key), "%s.mount_dir", prefix);
ret = dict_get_str (dict, key, &mount_dir);
@@ -12206,7 +12232,8 @@ glusterd_compare_volume_name(struct list_head *list1, struct list_head *list2)
}
int32_t
-glusterd_mount_lvm_snapshot (char *device_path, char *brick_mount_path)
+glusterd_mount_lvm_snapshot (char *device_path, char *brick_mount_path,
+ const char *fstype)
{
char msg[NAME_MAX] = "";
int32_t ret = -1;
@@ -12222,7 +12249,20 @@ glusterd_mount_lvm_snapshot (char *device_path, char *brick_mount_path)
runinit (&runner);
snprintf (msg, sizeof (msg), "mount %s %s",
device_path, brick_mount_path);
- runner_add_args (&runner, "mount", device_path, brick_mount_path, NULL);
+
+ /* XFS file-system does not allow to mount file-system with duplicate
+ * UUID. File-system UUID of snapshot and its origin volume is same.
+ * Therefore to mount such a snapshot in XFS we need to pass nouuid
+ * option
+ */
+ if (!strcmp (fstype, "xfs")) {
+ runner_add_args (&runner, "mount", "-o", "nouuid",
+ device_path, brick_mount_path, NULL);
+ } else {
+ runner_add_args (&runner, "mount", device_path,
+ brick_mount_path, NULL);
+ }
+
runner_log (&runner, this->name, GF_LOG_DEBUG, msg);
ret = runner_run (&runner);
if (ret) {
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h
index 3edb0c55db4..8d3af0689fd 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.h
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.h
@@ -757,7 +757,8 @@ gd_restore_snap_volume (dict_t *dict, dict_t *rsp_dict,
int32_t volcount);
int32_t
-glusterd_mount_lvm_snapshot (char *device_path, char *brick_mount_path);
+glusterd_mount_lvm_snapshot (char *device_path, char *brick_mount_path,
+ const char *fstype);
int32_t
glusterd_umount (const char *path);
@@ -926,6 +927,6 @@ glusterd_update_fstype (char *orig_brick_path,
char *fstype, size_t fslen);
int
-glusterd_update_fs_uuid (glusterd_brickinfo_t *brickinfo);
+glusterd_update_fs_label (glusterd_brickinfo_t *brickinfo);
#endif