Copy XFS UUID when copying the file system (!85)

For the same reason as in the previous commit, the UUID is copied when
copying every file system type except for XFS, where a new XFS is
created with a new UUID.

Again preview of the copy operation expects the UUID to be copied.
(Look in Partition > Information of the source and pasted partitions
before the operation is applied).

Fix as before by specifying the desired file system UUID when creating
the new XFS as part of the copy operation.

However there is an extra complication.  The XFS kernel driver refuses
to mount a file system with a duplicate UUID of an already mounted XFS.

    # mkfs.xfs -L xfs_copy /dev/sdb1
    # mount /dev/sdb1 /mnt/1
    # tail -2 /var/log/messages
    Jun  3 21:41:24 localhost kernel: XFS (sdb1): Mounting V5 Filesystem
    Jun  3 21:41:24 localhost kernel: XFS (sdb1): Ending clean mount

    # /dev/sdb1: LABEL="xfs_copy" UUID="d654fc7f-e417-4ec6-88e8-8a7d0d46b7d8" TYPE="xfs"
    # mkfs.xfs -L xfs_copy -m uuid="d654fc7f-e417-4ec6-88e8-8a7d0d46b7d8" /dev/sdb2
    # mount /dev/sdb2 /mnt/2
    mount: wrong fs type, bad option, bad superblock on /dev/sdb2,
           missing codepage or helper program, or other error.

           In some cases useful info is found in syslog - try
           dmesg | tail or so.
    # echo $?
    32
    # tail -1 /var/log/messages
    Jun  3 21:41:31 localhost kernel: XFS (sdb2): File system has duplicate UUID d654fc7f-e417-4ec6-88e8-8a7d0d46b7d8 - can't mount

Handle this specifying the needed option [1] when mounting the second
XFS during the copy.

    # mount -o nouuid /dev/sdb2 /mnt/2
    # mount | grep /dev/sdb
    /dev/sdb1 on /mnt/1 type xfs (rw,relatime,seclabel,attr2,inode64,noquota)
    /dev/sdb1 on /mnt/1 type xfs (rw,relatime,seclabel,nouuid,attr2,inode64,noquota)

Duplicating the UUID may seem troublesome, but it is being done:
1.  To make the GParted copied XFS be as much a clone as possible, to
    match what is does with other file systems.
2.  It has a valid use case; of cloning a Linux installation to a new
    drive or restoring a partition image backup.  In these cases it is
    much simpler if the UUID of the copy remains the same because it
    avoids having to edit GRUB2 configuration and fstab file system
    mounting which is nearly always done via UUID.
3.  GParted has the new UUID operation, to change the UUID for cases
    when a copied file system needs to be mounted at the same time as
    the source.

[1] xfs(5) - xfs - layout, mount options, and supported file attributes
    for the XFS filesystem
    https://man7.org/linux/man-pages/man5/xfs.5.html
    "MOUNT OPTIONS
    ...
    nouuid Don't check for double mounted file systems using the file
           system uuid.
    "

Closes !85 - Make XFS copy duplicate the file system label and UUID
This commit is contained in:
Mike Fleetwood 2021-06-03 21:33:33 +01:00 committed by Curtis Gedak
parent 36e43ed7a7
commit 39e7156697
1 changed files with 4 additions and 3 deletions

View File

@ -229,6 +229,7 @@ bool xfs::copy( const Partition & src_part,
bool success = true ; bool success = true ;
success &= ! execute_command("mkfs.xfs -f -L " + Glib::shell_quote(dest_part.get_filesystem_label()) + success &= ! execute_command("mkfs.xfs -f -L " + Glib::shell_quote(dest_part.get_filesystem_label()) +
" -m uuid=" + Glib::shell_quote(dest_part.uuid) +
" " + Glib::shell_quote(dest_part.get_path()), " " + Glib::shell_quote(dest_part.get_path()),
operationdetail, EXEC_CHECK_STATUS|EXEC_CANCEL_SAFE); operationdetail, EXEC_CHECK_STATUS|EXEC_CANCEL_SAFE);
if ( ! success ) if ( ! success )
@ -259,9 +260,9 @@ bool xfs::copy( const Partition & src_part,
if ( success ) if ( success )
{ {
success &= ! execute_command( "mount -v -t xfs " + Glib::shell_quote( dest_part.get_path() ) + success &= ! execute_command("mount -v -t xfs -o nouuid " + Glib::shell_quote(dest_part.get_path()) +
" " + Glib::shell_quote( dest_mount_point ), " " + Glib::shell_quote(dest_mount_point),
operationdetail, EXEC_CHECK_STATUS ); operationdetail, EXEC_CHECK_STATUS);
if ( success ) if ( success )
{ {