Add hardware RAID passthrough devices config

Add an opt-in SMART module config option for manually listing hardware RAID passthrough devices, expose configured physical disks to smartctl, and document the option.

https://github.com/webmin/webmin/issues/1704
This commit is contained in:
Ilia Ross
2026-06-21 19:47:19 +02:00
parent 8c631bceeb
commit 65f5beeb11
5 changed files with 106 additions and 5 deletions
+1
View File
@@ -2,3 +2,4 @@ smartctl=smartctl
mode=1
attribs=1
ata=0
raid_devices=
+1
View File
@@ -3,3 +3,4 @@ attribs=Show all attributes,1,1-Yes,0-No
smartctl=Full path to smartctl command,0
ata=Force ATA query mode?,1,1-Yes,0-No
extra=Extra command-line parameters to smartctl,3,None
raid_devices=Hardware RAID passthrough devices,15,raid_devices
+20
View File
@@ -0,0 +1,20 @@
sub show_raid_devices
{
my ($value) = @_;
$value ||= "";
$value =~ s/\t/\n/g;
my $placeholder = &quote_escape("/dev/sg0 cciss 0 3");
return &ui_textarea("raid_devices", $value, 3, 60, undef, 0,
"placeholder=\"$placeholder\"");
}
sub parse_raid_devices
{
my $value = $in{'raid_devices'} || "";
$value =~ s/\r//g;
$value =~ s/\n/\t/g;
$value =~ s/\s+$//;
return $value;
}
1;
@@ -0,0 +1,13 @@
<header>Hardware RAID passthrough devices</header>
This option can be used to add physical disks behind hardware RAID
controllers when they are not detected automatically, but can be queried
by <tt>smartctl</tt> through a passthrough device. Leave it empty unless
you need to monitor disks behind such a controller. <p>
For example, <tt>/dev/sg0 cciss 0 3</tt> adds three <tt>cciss</tt>
physical disks numbered 0, 1 and 2 through the <tt>/dev/sg0</tt>
passthrough device. The final value is the number of disks to add, not the
last disk number. <p>
<footer>
+71 -5
View File
@@ -31,16 +31,18 @@ Returns a sorted list of disks that can support SMART.
=cut
sub list_smart_disks_partitions
{
my @rv;
if (&foreign_check("fdisk")) {
return &list_smart_disks_partitions_fdisk();
@rv = &list_smart_disks_partitions_fdisk();
}
elsif (&foreign_check("bsdfdisk")) {
return &list_smart_disks_partitions_bsdfdisk();
@rv = &list_smart_disks_partitions_bsdfdisk();
}
elsif (&foreign_check("mount")) {
return &list_smart_disks_partitions_fstab();
@rv = &list_smart_disks_partitions_fstab();
}
return ( );
push(@rv, &list_configured_raid_disks());
return &unique_smart_disks(@rv);
}
=head2 list_smart_disks_partitions_fdisk
@@ -220,6 +222,71 @@ while(1) {
return $count;
}
=head2 list_configured_raid_disks()
Returns SMART disk entries for manually configured hardware RAID passthrough
devices. Each configured line is in device type first-disk disk-count format.
=cut
sub list_configured_raid_disks
{
my @rv;
foreach my $line (split(/\t/, $config{'raid_devices'} || "")) {
$line =~ s/^\s+//;
$line =~ s/\s+$//;
next if (!$line || $line =~ /^#/);
my ($device, $type, $first, $count, $extra) = split(/\s+/, $line, 5);
next if (!$device || !$type ||
!defined($first) || !defined($count) || defined($extra));
next if ($device !~ /^\/dev\/\S+$/);
next if ($type !~ /^[A-Za-z0-9_.+-]+$/);
next if ($first !~ /^\d+$/ || $count !~ /^\d+$/);
next if ($count < 1 || $count > 256);
for(my $i=$first; $i<$first+$count; $i++) {
push(@rv, { 'device' => $device,
'prefix' => $device,
'desc' => &configured_raid_disk_desc($type, $i),
'type' => 'scsi',
'subtype' => $type,
'subdisk' => $i,
'ids' => [ ],
'manual' => 1 });
}
}
return @rv;
}
=head2 configured_raid_disk_desc(type, subdisk)
Returns a description for a manually configured hardware RAID disk.
=cut
sub configured_raid_disk_desc
{
my ($type, $subdisk) = @_;
if ($type eq "cciss") {
return "HP Smart Array physical disk ".$subdisk;
}
return "Hardware RAID ".$type." physical disk ".$subdisk;
}
=head2 unique_smart_disks(&disks)
Returns SMART disk entries with duplicate device/type/subdisk entries removed.
=cut
sub unique_smart_disks
{
my %seen;
return grep {
my $key = $_->{'device'}.":".
($_->{'subtype'} || "").":".
(defined($_->{'subdisk'}) ? $_->{'subdisk'} : "");
!$seen{$key}++;
} @_;
}
=head2 list_smart_disks_partitions_fstab
Returns a list of disks on which we can use SMART, taken from /etc/fstab.
@@ -563,4 +630,3 @@ return $extra_args;
}
1;