/[fai]/trunk/bin/setup_harddisks
ViewVC logotype

Contents of /trunk/bin/setup_harddisks

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4292 - (show annotations) (download)
Wed May 23 15:49:57 2007 UTC (5 years, 11 months ago) by lange
File size: 37036 byte(s)
fix file system type of /proc
1 #!/usr/bin/perl
2
3 # $Id$
4 #*********************************************************************
5 #
6 # setup_harddisks -- create partitions and filesystems on harddisk
7 #
8 # This script is part of FAI (Fully Automatic Installation)
9 # Copyright (c) 1999, 2000 by ScALE Workgroup, Universitaet zu Koeln
10 # Copyright (c) 2000-2007 by Thomas Lange, Uni Koeln
11 #
12 #*********************************************************************
13 # This program is free software; you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation; either version 2 of the License, or
16 # (at your option) any later version.
17 #
18 # This program is distributed in the hope that it will be useful, but
19 # WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 # General Public License for more details.
22 #
23 # You should have received a copy of the GNU General Public License
24 # along with this program; see the file COPYING. If not, write to the
25 # Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
26 # MA 02111-1307, USA.
27 #*********************************************************************
28 #
29 # This program first read the configfiles, partitions and formats the harddisks,
30 # produces fstab and FAI-variables-file. It uses sfdisk, mke2fs, mkswap
31 #
32 # Parameters:
33 # [-X] no test, your harddisks will be formated
34 # default: only test, no real formating
35 # [-f<config-filename>] default: parse classes
36 # [-c<class-path>] default: $FAI/disk_config/
37 # [-d] default: no DOS alignment
38 #
39 #---------------------------------------------------
40 # Last changes: see svn log
41 # Last changes: 31.3.2005 by Thomas Lange add sub mapdisk{}
42 # Last changes: 8.11.2004 by Thomas Lange add $devdisklist when calling sfdisk
43 # Last changes: 3.2.2004 by Thomas Lange typos
44 # Last changes: 14.07.2003 by Thomas Lange add xfs filesystem support
45 # Last changes: 23.01.2003 by Thomas Lange print info data to stdout
46 # Last changes: 03.12.2002 by Thomas Lange remove ida, cciss stuff. Just match everything
47 # Last changes: 27.11.2002 by Thomas Lange allow more that 3 primary partitions
48 # Last changes: 14.05.2002 by Thomas Lange use strict
49 # Last changes: 04.05.2002 by Thomas Lange use strict
50 # Last changes: 29.04.2002 by Thomas Lange add swaplist
51 # Last changes: 12.01.2002 by Thomas Lange
52 # /dev/ida/ patch 12.01.2002 by Marc Martinez <lastxit+fai@technogeeks.org>
53 # Last changes: 9.11.2001 by Thomas Lange
54 # reiserfs patch 8.11.2001 by Diane Trout <diane@caltech.edu>
55 # Last changes: 25.10.2001 by Thomas Lange
56 # Last changes: 09.07.2001 by Thomas Lange
57 # Last changes: 04.07.2001 by Thomas Lange
58 # Last changes: 06.05.2001 by Thomas Lange
59 # Last changes: 09.03.2001 by Thomas Lange
60 # Last changes: 05.12.2000 by Thomas Lange
61 # Last changes: 03.05.2000 by Thomas Lange
62 # Last changes: 03.04.2000 by Mattias Gaertner
63 #---------------------------------------------------
64 #
65 # config-file format:
66 # lines beginning with # are comments
67 #
68 # "disk_config <device>|<diskN>|end"
69 # The disk_config command starts the parsing.
70 # It has to be the first command.
71 # <device> is the harddisk to format in short form like "hda" or "sdc".
72 # <diskN> if first is used, the N-th disk of $disklist is used
73 # "end" = end parsing here
74 # Example: "disk_config hdb"
75 # Example: "disk_config disk3"
76 #
77 # Defining one partition:
78 # "primary|logical mountpoint|swap|- <size in mb>|preserve<No> [fstab-options][;extraordinary options]"
79 # "primary|logical":
80 # "primary": this are the bootable partitions like the
81 # root directory "/" or the DOS "C:" disk.
82 # "logical": this are all other partitions like a linux
83 # "/var" or a swap partition or a DOS disk.
84 #
85 # "mountpoint|swap|-":
86 # "mountpoint":
87 # This is the mount-point for fstab.
88 # For example "/","/var","/usr". There must not
89 # be a space in the mountpoint.
90 # "swap":
91 # swap-partitions
92 # "-":
93 # do not mount this partition.
94 #
95 # "<size in mb>|preserve<No>":
96 # "<size in mb>":
97 # The size of the partition in megabyte
98 # Examples:
99 # "30" = 30 mb
100 # "10-100" = 10 to 100 mb
101 # "20-" = minimum of 20 mb
102 # "-500" = 1 to 500 mb
103 # The megabytes will be rounded up to cylinders.
104 # "preserve<No>":
105 # This is the alternative for the size attribute.
106 # <No> is the partition number. For example
107 # preserve3 for the third partition. If the
108 # <device> was hda then this results in hda3.
109 # The partition will be left unchanged. This
110 # is useful if you have partitions that do not
111 # need re-installation or if you want to have
112 # other operation systems on the device together
113 # with Linux. Extended Partitions can not be preserved.
114 # The bootable flag will not be preserved.
115 # Preserved partitions are mounted readonly during
116 # installation.
117 #
118 # "fstab-options":
119 # These options are copied to the fstab-file. The
120 # default is "default"
121 #
122 # After the semicolon there could be extra options like:
123 # -i <bytes> : Bytes per inodes
124 # (only ext2/3 filesystem)
125 # -m <blocks>% : reserved blocks percentage for superuser
126 # (only ext2/3 filesystem)
127 # -j : format in ext3
128 # -c : check for bad blocks
129 # format : Always format this partition even if preserve
130 # lazyformat : Do not format if partition has not moved
131 # (useful for testing the installation)
132 # boot : make this partition the boot-partition (the
133 # linux root filesystem is the default)
134 # ext2 : Extended 2 filesystem (this is the default)
135 # swap : swap partition
136 # dosfat16 : DOS 16bit FAT file system
137 # winfat32 : Win95 FAT32 file system
138 # writable : mounts a preserved partition writable
139 # xfs : xfs
140 # reiser : reiserfs
141 # -h <hash> : set reiserfs hash
142 # -v <ver> : set reiserfs version
143 #
144 use strict;
145 # getopts variables:
146 our ($opt_X, $opt_f, $opt_c, $opt_d);
147 my $test;
148
149 $| = 1; # flush always
150
151 #****************************************************
152 # Variables
153 #****************************************************
154
155 my $Version = "version 0.43fai";
156
157 my $megabyte = 1024 * 1024; # guess
158 # $gigabyte = 1024 * $megabyte;
159 my $sectorsize = 512;
160
161 # used programs
162 my $sfdisk_options = "-q $ENV{sfdisk}"; # be quiet
163 my $mke2fs_options = "-q"; # be quiet
164 my $mkreiserfs_options = "";
165 my $mkxfs_options = "-f";
166 my $mkswap_options = "";
167
168 # FAI input variables
169 my $ClassPath = "$ENV{FAI}/disk_config";# this directory contains the classes
170 my $ConfigFileName = ""; # alternative classfile, only for tests
171 my $DOS_Alignment = ""; # align partitions for tracks
172
173 # FAI output variables
174 my $BootPartition = ""; # the boot partition like "hda1"
175 my $BOOT_DEVICE = ""; # the root device like "hda" or "sdb"
176 my $FAIOutputFile = "$ENV{LOGDIR}/disk_var.sh"; # write output variables to this file
177
178 # old partition tables
179 my %DiskUnits = (); # unit size of each disk in sectors
180 my %DiskSize = (); # size of every disk in units
181 my %SectorsAlignment = (); # tracksize in sectors
182 my %PartOldBoot = (); # partition was bootable. "yes"=yes
183 my %PartOldStart = (); # old startunit of partition
184 my %PartOldEnd = (); # old endunit of partition
185 my %PartOldStartSec = (); # old startsector of partition
186 my %PartOldEndSec = (); # old endsector of partition
187 my %PartOldID = (); # old ID of partition
188 my %OldNotAligned = (); # "yes" if old partition boundaries are not DOS aligned
189
190 # mountpoints ("/<path>" or "swap<No>" or "no<No>" or "extended<disk>")
191 my $NofSwapPart = 0; # number of swap partitions
192 my $NofNotMoPart = 0; # number of not mountet partitions
193 my %DiskMountpoints = (); # mountpoints of every disk. separated by spaces
194 my %MountpointPart = (); # partition of every mountpoint. e.g. "hda2"
195 my %PartMountpoint = (); # mountpoint of every partition.
196 my @swaplist; # list of all swpa devices
197
198 # size of partition/mountpoint
199 my %MPMinSize = (); # minimum size of mountpoint in units
200 my %MPMaxSize = (); # maximum size of mountpoint in units
201 my %MPPreserve = (); # preserve partition: "yes"=yes
202 my %MPPrimary = (); # primary partition: "yes"=yes
203 my %MPStart = (); # start of partition in units
204 my %MPSize = (); # size of partition in units
205 my %MPID = (); # id of partition
206
207 # options
208 my %MPfstaboptions = (); # fstab options for every mountpoint
209 my %MPOptions = (); # extra options for every mountpoint
210
211 # sfdisk partition tables
212 my %sfdiskTables = (); # partition tables for sfdisk
213
214 my $verbose = 0;
215 $verbose = $ENV{verbose} if $ENV{verbose};
216
217 # Parse command line
218
219 use Getopt::Std;
220 &getopts('Xf:c:d') || die "
221 USAGE: [-X] no test, your harddisks will be formated
222 default: only test, no real formating
223 [-f<config-filename>] default: parse classes
224 [-c<class-path>] default: \$FAI/disk_config/
225 [-d] default: no DOS alignment
226 ";
227
228 print "setup_harddisks $Version\n";
229 if (defined $opt_X){
230 $test = 2;
231 } else {
232 print "TEST ONLY - no real formating\n\n";
233 $test = 1;
234 }
235 $ConfigFileName = $opt_f if $opt_f;# alternative config file
236 $ClassPath = $opt_c if $opt_c;# search classes here
237 $DOS_Alignment = "yes" if $opt_d; # track alignment
238
239 # main part
240 &GetAllDisks;
241 &ParseAllConfigFiles;
242 &BuildNewPartTables;
243 &PartitionPersfdisk;
244 &FormatDisks;
245 &WriteFSTab;
246 &WriteFAIVariables;
247 exit 0;
248 #****************************************************
249
250 #****************************************************
251 # get a partition pathname
252 #****************************************************
253 sub PartName {
254 my ($disk, $partno) = @_;
255 my $ppath;
256 for ($disk) {
257 /^(i2o\/)?[a-z]+$/ and $ppath = "${disk}${partno}";
258 /\d$/ and $ppath = "${disk}p${partno}";
259 }
260 return $ppath;
261 }
262
263 #****************************************************
264 # Read all partition tables of this machine
265 #****************************************************
266 sub GetAllDisks{
267 my $line=""; my $disk=""; my $device=""; my $rest; my $result; my $divi;
268 my $devdisklist="";
269
270 foreach my $device(split(/\s/,$ENV{disklist})){
271 $devdisklist = "$devdisklist /dev/$device";
272 }
273 print "Probing disks: $devdisklist\n";
274 print "Disks found:";
275 $result = `sh -c "LC_ALL=C sfdisk -g -q $devdisklist"`;
276 foreach my $line(split(/\n/,$result)){
277 if($line =~ m'^/dev/(.+?):\s+(\d+)\s+cylinders,\s+(\d+)\s+heads,\s+(\d+)\s+sectors'i){
278 $disk = $1;
279 $DiskUnits{$disk} = $3 * $4;# heads * sectors = cylinder size in sectors
280 $DiskSize{$disk} = $2; # cylinders
281 ($DOS_Alignment eq "yes") ? ($SectorsAlignment{$disk} = $4) : ($SectorsAlignment{$disk} = 1);
282 print " $disk";
283 }
284 }
285 $result = `sh -c "LC_ALL=C sfdisk -d -q $devdisklist"`;
286 foreach my $line(split(/\n/,$result)){
287 # if($line =~ m'# partition table of /dev/(cciss/c\dd\d|ida/c\dd\d|rd/c\dd\d|[a-z]+)'i){
288 # now just match all devices
289 if($line =~ m'# partition table of /dev/(\S+)$'i){
290 $disk = $1;
291 }
292 if($line =~ m#^/dev/(.+?)\s*:\s+start=\s*(\d+),\s+size=\s*(\d+),\s+Id=\s*([a-z0-9]+)\b(.*)$#i){
293 $device = $1;
294 # Sectors
295 $PartOldStartSec{$device} = $2;
296 $PartOldEndSec{$device} = $2 + $3 - 1;
297 # DiskUnits
298 $PartOldStart{$device} = int ($2 / $DiskUnits{$disk});
299 $PartOldEnd{$device} = int (($2 + $3 - 1) / $DiskUnits{$disk});
300 $divi = $2 / $SectorsAlignment{$disk};
301 ($divi != int ($divi)) && ($OldNotAligned{$device} = "yes");
302 $divi = $3 / $SectorsAlignment{$disk};
303 ($divi != int ($divi)) && ($OldNotAligned{$device} = "yes");
304 $PartOldID{$device} = $4;
305 $rest = $5;
306 $PartOldBoot{$device} = ($rest =~ /bootable/) ? "yes" : "";
307 }
308 }
309 print "\n\n";
310 }
311
312 #****************************************************
313 # parse config file or all class files
314 #****************************************************
315 sub ParseAllConfigFiles{
316 my $ConfigFileExists = 0; # no config file parsed yet
317 if ($ConfigFileName){
318 # Read config filename
319 &ParseConfigFile($ConfigFileName);
320 $ConfigFileExists = 1;
321 } else {
322 # Read classes
323 foreach my $classfile (reverse split(/\s+/,$ENV{"classes"})){
324 my $filename = "$ClassPath/$classfile";
325 if (($classfile) && (-r $filename)) {
326 &ParseConfigFile($filename);
327 $ConfigFileExists = 1;
328 }
329 ($ConfigFileExists) && last;
330 }
331 }
332 ($ConfigFileExists == 0) && die "ERROR: no config file for setup_harddisk found. Please check you classes and files in disk_config.\n";
333 }
334
335 #****************************************************
336 # map "disk_config first" to real disk device
337 #****************************************************
338 sub mapdisk {
339
340 my ($disk) = @_;
341 my @dlist = split /\s+/,$ENV{disklist};
342 unshift @dlist, "nodisk"; # add dummy element, so disk1 will be mapped to dlist[1]
343
344 if ($disk =~ /disk(\d+)/) {
345 my $n = $1;
346 print "Mapping disk name disk$n to $dlist[$n]\n";
347 $disk = $dlist[$n];
348 }
349 return $disk;
350 }
351
352 #****************************************************
353 # parse config-file
354 #****************************************************
355 sub ParseConfigFile{
356 my $size=""; my $mountpoint=""; my $device ="";
357 my $fstaboptions=""; my $options=""; my $disk=""; my $command = "";
358 my $LogPartNo; my $PrimPartNo; my $NoMoreLogicals;
359 my $LastPresPart; my $extmp; my $Min; my $Max;
360 my $filename = shift;
361 open (FILE,"$filename")
362 || die "config file not found: $filename\n";
363 (print "Using config file: $filename\n");
364 $disk = "";
365 my $a = 1, my $paras ="", my $number=0;
366 while (my $line = <FILE>){
367 chomp($line);
368 $a++;
369 next if( $line =~ /^#|^\s*$/ );
370
371 # disk_config - command
372 if ($line =~ /^disk_config(.*)/i){
373 $paras = $1;
374 if ($paras =~ / end/i){
375 $disk = "";
376 } else {
377 # if($paras =~ m# (/dev/)?(cciss/c\dd\d|ida/c\dd\d|rd/c\dd\d|[a-z]+)#i){
378 # now match all devives
379 if($paras =~ m# (/dev/)?(\S+)#i){
380 $disk = mapdisk($2);
381 ($DiskMountpoints{$disk})
382 && die "ERROR: there are more than one configuration of disk $disk.\n";
383 ($DiskSize{$disk}) || die "ERROR: could not read device /dev/$disk\n";
384 ($test != 1) || (print "config: $disk\n");
385 $DiskMountpoints{$disk} = "";
386 $MPPrimary{"extended$disk"} = "";
387 $LogPartNo = 4;
388 $PrimPartNo = 0;
389 $NoMoreLogicals = 0;
390 $LastPresPart = "";
391 $extmp = "extended$disk";
392 } else {
393 die "SYNTAX ERROR: in config file line $a, unknown disk_config parameter $paras\n$line\n";
394 }
395 }
396 }
397
398 if ($disk){
399 # primary|partition - command
400 if($line =~ /^\s*(primary|logical)\s+(.*)$/i){
401 $command = $1;
402 # split variables
403 $paras = $2;
404 $options = "";
405 if($paras =~ /(.*?)\s*;\s*(.*)$/){
406 $paras = $1;
407 $options = $2;
408 }
409 $size="";
410 $mountpoint ="";
411 $fstaboptions = "";
412 ($mountpoint,$size,$fstaboptions)=split(/\s+/,$paras);
413 # mountpoint
414 ($mountpoint =~ m#^/.*|^swap$|^-$#i)
415 || die "SYNTAX ERROR in config file line $a, mountpoint: $mountpoint\n$line\n";
416 ($MountpointPart{$mountpoint})
417 && die "SYNTAX ERROR in config file line $a. Mountpoint $mountpoint redefined.\n$line\n";
418 if($mountpoint eq "/"){
419 ($BootPartition) || ($BOOT_DEVICE = $disk);
420 }
421 if($mountpoint eq "-"){
422 $NofNotMoPart++;
423 $mountpoint = "no$NofNotMoPart";
424 }
425 if($mountpoint eq "swap"){
426 $NofSwapPart++;
427 $mountpoint = "swap$NofSwapPart";
428 ($options !~ /\bswap\b/i) && ($options .= " swap");
429 ($fstaboptions) || ($fstaboptions = "sw");
430 }
431 if($mountpoint =~ m#^/#){
432 ($fstaboptions) || ($fstaboptions = "defaults");
433 }
434 if ($command eq "primary") {
435 ($MPPrimary{$extmp} eq "yes") && ($NoMoreLogicals = 1);
436 $MPPrimary{$mountpoint} = "yes";
437 $PrimPartNo++;
438 # ($PrimPartNo == 3) && ($disk =~ /^sd/) && ($PrimPartNo++);
439 ($PrimPartNo >4 ) && die "ERROR: Too much primary partitions (max 4).".
440 " All logicals together need one primary too.\n";
441 $MountpointPart{$mountpoint} = PartName($disk,$PrimPartNo);
442 if($options =~ /\bboot\b/i){
443 ($BootPartition) && die "ERROR: only one partition can be bootable at a time.";
444 $BootPartition = $MountpointPart{$mountpoint};
445 $BOOT_DEVICE = $disk;
446 }
447 } else {
448 ($NoMoreLogicals != 0) && die "ERROR: the logical partitions must be together.\n";
449 $MPPrimary{$mountpoint} = "";
450 $LogPartNo++;
451 $MountpointPart{$mountpoint} = PartName($disk,$LogPartNo);
452 if (!$MPPrimary{$extmp}){
453 $MPPreserve{$extmp} = "";
454 $MPPrimary{$extmp} = "yes";
455 $MPMinSize{$extmp} = 0;
456 $MPMaxSize{$extmp} = 0;
457 $MPID{$extmp} = 5;
458 $PrimPartNo++;
459 ($PrimPartNo == 3) && ($disk =~ /^sd/) && ($PrimPartNo++);
460 ($PrimPartNo >4 )
461 && die "ERROR: too much primary partitions (max 4).".
462 " All logicals together need one primary too.\n";
463 $MountpointPart{$extmp} = PartName($disk,$PrimPartNo);
464 $DiskMountpoints{$disk} .= " $extmp";
465 }
466 # ($options =~ /\bboot\b/i) && die "ERROR: line $a, only primary partitions can be bootable.\n";
467 }
468 $DiskMountpoints{$disk} .= " $mountpoint";
469 # size
470 ($size =~ /^preserve\d+$|^\d+\-?\d*$|^-\d+$/i)
471 || die "SYNTAX ERROR in config file line $a, size: $size\n$line\n";
472 if($size =~ /^preserve(\d+)$/i){
473 my $number = $1;
474 $device = PartName($disk,$number);
475 ($OldNotAligned{$device} eq "yes")
476 && die "ERROR: unable to preserve partition /dev/$device. Partition is not DOS aligned.";
477 ($command eq "primary") && ($number != $PrimPartNo)
478 && die "NUMERATION ERROR in line $a, the number of the partition can not be preserved:\n$line\n";
479 ($command eq "logical") && ($number != $LogPartNo)
480 && die "NUMERATION ERROR in line $a, the number of the partition can not be preserved:\n$line\n";
481 if ($PartOldEnd{$device}){
482 (($PartOldID{$device} == 5) || ($PartOldID{$device} == 85)) &&
483 die "ERROR in config file line $a.".
484 " Extended partitions can not be preserved. /dev/$device\n$line\n";
485 $MPPreserve{$mountpoint}="yes";
486 $MPMinSize{$mountpoint} = $PartOldEnd{$device}-$PartOldStart{$device}+1;
487 $MPMaxSize{$mountpoint} = $MPMinSize{$mountpoint}; # Max=Min
488 $MPStart{$mountpoint} = $PartOldStart{$device};
489 $MPSize{$mountpoint} = $MPMinSize{$mountpoint};
490 $MPID{$mountpoint} = $PartOldID{$device};
491 } else {
492 die "ERROR: cannot preserve partition $device. partition not found.$PartOldEnd{$device}\n";
493 }
494 if ($LastPresPart) {
495 ($PartOldStart{$device} < $PartOldStart{$LastPresPart}) &&
496 die "ERROR: misordered partitions: cannot preserve partitions $LastPresPart and $device\n".
497 " in this order because of their positions on disk.";
498 }
499 $LastPresPart = $device;
500 ($MPMinSize{$mountpoint} < 1)
501 && die "ERROR: unable to preserve partitions of size 0.\n$line\n ";
502 } else {
503 # If not preserve we must know the filesystemtype
504 ($options !~ /\b(ext2|ext3|auto|swap|dosfat16|winfat32|reiser|xfs)\b/i ) && ($options .= " auto");
505 }
506 if($size =~ /^(\d*)(\-?)(\d*)$/){
507 $Min = $1;
508 $Min||= 1;
509 $Max = $3;
510 $MPMinSize{$mountpoint} = int (($Min * $megabyte - 1) / ($DiskUnits{$disk} * $sectorsize)) + 1;
511 if ($2 eq "-"){
512 if($Max =~ /\d+/){
513 $MPMaxSize{$mountpoint} = int (($Max * $megabyte - 1) / ($DiskUnits{$disk} * $sectorsize)) + 1;
514 } else {
515 $MPMaxSize{$mountpoint} = $DiskSize{$disk};
516 }
517 } else {
518 $MPMaxSize{$mountpoint} = $MPMinSize{$mountpoint}; # Max=Min
519 }
520 ($MPMinSize{$mountpoint} > $DiskSize{$disk})
521 && die "ERROR in config file line $a: Minsize larger than disk.\n$line\n";
522 ($MPMinSize{$mountpoint} > $MPMaxSize{$mountpoint})
523 && die "SYNTAX ERROR in config file line $a, MIN-MAX-size: $MPMinSize{$mountpoint}-$MPMaxSize{$mountpoint}\n$line\n";
524 ($MPMinSize{$mountpoint} < 1)
525 && die "SYNTAX ERROR in config file line $a. Minsize must be greater than 1.\n$line\n";
526 $MPPreserve{$mountpoint} = "";
527 }
528 # fstaboptions
529 $MPfstaboptions{$mountpoint} = $fstaboptions;
530 # extra options
531 ($options =~ /\b(ext[23]|auto)\b/i) && ($MPID{$mountpoint} = 83); # Linux native
532 ($options =~ /\bswap\b/i) && ($MPID{$mountpoint} = 82); # Linux swap
533 ($options =~ /\bdosfat16\b/i) && ($MPID{$mountpoint} = 6); # DOS FAT 16bit (>=32MB, will be changed later)
534 ($options =~ /\bwinfat32\b/i) && ($MPID{$mountpoint} = "b"); # Win 95 FAT 32
535 $MPOptions{$mountpoint} = $options;
536 if($test == 1){
537 print "$mountpoint,$MPMinSize{$mountpoint}-$MPMaxSize{$mountpoint},";
538 print "$fstaboptions,$options";
539 ($MPPreserve{$mountpoint} eq "yes") && (print " Preserve: $MountpointPart{$mountpoint}");
540 print "\n";
541 }
542 }
543 }
544 }
545 close(FILE);
546 }
547
548 #****************************************************
549 # Build all partition tables
550 #****************************************************
551 sub BuildNewPartTables{
552 my ($disk, $mountpoint, $part, $PrimaryMP, $LogicalMP);
553 ($test != 1) || (print "\nBuilding partition tables:\n");
554 # Build PartMountpoint array
555 foreach $disk(keys %DiskMountpoints) {
556 $DiskMountpoints{$disk} =~ s/\s(\s)/$1/g;
557 $DiskMountpoints{$disk} =~ s/^\s//;
558 $DiskMountpoints{$disk} =~ s/\s$//;
559 foreach $mountpoint(split(/\s/,$DiskMountpoints{$disk})) {
560 $PartMountpoint{$MountpointPart{$mountpoint}} = $mountpoint;
561 }
562 }
563 foreach $disk(keys %DiskMountpoints) {
564 &SetPartitionPositions($disk);
565 # change units to sectors
566 foreach $mountpoint(split(/\s/,$DiskMountpoints{$disk})) {
567 if($MPPreserve{$mountpoint} eq "yes"){
568 $MPStart{$mountpoint} = $PartOldStartSec{$MountpointPart{$mountpoint}};
569 $MPSize{$mountpoint} = $PartOldEndSec{$MountpointPart{$mountpoint}} - $MPStart{$mountpoint} + 1;
570 } else {
571 $MPStart{$mountpoint} *= $DiskUnits{$disk};
572 $MPSize{$mountpoint} *= $DiskUnits{$disk};
573 # align first partition for mbr
574 if($MPStart{$mountpoint} == 0){
575 $MPStart{$mountpoint} += $SectorsAlignment{$disk};
576 $MPSize{$mountpoint} -= $SectorsAlignment{$disk};
577 }
578 }
579 }
580 # align all logical partitions
581 foreach $mountpoint(split(/\s/,$DiskMountpoints{$disk})) {
582 next if ($MPPrimary{$mountpoint} eq "yes");
583 if ($MountpointPart{$mountpoint} eq "${disk}5") {
584 # partition with number 5 is first logical partition and start of extended partition
585 $MPStart{"extended$disk"} = $MPStart{$mountpoint};
586 ($MPPreserve{$mountpoint} eq "yes") && ($MPStart{"extended$disk"} -= $SectorsAlignment{$disk});
587 }
588 if ($MPPreserve{$mountpoint} ne "yes") {
589 $MPStart{$mountpoint} += $SectorsAlignment{$disk};
590 $MPSize{$mountpoint} -= $SectorsAlignment{$disk};
591 }
592 }
593 &CalculateExtPartSize($disk);
594 # sort mountpoints of partition number
595 $PrimaryMP = "";
596 $LogicalMP = "";
597 foreach $mountpoint(split(/\s/,$DiskMountpoints{$disk})) {
598 ($MPPrimary{$mountpoint} eq "yes") ? ($PrimaryMP .= " $mountpoint") : ($LogicalMP .= " $mountpoint");
599 }
600 $DiskMountpoints{$disk} = "$PrimaryMP$LogicalMP";
601 $DiskMountpoints{$disk} =~ s/^\s//;
602 # print partition table
603 ($test != 1) || (PrintPartitionTable($disk));
604 }
605 if (!$BootPartition){
606 $BootPartition = $MountpointPart{"/"};
607 }
608 }
609
610 #****************************************************
611 # set position for every partition
612 #****************************************************
613 sub SetPartitionPositions{
614 my $disk = shift;
615 my $mountpoint; my $DynGroup =""; my $StartPos; my $EndPos;
616 # Build groups of unpreserved partitions between
617 # preserved partitions
618 $StartPos = 0;
619 foreach $mountpoint(split(/\s/,$DiskMountpoints{$disk})) {
620 if ($MPPreserve{$mountpoint} eq "yes") {
621 $EndPos = $PartOldStart{$MountpointPart{$mountpoint}} - 1;
622 &SetGroupPos($DynGroup,$StartPos,$EndPos);
623 $DynGroup = "";
624 $StartPos = $PartOldEnd{$MountpointPart{$mountpoint}} + 1;
625 } else {
626 $DynGroup .= " $mountpoint";
627 }
628 }
629 $EndPos = $DiskSize{$disk} - 1;
630 &SetGroupPos($DynGroup,$StartPos,$EndPos);
631 foreach $mountpoint(split(/\s/,$DiskMountpoints{$disk})) {
632 ($MPOptions{$mountpoint} =~ /\bdosfat16\b/i)
633 && (($MPSize{$mountpoint} * $DiskUnits{$disk} * $sectorsize) < 32 * $megabyte)
634 && ($MPID{$mountpoint} = 4); # DOS 16-bit FAT <32MB
635 }
636 }
637
638 #****************************************************
639 # set position for a group of unpreserved partitions
640 # between start and end
641 #****************************************************
642 sub SetGroupPos{
643 my ($PartGroup,$Start,$End) = @_;
644 $PartGroup =~ s/^ //;
645 ($PartGroup) || return;
646 my $totalsize = $End - $Start + 1;
647 ($totalsize <= 0) && return;
648 my $mountpoint; my $mintotal = 0; my $maxmintotal = 0; my $rest = 0; my $EndUnit = 0;
649 # compute total of MinSizes and difference to MaxSizes
650 foreach $mountpoint (split(/\s/,$PartGroup)) {
651 $mintotal += $MPMinSize{$mountpoint};
652 $maxmintotal += ($MPMaxSize{$mountpoint} - $MPMinSize{$mountpoint});
653 $MPSize{$mountpoint} = $MPMinSize{$mountpoint};
654 }
655 # Test if partitions fit
656 ($mintotal > $totalsize)
657 && die "ERROR: Mountpoints $PartGroup do not fit.\n";
658 # Maximize partitions
659 $rest = $totalsize - $mintotal;
660 ($rest > $maxmintotal) && ($rest = $maxmintotal);
661 if ($rest > 0) {
662 foreach $mountpoint (split(/\s/,$PartGroup)) {
663 $MPSize{$mountpoint} += int ((($MPMaxSize{$mountpoint} - $MPMinSize{$mountpoint}) * $rest) / $maxmintotal);
664 }
665 }
666 # compute rest
667 $rest = $totalsize;
668 foreach $mountpoint (split(/\s/,$PartGroup)) {
669 $rest -= $MPSize{$mountpoint};
670 }
671 # Minimize rest
672 foreach $mountpoint (split(/\s/,$PartGroup)) {
673 if (($rest >0) && ($MPSize{$mountpoint} < $MPMaxSize{$mountpoint})){
674 $MPSize{$mountpoint}++;
675 $rest--;
676 }
677 }
678 # Set start for every partition
679 foreach $mountpoint (split(/\s/,$PartGroup)) {
680 $MPStart{$mountpoint} = $Start;
681 $Start += $MPSize{$mountpoint};
682 $EndUnit = $MPStart{$mountpoint} + $MPSize{$mountpoint} - 1;
683 }
684 }
685
686 #****************************************************
687 # calculate extended partition size
688 #****************************************************
689 sub CalculateExtPartSize{
690 my ($disk) = @_;
691 my $extmp = "extended$disk";
692 my $mountpoint; my $ExtEnd; my $NewEnd;
693 ($MPPrimary{$extmp}) || return;
694 $ExtEnd = $MPStart{$extmp};
695 foreach $mountpoint(split(/\s/,$DiskMountpoints{$disk})) {
696 next if ($MPPrimary{$mountpoint} eq "yes");
697 $NewEnd = $MPStart{$mountpoint} + $MPSize{$mountpoint} - 1;
698 ($NewEnd > $ExtEnd) && ($ExtEnd = $NewEnd);
699 }
700 $MPSize{$extmp} = ($ExtEnd - $MPStart{$extmp} + 1);
701 }
702
703 #****************************************************
704 # Print partition "number - mountpoint" table
705 #****************************************************
706 sub PrintPartitionTable{
707 my ($disk) = @_;
708 my $part; my $mountpoint; my $mountpointname; my $end;
709 foreach $part (sort %MountpointPart) {
710 next if($part !~ /^$disk/);
711 $mountpoint = $PartMountpoint{$part};
712 if ($mountpoint =~ /^no(.*)/){
713 $mountpointname = "no mountpoint ($1)";
714 } else {
715 $mountpointname = $mountpoint;
716 }
717 $end = $MPStart{$mountpoint} + $MPSize{$mountpoint} - 1;
718 print <<"EOM";
719 /dev/$part $mountpointname start=$MPStart{$mountpoint} size=$MPSize{$mountpoint} end=$end id=$MPID{$mountpoint}
720 EOM
721 }
722 }
723
724 #****************************************************
725 # build all partition tables for sfdisk
726 #****************************************************
727 sub PartitionPersfdisk{
728 my ($disk, $mountpoint, $line, $part, $PrimaryNo);
729 my ($command, $result, $filename, $number);
730 print "Creating partition table: ";
731 foreach $disk(keys %DiskMountpoints) {
732 $sfdiskTables{$disk} = "# partition table of device: /dev/$disk\nunit: sectors\n\n";
733 $PrimaryNo = 1;
734 foreach $mountpoint(split(/\s/,$DiskMountpoints{$disk})) {
735 $part = $MountpointPart{$mountpoint};
736 $part =~ /(\d+)$/;
737 ($1 < 5) && ($PrimaryNo++);
738 if ( ($1 == 5) && ($PrimaryNo < 5) ){
739 for my $number($PrimaryNo..4) {
740 $sfdiskTables{$disk} .= BuildsfdiskDumpLine(PartName($disk,$number),0,0,0)."\n";
741 }
742 }
743 $line = BuildsfdiskDumpLine($MountpointPart{$mountpoint},$MPStart{$mountpoint},$MPSize{$mountpoint},$MPID{$mountpoint});
744 ($part eq $BootPartition) && ($line .= ", bootable");
745 $sfdiskTables{$disk} .= "$line\n";
746 }
747 # print $sfdiskTables{$disk};
748 $filename = "$ENV{LOGDIR}/partition." . (($disk=~ m#/#) ? join('_', split('/', $disk)) : $disk);
749 if(($test != 1) && ($filename)){
750 open(FILE, ">$filename") || die "unable to write temporary file $filename\n";
751 print FILE $sfdiskTables{$disk};
752 close(FILE);
753 }
754 $command = "LC_ALL=C sfdisk $sfdisk_options /dev/$disk < $filename";
755 if($test != 1){
756 print "$command\n";
757 $result = `sh -c "$command"`;
758 (($? >> 8) == 0) || (die "\nSFDISK ERROR:\n $result\n");
759 -f "/etc/init.d/udev" && sleep 10; # when using udev, it takes some time until the device entries for each partition are available
760 }
761 }
762 }
763
764 #****************************************************
765 # build a sfdisk dump line
766 #****************************************************
767 sub BuildsfdiskDumpLine{
768
769 sprintf "/dev/%-5s: start=%10s, size=%10s, Id=%3s",@_;
770 }
771
772 #****************************************************
773 # Format all disks
774 #****************************************************
775 sub FormatDisks{
776 my ($disk, $device, $mountpoint, $mountpointname, $command, $result);
777 print "Creating file systems:\n";
778 foreach $disk(keys %DiskMountpoints) {
779 foreach $mountpoint (split(/\s/,$DiskMountpoints{$disk})) {
780 $device = $MountpointPart{$mountpoint};
781 if ($mountpoint =~ /^no/){
782 $mountpointname = "no mountpoint";
783 } else {
784 $mountpointname = $mountpoint;
785 }
786 # preserved partition
787 if ( ($MPPreserve{$mountpoint} eq "yes") && ($MPOptions{$mountpoint} !~ /\bformat\b/i)){
788 print "Preserve partition $device";
789 if ($mountpoint =~ /^no$1/){
790 print " with no mountpoint\n";
791 } else {
792 print " with mountpoint $mountpoint\n";
793 }
794 next;
795 }
796 # lazy format
797 if ( ( $MPOptions{$mountpoint} =~ /\blazyformat\b/i )
798 && ($MPStart{$mountpoint} == $PartOldStartSec{$device})
799 && (($MPStart{$mountpoint} + $MPSize{$mountpoint} - 1) == $PartOldEndSec{$device}) ){
800 print "Lazy format: $device";
801 if ($mountpoint =~ /^no$1/){
802 print " with no mountpoint";
803 } else {
804 print " with mountpoint $mountpoint";
805 }
806 print " was neither moved nor formated.\n";
807 next;
808 }
809 # swap
810 if ($mountpoint =~ /^swap/i) {
811 # print "Make swap partition:\n";
812 $command = "mkswap $mkswap_options";
813 ($MPOptions{$mountpoint} =~ /(\-c)\b/i) && ($command .= " $1");
814 push @swaplist, "/dev/$device";
815 $command .= " /dev/$device";
816 print " $command\n";
817 if($test != 1){
818 $result = `$command`;
819 (($? >> 8) == 0) || (die "\nMKSWAP ERROR:\n $result\n");
820 }
821 next;
822 }
823 # Linux Reiser file system
824 if ($MPOptions{$mountpoint} =~ /\breiser\b/i) {
825 # print "Make Reiser Filesystem:\n";
826 $command = "echo y | LC_ALL=C mkreiserfs $mkreiserfs_options";
827 ($MPOptions{$mountpoint} =~ /(\-h\s*\w+)\b/) && ($command .= " $1");
828 ($MPOptions{$mountpoint} =~ /(\-v\s*\d+)\b/) && ($command .= " $1");
829 $command .= " /dev/$device";
830 print " $command\n";
831 if ($test != 1){
832 $result = `$command`;
833 (($? >> 8) == 0) || die "\nMKREISERFS ERROR:\n $result\n";
834 }
835 next;
836 }
837 # Linux XFS file system
838 if ($MPOptions{$mountpoint} =~ /\bxfs\b/i) {
839 # print "Make XFS Filesystem:\n";
840 $command = "mkfs.xfs $mkxfs_options";
841 $command .= " /dev/$device";
842 print " $command\n";
843 if ($test != 1){
844 $result = `$command`;
845 (($? >> 8) == 0) || die "\nMKFS.XFS ERROR:\n $result\n";
846 }
847 next;
848 }
849 # Linux Extended 2 file system
850 if ($MPOptions{$mountpoint} =~ /\b(ext[23]|auto)\b/i) {
851 # print "Make Extended 2/3 Filesystem:\n";
852 $command = "mke2fs $mke2fs_options";
853 ($MPOptions{$mountpoint} =~ /(\-c)\b/i) && ($command .= " $1");
854 ($MPOptions{$mountpoint} =~ /(\-i\s*\d+)\b/) && ($command .= " $1");
855 ($MPOptions{$mountpoint} =~ /(\-m\s*\d+)\b/) && ($command .= " $1");
856 ($MPOptions{$mountpoint} =~ /(\-j)\b/) && ($command .= " $1");
857 $command .= " /dev/$device";
858 print " $command\n";
859 if ($test != 1){
860 $result = `$command`;
861 (($? >> 8) == 0) || die "\nMKE2FS ERROR:\n $result\n";
862 }
863 next;
864 }
865 # DOS 16bit FAT / Win95 FAT 32
866 if ($MPOptions{$mountpoint} =~ /\b(dosfat16|winfat32)\b/i) {
867 print "Clear first sector for DOS/Windows\n";
868 $command = "dd if=/dev/zero of=/dev/$MountpointPart{$mountpoint} bs=512 count=1";
869 print " $command\n";
870 if ($test != 1){
871 $result = `$command`;
872 (($? >> 8) == 0) || die "\nDD ERROR:\n $result\n";
873 }
874 next;
875 }
876 }
877 }
878 }
879
880 #****************************************************
881 # Build fstab and write it to <root>/etc/fstab
882 #****************************************************
883 sub WriteFSTab{
884 my ($FileSystemTab, $device, $type, $filename);
885 $FileSystemTab = << "EOM";
886 # /etc/fstab: static file system information.
887 #
888 #<file sys> <mount point> <type> <options> <dump> <pass>
889 EOM
890 # 1. /
891 $type = "ext2";
892 ($MPOptions{'/'} =~ /\b(reiser)\b/i) && ($type = "reiserfs");
893 ($MPOptions{'/'} =~ /\b(xfs)\b/i) && ($type = "xfs");
894 ($MPOptions{'/'} =~ /\b(ext3)\b/i) && ($type = "ext3");
895 ($MPOptions{'/'} =~ /\b(ext2)\b/i) && ($type = "ext2");
896 $FileSystemTab .= BuildfstabLine("/dev/$MountpointPart{'/'}","/",$type,$MPfstaboptions{'/'},0,1);
897 # 2. swap partitions
898 foreach my $mountpoint (%PartMountpoint){
899 next if( $mountpoint !~ /^swap/i);
900 $FileSystemTab .= BuildfstabLine("/dev/$MountpointPart{$mountpoint}",
901 "none","swap",$MPfstaboptions{$mountpoint},0,0);
902 }
903 # 3. /proc
904 $FileSystemTab .= BuildfstabLine("proc","/proc","proc","rw,nosuid,noexec",0,0);
905 # 4. sorted others
906 foreach my $mountpoint (sort %PartMountpoint){
907 next if ( ($mountpoint !~ m#^/#) || ($mountpoint eq "/"));
908 $device = $MountpointPart{$mountpoint};
909 $type = "ext2";
910 ($MPOptions{$mountpoint} =~ /\b(dosfat16|winfat32)\b/i) && ($type = "vfat");
911 ($MPOptions{$mountpoint} =~ /\b(ntfs)\b/i) && ($type = "ntfs");
912 ($MPOptions{$mountpoint} =~ /\b(reiser)\b/i) && ($type = "reiserfs");
913 ($MPOptions{$mountpoint} =~ /\b(xfs)\b/i) && ($type = "xfs");
914 ($MPOptions{$mountpoint} =~ /\b(ext3)\b/i) && ($type = "ext3");
915 ($MPOptions{$mountpoint} =~ /\b(ext2)\b/i) && ($type = "ext2");
916 $FileSystemTab .= BuildfstabLine("/dev/$device",$mountpoint,$type,$MPfstaboptions{$mountpoint},0,2);
917 }
918 # write it
919 $filename = "$ENV{LOGDIR}/fstab";
920 # print $FileSystemTab;
921 print "Write fstab to $filename\n" if $verbose;
922 if($test != 1){
923 open(FILE, ">$filename") || die "unable to write fstab $filename\n";
924 print FILE $FileSystemTab;
925 close(FILE);
926 }
927 }
928
929 #****************************************************
930 # Build fstab line
931 #****************************************************
932 sub BuildfstabLine{
933
934 sprintf "%-10s %-15s %-6s %-8s %-4s %-4s\n",@_;
935 }
936
937 #****************************************************
938 # Write all FAI variables of this program to file
939 #****************************************************
940 sub WriteFAIVariables{
941
942 my $swaps;
943
944 print "Write FAI variables to file $FAIOutputFile\n" if $verbose;
945 return if ($test == 1);
946 $swaps = join ' ',@swaplist;
947 open(FILE, ">$FAIOutputFile") || die "Unable to write file $FAIOutputFile\n";
948 print FILE << "EOM";
949 BOOT_DEVICE=/dev/$BOOT_DEVICE
950 ROOT_PARTITION=/dev/$MountpointPart{'/'}
951 BOOT_PARTITION=/dev/$BootPartition
952 SWAPLIST="$swaps"
953 EOM
954 close(FILE);
955 }

Properties

Name Value
svn:eol-style native
svn:executable *
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.5