Skip to content

Commit

Permalink
Fix RAID handling in device lookup (#252)
Browse files Browse the repository at this point in the history
  • Loading branch information
KeithB committed Dec 20, 2023
1 parent 4c2bc54 commit a185cef
Showing 1 changed file with 52 additions and 30 deletions.
82 changes: 52 additions & 30 deletions src/Utility/Device.vala
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,21 @@ public class Device : GLib.Object{
return false;
}

public bool type_is_raid() {

switch (type){
case "raid0":
case "raid1":
case "raid4":
case "raid5":
case "raid6":
case "raid10":
return true;
default:
return false;
}
}

public bool has_linux_filesystem(){
switch (fstype){
case "ext2":
Expand Down Expand Up @@ -371,6 +386,37 @@ public class Device : GLib.Object{
}


//
// Used recursively to navigate up the parent tree removing items where found and
// let the original caller know how many items were removed.
public static int remove_parents(Gee.ArrayList<Device> list, Device dev) {

int removed = 0;

if ( dev.pkname != "" ) {
for (int i = list.size - 1; i >= 0; --i) {
if (list[i].kname == dev.pkname) {
if (list[i].pkname != "") {
removed = remove_parents(list, list[i]);
i-=removed;
}
list.remove_at(i);
--i;
dev.pkname = "";
++removed;
}
}

// If the parent is still set then it didn't exist to remove - likely removed while handling a dupe
// Clean up but nothing removed
if ( dev.pkname != "" ) {
dev.pkname = "";
}
}

return removed;
}

public static Gee.ArrayList<Device> get_block_devices_using_lsblk(string dev_name = ""){

//log_debug("Device: get_block_devices_using_lsblk()");
Expand Down Expand Up @@ -583,21 +629,8 @@ public class Device : GLib.Object{

// Cleanup for raid: remove member disks and double children
for (int i = list.size - 1; i >= 0; --i) {
if (list[i].type == "raid5") {
// This is a raid5 device, lsblk shows one member disk and a partition
// as parents and we remove them

for (int j = i - 1; j >= 0; --j) {
if (list[j].kname == list[i].pkname) {
list.remove_at(j);
list.remove_at(j-1);
i-=2; // we are removing 2 elements before i
break;
}
}

// Does not have a parent anymore
list[i].pkname = "";
if (list[i].type_is_raid()) {
i-=remove_parents(list, list[i]);

// Its children have to be unique (e.g. when mirroring,
// lsblk shows each member partition twice)
Expand All @@ -606,6 +639,7 @@ public class Device : GLib.Object{
for (int k = j - 1; k >= 0; --k) {
if (list[k].kname == list[j].kname) {
list.remove_at(k);
--i; // keep the outer counter in sync
--j; // we are removing an element between i and j
}
}
Expand All @@ -616,14 +650,14 @@ public class Device : GLib.Object{

// Some more cleanup: raid are to be seen as disks and need deduplication
for (int i = list.size - 1; i >= 0; --i) {
if (list[i].type == "raid5") {
if (list[i].type_is_raid()) {
// It's now a disk
list[i].type = "disk";
list[i].model = list[i].name;

// We remove other copies of the same raid device
for (int j = list.size - 1; j >= 0; --j) {
if ((i != j) && (list[j].type == "raid5") && (list[j].kname == list[i].kname)) {
if ((i != j) && (list[j].type == list[i].type) && (list[j].kname == list[i].kname)) {
list.remove_at(j);
if (j < i)
--i; // we are removing an element before i
Expand All @@ -637,19 +671,7 @@ public class Device : GLib.Object{
// Cleanup for dmraid: remove member disks and double children
for (int i = list.size - 1; i >= 0; --i) {
if (list[i].type == "dmraid") {
// This is a dmraid device, lsblk shows one member disk
// as parent and we remove it

for (int j = i - 1; j >= 0; --j) {
if (list[j].kname == list[i].pkname) {
list.remove_at(j);
--i; // we are removing an element before i
break;
}
}

// Does not have a parent anymore
list[i].pkname = "";
i-=remove_parents(list, list[i]);

// Its children have to be unique (e.g. when mirroring,
// lsblk shows each member partition twice)
Expand Down

0 comments on commit a185cef

Please sign in to comment.