RAID grow fix and 5 -> 6 conversion, from Caspar Smit
authorJamie Cameron <jcameron@webmin.com>
Mon, 12 Apr 2010 18:43:51 +0000 (11:43 -0700)
committerJamie Cameron <jcameron@webmin.com>
Mon, 12 Apr 2010 18:43:51 +0000 (11:43 -0700)
raid/CHANGELOG
raid/lang/en
raid/log_parser.pl
raid/raid-lib.pl
raid/save_raid.cgi
raid/view_raid.cgi

index 5ac01c6..eea7777 100644 (file)
@@ -30,3 +30,5 @@ RAID 6 devices can now have spares, thanks to Caspar Smit.
 Added a button to remove a detached partition, thanks to Caspar Smit.
 ---- Changes since 1.500 ----
 Added support for creating EXT4 filesystems.
+---- Changes since 1.510 ----
+Conversion from RAID 5 to 6 and vice versa is now possible, thanks to Caspar Smit.
index 0450064..5916ea1 100644 (file)
@@ -4,7 +4,7 @@ index_add=Create RAID device of level:
 index_return=RAID devices
 index_emdstat=The kernel RAID status file $1 does not exist on your system. Your kernel probably does not support RAID.
 index_eprogs=Neither the RAID tools or MDADM packages are installed on your system.
-index_mdadm=Using MDADM
+index_mdadm=Using MDADM version $1
 index_raidtools=Using RaidTools
 index_name=Device name
 index_active=Active?
@@ -78,7 +78,6 @@ view_start=Activate
 view_startdesc=Click this button to re-activate this RAID device.
 view_disks=Partitions in RAID
 view_spares=Spare partitions
-view_addspare=Add $1
 view_size=Usable size
 view_resync=Percent of resync done
 view_down=(Down)
@@ -96,6 +95,10 @@ view_remove_det=Remove detached
 view_remove_detdesc=Remove partitions that are already physically detached from the system.
 view_grow=Grow RAID:
 view_growdesc=Grow array (convert hot spares to active members)
+view_convert_to_raid6=Convert to RAID6
+view_convert_to_raid6desc=Convert RAID level to RAID6 by adding one or more drives.
+view_convert_to_raid5=Convert to RAID5
+view_convert_to_raid5desc=Convert RAID level to RAID5 by removing a drive.
 view_state=RAID status
 view_rebuild=Rebuilding progress
 view_newmount=Mount RAID on:
@@ -131,6 +134,9 @@ log_delete=Deleted RAID device $1
 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_grow=Grown RAID device $1 to a total of $2 disks
+log_convert_to_raid6=Converted RAID5 device $1 to a RAID6 device
+log_convert_to_raid5=Converted RAID6 device $1 to a RAID5 device
 log_notif=Updated RAID problem notification options
 
 notif_err=Failed to save RAID problem notification options
index 5aa7712..8ece806 100755 (executable)
@@ -30,6 +30,15 @@ elsif ($action eq 'add') {
 elsif ($action eq 'remove') {
        return &text('log_remove', "<tt>$object</tt>", "<tt>$p->{'disk'}</tt>");
        }
+elsif ($action eq 'grow') {
+       return &text('log_grow', "<tt>$object</tt>", "<tt>$p->{'disk'}</tt>");
+       }
+elsif ($action eq 'convert_to_raid6') {
+       return &text('log_convert_to_raid6', "<tt>$object</tt>", "<tt>$p->{'disk'}</tt>");
+       }
+elsif ($action eq 'convert_to_raid5') {
+       return &text('log_convert_to_raid5', "<tt>$object</tt>", "<tt>$p->{'disk'}</tt>");
+       }
 else {
        return undef;
        }
index 01b44be..68fc832 100755 (executable)
@@ -440,16 +440,52 @@ if ($raid_mode eq "mdadm") {
 # Grows a RAID set to contain totaldisks active partitions
 sub grow
 {
-local ($raid, $newdisk) = @_;
 if ($raid_mode eq "mdadm") {
        # Call mdadm command to add
-       $cmd = "mdadm --grow $raid->{'value'} -n $newdisk 2>&1";
+       $cmd="mdadm --grow $_[0]->{'value'} -n $_[1] 2>&1";
        local $out = &backquote_logged(
                $cmd);
        &error(&text('emdadmgrow', "<tt>'$cmd' -> $out</tt>")) if ($?);
        }
 }
 
+# convert_raid(&raid, oldcount, newcount, level)
+# Converts a RAID set to a defferent level RAID set
+sub convert_raid
+{
+if ($raid_mode eq "mdadm") {
+       if ($_[2]) {
+               # Call mdadm command to convert
+               $cmd="mdadm --grow $_[0]->{'value'} --level $_[3]";
+               $grow_by = $_[2] - $_[1];
+               if ($grow_by == 1) {
+                       $raid_device_short = $_[0]->{'value'};
+                       $raid_device_short =~ s/\/dev\///;
+                       $date = `date \+\%Y\%m\%d-\%H\%M`;
+                       chomp($date);
+                       $cmd .= " --backup-file /tmp/convert-$raid_device_short-$date";
+               }
+               $cmd .= " -n $_[2]  2>&1";
+        
+               local $out = &backquote_logged(
+                       $cmd);
+               &error(&text('emdadmgrow', "<tt>'$cmd' -> $out</tt>")) if ($?);
+               }
+       else {
+               $newcount = $_[1] - 1;
+               $cmd="mdadm --grow $_[0]->{'value'} --level $_[3] -n $newcount";
+               $raid_device_short = $_[0]->{'value'};
+                $raid_device_short =~ s/\/dev\///;
+                $date = `date \+\%Y\%m\%d-\%H\%M`;
+                chomp($date);
+                $cmd .= " --backup-file /tmp/convert-$raid_device_short-$date";
+               local $out = &backquote_logged(
+                        $cmd);
+                &error(&text('emdadmgrow', "<tt>'$cmd' -> $out</tt>")) if ($?);
+               }
+       }
+}
+
 # remove_partition(&raid, device)
 # Removes a device from some RAID set, both in the config file and for real
 sub remove_partition
@@ -753,5 +789,14 @@ if (&has_command("update-initramfs")) {
        }
 }
 
+# get_mdadm_version()
+# Returns the mdadm version number
+sub get_mdadm_version
+{
+local $out = `mdadm --version 2>&1`;
+local $ver = $out =~ /\s+v([0-9\.]+)/ ? $1 : undef;
+return wantarray ? ( $ver, $out ) : $ver;
+}
+
 1;
 
index a4821a6..7c9d51b 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/local/bin/perl
+#!/usr/bin/perl
 # save_raid.cgi
 # Activate, deactivate, delete or make a filesystem on a raid set
 
@@ -74,9 +74,9 @@ elsif ($in{'add'}) {
 elsif ($in{'grow'}) {
        # Grow the array
        &lock_raid_files();
-       &grow($old, $in{'ndisk'});
+       &grow($old, $in{'ndisk_grow'});
        &unlock_raid_files();
-       &webmin_log("grow", undef, $old->{'value'}, { 'disk' => $in{'ndisk'} } );
+       &webmin_log("grow", undef, $old->{'value'}, { 'disk' => $in{'ndisk_grow'} } );
        &redirect("");
        }
 elsif ($in{'remove'}) {
@@ -94,6 +94,22 @@ elsif ($in{'remove_det'}) {
        &unlock_raid_files();
        &redirect("");
        }
+elsif ($in{'convert_to_raid6'}) {
+       # Convert RAID level to RAID6
+       &lock_raid_files();
+       &convert_raid($old, $in{'oldcount'}, $in{'ndisk_convert'}, 6);
+       &unlock_raid_files();
+       &webmin_log("convert_to_raid6", undef, $old->{'value'}, { 'disk' => $in{'ndisk_convert'} } );
+       &redirect("");
+       }
+elsif ($in{'convert_to_raid5'}) {
+       # Convert RAID level to RAID5
+       &lock_raid_files();
+       &convert_raid($old, $in{'oldcount'}, undef, 5);
+       &unlock_raid_files();
+       &webmin_log("convert_to_raid5", undef, $old->{'value'}, undef );
+       &redirect("");
+       }
 elsif ($in{'mount'} || $in{'mountswap'}) {
        # Re-direct to mount module
        $type = $in{'mountswap'} ? "swap" :
index 790bb05..b499b13 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/local/bin/perl
+#!/usr/bin/perl
 # view_raid.cgi
 # Display information about a raid device
 
@@ -102,6 +102,9 @@ foreach $d (@devs) {
                push(@rdisks, [ $d->{'value'}, $name ]);
                }
        }
+
+$raidcnt = @rdisks;
+
 print &ui_table_row($text{'view_disks'}, $rp);
 
 # Display spare partitions
@@ -116,8 +119,7 @@ foreach $d (@devs) {
                push(@rdisks, [ $d->{'value'}, $name ]);
                $sparescnt++;
                $newdisks++;
-               push(@spares, [ $newdisks,
-                               &text('view_addspare', $sparescnt) ]);
+               push(@spares, [ "$newdisks", "+ $sparescnt" ]);
                }
        }
 if ($sp) {
@@ -161,8 +163,17 @@ if ($raid_mode eq "mdadm") {
        if ($sparescnt > 0 && $lvl != 10) {
                @spares = sort { $a->[0] cmp $b->[0] } @spares;
                push(@grid, &ui_submit($text{'view_grow'}, "grow")." ".
-                           &ui_select("ndisk", undef, \@spares),
+                           &ui_select("ndisk_grow", undef, \@spares),
                            $text{'view_growdesc'});
+               if ($lvl == 5 && &get_mdadm_version() >= 3.1) {
+                       push(@grid, &ui_submit($text{'view_convert_to_raid6'}, "convert_to_raid6")." ".
+                        &ui_select("ndisk_convert", undef, \@spares)." ".&ui_hidden("oldcount", $raidcnt),
+                        $text{'view_convert_to_raid6desc'});
+                       }
+               }
+       if ($lvl == 6 && &get_mdadm_version() >= 3.1) {
+               push(@grid, &ui_submit($text{'view_convert_to_raid5'}, "convert_to_raid5")." ".&ui_hidden("oldcount", $raidcnt),
+                               $text{'view_convert_to_raid5desc'});
                }
        }