home *** CD-ROM | disk | FTP | other *** search
/ Inter.Net 55-2 / Inter.Net 55-2.iso / Mandrake / mdkinst / usr / bin / perl-install / raid.pm < prev    next >
Encoding:
Perl POD Document  |  2000-01-12  |  3.7 KB  |  163 lines

  1. package raid;
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9. use common qw(:common :functional);
  10. use run_program;
  11. use devices;
  12. use commands;
  13. use fs;
  14.  
  15. sub nb($) { 
  16.     my ($nb) = @_;
  17.     first((ref $nb ? $nb->{device} : $nb) =~ /(\d+)/);
  18. }
  19.  
  20. sub is($) {
  21.     my ($part) = @_;
  22.     $part->{device} =~ /^md/;
  23. }
  24.  
  25. sub new($$) {
  26.     my ($raid, $part) = @_;
  27.     my $nb = @$raid; 
  28.     $raid->[$nb] = { 'chunk-size' => "64k", type => 0x83, disks => [ $part ], device => "md$nb", notFormatted => 1 };
  29.     $part->{raid} = $nb;
  30.     delete $part->{mntpoint};
  31.     $nb;
  32. }
  33.  
  34. sub add($$$) {
  35.     my ($raid, $part, $nb) = @_; $nb = nb($nb);
  36.     $raid->[$nb]{isMounted} and die _("Can't add a partition to _formatted_ RAID md%d", $nb);
  37.     $part->{raid} = $nb;
  38.     delete $part->{mntpoint};
  39.     push @{$raid->[$nb]{disks}}, $part;
  40. }
  41.  
  42. sub delete($$) {
  43.     my ($raid, $nb) = @_;
  44.     $nb = nb($nb);
  45.  
  46.     delete $_->{raid} foreach @{$raid->[$nb]{disks}};
  47.     undef $raid->[$nb];
  48. }
  49.  
  50. sub changeNb($$$) {
  51.     my ($raid, $oldnb, $newnb) = @_;
  52.     if ($oldnb != $newnb) {
  53.     ($raid->[$newnb], $raid->[$oldnb]) = ($raid->[$oldnb], undef);
  54.     $raid->[$newnb]{device} = "md$newnb";
  55.     $_->{raid} = $newnb foreach @{$raid->[$newnb]{disks}};
  56.     }
  57.     $newnb;
  58. }
  59.  
  60. sub removeDisk($$) {
  61.     my ($raid, $part) = @_;
  62.     my $nb = nb($part->{raid});
  63.     run_program::run("raidstop", devices::make($part->{device}));
  64.     delete $part->{raid};
  65.     @{$raid->[$nb]{disks}} = grep { $_ != $part } @{$raid->[$nb]{disks}};
  66.     update($raid->[$nb]);
  67. }
  68.  
  69. sub updateSize($) {
  70.     my ($part) = @_;
  71.     local $_ = $part->{level};
  72.     my @l = map { $_->{size} } @{$part->{disks}};
  73.  
  74.     $part->{size} = do {
  75.     if (/0|linear/) { sum @l        }
  76.     elsif (/1/  )   { min @l        }
  77.     elsif (/4|5/)   { min(@l) * $#l }
  78.     };
  79. }
  80.  
  81. sub module($) {
  82.     my ($part) = @_;
  83.     my $mod = $part->{level};
  84.  
  85.     $mod = 5 if $mod eq "4";
  86.     $mod = "raid$mod" if $mod =~ /^\d+$/;
  87.     $mod;
  88. }
  89.  
  90. sub updateIsFormatted($) {
  91.     my ($part) = @_;
  92.     $part->{isFormatted}  = and_ map { $_->{isFormatted}  } @{$part->{disks}};
  93.     $part->{notFormatted} = and_ map { $_->{notFormatted} } @{$part->{disks}};
  94. }
  95. sub update {
  96.     foreach (@_) {
  97.     updateSize($_);
  98.     updateIsFormatted($_);
  99.     }
  100. }
  101.  
  102. sub write($) {
  103.     my ($raid, $file) = @_;
  104.     local *F;
  105.     local $\ = "\n";
  106.     open F, ">$file" or die _("Can't write file $file");
  107.  
  108.     foreach (grep {$_} @$raid) {
  109.     print F <<"EOF";
  110. raiddev       /dev/$_->{device}
  111. raid-level    $_->{level}
  112. chunk-size    $_->{'chunk-size'}
  113. persistent-superblock 1
  114. EOF
  115.     print F "nr-raid-disks ", int @{$_->{disks}};
  116.     map_index {        
  117.         print F "    device    ", devices::make($_->{device});
  118.         print F "    raid-disk $::i";
  119.     } @{$_->{disks}};
  120.     }
  121. }
  122.  
  123. sub make {
  124.     my ($raid, $part) = @_;
  125.     is($_) and make($raid, $_) foreach @{$part->{disks}};
  126.     my $dev = devices::make($part->{device});
  127.     eval { commands::modprobe(module($part)) };
  128.     run_program::run("raidstop", $dev);
  129.     &write($raid, "/etc/raidtab");
  130.     run_program::run("mkraid", "--really-force", $dev);
  131. }
  132.  
  133. sub format_part($$) {
  134.     my ($raid, $part) = @_;
  135.     make($raid->{raid}, $part) if is($part);
  136.     fs::format_part($part, $_->{toFormatCheck} ? "-c" : ());
  137.     if (is($part)) {
  138.     $_->{isFormatted} = 1 foreach @{$part->{disks}};
  139.     }
  140. }
  141.  
  142. sub verify($) {
  143.     my ($raid) = @_;
  144.     $raid && $raid->{raid} or return;
  145.     foreach (grep {$_} @{$raid->{raid}}) {
  146.     @{$_->{disks}} >= ($_->{level} =~ /4|5/ ? 3 : 2) or die _("Not enough partitions for RAID level %d\n", $_->{level});
  147.     }
  148. }
  149.  
  150. sub prepare_prefixed($$) {
  151.     my ($raid, $prefix) = @_;
  152.     $raid && $raid->{raid} or return;
  153.  
  154.     eval { commands::cp("-f", "/etc/raidtab", "$prefix/etc/raidtab") };
  155.     foreach (@{$raid->{raid}}) {
  156.     devices::make("$prefix/dev/$_->{device}") foreach @{$_->{disks}};
  157.     }
  158. }
  159.  
  160. sub stopAll() { run_program::run("raidstop", devices::make("md$_")) foreach 0..7 }
  161.  
  162. 1;
  163.