diff --git a/include/Makefile.am b/include/Makefile.am
index 4b00f1cc..4c308d9d 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -38,6 +38,7 @@ EXTRA_DIST = \
Partition.h \
PipeCapture.h \
Proc_Partitions_Info.h \
+ SWRaid_Info.h \
TreeView_Detail.h \
Utils.h \
Win_GParted.h \
diff --git a/include/SWRaid_Info.h b/include/SWRaid_Info.h
new file mode 100644
index 00000000..e59275eb
--- /dev/null
+++ b/include/SWRaid_Info.h
@@ -0,0 +1,49 @@
+/* Copyright (C) 2015 Mike Fleetwood
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see .
+ */
+
+
+/* SWRaid_Info
+ *
+ * Cache of information about Linux Software RAID arrays so that the
+ * mdadm command only needs to be executed once per refresh.
+ */
+
+#ifndef GPARTED_SWRAID_INFO_H
+#define GPARTED_SWRAID_INFO_H
+
+#include
+#include
+
+namespace GParted
+{
+
+class SWRaid_Info
+{
+public:
+ static void load_cache();
+ static bool is_member( const Glib::ustring & member_path );
+
+private:
+ static void set_command_found();
+ static void load_swraid_info_cache();
+
+ static bool mdadm_found;
+ static std::vector swraid_info_cache;
+};
+
+}//GParted
+
+#endif /* GPARTED_SWRAID_INFO_H */
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 38bf0f68..29741cf1 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -31,6 +31,7 @@ src/OperationLabelFileSystem.cc
src/OperationNamePartition.cc
src/OperationResizeMove.cc
src/Partition.cc
+src/SWRaid_Info.cc
src/TreeView_Detail.cc
src/Utils.cc
src/Win_GParted.cc
diff --git a/src/GParted_Core.cc b/src/GParted_Core.cc
index ee97efab..59c7c157 100644
--- a/src/GParted_Core.cc
+++ b/src/GParted_Core.cc
@@ -29,6 +29,7 @@
#include "../include/OperationLabelFileSystem.h"
#include "../include/OperationNamePartition.h"
#include "../include/Proc_Partitions_Info.h"
+#include "../include/SWRaid_Info.h"
#include "../include/btrfs.h"
#include "../include/exfat.h"
@@ -165,6 +166,7 @@ void GParted_Core::set_devices_thread( std::vector * pdevices )
DMRaid dmraid( true ) ; //Refresh cache of dmraid device information
LVM2_PV_Info::clear_cache(); // Cache automatically loaded if and when needed
btrfs::clear_cache(); // Cache incrementally loaded if and when needed
+ SWRaid_Info::load_cache();
init_maps() ;
@@ -1516,10 +1518,21 @@ FILESYSTEM GParted_Core::detect_filesystem( PedDevice * lp_device, PedPartition
static Glib::ustring luks_unsupported = _("Linux Unified Key Setup encryption is not yet supported.");
if ( lp_partition )
- {
+ // Will query partition using methods: (Q1) SWRaid, (Q2) libparted,
+ // (Q3) blkid, (Q4) internal
path = get_partition_path( lp_partition );
+ else
+ // Will query whole disk device using methods: (Q1) SWRaid, (Q3) blkid,
+ // (Q4) internal
+ path = lp_device->path;
- // Standard libparted file system detection
+ // (Q1) Linux Software RAID member detection
+ if ( SWRaid_Info::is_member( path ) )
+ return FS_LINUX_SWRAID;
+
+ if ( lp_partition )
+ {
+ // (Q2) Standard libparted file system detection
if ( lp_partition->fs_type )
{
fsname = lp_partition->fs_type->name;
@@ -1531,14 +1544,10 @@ FILESYSTEM GParted_Core::detect_filesystem( PedDevice * lp_device, PedPartition
fsname = temp;
}
}
- else
- {
- // Querying whole disk device instead of libparted PedPartition
- path = lp_device->path;
- }
- //FS_Info (blkid) file system detection because current libparted (v2.2) does not
- // appear to detect file systems for sector sizes other than 512 bytes.
+ // (Q3) FS_Info (blkid) file system detection
+ // Originally just because libparted v2.2 didn't appear to detect file system for
+ // sector sizes other than 512 bytes. Now to also detect what libparted doesn't.
if ( fsname.empty() )
{
//TODO: blkid does not return anything for an "extended" partition. Need to handle this somehow
@@ -1609,7 +1618,7 @@ FILESYSTEM GParted_Core::detect_filesystem( PedDevice * lp_device, PedPartition
return FS_ZFS;
}
- // Fallback to GParted simple internal file system detection
+ // (Q4) Fallback to GParted simple internal file system detection
FILESYSTEM fstype = detect_filesystem_internal( lp_device, lp_partition );
if ( fstype == FS_LUKS )
messages.push_back( luks_unsupported );
diff --git a/src/Makefile.am b/src/Makefile.am
index cd11213d..0d9cd362 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -49,6 +49,7 @@ gpartedbin_SOURCES = \
Partition.cc \
PipeCapture.cc \
Proc_Partitions_Info.cc \
+ SWRaid_Info.cc \
TreeView_Detail.cc \
Utils.cc \
Win_GParted.cc \
diff --git a/src/SWRaid_Info.cc b/src/SWRaid_Info.cc
new file mode 100644
index 00000000..5a367918
--- /dev/null
+++ b/src/SWRaid_Info.cc
@@ -0,0 +1,124 @@
+/* Copyright (C) 2015 Mike Fleetwood
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see .
+ */
+
+#include "../include/SWRaid_Info.h"
+
+#include "../include/Utils.h"
+
+#include
+
+namespace GParted
+{
+
+// Data model:
+// mdadm_found - Is the "mdadm" command available?
+// swraid_info_cache - Vector of /dev entries of members in Linux Software RAID arrays.
+// E.g.
+// ["/dev/sda1", "/dev/sda2", ...]
+
+// Initialise static data elements
+bool SWRaid_Info::mdadm_found = false;
+std::vector SWRaid_Info::swraid_info_cache;
+
+void SWRaid_Info::load_cache()
+{
+ set_command_found();
+ load_swraid_info_cache();
+}
+
+bool SWRaid_Info::is_member( const Glib::ustring & member_path )
+{
+ for ( unsigned int i = 0 ; i < swraid_info_cache.size() ; i ++ )
+ if ( member_path == swraid_info_cache[i] )
+ return true;
+
+ return false;
+}
+
+// Private methods
+
+void SWRaid_Info::set_command_found()
+{
+ mdadm_found = ! Glib::find_program_in_path( "mdadm" ).empty();
+}
+
+void SWRaid_Info::load_swraid_info_cache()
+{
+ Glib::ustring output, error;
+
+ swraid_info_cache.clear();
+
+ if ( ! mdadm_found )
+ return;
+
+ // Load SWRaid members into the cache.
+ Glib::ustring cmd = "mdadm --examine --scan --verbose";
+ if ( ! Utils::execute_command( cmd, output, error, true ) )
+ {
+ // Extract member /dev entries from Linux Software RAID arrays only,
+ // excluding IMSM and DDF arrays. Example output:
+ // ARRAY metadata=imsm UUID=...
+ // devices=/dev/sdd,/dev/sdc,/dev/md/imsm0
+ // ARRAY /dev/md/MyRaid container=...
+ //
+ // ARRAY /dev/md/1 level=raid1 metadata=1.0 num-devices=2 UUID=...
+ // devices=/dev/sda1,/dev/sdb1
+ // ARRAY /dev/md5 level=raid1 num-devices=2 UUID=...
+ // devices=/dev/sda6,/dev/sdb6
+ std::vector lines;
+ Utils::split( output, lines, "\n" );
+ enum LINE_TYPE
+ {
+ LINE_TYPE_OTHER = 0,
+ LINE_TYPE_ARRAY = 1,
+ LINE_TYPE_DEVICES = 2
+ };
+ LINE_TYPE line_type = LINE_TYPE_OTHER;
+ for ( unsigned int i = 0 ; i < lines.size() ; i ++ )
+ {
+ Glib::ustring metadata_type;
+ if ( lines[i].substr( 0, 6 ) == "ARRAY " )
+ {
+ line_type = LINE_TYPE_ARRAY;
+ Glib::ustring metadata_type = Utils::regexp_label( lines[i],
+ "metadata=([[:graph:]]+)" );
+ // Mdadm with these flags doesn't seem to print the
+ // metadata tag for 0.90 version arrays. Accept no tag
+ // (or empty version) as well as "0.90".
+ if ( metadata_type != "" && metadata_type != "0.90" &&
+ metadata_type != "1.0" && metadata_type != "1.1" &&
+ metadata_type != "1.2" )
+ // Skip mdadm reported non-Linux Software RAID arrays
+ line_type = LINE_TYPE_OTHER;
+ }
+ else if ( line_type == LINE_TYPE_ARRAY &&
+ lines[i].find( "devices=" ) != Glib::ustring::npos )
+ {
+ line_type = LINE_TYPE_DEVICES;
+ Glib::ustring devices_str = Utils::regexp_label( lines[i],
+ "devices=([[:graph:]]+)" );
+ std::vector devices;
+ Utils::split( devices_str, devices, "," );
+ for ( unsigned int j = 0 ; j < devices.size() ; j ++ )
+ swraid_info_cache.push_back( devices[j] );
+ }
+ else
+ line_type = LINE_TYPE_OTHER;
+ }
+ }
+}
+
+} //GParted