Detect busy status of dmraid started ATARAID members (#75)
Again this is to stop GParted allowing overwrite operations being performed on an ATARAID member while the array is actively using the member. This time for dmraid started arrays using the kernel DM (Device Mapper) driver. The DMRaid module already uses dmraid to report active array names: # dmraid -sa -c isw_ecccdhhiga_MyArray To find active members in this array, (1) use udev to lookup the kernel device name: # udevadm info --query=name /dev/mapper/isw_ecccdhhiga_MyArray dm-0 (2) list the member names exposed by the kernel DM driver through the /sys file system. # ls /sys/block/dm-0/slaves sdc sdd # ls -l /sys/block/dm-0/slaves lrwxrwxrwx 1 root root 0 Nov 24 09:52 sdc -> ../../../../pci0000:00/0000:00:0d.0/ata3/host2/target2:0:0/2:0:0:0/block/sdc lrwxrwxrwx 1 root root 0 Nov 24 09:52 sdc -> ../../../../pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdd Closes #75 - Errors with GPT on RAID 0 ATARAID array
This commit is contained in:
parent
425dfa3709
commit
caec22871e
|
@ -27,11 +27,14 @@
|
|||
#define GPARTED_DMRAID_H
|
||||
|
||||
#include "Utils.h"
|
||||
#include "BlockSpecial.h"
|
||||
#include "Partition.h"
|
||||
#include "OperationDetail.h"
|
||||
|
||||
#include <glibmm/ustring.h>
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace GParted
|
||||
{
|
||||
|
||||
|
@ -56,17 +59,22 @@ public:
|
|||
bool delete_dev_map_entry( const Partition & partition, OperationDetail & operationdetail ) ;
|
||||
bool purge_dev_map_entries( const Glib::ustring & dev_path ) ;
|
||||
bool update_dev_map_entry( const Partition & partition, OperationDetail & operationdetail ) ;
|
||||
bool is_member_active(const Glib::ustring& member_path);
|
||||
|
||||
private:
|
||||
void load_dmraid_cache() ;
|
||||
void set_commands_found() ;
|
||||
void get_dmraid_dir_entries( const Glib::ustring & dev_path, std::vector<Glib::ustring> & dir_list ) ;
|
||||
void get_affected_dev_map_entries( const Partition & partition, std::vector<Glib::ustring> & affected_entries ) ;
|
||||
void get_partition_dev_map_entries( const Partition & partition, std::vector<Glib::ustring> & partition_entries ) ;
|
||||
static std::vector<Glib::ustring> lookup_dmraid_members(const Glib::ustring& array);
|
||||
|
||||
static bool dmraid_cache_initialized ;
|
||||
static bool dmraid_found ;
|
||||
static bool dmsetup_found ;
|
||||
static bool udevadm_found ;
|
||||
static std::vector<Glib::ustring> dmraid_devices ;
|
||||
static std::vector<BlockSpecial> dmraid_member_cache;
|
||||
};
|
||||
|
||||
}//GParted
|
||||
|
|
|
@ -15,7 +15,9 @@
|
|||
*/
|
||||
|
||||
#include "DMRaid.h"
|
||||
#include "BlockSpecial.h"
|
||||
#include "Partition.h"
|
||||
#include "Utils.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdlib.h> //atoi function
|
||||
|
@ -28,12 +30,26 @@
|
|||
namespace GParted
|
||||
{
|
||||
|
||||
// Data model:
|
||||
// dmraid_cache_initialized - Has the cache been loaded?
|
||||
// dmraid_found - Is the "dmraid" command available?
|
||||
// dmsetup_found - Is the "dmsetup" command available?
|
||||
// udevadm_found - Is the "udevadm" command available?
|
||||
// dmraid_devices - Vector of active array names.
|
||||
// E.g.
|
||||
// ["isw_ecccdhhiga_MyArray"]
|
||||
// dmraid_member_cache - Vector of members of active DMRaid arrays.
|
||||
// E.g.
|
||||
// [BlockSpecial("/dev/sdc"), BlockSpecial("/dev/sdd")]
|
||||
|
||||
//Initialize static data elements
|
||||
bool DMRaid::dmraid_cache_initialized = false ;
|
||||
bool DMRaid::dmraid_found = false ;
|
||||
bool DMRaid::dmsetup_found = false ;
|
||||
bool DMRaid::udevadm_found = false ;
|
||||
std::vector<Glib::ustring> DMRaid::dmraid_devices ;
|
||||
std::vector<BlockSpecial> DMRaid::dmraid_member_cache;
|
||||
|
||||
|
||||
DMRaid::DMRaid()
|
||||
{
|
||||
|
@ -67,10 +83,11 @@ DMRaid::~DMRaid()
|
|||
|
||||
void DMRaid::load_dmraid_cache()
|
||||
{
|
||||
//Load data into dmraid structures
|
||||
Glib::ustring output, error ;
|
||||
dmraid_devices .clear() ;
|
||||
dmraid_member_cache.clear();
|
||||
|
||||
// Load active DMRaid array names.
|
||||
if ( dmraid_found )
|
||||
{
|
||||
if ( ! Utils::execute_command( "dmraid -sa -c", output, error, true ) )
|
||||
|
@ -79,8 +96,17 @@ void DMRaid::load_dmraid_cache()
|
|||
Utils::tokenize( output, dmraid_devices, "\n" ) ;
|
||||
}
|
||||
}
|
||||
|
||||
// Load members of active DMRaid arrays.
|
||||
for (unsigned int i = 0; i < dmraid_devices.size(); i++)
|
||||
{
|
||||
std::vector<Glib::ustring> members = lookup_dmraid_members(DEV_MAPPER_PATH + dmraid_devices[i]);
|
||||
for (unsigned int j = 0; j < members.size(); j++)
|
||||
dmraid_member_cache.push_back(BlockSpecial(members[j]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DMRaid::set_commands_found()
|
||||
{
|
||||
//Set status of commands found
|
||||
|
@ -492,4 +518,56 @@ bool DMRaid::update_dev_map_entry( const Partition & partition, OperationDetail
|
|||
return exit_status ;
|
||||
}
|
||||
|
||||
|
||||
// Return whether the named device (e.g. "/dev/sdc") is a member of an active DMRaid array
|
||||
// or not.
|
||||
bool DMRaid::is_member_active(const Glib::ustring& member_path)
|
||||
{
|
||||
BlockSpecial bs = BlockSpecial(member_path);
|
||||
for (unsigned int i = 0; i < dmraid_member_cache.size(); i++)
|
||||
{
|
||||
if (bs == dmraid_member_cache[i])
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Return vector of member devices of an active DMRaid array.
|
||||
// E.g. lookup_dmraid_members("/dev/mapper/isw_ecccdhhiga_MyArray") -> ["/dev/sdc", "/dev/sdd"]
|
||||
std::vector<Glib::ustring> DMRaid::lookup_dmraid_members(const Glib::ustring& array)
|
||||
{
|
||||
// Method:
|
||||
// (1) Query udev for the kernel device name;
|
||||
// (2) List member names from the directory /sys/block/${name}/slaves.
|
||||
|
||||
std::vector<Glib::ustring> members;
|
||||
if (! udevadm_found)
|
||||
return members; // Empty vector
|
||||
|
||||
Glib::ustring output;
|
||||
Glib::ustring error;
|
||||
Utils::execute_command("udevadm info --query=name " + Glib::shell_quote(array),
|
||||
output, error, true);
|
||||
|
||||
// Strip terminating new line from output.
|
||||
size_t len = output.length();
|
||||
if (len > 0 && output[len-1] == '\n')
|
||||
output.resize(len-1);
|
||||
|
||||
if (output.empty())
|
||||
return members; // Empty vector
|
||||
|
||||
Glib::ustring filename;
|
||||
Glib::Dir dir("/sys/block/" + output + "/slaves");
|
||||
while ((filename = dir.read_name()) != "")
|
||||
{
|
||||
members.push_back("/dev/" + filename);
|
||||
}
|
||||
|
||||
return members;
|
||||
}
|
||||
|
||||
|
||||
}//GParted
|
||||
|
|
|
@ -1525,13 +1525,16 @@ bool GParted_Core::is_busy( FSType fstype, const Glib::ustring & path )
|
|||
}
|
||||
else
|
||||
{
|
||||
DMRaid dmraid;
|
||||
|
||||
//Still search GParted internal mounted partitions map in case an
|
||||
// unknown file system is mounted
|
||||
busy = Mount_Info::is_dev_mounted( path );
|
||||
|
||||
// Custom checks for recognised but other not-supported file system types.
|
||||
busy |= (fstype == FS_LINUX_SWRAID && SWRaid_Info::is_member_active(path));
|
||||
busy |= (fstype == FS_ATARAID && SWRaid_Info::is_member_active(path));
|
||||
busy |= (fstype == FS_ATARAID && (SWRaid_Info::is_member_active(path) ||
|
||||
dmraid.is_member_active(path) ));
|
||||
}
|
||||
|
||||
return busy ;
|
||||
|
|
Loading…
Reference in New Issue