summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPascal Rigaux <pixel@mandriva.com>2004-08-08 07:10:15 +0000
committerPascal Rigaux <pixel@mandriva.com>2004-08-08 07:10:15 +0000
commit3c6fbfb082361277877a5dd82f7014eff0afaa92 (patch)
tree08abbcab50b6eecbf5f1f4821ccbbf5865f041df
parent98a4be8ec81d7865a4655fc322b52e866e1c64a2 (diff)
downloaddrakx-3c6fbfb082361277877a5dd82f7014eff0afaa92.tar
drakx-3c6fbfb082361277877a5dd82f7014eff0afaa92.tar.gz
drakx-3c6fbfb082361277877a5dd82f7014eff0afaa92.tar.bz2
drakx-3c6fbfb082361277877a5dd82f7014eff0afaa92.tar.xz
drakx-3c6fbfb082361277877a5dd82f7014eff0afaa92.zip
- switch to mdadm (instead of raidtools)
- create mdadm.conf instead of raidtab - internal {raids} is no more indexed by X for mdX, and so don't have holes anymore - internal {chunk-size} is now a number in KiB - internal {raid} is the raid device name, not the number - various cleanup for raid detection
-rw-r--r--perl-install/bootloader.pm2
-rw-r--r--perl-install/detect_devices.pm43
-rw-r--r--perl-install/diskdrake/hd_gtk.pm2
-rw-r--r--perl-install/diskdrake/interactive.pm46
-rw-r--r--perl-install/fs/get.pm6
-rw-r--r--perl-install/fsedit.pm63
-rw-r--r--perl-install/install2.pm2
-rw-r--r--perl-install/install_any.pm2
-rw-r--r--perl-install/raid.pm204
-rw-r--r--perl-install/share/list.i3863
10 files changed, 169 insertions, 204 deletions
diff --git a/perl-install/bootloader.pm b/perl-install/bootloader.pm
index 7a14693d8..809f87acc 100644
--- a/perl-install/bootloader.pm
+++ b/perl-install/bootloader.pm
@@ -315,7 +315,7 @@ sub allowed_boot_parts {
(
@{$all_hds->{hds}},
if_($bootloader->{method} =~ /lilo/,
- grep { $_ && $_->{level} eq '1' } @{$all_hds->{raids}}
+ grep { $_->{level} eq '1' } @{$all_hds->{raids}}
),
(grep { !isFat_or_NTFS($_) } fs::get::hds_fstab(@{$all_hds->{hds}})),
detect_devices::floppies(),
diff --git a/perl-install/detect_devices.pm b/perl-install/detect_devices.pm
index a22af1115..7af813337 100644
--- a/perl-install/detect_devices.pm
+++ b/perl-install/detect_devices.pm
@@ -803,49 +803,6 @@ sub hasMousePS2 {
my $t; sysread(tryOpen($_[0]) || return, $t, 256) != 1 || $t ne "\xFE";
}
-sub raidAutoStartIoctl() {
- sysopen(my $F, devices::make("md0"), 2) or return;
- ioctl $F, 0x914, 0; #- RAID_AUTORUN
-}
-
-sub raidAutoStartRaidtab {
- my (@parts) = @_;
- $::isInstall or return;
- require raid;
- #- faking a raidtab, it seems to be working :-)))
- #- (choosing any inactive md)
- raid::inactivate_all();
- my $detect_one = sub {
- my ($device) = @_;
- my $free_md = devices::make(find { !raid::is_active($_) } map { "md$_" } 0 .. raid::max_nb());
- output("/tmp/raidtab", "raiddev $free_md\n device " . devices::make($device) . "\n");
- log::l("raidAutoStartRaidtab: trying $device");
- run_program::run('raidstart', '-c', "/tmp/raidtab", $free_md);
- };
- $detect_one->($_->{device}) foreach @parts;
-
- #- try again to detect RAID 10
- $detect_one->($_) foreach raid::active_mds();
-
- unlink "/tmp/raidtab";
-}
-
-sub raidAutoStart {
- my (@parts) = @_;
-
- log::l("raidAutoStart");
- eval { modules::load('md') };
- my %personalities = ('1' => 'linear', '2' => 'raid0', '3' => 'raid1', '4' => 'raid5');
- raidAutoStartIoctl() or raidAutoStartRaidtab(@parts);
- foreach (1..2) { #- try twice for RAID 10
- my @needed_perso = map {
- if_(/^kmod: failed.*md-personality-(.)/ ||
- /^md: personality (.) is not loaded/, $personalities{$1}) } syslog() or last;
- eval { modules::load(@needed_perso) };
- raidAutoStartIoctl() or raidAutoStartRaidtab(@parts);
- }
-}
-
sub usb_description2removable {
local ($_) = @_;
return 'camera' if /\bcamera\b/i;
diff --git a/perl-install/diskdrake/hd_gtk.pm b/perl-install/diskdrake/hd_gtk.pm
index 4af2a36a1..a9ebdc769 100644
--- a/perl-install/diskdrake/hd_gtk.pm
+++ b/perl-install/diskdrake/hd_gtk.pm
@@ -244,7 +244,7 @@ sub create_automatic_notebooks {
};
$may_add->(hd2kind($_)) foreach @{$all_hds->{hds}};
$may_add->(lvm2kind($_)) foreach @{$all_hds->{lvms}};
- $may_add->(raid2kind()) if any { $_ } @{$all_hds->{raids}};
+ $may_add->(raid2kind()) if @{$all_hds->{raids}};
$may_add->(loopback2kind()) if @{$all_hds->{loopbacks}};
@notebook = grep_index {
diff --git a/perl-install/diskdrake/interactive.pm b/perl-install/diskdrake/interactive.pm
index f5b2524b0..01c9b0292 100644
--- a/perl-install/diskdrake/interactive.pm
+++ b/perl-install/diskdrake/interactive.pm
@@ -49,7 +49,7 @@ struct part {
# !isFormatted && notFormatted means the device is not formatted
# !isFormatted && !notFormatted means we don't know which state we're in
- int raid # for partitions of type isRawRAID and which isPartOfRAID, the raid device number
+ string raid # for partitions of type isRawRAID and which isPartOfRAID, the raid device
string lvm # partition used as a PV for the VG with {lvm} as VG_name #-#
loopback loopback[] # loopback living on this partition
@@ -68,7 +68,7 @@ struct part_allocate inherits part {
}
struct part_raid inherits part {
- string chunk-size # usually '64k'
+ string chunk-size # in KiB, usually '64'
string level # one of { 0, 1, 4, 5, 'linear' }
part disks[]
@@ -155,7 +155,7 @@ struct raw_hd inherits hd {
struct all_hds {
hd hds[]
hd_lvm lvms[]
- part_raid raids[] # indexed by number: raids[$n]{device} is "md$n"
+ part_raid raids[]
part_loopback loopbacks[]
raw_hd raw_hds[]
raw_hd nfss[]
@@ -407,7 +407,7 @@ sub Hd_info {
################################################################################
sub part_possible_actions {
- my ($_in, $hd, $part, $_all_hds) = @_;
+ my ($_in, $hd, $part, $all_hds) = @_;
$part or return;
my %actions = my @l = (
@@ -424,7 +424,7 @@ sub part_possible_actions {
N_("Delete") => '!isBusy && !readonly',
N_("Remove from RAID") => 'isPartOfRAID',
N_("Remove from LVM") => 'isPartOfLVM',
- N_("Modify RAID") => 'isPartOfRAID && !isMounted($all_hds->{raids}[$part->{raid}])',
+ N_("Modify RAID") => 'canModifyRAID',
N_("Use for loopback") => '!$part->{real_mntpoint} && isMountableRW && !isSpecial && hasMntpoint && $::expert',
);
my ($actions_names) = list2kv(@l);
@@ -432,6 +432,7 @@ sub part_possible_actions {
readonly => '$hd->{readonly}',
hasMntpoint => '$part->{mntpoint}',
isPrimary => 'isPrimary($part, $hd)',
+ canModifyRAID => 'isPartOfRAID($part) && !isMounted(fs::get::device2part($part->{raid}, $all_hds->{raids}))',
);
if ($part->{pt_type} eq '0') {
if_(!$hd->{readonly}, N_("Create"));
@@ -803,17 +804,16 @@ sub Add2RAID {
my ($in, $_hd, $part, $all_hds) = @_;
my $raids = $all_hds->{raids};
- local $_ = @$raids == () ? "new" :
- $in->ask_from_list_('', N("Choose an existing RAID to add to"),
- [ (grep { $_ } map_index { $_ && "md$::i" } @$raids), N_("new") ]) or return;
+ my $md_part = $in->ask_from_listf('', N("Choose an existing RAID to add to"),
+ sub { ref($_[0]) ? $_[0]{device} : $_[0] },
+ [ @$raids, N_("new") ]) or return;
- if (/new/) {
- my $nb1 = raid::new($raids, $part);
- defined modifyRAID($in, $raids, $nb1) or return raid::delete($raids, $nb1);
+ if (ref($md_part)) {
+ raid::add($md_part, $part);
} else {
- raid::add($raids, $part, $_);
+ my $md_part = raid::new($raids, disks => [ $part ]);
+ modifyRAID($in, $raids, $md_part) or return raid::delete($raids, $md_part);
}
- raid::update(@$raids);
}
sub Add2LVM {
my ($in, $hd, $part, $all_hds) = @_;
@@ -856,7 +856,7 @@ sub RemoveFromLVM {
}
sub ModifyRAID {
my ($in, $_hd, $part, $all_hds) = @_;
- modifyRAID($in, $all_hds->{raids}, $part->{raid});
+ modifyRAID($in, $all_hds->{raids}, fs::get::device2part($part->{raid}, $all_hds->{raids}));
}
sub Loopback {
my ($in, $hd, $real_part, $all_hds) = @_;
@@ -976,17 +976,19 @@ sub is_part_existing {
}
sub modifyRAID {
- my ($in, $raids, $nb) = @_;
- my $md = "md$nb";
+ my ($in, $raids, $md_part) = @_;
+ my @free_mds = difference2([ map { "md$_" } 0 .. raid::max_nb() ], [ map { $_->{device} } @$raids ]);
+ my $prev_device = $md_part->{device};
$in->ask_from('', '',
[
-{ label => N("device"), val => \$md, list => [ map { "md$_" } grep { $nb == $_ || !$raids->[$_] } 0..8 ] },
-{ label => N("level"), val => \$raids->[$nb]{level}, list => [ qw(0 1 4 5 linear) ] },
-{ label => N("chunk size"), val => \$raids->[$nb]{'chunk-size'} },
+{ label => N("device"), val => \$md_part->{device}, list => [ $md_part->{device}, @free_mds ] },
+{ label => N("level"), val => \$md_part->{level}, list => [ qw(0 1 4 5 linear) ] },
+{ label => N("chunk size in KiB"), val => \$md_part->{'chunk-size'} },
],
) or return;
- raid::updateSize($raids->[$nb]); # changing the raid level changes the size available
- raid::changeNb($raids, $nb, first($md =~ /(\d+)/));
+ raid::change_device($md_part, $prev_device);
+ raid::updateSize($md_part); # changing the raid level changes the size available
+ 1;
}
@@ -1182,7 +1184,7 @@ sub format_part_info {
$info .= N("Partition booted by default\n (for MS-DOS boot, not for lilo)\n") if $part->{active} && $::expert;
if (isRAID($part)) {
$info .= N("Level %s\n", $part->{level});
- $info .= N("Chunk size %s\n", $part->{'chunk-size'});
+ $info .= N("Chunk size %d KiB\n", $part->{'chunk-size'});
$info .= N("RAID-disks %s\n", join ", ", map { $_->{device} } @{$part->{disks}});
} elsif (isLoopback($part)) {
$info .= N("Loopback file name: %s", $part->{loopback_file});
diff --git a/perl-install/fs/get.pm b/perl-install/fs/get.pm
index 3ac3ba0b4..cce7b61ec 100644
--- a/perl-install/fs/get.pm
+++ b/perl-install/fs/get.pm
@@ -15,8 +15,7 @@ sub empty_all_hds() {
sub fstab {
my ($all_hds) = @_;
my @parts = map { partition_table::get_normal_parts($_) } hds($all_hds);
- my @raids = grep { $_ } @{$all_hds->{raids}};
- @parts, @raids, @{$all_hds->{loopbacks}};
+ @parts, @{$all_hds->{raids}}, @{$all_hds->{loopbacks}};
}
sub really_all_fstab {
my ($all_hds) = @_;
@@ -26,8 +25,7 @@ sub really_all_fstab {
sub fstab_and_holes {
my ($all_hds) = @_;
- my @raids = grep { $_ } @{$all_hds->{raids}};
- hds_fstab_and_holes(hds($all_hds)), @raids, @{$all_hds->{loopbacks}};
+ hds_fstab_and_holes(hds($all_hds)), @{$all_hds->{raids}}, @{$all_hds->{loopbacks}};
}
sub holes {
diff --git a/perl-install/fsedit.pm b/perl-install/fsedit.pm
index 0d368172f..1990becd1 100644
--- a/perl-install/fsedit.pm
+++ b/perl-install/fsedit.pm
@@ -61,57 +61,12 @@ sub raids {
my ($hds) = @_;
my @parts = fs::get::hds_fstab(@$hds);
- {
- my @l = grep { isRawRAID($_) } @parts or return [];
- detect_devices::raidAutoStart(@l);
- }
-
- fs::get_major_minor(@parts);
-
- my @raids;
- my @mdstat = cat_("/proc/mdstat");
- for (my $i = 0; $i < @mdstat; $i++) {
-
- my ($nb, $level, $mdparts) =
- #- line format is:
- #- md%d : {in}?active{ (read-only)}? {linear|raid1|raid4|raid5}{ DEVNAME[%d]{(F)}?}*
- $mdstat[$i] =~ /^md(\d+).* ([^ \[\]]+) (\S+\[\d+\].*)/ or next;
-
- $level =~ s/raid//; #- { linear | raid0 | raid1 | raid5 } -> { linear | 0 | 1 | 5 }
-
- my $chunks = $mdstat[$i+1] =~ /(\S+) chunks/ ? $1 : "64k";
-
- my @raw_mdparts = map { /([^\[]+)/ } split ' ', $mdparts;
-
- my $fs_type = fs::type::fs_type_from_magic({ device => "md$nb" });
- log::l("RAID: found md$nb (raid $level) chunks $chunks ", if_($fs_type, "type $fs_type "), "with parts ", join(", ", @raw_mdparts));
- $raids[$nb] = { 'chunk-size' => $chunks, fs_type => $fs_type || 'ext2', raw_mdparts => \@raw_mdparts,
- device => "md$nb", notFormatted => !$fs_type, level => $level };
- }
-
- my %devname2part = map { $_->{dev} => { %$_, device => $_->{dev} } } devices::read_proc_partitions_raw();
- each_index {
- my $raw_mdparts = delete $_->{raw_mdparts};
- my @mdparts =
- map {
- my $mdpart = $devname2part{$_} || { device => $_ };
- if (my $part = find { is_same_hd($mdpart, $_) } @parts, @raids) {
- $part->{raid} = $::i;
- fs::type::set_pt_type($part, 0xfd);
- delete $part->{mntpoint};
- $part;
- } else {
- #- forget it when not found? that way it won't break much... beurk.
- ();
- }
- } @$raw_mdparts;
-
- $_->{disks} = \@mdparts;
- } @raids;
+ my @l = grep { isRawRAID($_) } @parts or return [];
+
require raid;
- raid::update(@raids);
- \@raids;
+ raid::detect_during_install(@l) if $::isInstall;
+ raid::get_existing(@l);
}
sub lvms {
@@ -517,13 +472,15 @@ sub auto_allocate_raids {
foreach my $md (@mds) {
my @raids_ = grep { !$md->{parts} || $md->{parts} =~ /\Q$_->{mntpoint}/ } @raids;
@raids = difference2(\@raids, \@raids_);
- my $nb = raid::new($all_hds->{raids}, @raids_);
- my $part = $all_hds->{raids}[$nb];
my %h = %$md;
- delete @h{'hd', 'parts'};
- put_in_hash($part, \%h); # mntpoint, level, chunk-size, fs_type
+ delete @h{'hd', 'parts'}; # keeping mntpoint, level, chunk-size, fs_type/pt_type
+ $h{disks} = \@raids_;
+
+ my $part = raid::new($all_hds->{raids}, %h);
+
raid::updateSize($part);
+ push @raids, $part; #- we can build raid over raid
}
}
diff --git a/perl-install/install2.pm b/perl-install/install2.pm
index 5b3211dd3..d7e6c4977 100644
--- a/perl-install/install2.pm
+++ b/perl-install/install2.pm
@@ -201,7 +201,7 @@ sub formatPartitions {
}
require raid;
- raid::prepare_prefixed($o->{all_hds}{raids}, $o->{prefix});
+ raid::prepare_prefixed($o->{all_hds}{raids});
#- needed by lilo
if (my @vgs = map { $_->{VG_name} } @{$o->{all_hds}{lvms}}) {
diff --git a/perl-install/install_any.pm b/perl-install/install_any.pm
index 69aca812d..e1fd4a458 100644
--- a/perl-install/install_any.pm
+++ b/perl-install/install_any.pm
@@ -472,7 +472,7 @@ sub setDefaultPackages {
push @{$o->{default_packages}}, "brltty" if cat_("/proc/cmdline") =~ /brltty=/;
push @{$o->{default_packages}}, "nfs-utils-clients" if $o->{method} eq "nfs";
push @{$o->{default_packages}}, "numlock" if $o->{miscellaneous}{numlock};
- push @{$o->{default_packages}}, "raidtools" if !is_empty_array_ref($o->{all_hds}{raids});
+ push @{$o->{default_packages}}, "mdadm" if !is_empty_array_ref($o->{all_hds}{raids});
push @{$o->{default_packages}}, "lvm2" if !is_empty_array_ref($o->{all_hds}{lvms});
push @{$o->{default_packages}}, "alsa", "alsa-utils" if any { $o->{modules_conf}->get_alias("sound-slot-$_") =~ /^snd-/ } 0 .. 4;
push @{$o->{default_packages}}, "grub" if isLoopback(fs::get::root($o->{fstab}));
diff --git a/perl-install/raid.pm b/perl-install/raid.pm
index d91f3984b..a91466a6b 100644
--- a/perl-install/raid.pm
+++ b/perl-install/raid.pm
@@ -15,65 +15,60 @@ use fs;
sub max_nb() { 31 }
-sub nb {
- my ($nb) = @_;
- first((ref($nb) ? $nb->{device} : $nb) =~ /(\d+)/);
-}
-
sub new {
- my ($raids, @parts) = @_;
- my $nb = @$raids;
- $raids->[$nb] = { 'chunk-size' => "64k", fs_type => 'ext3', disks => [ @parts ], device => "md$nb", notFormatted => 1, level => 1 };
- foreach my $part (@parts) {
- $part->{raid} = $nb;
- delete $part->{mntpoint};
+ my ($raids, %opts) = @_;
+ my $md_part = { %opts };
+ add2hash_($md_part, { 'chunk-size' => '64', disks => [],
+ device => 'md' . int(@$raids),
+ notFormatted => 1, level => 1 });
+ push @$raids, $md_part;
+ foreach (@{$md_part->{disks}}) {
+ $_->{raid} = $md_part->{device};
+ fs::type::set_pt_type($_, 0xfd);
+ delete $_->{mntpoint};
}
- update($raids->[$nb]);
- $nb;
+ update($md_part);
+ $md_part;
}
sub add {
- my ($raids, $part, $nb) = @_; $nb = nb($nb);
- $raids->[$nb]{isMounted} and die N("Can't add a partition to _formatted_ RAID md%d", $nb);
- inactivate_and_dirty($raids->[$nb]);
+ my ($md_part, $part) = @_;
+ $md_part->{isMounted} and die N("Can't add a partition to _formatted_ RAID %s", $md_part->{device});
+ inactivate_and_dirty($md_part);
set_isFormatted($part, 0);
- $part->{raid} = $nb;
+ $part->{raid} = $md_part->{device};
delete $part->{mntpoint};
- push @{$raids->[$nb]{disks}}, $part;
- update($raids->[$nb]);
+ push @{$md_part->{disks}}, $part;
+ update($md_part);
}
sub delete {
- my ($raids, $nb) = @_;
- $nb = nb($nb);
- inactivate_and_dirty($raids->[$nb]);
- delete $_->{raid} foreach @{$raids->[$nb]{disks}};
- undef $raids->[$nb];
+ my ($raids, $md_part) = @_;
+ inactivate_and_dirty($md_part);
+ delete $_->{raid} foreach @{$md_part->{disks}};
+ @$raids = grep { $_ != $md_part } @$raids;
}
-sub changeNb {
- my ($raids, $oldnb, $newnb) = @_;
- if ($oldnb != $newnb) {
- inactivate_and_dirty($raids->[$_]) foreach $oldnb, $newnb;
-
- ($raids->[$newnb], $raids->[$oldnb]) = ($raids->[$oldnb], undef);
- $raids->[$newnb]{device} = "md$newnb";
- $_->{raid} = $newnb foreach @{$raids->[$newnb]{disks}};
+sub change_device {
+ my ($md_part, $prev_device) = @_;
+ if ($prev_device ne $md_part->{device}) {
+ inactivate_and_dirty({ device => $prev_device });
+ $_->{raid} = $md_part->{device} foreach @{$md_part->{disks}};
}
- $newnb;
}
sub removeDisk {
my ($raids, $part) = @_;
- my $nb = nb($part->{raid});
- inactivate_and_dirty($raids->[$nb]);
+ my $md_part = fs::get::device2part($part->{raid}, $raids);
+ inactivate_and_dirty($md_part);
+ fs::type::set_isFormatted($part, 0);
delete $part->{raid};
- my $disks = $raids->[$nb]{disks};
+ my $disks = $md_part->{disks};
@$disks = grep { $_ != $part } @$disks;
if (@$disks) {
- update($raids->[$nb]);
+ update($md_part);
} else {
- undef $raids->[$nb];
+ @$raids = grep { $_ != $md_part } @$raids;
}
}
@@ -103,27 +98,6 @@ sub update {
updateSize($_) foreach @_;
}
-sub write {
- my ($raids, $file) = @_;
- return if $::testing;
-
- output($file,
- map {
- my $s = sprintf(<<EOF, devices::make($_->{device}), $_->{level}, $_->{'chunk-size'}, int @{$_->{disks}});
-raiddev %s
-raid-level %s
-chunk-size %s
-persistent-superblock 1
-nr-raid-disks %d
-EOF
- my @devs = map_index {
- " device " . devices::make($_->{device}) . "\n raid-disk $::i\n";
- } @{$_->{disks}};
-
- $s, @devs
- } grep { $_ } @$raids);
-}
-
sub make {
my ($raids, $part) = @_;
@@ -132,11 +106,15 @@ sub make {
inactivate_and_dirty($part);
isRAID($_) and make($raids, $_) foreach @{$part->{disks}};
- my $dev = devices::make($part->{device});
eval { modules::load(module($part)) };
- &write($raids, "/etc/raidtab");
- run_program::run("mkraid", "--really-force", $dev) or die
- $::isStandalone ? N("mkraid failed (maybe raidtools are missing?)") : N("mkraid failed");
+
+ whereis_binary('mdadm') or die 'mdadm not installed';
+
+ run_program::run_or_die('mdadm', '--create', '--run', devices::make($part->{device}),
+ '--chunk=' . $part->{'chunk-size'},
+ "--level=$part->{level}",
+ '--raid-devices=' . int(@{$part->{disks}}),
+ map { devices::make($_->{device}) } @{$part->{disks}});
}
sub format_part {
@@ -150,27 +128,18 @@ sub format_part {
sub verify {
my ($raids) = @_;
- $raids or return;
- foreach (grep { $_ } @$raids) {
+ foreach (@$raids) {
@{$_->{disks}} >= ($_->{level} =~ /4|5/ ? 3 : 2) or die N("Not enough partitions for RAID level %d\n", $_->{level});
}
}
sub prepare_prefixed {
- my ($raids, $prefix) = @_;
- $raids or return;
-
- &write($raids, "/etc/raidtab") if ! -e "/etc/raidtab";
-
- eval { cp_af("/etc/raidtab", "$prefix/etc/raidtab") };
- foreach (grep { $_ } @$raids) {
- devices::make("$prefix/dev/$_->{device}") foreach @{$_->{disks}};
- }
+ my ($_raids) = @_;
}
sub inactivate_and_dirty {
my ($part) = @_;
- run_program::run("raidstop", devices::make($part->{device}));
+ run_program::run('mdadm', '--stop', devices::make($part->{device}));
set_isFormatted($part, 0);
}
@@ -178,11 +147,94 @@ sub active_mds() {
map { if_(/^(md\d+) /, $1) } cat_("/proc/mdstat");
}
+sub detect_during_install {
+ my (@parts) = @_;
+ detect_during_install_once(@parts);
+ detect_during_install_once(@parts) if active_mds(); #- try again to detect RAID 10
+}
+
+sub detect_during_install_once {
+ my (@parts) = @_;
+ devices::make("md$_") foreach 0 .. max_nb();
+ output('/etc/mdadm.conf', join(' ', 'DEVICE',
+ (map { "/dev/$_" } active_mds()),
+ map { devices::make($_->{device}) } @parts), "\n");
+ run_program::run('mdadm', '>>', '/etc/mdadm.conf', '--examine', '--scan');
+
+ foreach (@{parse_mdadm_conf(scalar cat_('/etc/mdadm.conf'))->{ARRAY}}) {
+ eval { modules::load($_->{level}) };
+ }
+ run_program::run('mdadm', '--assemble', '--scan');
+}
+
+sub get_existing {
+ my @parts = @_;
+ my $raids = [];
+ foreach my $md (active_mds()) {
+ my $conf = parse_mdadm_conf(scalar run_program::get_stdout('mdadm', '--detail', '--brief', devices::make($md)));
+
+ @{$conf->{ARRAY}} == 1 or internal_error("too many answers");
+ my $raw_part = $conf->{ARRAY}[0];
+
+ $raw_part->{level} =~ s/raid//; #- { linear | raid0 | raid1 | raid5 } -> { linear | 0 | 1 | 5 }
+
+ my @mdparts =
+ map {
+ if (my $part = fs::get::device2part($_, [ @parts, @$raids ])) {
+ $part;
+ } else {
+ log::l("ERROR: unknown raw raid device $_");
+ ();
+ }
+ } split(',', $raw_part->{devices});
+
+ my $md_part = new($raids, device => $md, level => $raw_part->{level}, disks => \@mdparts);
+
+ my $fs_type = fs::type::fs_type_from_magic($md_part);
+ fs::type::set_fs_type($md_part, $fs_type || 'ext3');
+ fs::type::set_isFormatted($md_part, to_bool($fs_type));
+
+ log::l("RAID: found $md (raid $md_part->{level}) type $fs_type with parts $raw_part->{devices}");
+ }
+ $raids;
+}
+
sub is_active {
my ($dev) = @_;
member($dev, active_mds());
}
-sub inactivate_all() { run_program::run("raidstop", devices::make($_)) foreach active_mds() }
+sub inactivate_all() {
+ run_program::run('mdadm', '--stop', devices::make($_)) foreach active_mds();
+}
+
+sub prepare_prefixed {
+ my ($raids) = @_;
+ my %raids = map {
+ devices::make($_->{device}) =>
+ [ map { devices::make($_->{device}) } @{$_->{disks}} ]
+ } @$raids;
+
+ output("$::prefix/etc/mdadm.conf",
+ join(' ', 'DEVICE', uniq(map { @$_ } values %raids)) . "\n",
+ map_each { "ARRAY $::a devices=" . join(',', @$::b) . "\n" } %raids);
+}
+
+sub parse_mdadm_conf {
+ my ($s) = @_;
+ my %conf = (DEVICE => [], ARRAY => []);
+ $s =~ s!^\s*#.*!!gm; #- remove comments
+ $s =~ s!\n(\s)!$1!g; #- join lines starting with a space
+ foreach (split("\n", $s)) {
+ if (/^DEVICE\s+(.*)/) {
+ push @{$conf{DEVICE}}, split(' ', $1);
+ } elsif (my ($md, $md_conf) = /^ARRAY\s+(\S+)\s*(.*)/) {
+ my %md_conf = map { if_(/(.*)=(.*)/, $1 => $2) } split(' ', $md_conf);
+ $md_conf{device} = $md;
+ push @{$conf{ARRAY}}, \%md_conf;
+ }
+ }
+ \%conf
+}
1;
diff --git a/perl-install/share/list.i386 b/perl-install/share/list.i386
index b97149f4b..2ac279ec4 100644
--- a/perl-install/share/list.i386
+++ b/perl-install/share/list.i386
@@ -1,9 +1,8 @@
-/sbin/mkraid
+/sbin/mdadm
/sbin/mkreiserfs
/sbin/mkfs.jfs
/sbin/mkfs.xfs
/sbin/fsck.jfs
-/sbin/raidstart
/sbin/ifport
/sbin/mkdosfs
/sbin/resize_reiserfs