summaryrefslogtreecommitdiffstats
path: root/perl-install/raid.pm
blob: 7cc2eb7d673658b5655be157b26ec5d8f11a8358 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
package raid;

use diagnostics;
use strict;

#-######################################################################################
#- misc imports
#-######################################################################################
use common qw(:common :functional);
use run_program;
use devices;
use fs;

sub nb($) { 
    my ($nb) = @_;
    first((ref $nb ? $nb->{device} : $nb) =~ /(\d+)/);
}

sub is($) {
    my ($part) = @_;
    $part->{device} =~ /^md/;
}

sub new($$) {
    my ($raid, $part) = @_;
    my $nb = @$raid; 
    $raid->[$nb] = { 'chunk-size' => "64k", type => 0x83, disks => [ $part ], device => "md$nb", notFormatted => 1 };
    $part->{raid} = $nb;
}

sub add($$$) {
    my ($raid, $part, $nb) = @_;
    $raid->[$nb]{isMounted} and die _("Can't add a partition to _formatted_ RAID md%d", $nb);
    $part->{raid} = $nb;
    push @{$raid->[$nb]{disks}}, $part;
}

sub delete($$) {
    my ($raid, $nb) = @_;
    $nb = nb($nb);

    delete $_->{raid} foreach @{$raid->[$nb]{disks}};
    $raid->[$nb] = undef;
}

sub removeDisk($$) {
    my ($raid, $part) = @_;
    my $nb = nb($part->{raid});
    delete $part->{raid};
    @{$raid->[$nb]{disks}} = grep { $_ != $part } @{$raid->[$nb]{disks}};
    update($raid->[$nb]);
}

sub updateSize($) {
    my ($part) = @_;
    local $_ = $part->{level};
    my @l = map { $_->{size} } @{$part->{disks}};

    $part->{size} = do {
	if (/0|linear/) { sum @l        }
	elsif (/1/  )   { min @l        }
	elsif (/4|5/)   { min(@l) * $#l }
    };
}

sub updateIsFormatted($) {
    my ($part) = @_;
    $part->{isFormatted}  = and_ map { $_->{isFormatted}  } @{$part->{disks}};
    $part->{notFormatted} = and_ map { $_->{notFormatted} } @{$part->{disks}};
}
sub update($) {
    &updateSize;
    &updateIsFormatted;
}

sub write($) {
    my ($raid, $file) = @_;
    local *F;
    local $\ = "\n";

    foreach (grep {$_} @$raid) {
	open F, ">$file" or die _("Can't write file $file");
	print F <<"EOF";
raiddev       /dev/$_->{device}
raid-level    $_->{level}
chunk-size    $_->{'chunk-size'}
persistent-superblock 1
EOF
	print F "nr-raid-disks ", int @{$_->{disks}};
	map_index {
	    print F "    device    /dev/$_->{device}";
	    print F "    raid-disk $::i";
	} @{$_->{disks}};
    }
}

sub make($$) {
    my ($raid, $part) = @_;
    my $dev = devices::make($part->{device});
    run_program::run("raidstop", $dev);
    &write($raid, "/etc/raidtab");
    run_program::run("mkraid", "--really-force", $dev);
    run_program::run("raidstart", $dev);
}

sub format_part($$) {
    my ($raid, $part) = @_;
    make($raid->{raid}, $part) if is($part);
    fs::format_part($part);
}

1;