local $temp = &transname();
&foreign_require("proc", "proc-lib.pl");
open(TEMP, ">$temp");
- &proc::safe_process_exec_logged("$fh start", 0, 0, TEMP);
+ &proc::safe_process_exec_logged("$fn start", 0, 0, TEMP);
close(TEMP);
local $ex = $?;
local $out = &read_file_contents($temp);
local $temp = &transname();
&foreign_require("proc", "proc-lib.pl");
open(TEMP, ">$temp");
- &proc::safe_process_exec_logged("$fh stop", 0, 0, TEMP);
+ &proc::safe_process_exec_logged("$fn stop", 0, 0, TEMP);
close(TEMP);
local $ex = $?;
local $out = &read_file_contents($temp);
Added support for RAID 6 arrays when using MDADM.
---- Changes since 1.340 ----
Removed need to explicitly select a parity disk for RAID 4 when using MDADM.
+---- Changes since 1.360 ----
+Added support for RAID 10 arrays when using MDADM.
+Changed the main page to use a table for existing RAID arrays, rather than icons.
+Added a section for configuring RAID problem notification when using MDADM.
# Display configured raid devices
$conf = &get_raidtab();
if (@$conf) {
- &show_button();
+ print &ui_columns_start([ $text{'index_name'},
+ $text{'index_active'},
+ $text{'index_level'},
+ $text{'index_members'} ]);
foreach $c (@$conf) {
$lvl = &find_value('raid-level', $c->{'members'});
- push(@titles, &html_escape($c->{'value'}));
- push(@images, $c->{'active'} ? "images/$lvl.gif"
- : "images/$lvl.ia.gif");
- push(@links, "view_raid.cgi?idx=$c->{'index'}");
+ @mems = ( );
+ foreach $d (&find('device', $c->{'members'})) {
+ if (&find('raid-disk', $d->{'members'}) ||
+ &find('parity-disk', $d->{'members'})) {
+ push(@mems, $d->{'value'});
+ }
+ }
+ print &ui_columns_row([
+ "<a href='view_raid.cgi?idx=$c->{'index'}'>".
+ &html_escape($c->{'value'})."</a>",
+ $c->{'active'} ?
+ "<font color=#00aa00>$text{'yes'}</font>" :
+ "<font color=#ff0000>$text{'no'}</font>",
+ $lvl eq 'linear' ? $text{'linear'} : $text{'raid'.$lvl},
+ join(" ", @mems),
+ ]);
}
- &icons_table(\@links, \@titles, \@images);
+ print &ui_columns_end();
}
else {
print "<p><b>$text{'index_none'}</b><p>\n";
}
&show_button();
+# Form for mdadm monitoring options
+if ($raid_mode eq "mdadm") {
+ $notif = &get_mdadm_notifications();
+ print "<hr>\n";
+ print &ui_form_start("save_mdadm.cgi", "post");
+ print &ui_table_start($text{'index_header'}, undef, 2, [ "width=30%" ]);
+
+ # Is monitoring enabled?
+ if (&get_mdadm_action()) {
+ print &ui_table_row($text{'index_monitor'},
+ &ui_yesno_radio("monitor", &get_mdadm_monitoring() ? 1 : 0));
+ }
+
+ # Notification address
+ print &ui_table_row($text{'index_mailaddr'},
+ &ui_opt_textbox("mailaddr", $notif->{'MAILADDR'}, 40,
+ $text{'index_mailaddrnone'}));
+
+ # Notification sender
+ print &ui_table_row($text{'index_mailfrom'},
+ &ui_opt_textbox("mailfrom", $notif->{'MAILFROM'}, 40,
+ $text{'index_mailfromnone'}));
+
+ # Program to call for problems
+ print &ui_table_row($text{'index_program'},
+ &ui_opt_textbox("program", $notif->{'PROGRAM'}, 40,
+ $text{'index_programnone'}));
+
+ print &ui_table_end();
+ print &ui_form_end([ [ undef, $text{'save'} ] ]);
+ }
+
&ui_print_footer("/", $text{'index'});
sub show_button
{
print &ui_form_start("raid_form.cgi");
print &ui_submit($text{'index_add'});
-local @levels = ( 0, 1, 4, 5 );
-push(@levels, 6) if ($raid_mode eq "mdadm");
+local @levels = &get_raid_levels();
print &ui_select("level", "linear",
[ [ "linear", $text{'linear'} ],
map { [ $_, $text{'raid'.$_} ] } @levels ]),"\n";
index_eprogs=Niether the RAID tools or MDADM packages are installed on your system.
index_mdadm=Using MDADM
index_raidtools=Using RaidTools
+index_name=Device name
+index_active=Active?
+index_level=RAID level
+index_members=Member disk devices
+index_header=RAID problem notification options
+index_mailaddr=Send notifications to
+index_mailaddrnone=Don't send
+index_mailfrom=From address for notifications
+index_mailfromnone=Default (<tt>root</tt>)
+index_program=Command to run when problems are detected
+index_programnone=Don't run any
+index_monitor=Monitoring enabled?
linear=Concatenated (Linear)
raid0=Striped (RAID0)
raid4=Parity (RAID4)
raid5=Redundant (RAID5)
raid6=Dual Redundant (RAID6)
+raid10=Striped and Mirrored (RAID10)
blocks=blocks
create_title=Create RAID Device
log_mkfs=Created $1 filesystem on $2
log_add=Added partition $2 to RAID device $1
log_remove=Removed partition $2 from RAID device $1
+log_notif=Updated RAID problem notification options
+
+notif_err=Failed to save RAID problem notification options
+notif_emailaddr=Missing or invalid notification address
+notif_emailfrom=Missing or invalid From address
+notif_eprogram=Missing or non-existant program to run
%container = ( 'raiddev', 1,
'device', 1 );
+# get_raid_levels()
+# Returns a list of allowed RAID levels
+sub get_raid_levels
+{
+if ($raid_mode eq "mdadm") {
+ return ( 0, 1, 4, 5, 6, 10 );
+ }
+else {
+ return ( 0, 1, 4, 5 );
+ }
+}
+
# get_mdstat()
# Read information about active RAID devices. Returns a hash indexed by
# device name (like /dev/md0), with each value being an array reference
}
}
+%mdadm_notification_opts = map { $_, 1 } ( 'MAILADDR', 'MAILFROM', 'PROGRAM' );
+
+# get_mdadm_notifications()
+# Returns a hash from mdadm.conf notification-related settings to values
+sub get_mdadm_notifications
+{
+local $lref = &read_file_lines($config{'mdadm'});
+local %rv;
+foreach my $l (@$lref) {
+ $l =~ s/#.*$//;
+ if ($l =~ /^(\S+)\s+(\S.*)/ && $mdadm_notification_opts{$1}) {
+ $rv{$1} = $2;
+ }
+ }
+return \%rv;
+}
+
+# save_mdadm_notifications(¬ifications)
+# Updates mdadm.conf with settings from the given hash. Those set to undef
+# are removed from the file.
+sub save_mdadm_notifications
+{
+local ($notif) = @_;
+local $lref = &read_file_lines($config{'mdadm'});
+local %done;
+for(my $i=0; $i<@$lref; $i++) {
+ my $l = $lref->[$i];
+ $l =~ s/#.*$//;
+ local ($k, $v) = split(/\s+/, $l, 2);
+ if (exists($notif->{$k})) {
+ if (defined($notif->{$k})) {
+ $lref->[$i] = "$k $notif->{$k}";
+ }
+ else {
+ splice(@$lref, $i--, 1);
+ }
+ $done{$k}++;
+ }
+ }
+foreach my $k (grep { !$done{$_} && defined($notif->{$_}) } keys %$notif) {
+ push(@$lref, "$k $notif->{$k}");
+ }
+&flush_file_lines($config{'mdadm'});
+}
+
+# get_mdadm_action()
+# Returns the name of an init module action for mdadm monitoring, or undef if
+# not supported.
+sub get_mdadm_action
+{
+if (&foreign_installed("init")) {
+ &foreign_require("init", "init-lib.pl");
+ foreach my $a ("mdmonitor", "mdadm", "mdadmd") {
+ local $st = &init::action_status($a);
+ return $a if ($st);
+ }
+ }
+return undef;
+}
+
+# get_mdadm_monitoring()
+# Returns 1 if mdadm monitoring is enabled, 0 if not
+sub get_mdadm_monitoring
+{
+local $act = &get_mdadm_action();
+if ($act) {
+ &foreign_require("init", "init-lib.pl");
+ local $st = &init::action_status($act);
+ return $st == 2;
+ }
+return 0;
+}
+
+# save_mdadm_monitoring(enabled)
+# Tries to enable or disable mdadm monitoring. Returns an error mesage
+# if something goes wrong, undef on success
+sub save_mdadm_monitoring
+{
+local ($enabled) = @_;
+local $act = &get_mdadm_action();
+if ($act) {
+ &foreign_require("init", "init-lib.pl");
+ if ($enabled) {
+ &init::enable_at_boot($act);
+ &init::stop_action($act);
+ sleep(2);
+ local ($ok, $err) = &init::start_action($act);
+ return $err if (!$ok);
+ }
+ else {
+ &init::disable_at_boot($act);
+ &init::stop_action($act);
+ }
+ }
+return undef;
+}
+
1;
print $disks;
print "</select></td> </tr>\n";
-if ($lvl >= 4) {
+if ($lvl >= 4 && $lvl != 10) {
print "<tr> <td valign=top><b>$text{'create_spares'}</b></td>\n";
print "<td><select name=spares multiple size=4>\n";
print $disks;
--- /dev/null
+#!/usr/local/bin/perl
+# Update mdadm.conf with notification settings
+
+require './raid-lib.pl';
+&ReadParse();
+&error_setup($text{'notif_err'});
+
+# Validate inputs
+$notif = { };
+if (!$in{'mailaddr_def'}) {
+ $in{'mailaddr'} =~ /^\S+\@\S+$/ || &error($text{'notif_emailaddr'});
+ $notif->{'MAILADDR'} = $in{'mailaddr'};
+ }
+else {
+ $notif->{'MAILADDR'} = undef;
+ }
+if (!$in{'mailfrom_def'}) {
+ $in{'mailfrom'} =~ /^\S+\@\S+$/ || &error($text{'notif_emailfrom'});
+ $notif->{'MAILFROM'} = $in{'mailfrom'};
+ }
+else {
+ $notif->{'MAILFROM'} = undef;
+ }
+if (!$in{'program_def'}) {
+ -x $in{'program'} || &error($text{'notif_eprogram'});
+ $notif->{'PROGRAM'} = $in{'program'};
+ }
+else {
+ $notif->{'PROGRAM'} = undef;
+ }
+
+# Save them
+&lock_file($config{'mdadm'});
+&save_mdadm_notifications($notif);
+&unlock_file($config{'mdadm'});
+
+# Enable/disable
+if (&get_mdadm_action()) {
+ &save_mdadm_monitoring($in{'monitor'});
+ }
+
+&webmin_log("notif");
+
+&redirect("");
+
if ($raid->{'active'} && !$st[2]) {
# Show buttons for creating filesystems
+ $fstype = $st[1] || "ext3";
print "<tr> <td nowrap><input type=submit name=mkfs ",
"value='$text{'view_mkfs2'}'>\n";
print "<select name=fs>\n";
foreach $f (&fdisk::supported_filesystems()) {
printf "<option value=%s %s>%s (%s)\n",
- $f, $stat[1] eq $f ? "selected" : "",
+ $f, $fstype eq $f ? "selected" : "",
$fdisk::text{"fs_$f"}, $f;
}
print "</select></td>\n";