[gparted] Detect busy status of Linux Software RAID members (#709640)



commit d2e1130ad22eb3f52db4dc7f645ed4d5bf119d24
Author: Mike Fleetwood <mike fleetwood googlemail com>
Date:   Mon Oct 7 23:37:31 2013 +0100

    Detect busy status of Linux Software RAID members (#709640)
    
    Read the contents of /proc/mdstat file to determine if a device is a
    member of of an active RAID array.
    
        $ cat /proc/mdstat
        Personalities : [raid1]
        md1 : active raid1 sda1[2] sdb1[3]
              524224 blocks super 1.0 [2/2] [UU]
    
        md2 : active raid1 sdb2[2] sda2[3](F)
              5238720 blocks super 1.1 [2/1] [U_]
    
        md3 : active raid1 sdb3[1]
              10477440 blocks super 1.1 [2/1] [_U]
              bitmap: 1/1 pages [4KB], 65536KB chunk
    
        md4 : inactive sda4[0](S)
              1048564 blocks super 1.2
    
        unused devices: <none>
    
    There are 5 example Linux Software RAID arrays, md1 to md5.  All are
    RAID1 mirrors with 2 members, in various states.
    
        Array  Members     Status
        md1    sda1, sdb2  Fully operational.
        md2    sda2, sdb2  Member sda2 marked as faulty.  (Device sda2 is
                           still in use).
        md3    sda3, sdb3  Member sda3 has been removed.  (Device sda3 is
                           not in use).
        md4    sda4, sdb4  Incremental start of member sda4 only.  (Neither
                           member devices is in use).
        md5    sda5, sdb5  Array stopped.  (Neither member device is in
                           use).
    
    Also disable "Unmount" in the partition menu for active RAID array
    members.
    
    Bug #709640 - Linux Swap Suspend and Software RAID partitions not
                  recognised

 include/Utils.h     |    1 +
 src/GParted_Core.cc |    5 +++--
 src/Utils.cc        |   33 +++++++++++++++++++++++++++++++++
 src/Win_GParted.cc  |    3 ++-
 4 files changed, 39 insertions(+), 3 deletions(-)
---
diff --git a/include/Utils.h b/include/Utils.h
index a768283..86335f7 100644
--- a/include/Utils.h
+++ b/include/Utils.h
@@ -168,6 +168,7 @@ public:
        static Glib::ustring get_filesystem_software( FILESYSTEM filesystem ) ;
        static bool kernel_supports_fs( const Glib::ustring & fs ) ;
        static bool kernel_version_at_least( int major_ver, int minor_ver, int patch_ver ) ;
+       static bool swraid_member_is_active( const Glib::ustring & path ) ;
        static Glib::ustring format_size( Sector sectors, Byte_Value sector_size ) ;
        static Glib::ustring format_time( std::time_t seconds ) ;
        static double sector_to_unit( Sector sectors, Byte_Value sector_size, SIZE_UNIT size_unit ) ;
diff --git a/src/GParted_Core.cc b/src/GParted_Core.cc
index 1959efa..dc19f5b 100644
--- a/src/GParted_Core.cc
+++ b/src/GParted_Core.cc
@@ -1051,8 +1051,9 @@ void GParted_Core::set_device_partitions( Device & device, PedDevice* lp_device,
                                }
                                else
 #endif
-                                       partition_is_busy = ped_partition_is_busy( lp_partition ) ||
-                                                           ( filesystem == GParted::FS_LVM2_PV && 
lvm2_pv_info .has_active_lvs( partition_path ) ) ;
+                                       partition_is_busy =    ped_partition_is_busy( lp_partition )
+                                                           || ( filesystem == FS_LVM2_PV      && 
lvm2_pv_info .has_active_lvs( partition_path ) )
+                                                           || ( filesystem == FS_LINUX_SWRAID && 
Utils::swraid_member_is_active( partition_path ) ) ;
 
                                partition_temp .Set( device .get_path(),
                                                     partition_path,
diff --git a/src/Utils.cc b/src/Utils.cc
index 2b30515..2b3ad4a 100644
--- a/src/Utils.cc
+++ b/src/Utils.cc
@@ -324,6 +324,39 @@ bool Utils::kernel_version_at_least( int major_ver, int minor_ver, int patch_ver
        return result ;
 }
 
+//Report whether the device is an active member of a Linux Software RAID array
+bool Utils::swraid_member_is_active( const Glib::ustring & path )
+{
+       //Read /proc/mdstat and look for the device name on an active RAID array
+       //  line.   Example line: "md1 : active raid1 sda1[2] sdb1[3]"
+       //                                           ^^^^^^
+       //                                           needle
+       //  Strip "/dev/" prefix and search for device name with surrounding
+       //  " " and "[" to avoid substring matches.
+       if ( path .substr( 0, 5 ) != "/dev/" )
+               return false ;
+
+       bool member_active = false ;
+       Glib::ustring needle = " " + path .substr( 5 ) + "[" ;
+       std::string line ;
+       std::ifstream input( "/proc/mdstat" ) ;
+       if ( input )
+       {
+               while ( getline( input, line ) )
+               {
+                       if (    line .find( " : active " ) != std::string::npos
+                            && line .find( needle ) != std::string::npos       )
+                       {
+                               member_active = true ;
+                               break ;
+                       }
+               }
+               input .close() ;
+       }
+
+       return member_active ;
+}
+
 Glib::ustring Utils::format_size( Sector sectors, Byte_Value sector_size )
 {
        std::stringstream ss ;
diff --git a/src/Win_GParted.cc b/src/Win_GParted.cc
index f34fe4f..8730776 100644
--- a/src/Win_GParted.cc
+++ b/src/Win_GParted.cc
@@ -967,10 +967,11 @@ void Win_GParted::set_valid_operations()
                                                                   : CTEXT_ACTIVATE_FILESYSTEM )
                                                                  ) ;
 
-       //Only permit mount/unmount, swapon/swapoff, ... if action is available
+       //Only permit mount/unmount, swapon/swapoff, activate/deactivate if action is available
        if (    selected_partition .status == GParted::STAT_REAL
             && selected_partition .type != GParted::TYPE_EXTENDED
             && selected_partition .filesystem != GParted::FS_LVM2_PV
+            && selected_partition .filesystem != FS_LINUX_SWRAID
             && (    selected_partition .busy
                  || selected_partition .get_mountpoints() .size() /* Have mount point(s) */
                  || selected_partition .filesystem == GParted::FS_LINUX_SWAP


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