[gparted] Add labelling of mounted xfs (#163)



commit 0c13855d5250f5565a8d3f4da943b63d55c13972
Author: Mike Fleetwood <mike fleetwood googlemail com>
Date:   Thu Jul 22 15:26:11 2021 +0100

    Add labelling of mounted xfs (#163)
    
    XFS also supports labelling of the file system while it is mounted.
    This was added into Linux kernel 4.18 [1] and xfsprogs 4.17.0 [2].
    These versions are newer than available in older but still supported
    distributions so we'll need to detect versions before enabling support.
    These are the oldest releases of distributions which meet the
    requirements.
    
        Distro             EOL        Linux kernel   xfsprogs
        Debian 10          2024-Jun   4.19.0         4.20.0
        RHEL 8             2029-May   4.18.0         5.0.0
        Ubuntu 20.04 LTS   2030-Apr   5.4            5.3.0
    
    As with btrfs a mounted XFS is labelled via it's mount point:
        # mkfs.xfs -L label_1 /dev/sdb2
        # mount /dev/sdb2 /mnt/2
        # xfs_io -c 'label -s mnt_label_2' /mnt/2
        label = "mnt_label_2"
        # blkid /dev/sdb2
        /dev/sdb2: LABEL="mnt_label_2" ...
    
    And cleared with:
        # xfs_io -c 'label -c' /mnt/2
        label = ""
    
    Note that in some error situations xfs_io reports exit status zero and
    writes the failure message to stdout.
        # xfs_io -c 'label -s "mnt label 3"' /mnt/2
        bad argument count 4 to label, expected between 0 and 3 arguments
        # echo $?
        0
    Therefore determine success based on stdout starting with 'label = "'
    reporting the new label or not.
    
    Also note that as seen in this failure case, it is not possible to set
    an XFS label which contains a space character using xfs_io.  However
    that is nothing new as that can't be done using the existing xfs_admin
    command for an unmounted XFS either.
        # umount /mnt/2
        # xfs_admin -L 'umnt label 4' /dev/sdb2
        Usage: xfs_admin [-efjlpuV] [-c 0|1] [-L label] [-U uuid] device
        # echo $?
        2
    
    [1] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f7664b31975bd893190708e76b2c424328f0c49b
        xfs: implement online get/set fs label
    [2] 
https://git.kernel.org/pub/scm/fs/xfs/xfsprogs-dev.git/commit/?id=cfa10b0f972005b38ed294bca66cebf2f65298ec
        xfs_io: add label command
    
    Closes #163 - Feature request: set label on a mounted btrfs

 src/xfs.cc | 45 +++++++++++++++++++++++++++++++++++++++------
 1 file changed, 39 insertions(+), 6 deletions(-)
---
diff --git a/src/xfs.cc b/src/xfs.cc
index 3a4dc695..7f40bc6f 100644
--- a/src/xfs.cc
+++ b/src/xfs.cc
@@ -48,6 +48,15 @@ FS xfs::get_filesystem_support()
                fs .write_uuid = FS::EXTERNAL ;
        }
 
+       if (! Glib::find_program_in_path("xfs_io").empty())
+       {
+               // Check for online label support in xfs_io from xfsprogs >= 4.17 and
+               // for kernel >= 4.18 before enabling support.
+               Utils::execute_command("xfs_io -c help", output, error, true);
+               if (output.find("\nlabel") < output.length() && Utils::kernel_version_at_least(4, 18, 0))
+                       fs.online_write_label = FS::EXTERNAL;
+       }
+
        if ( ! Glib::find_program_in_path( "mkfs.xfs" ) .empty() )
        {
                fs.create = FS::EXTERNAL;
@@ -147,17 +156,41 @@ void xfs::read_label( Partition & partition )
        }
 }
 
+
 bool xfs::write_label( const Partition & partition, OperationDetail & operationdetail )
 {
-       Glib::ustring cmd = "" ;
-       if( partition.get_filesystem_label().empty() )
-               cmd = "xfs_admin -L -- " + Glib::shell_quote( partition.get_path() );
+       Glib::ustring cmd;
+       bool empty_label = partition.get_filesystem_label().empty();
+
+       if (partition.busy)
+       {
+               if (empty_label)
+                       cmd = "xfs_io -c " + Glib::shell_quote("label -c") + " " + partition.get_mountpoint();
+               else
+                       cmd = "xfs_io -c " + Glib::shell_quote("label -s " + 
partition.get_filesystem_label()) +
+                             " " + partition.get_mountpoint();
+
+               execute_command(cmd, operationdetail);
+               // In a some error situations xfs_io reports exit status zero but writes a
+               // failure message to stdout.  Therefore determine success based on the
+               // output starting with the fixed text, reporting the new label.
+               bool success = output.compare(0, 9, "label = \"") == 0;
+               set_status(operationdetail, success);
+               return success;
+       }
        else
-               cmd = "xfs_admin -L " + Glib::shell_quote( partition.get_filesystem_label() ) +
-                     " " + partition.get_path();
-       return ! execute_command( cmd, operationdetail, EXEC_CHECK_STATUS );
+       {
+               if (empty_label)
+                       cmd = "xfs_admin -L -- " + Glib::shell_quote(partition.get_path());
+               else
+                       cmd = "xfs_admin -L " + Glib::shell_quote(partition.get_filesystem_label()) +
+                             " " + partition.get_path();
+
+               return ! execute_command(cmd, operationdetail, EXEC_CHECK_STATUS);
+       }
 }
 
+
 void xfs::read_uuid( Partition & partition )
 {
        if ( ! Utils::execute_command( "xfs_admin -u " + Glib::shell_quote( partition.get_path() ),


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]