-=-=-- DrakX is a very big project, and it needs special setups to work. The purpose of this file is to explain how you can setup your box to make it compile and run. -=-=-- Beware, don't try this on a production machine with important data. -------------------------------------------------------------------------- Sources installation: First grab the gi.tar.bz2 archive and untar it in your home directory, for example from DrakX-*.src.rpm on your Mandrake Linux distribution. cd to gi for i in `du -a | grep CVS/Root | cut -f 2` do sed -e 's/prigaux/anoncvs/' $i > $i.tmp mv $i.tmp $i done Then, log yourself into the cvs: % export CVS_RSH=ssh % export CVSROOT=:ext:anoncvs@cvs.mandrakesoft.com:/cooker % cvs checkout gi (passwd: 'cvs') And update the gi package: cvs update -P -d -------------------------------------------------------------------------- Preparing the compilation process: (1) target directory create a /export directory and copy a recent Mandrake Linux CD in there. (You don't have to put have all the RPMS...) ; you'll need roughly 1.5 Gbytes for a full install. [gc@obiwan ~/cvs/gi] su -c "mkdir /export" (2) devel packages you need quite a few devel packages to run the stuff; roughly: gcc, make, glibc-devel, perl-devel, XFree86-devel, libglib-devel, libgtk+-devel, perl-GTK, ldetect*, libslang-devel, libnewt-devel, e2fsprogs, dosfstools, rpm-devel, popt-devel, rpmtools, libbzip2*, libncurses*. you may need a few others I forgot to mention. if the compilation fails, try to understand the message and install any necessary remaining package. (3) sudo never build or run DrakX as root; install package sudo, and set up relevant permissions; the following should be enough: (in your /etc/sudoers) gc ALL=(root) NOPASSWD:/usr/bin/patch,NOPASSWD:/bin/rpm,NOPASSWD:/bin/mount,NOPASSWD:/bin/cp,NOPASSWD:/bin/umount,NOPASSWD:/usr/bin/install,NOPASSWD:/bin/rm,NOPASSWD:/bin/mv,NOPASSWD:/bin/tar,NOPASSWD:/bin/cpio,NOPASSWD:/bin/chown,NOPASSWD:/bin/mkdir,NOPASSWD:/usr/bin/strip,NOPASSWD:/bin/mknod (4) boot kernel you need one or more kernels and (all?) their modules. it's located in subdirectory "all.kernels" in DrakX-*.src.rpm ; if you ever grab (or build) another boot kernel, replace or add an entry in "all.kernels" as: (a) create your modules subdir (useful to describe the VERSION_RELEASE) and untar your kernel [gc@obiwan ~/cvs/gi/all.kernels] mkdir 2.4.1-BOOTcustom [gc@obiwan ~/cvs/gi/all.kernels] cd 2.4.1-BOOTcustom [gc@obiwan ~/cvs/gi/all.kernels/2.4.1-BOOTcustom] tar jxvf ~/mycustomkernel.tar.bz2 [gc@obiwan ~/cvs/gi/all.kernels/2.4.1-BOOTcustom] ls boot/ cardmgr/ lib/ (c) build kernel/modules stuff for stage1 and stage2 [gc@obiwan ~/cvs/gi] ./update_kernel (5) pray [gc@obiwan ~/cvs/gi] make --------------------------------------------------------------------------- The comments written with #- are automatically stripped out at install. --------------------------------------------------------------------------- testing all: go to the perl-install directory and execute ./g_auto_install --test You should be able to test the whole thing in a non-destructive way. NEVER compile and/or execute DrakX as root! Here is how I (dams) made it work on my computer. ------------------------------------------------- - get the sources - install the librairies needed included newt-devel gtk+-devel popt-devel popt gtk-engines - cd path/to/gi - make - mkdir /usr/share/gtk - ln -s path/to/gi/perl-install/share/themes /usr/share/gtk - ln -s path/to/gi/perl-install/share/step-* /usr/share - ln -s path/to/gi/perl-install/share/help.xpm /usr/share - ln -s path/to/gi/perl-install/share/isdn* /etc/sysconfdir/network-scripts - have a cd architecture linked on /export - ln -s /export /tmp/rhimage - export PERL_INSTALL_TEST=1 - cd path/to/gi/perl-install - gendistrib --noclean --distrib /export - ./install2 in root (dangerous) or chmod a+r /dev/hd* and ./install2 in user address all bugreports to dave@null.com -13680'>user/erwan/bug-13680 Mageia Installer and base platform for many utilitiesThierry Vignaud [tv]
summaryrefslogtreecommitdiffstats
path: root/perl-install/raid.pm
blob: 4c0b6ca2c98d055222a586d090f380c9c1354f1f (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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
package raid; # $Id$

use diagnostics;
use strict;

#-######################################################################################
#- misc imports
#-######################################################################################
use common;
use fs::type;
use run_program;
use devices;
use modules;

sub max_nb() { 31 }

sub check_prog {
    my ($in) = @_;
    $::isInstall || $in->do_pkgs->ensure_binary_is_installed('mdadm', 'mdadm');
}

sub new {
    my ($raids, %opts) = @_;
    my $md_part = { %opts };
    add2hash_($md_part, { 'chunk-size' => '64', disks => [], 
			  fs_type => 'ext3',
			  device => first(free_mds($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($md_part);
    $md_part;
}

sub add {
    my ($md_part, $part) = @_;
    $md_part->{isMounted} and die N("Can not add a partition to _formatted_ RAID %s", $md_part->{device});
    inactivate_and_dirty($md_part);
    set_isFormatted($part, 0);
    $part->{raid} = $md_part->{device};
    delete $part->{mntpoint};
    push @{$md_part->{disks}}, $part;
    update($md_part);
}

sub delete {
    my ($raids, $md_part) = @_;
    inactivate_and_dirty($md_part);
    delete $_->{raid} foreach @{$md_part->{disks}};
    @$raids = grep { $_ != $md_part } @$raids;
}

sub change_device {
    my ($md_part, $new_device) = @_;
    if ($new_device ne $md_part->{device}) {
	inactivate_and_dirty($md_part);
	$md_part->{device} = $new_device;
	$_->{raid} = $new_device foreach @{$md_part->{disks}};
    }
}

sub removeDisk {
    my ($raids, $part) = @_;
    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 = $md_part->{disks};
    @$disks = grep { $_ != $part } @$disks;
    if (@$disks) {
	update($md_part);
    } else {
	@$raids = grep { $_ != $md_part } @$raids;
    }
}

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 module {
    my ($part) = @_;
    my $mod = $part->{level};

    $mod = 5 if $mod eq "4";
    $mod = "raid$mod" if $mod =~ /^\d+$/;
    $mod;
}


sub update {
    updateSize($_) foreach @_;
}

sub make {
    my ($raids, $part) = @_;    

    return if is_active($part->{device});

    inactivate_and_dirty($part);

    isRAID($_) and make($raids, $_) foreach @{$part->{disks}};
    eval { modules::load(module($part)) };

    whereis_binary('mdadm') or die 'mdadm not installed';

    my $dev = devices::make($part->{device});

    run_program::run_or_die('mdadm', '--create', '--run', $dev, 
			    '--chunk=' . $part->{'chunk-size'}, 
			    "--level=$part->{level}", 
			    '--raid-devices=' . int(@{$part->{disks}}),
			    map { devices::make($_->{device}) } @{$part->{disks}});

    if (my $raw_part = get_md_info($dev)) {
	$part->{UUID} = $raw_part->{UUID};
    }
    write_conf($raids) if $::isStandalone;
}

sub format_part {
    my ($raids, $part) = @_;
    $part->{isFormatted} and return;

    make($raids, $part);
    fs::format::part_raw($part, undef);
    set_isFormatted($_, 1) foreach @{$part->{disks}};
}

sub verify {
    my ($raids) = @_;
    foreach (@$raids) {
	@{$_->{disks}} >= ($_->{level} =~ /4|5/ ? 3 : 2) or die N("Not enough partitions for RAID level %d\n", $_->{level});
    }
}

sub inactivate_and_dirty {
    my ($part) = @_;
    run_program::run('mdadm', '--stop', devices::make($part->{device}));
    set_isFormatted($part, 0);
}

sub active_mds() {
    map { if_(/^(md\d+)\s*:\s*active/, $1) } cat_("/proc/mdstat");
}
sub inactive_mds() {
    map { if_(/^(md\d+)\s*:\s*inactive/, $1) } cat_("/proc/mdstat");
}

sub free_mds {
    my ($raids) = @_;
    difference2([ map { "md$_" } 0 .. max_nb() ], [ map { $_->{device} } @$raids ]);
}

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

    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($_));
    }
}

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 $raw_part = get_md_info(devices::make($md)) or next;

	$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, UUID => $raw_part->{UUID}, level => $raw_part->{level}, disks => \@mdparts);

	my $type = fs::type::type_subpart_from_magic($md_part);
	if ($type) {
	    put_in_hash($md_part, $type);
	} else {
	    fs::type::set_fs_type($md_part, 'ext3');
	}
	my $fs_type = $type && $type->{fs_type};
	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 write_conf {
    my ($raids) = @_;

    @$raids or return;

    my @devices = uniq(map { devices::make($_->{device}) } map { @{$_->{disks}} } @$raids);

    output("$::prefix/etc/mdadm.conf",
	   join(' ', 'DEVICE', @devices) . "\n",
	   map { "ARRAY " . devices::make($_->{device}) . " UUID=$_->{UUID} auto=yes\n" } @$raids);
}

sub get_md_info {
    my ($dev) = @_;
    my $conf = parse_mdadm_conf(scalar run_program::get_stdout('mdadm', '--detail', '--brief', $dev));