diff options
Diffstat (limited to 'perl-install/raid.pm')
| -rw-r--r-- | perl-install/raid.pm | 120 | 
1 files changed, 110 insertions, 10 deletions
| diff --git a/perl-install/raid.pm b/perl-install/raid.pm index 5270d2218..f20a511eb 100644 --- a/perl-install/raid.pm +++ b/perl-install/raid.pm @@ -1,4 +1,4 @@ -package raid; # $Id: raid.pm 269279 2010-05-24 14:12:09Z pterjan $ +package raid;  use diagnostics;  use strict; @@ -13,10 +13,21 @@ use run_program;  use devices;  use modules; -sub max_nb() { 31 } +=head1 SYNOPSYS + +Manage regular soft RAID (MD=Multiple Drive). + +=head1 Functions + +=over + +=cut + +sub max_nb() { 131 }  sub check_prog { -    my ($in) = @_; +    # perl_checker: require interactive +    my ($in) = @_; # perl_checker: $in = interactive->new      $::prefix ? whereis_binary('mdadm') : $in->do_pkgs->ensure_binary_is_installed('mdadm', 'mdadm');  } @@ -37,6 +48,12 @@ sub new {      $md_part;  } +=item add() + +Add a partition to a RAID array + +=cut +  sub add {      my ($md_part, $part) = @_;      $md_part->{isMounted} and die N("Cannot add a partition to _formatted_ RAID %s", $md_part->{device}); @@ -48,6 +65,12 @@ sub add {      update($md_part);  } +=item delete() + +Remove a partition from a RAID array + +=cut +  sub delete {      my ($raids, $md_part) = @_;      inactivate_and_dirty($md_part); @@ -95,10 +118,22 @@ sub updateSize {      };  } +=item allmodules() + +Return list of the RAID modules we support + +=cut +  sub allmodules { -    [ 'raid0', 'raid1', 'raid10', 'raid456' ]; +    ('raid0', 'raid1', 'raid10', 'raid456');  } +=item module($part) + +Return list of modules need by a md device (according to its RAID level) + +=cut +  sub module {      my ($part) = @_;      my $level = $part->{level}; @@ -137,7 +172,8 @@ sub make {      run_program::run_or_die('mdadm', '--create', '--run', $dev,   			    if_($nb == 1, '--force'), -			    '--chunk=' . $part->{'chunk-size'},  +			    if_($nb == 2 && $part->{level} == 10, '--layout=f2'), +			    if_($part->{level} != 1, '--chunk=' . $part->{'chunk-size'}),  			    "--level=$part->{level}",   			    "--raid-devices=$nb",  			    if_($part->{metadata}, "--metadata=$part->{metadata}"), @@ -161,7 +197,7 @@ sub format_part {  sub verify {      my ($raids) = @_;      foreach (@$raids) { -	my $nb = $_->{level} =~ /6|10/ ? 4 : $_->{level} =~ /4|5/ ? 3 : 2; +	my $nb = $_->{level} =~ /4|5|6/ ? 3 : 2;  	@{$_->{disks}} >= $nb or die N("Not enough partitions for RAID level %d\n", $_->{level});      }  } @@ -172,32 +208,77 @@ sub inactivate_and_dirty {      set_isFormatted($part, 0);  } +=item active_mds() + +Return list of active MDs + +=cut +  sub active_mds() {      map { if_(/^(md\S+)\s*:\s*active/, $1) } cat_("/proc/mdstat");  } + +=item inactive_mds() + +Return list of inactive MDs + +=cut +  sub inactive_mds() {      map { if_(/^(md\S+)\s*:\s*inactive/, $1) } cat_("/proc/mdstat");  } +=item free_mds() + +Return list of unused MD device nodes + +=cut +  sub free_mds {      my ($raids) = @_;      difference2([ map { "md$_" } 0 .. max_nb() ], [ map { $_->{device} } @$raids ]);  } +=item detect_durting_install() + +Load RAID modules. +Stop RAIDS that might have been started too early by udev. +Scan & starts RAID arrays, then stop any inactive md. + +=cut +  sub detect_during_install {      my (@parts) = @_; -    foreach (@{allmodules()}) { -	eval { modules::load($_) }; -    } +    eval { modules::load($_) } foreach allmodules(); + +    # udev may have started raids but failed due to not yet loaded modules and +    # they remains inactive ("md: personality for level 1 is not loaded!") +    stop_inactive_mds(); +      detect_during_install_once(@parts);      detect_during_install_once(@parts) if active_mds(); #- try again to detect RAID 10 +    stop_inactive_mds(); +} + +=item stop_inactive_mds() + +Stop any inactive md. +=cut + +sub stop_inactive_mds() {      foreach (inactive_mds()) {  	log::l("$_ is an inactive md, we stop it to ensure it doesn't busy devices");  	run_program::run('mdadm', '--stop', devices::make($_));      }  } +=item detect_during_install_once(@parts) + +Scan & starts RAID arrays, then stop any inactive md. + +=cut +  sub detect_during_install_once {      my (@parts) = @_;      devices::make("md$_") foreach 0 .. max_nb(); @@ -214,7 +295,7 @@ sub get_existing {      foreach my $md (active_mds()) {  	my $raw_part = get_md_info(devices::make($md)) or next; -	$raw_part->{level} =~ s/raid//; #- { linear | raid0 | raid1 | raid5 | raid6 } -> { linear | 0 | 1 | 5 | 6 } +	$raw_part->{level} =~ s/raid//; #- { linear | raid0 | raid1 | raid5 | raid6 | raid10 } -> { linear | 0 | 1 | 5 | 6 | 10 }  	my @mdparts =   	  map {  @@ -226,11 +307,13 @@ sub get_existing {  	      }  	  } split(',', $raw_part->{devices}); +	my ($info) = $md =~ m!([^/]*)$!;  	my $md_part = new($raids,  		device => $md,  		UUID => $raw_part->{UUID},  		level => $raw_part->{level},  		metadata => $raw_part->{metadata}, +		info => $info . " (RAID$raw_part->{level})",  		disks => \@mdparts);  	my $type = fs::type::type_subpart_from_magic($md_part); @@ -247,11 +330,23 @@ sub get_existing {      $raids;  } +=item is_active($dev) + +Is it an?active md + +=cut +  sub is_active {      my ($dev) = @_;      member($dev, active_mds());  } +=item write_conf() + +Write /etc/mdadm.conf + +=cut +  sub write_conf {      my ($raids) = @_; @@ -259,6 +354,7 @@ sub write_conf {      my @devices = uniq(map { devices::make($_->{device}) } map { @{$_->{disks}} } @$raids); +    # $::isInstall test for draklive-install:      output($::isInstall ? "$::prefix/etc/mdadm.conf" : "/etc/mdadm.conf",  	   join(' ', 'DEVICE', @devices) . "\n",  	   map { "ARRAY " . devices::make($_->{device}) . " UUID=$_->{UUID} auto=yes\n" } @$raids); @@ -291,4 +387,8 @@ sub parse_mdadm_conf {      \%conf;  } +=back + +=cut +  1; | 
