source: MondoRescue/branches/2.05/mindi/parted2fdisk.pl@ 215

Last change on this file since 215 was 196, checked in by bcornec, 18 years ago

Usage of parted2fdisk instead of fdisk everywhere.
on ia64 this is mandatory, and simplifies the infrastructure
on other archs, it doesn't change anything as parted2fdisk here is a link to fdisk

  • Property svn:keywords set to Id
File size: 12.9 KB
Line 
1#!/usr/bin/perl -w
2#
3# $Id: parted2fdisk.pl 196 2005-12-13 23:04:21Z bcornec $
4#
5# parted2fdisk: fdisk like interface for parted
6# [developped for mindi/mondo http://mondorescue.berlios.de]
7#
8# Aims to be architecture independant (i386/ia64)
9# Tested on RHAS 2.1 ia64 - Mandrake 9.0 ia64 - RHAS 3.0 ia64
10#
11# (c) Bruno Cornec <Bruno.Cornec@hp.com>
12# Licensed under the GPL
13
14use strict;
15
16$ENV{LANG} = "C";
17$ENV{LANGUAGE} = "C";
18$ENV{LC_ALL} = "C";
19
20# Log
21my $flog = "/tmp/parted2fdisk.log";
22open(FLOG, "> $flog") || die "Unable to open $flog";
23
24my $fdisk = "/sbin/fdisk";
25my $parted = "/sbin/parted";
26
27my $i;
28my $l;
29my $part;
30my $wpart;
31my $start = "";
32my $end = "";
33my $cylstart;
34my $cylend;
35my %start;
36my %end;
37my %type;
38my %flags;
39my $arch;
40my $fake = 0;
41
42# Determine on which arch we're running
43if (defined ($ENV{ARCH})) {
44 $arch = $ENV{ARCH};
45} else {
46 $arch = `"/bin/arch"`;
47 chomp($arch);
48}
49
50#
51# Looking for fdisk
52#
53$fdisk = is_lsb($fdisk);
54#
55# We always use fdisk except on ia64 with GPT types of
56# partition tables where we need parted
57# All should return fdisk like format so that callers
58# think they have called fdisk directly
59#
60my $un;
61my $type;
62my $args = "";
63my $device = "";
64my $endmax = "";
65
66if ($#ARGV < 0) {
67 printf FLOG "No arguments given exiting ...\n";
68 mysyn();
69}
70
71my %pid = ( "FAT" => "6",
72 "fat32" => "b",
73 "fat16" => "e",
74 "ext2" => "83",
75 "ext3" => "83",
76 "linux-swap" => "82",
77 "LVM" => "8e",
78 "" => "",
79 );
80my %pnum;
81
82# Reverse table of pid
83while (($i,$l) = each %pid) {
84 next if ($i eq "ext2");
85 $pnum{$l} = $i;
86}
87
88foreach $i (@ARGV) {
89 # We support at most one option and one device
90 print FLOG "Parameter found : $i\n";
91 if ($i =~ /^\/dev\//) {
92 $device = $i;
93 next;
94 } elsif ($i =~ /^-/) {
95 $args = $i;
96 next;
97 } else {
98 mysyn();
99 }
100}
101
102if (($args ne "") and ($device eq "")) {
103 mysyn();
104}
105
106# -s takes a partition as arg
107if ($args =~ /-s/) {
108 $wpart = $device;
109 $device =~ s/[0-9]+$//;
110}
111
112if ($args =~ /-n/) {
113 print FLOG "Fake mode. Nothing will be really done\n";
114 $fake = 1;
115}
116
117print FLOG "Called with device $device and arg $args\n";
118
119if ($arch =~ /^ia64/) {
120 # Check partition table type
121 print FLOG "We're on ia64 ...\n";
122 $parted = is_lsb($parted);
123 $type = which_type($device);
124 if ($type ne "msdos") {
125 print FLOG "Not an msdos type of disk label\n";
126 if ($args =~ /-l/) {
127 fdisk_list($device,undef,\%start,\%end, 1);
128 } elsif ($args =~ /-s/) {
129 fdisk_list($device,$wpart,\%start,\%end, 1);
130 } elsif (($args =~ /-/) and ($fake == 0)) {
131 printf FLOG "Option not supported ($args) ...\n";
132 printf FLOG "Please report to the author\n";
133 mysyn();
134 } else {
135 # Read fdisk orders on stdin and pass them to parted
136 # on the command line as parted doesn't read on stdin
137 print FLOG "Translating fdisk command to parted\n";
138 while ($i = <STDIN>) {
139 if ($i =~ /^p$/) {
140 fdisk_list($device,undef,\%start,\%end, 1);
141 }
142 elsif ($i =~ /^n$/) {
143 fdisk_list($device,undef,\%start,\%end, 0);
144 if ($type ne "gpt") {
145 print FLOG "Forcing GPT type of disk label\n";
146 print FLOG "mklabel gpt\n";
147 system "$parted -s $device mklabel gpt\n" if ($fake == 0);
148 $type = "gpt";
149 }
150 $l = <STDIN>;
151 if (not (defined $l)) {
152 print FLOG "no primary/extended arg given for creation... assuming primary\n";
153 $l = "p";
154 }
155 chomp($l);
156 $part = <STDIN>;
157 if ((not (defined $part)) || ($part eq "")) {
158 print FLOG "no partition given for creation... skipping\n";
159 next;
160 }
161 chomp($part);
162 $cylstart = <STDIN>;
163 chomp($cylstart);
164 if ((not (defined $cylstart)) || ($cylstart eq "")) {
165 if (defined $start{$part-1}) {
166 # in MB => cyl
167 $cylstart = sprintf("%d",$end{$part-1}*1048576/$un + 1);
168 print FLOG "no start cyl given for creation... assuming the following $cylstart\n";
169 } else {
170 print FLOG "no start cyl given for creation... assuming the following 1\n";
171 $cylstart = 1;
172 }
173 }
174 $cylstart = 1 if ($cylstart < 1);
175 print FLOG "start cyl : $cylstart\n";
176 $un = get_un($device, "", 0);
177 # parted needs MB
178 if ($cylstart == 1) {
179 $start = 0.01;
180 } else {
181 $start = $cylstart* $un / 1048576 +0.001;
182 }
183 # this is a size in B/KB/MB/GB
184
185 $endmax = get_max($device);
186 $cylend = <STDIN>;
187 chomp($cylend);
188 if ((not (defined $cylend)) || ($cylend eq "")) {
189 print FLOG "no end cyl given for creation... assuming full disk)\n";
190 $cylend = $endmax;
191 }
192 # Handles end syntaxes (+, K, M, ...)
193 # to give cylinders
194 if ($cylend =~ /^\+/) {
195 $cylend =~ s/^\+//;
196 if ($cylend =~ /K$/) {
197 $cylend =~ s/K$//;
198 $cylend *= 1024;
199 } elsif ($cylend =~ /M$/) {
200 $cylend =~ s/M$//;
201 $cylend *= 1048576;
202 } elsif ($cylend =~ /G$/) {
203 $cylend =~ s/G$//;
204 $cylend *= 1073741824;
205 }
206 # This gives the number of cyl
207 $cylend /= $un;
208 $cylend = sprintf("%d",$cylend);
209 $cylend += $cylstart - 0.001;
210 # We now have the end cyl
211 }
212 $cylend = $endmax if ($cylend > $endmax);
213 print FLOG "end cyl : $cylend\n";
214 # parted needs MB
215 $end = $cylend * $un / 1048576;
216 print FLOG "n $l $part $cylstart $cylend => mkpart primary $start $end\n";
217 system "$parted -s $device mkpart primary ext2 $start $end\n" if ($fake == 0);
218 }
219 elsif ($i =~ /^d$/) {
220 $part = <STDIN>;
221 if (not (defined $part)) {
222 print FLOG "no partition given for deletion... skipping\n";
223 next;
224 }
225 chomp($part);
226 print FLOG "d $part => rm $part\n";
227 system "$parted -s $device rm $part\n" if ($fake == 0);
228 get_parted($device,undef,\%start,\%end,undef);
229 }
230 elsif ($i =~ /^w$/) {
231 print FLOG "w => quit\n";
232 }
233 elsif ($i =~ /^t$/) {
234 $part = <STDIN>;
235 if (not (defined $part)) {
236 print FLOG "no partition given for tagging... skipping\n";
237 next;
238 }
239 chomp($part);
240 $l = <STDIN>;
241 if (not (defined $l)) {
242 print FLOG "no type given for tagging partition $part... skipping\n";
243 next;
244 }
245 chomp($l);
246 if (not (defined $pnum{$l})) {
247 print FLOG "no partition number given for $l... please report to the author\n";
248 next;
249 }
250 print FLOG "t $part $l => mkfs $part $pnum{$l}\n";
251 system "$parted -s $device mkfs $part $pnum{$l}\n" if ($fake == 0);
252 }
253 elsif ($i =~ /^a$/) {
254 $part = <STDIN>;
255 if (not (defined $part)) {
256 print FLOG "no partition given for tagging... skipping\n";
257 next;
258 }
259 chomp($part);
260 print FLOG "a $part => set $part boot on\n";
261 system "$parted -s $device set $part boot on\n" if ($fake == 0);
262 }
263 elsif ($i =~ /^q$/) {
264 print FLOG "q => quit\n";
265 }
266 else {
267 print FLOG "Unknown command: $i\n";
268 next;
269 }
270
271 }
272 }
273 myexit(0);
274 }
275}
276
277#
278# Else everything is for fdisk
279#
280# Print only mode
281print FLOG "Passing everything to the real fdisk\n";
282my $fargs = join(@ARGV);
283
284if ($args =~ /^-/) {
285 # -l or -s
286 open (FDISK, "$fdisk $fargs |") || die "Unable to read from $fdisk";
287 while (<FDISK>) {
288 print;
289 }
290 close(FDISK);
291} else {
292 # Modification mode
293 open (FDISK, "| $fdisk $fargs") || die "Unable to modify through $fdisk";
294 while (<STDIN>) {
295 print FDISK;
296 }
297 close(FDISK);
298 close(STDIN);
299}
300myexit(0);
301
302
303# Is your system LSB ?
304sub is_lsb {
305
306my $cmd = shift;
307my $basename = basename($cmd);
308
309if (not (-x $cmd)) {
310 print FLOG "Your system is not LSB/mondo compliant: $basename was not found as $cmd\n";
311 print FLOG "Searching elswhere...";
312 foreach $i (split(':',$ENV{PATH})) {
313 if (-x "$i/$basename") {
314 $cmd = "$i/$basename";
315 print FLOG "Found $cmd, using it !\n";
316 last;
317 }
318 }
319 if (not (-x $cmd)) {
320 print FLOG "Your system doesn't provide $basename in the PATH\n";
321 print FLOG "Please correct it before relaunching\n";
322 myexit(-1);
323 }
324}
325return($cmd);
326}
327
328sub fdisk_list {
329
330my $device = shift;
331my $wpart = shift;
332my $start = shift;
333my $end = shift;
334my $verbose = shift;
335
336my $un;
337my $endmax;
338my $d;
339my $n;
340
341my %cmt = ( "FAT" => "FAT",
342 "ext2" => "Linux",
343 "ext3" => "Linux",
344 "linux-swap" => "Linux swap",
345 "LVM" => "Linux LVM",
346 "fat16" => "fat16",
347 "fat32" => "fat32",
348 "" => "Linux",
349);
350
351my $part;
352my $mstart;
353my $mend;
354my $length;
355my $pid;
356my $cmt;
357format FLOG1 =
358@<<<<<<<<<<<< @>>>>>>>> @>>>>>>>> @>>>>>>>> @>>> @<<<<<<<<<<<<<<<<<<<<<<<<<<<<
359$part, $mstart, $mend, $length, $pid, $cmt
360.
361format FLOG2 =
362@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
363$part,
364 @>>>>>>>> @>>>>>>>> @>>>>>>>> @>>> @<<<<<<<<<<<<<<<<<<<<<<<<<<<<
365 $mstart, $mend, $length, $pid, $cmt
366.
367format STDOUT1 =
368@<<<<<<<<<<<< @>>>>>>>> @>>>>>>>> @>>>>>>>> @>>> @<<<<<<<<<<<<<<<<<<<<<<<<<<<<
369$part, $mstart, $mend, $length, $pid, $cmt
370.
371format STDOUT2 =
372@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
373$part,
374 @>>>>>>>> @>>>>>>>> @>>>>>>>> @>>> @<<<<<<<<<<<<<<<<<<<<<<<<<<<<
375 $mstart, $mend, $length, $pid, $cmt
376.
377#/dev/hda1 1 77579 39099374+ ee EFI GPT
378
379#
380# Keep Fdisk headers
381#
382# this will return bytes
383$un = get_un ($device,$wpart,$verbose);
384
385$endmax = get_max($device);
386
387# This will return MB
388get_parted ($device,$start,$end,\%type,\%flags);
389
390while (($n,$d) = each %type) {
391 # Print infos fdisk like
392 $part = ${device}.$n;
393 # start and end are in cylinder in fdisk format
394 # so return in MB * 1MB / what represents 1 cyl in B
395 $mstart = sprintf("%d",$$start{$n}*1048576/$un);
396 $mstart = 1 if ($mstart < 1);
397 $mend = sprintf("%d",$$end{$n}*1048576/$un - 1);
398 $mend = $endmax if ($mend > $endmax);
399 # length is in 1K blocks
400 $length = sprintf("%d",($mend-$mstart+1)*$un/1024);
401 $pid = $pid{$type{$n}};
402 $cmt = $cmt{$type{$n}};
403 #print FLOG "$part - $mstart - $mend - $length\n";
404
405 if ($verbose == 1) {
406 if (not (defined $wpart)) {
407 if (length($part) > 13) {
408 open(STDOUT2,">&STDOUT") || die "Unable to open STDOUT2";
409 select(STDOUT2);
410 write;
411 open(FLOG2,">&FLOG") || die "Unable to open FLOG2";
412 select(FLOG2);
413 write;
414 select(STDOUT);
415 close(FLOG2);
416 close(STDOUT2);
417 } else {
418 open(STDOUT1,">&STDOUT") || die "Unable to open STDOUT1";
419 select(STDOUT1);
420 write;
421 open(FLOG1,">&FLOG") || die "Unable to open FLOG1";
422 select(FLOG1);
423 write;
424 select(STDOUT);
425 close(FLOG1);
426 close(STDOUT1);
427 }
428 } else {
429 # manage the -s option of fdisk here
430 print "$length\n" if ($part eq $wpart);
431 print FLOG "$part has $length KBytes\n" if ($part eq $wpart);
432 }
433 }
434}
435close(FDISK);
436close(PARTED);
437}
438
439#
440# Get max size from fdisk
441#
442sub get_max {
443
444my $device = shift;
445my $max = 0;
446my $foo;
447
448open (FDISK, "$fdisk -l $device |") || die "Unable to read from $fdisk";
449while (<FDISK>) {
450 if ($_ =~ /heads/) {
451 chomp;
452 $max = $_;
453 $max =~ s/.* ([0-9]+) cylinders/$1/;
454 }
455}
456close(FDISK);
457print FLOG "get_max returns $max\n";
458return($max);
459}
460
461#
462# Get units from fdisk (cylinder size)
463#
464sub get_un {
465
466my $device = shift;
467my $wpart = shift;
468my $verbose = shift;
469my $un = 0;
470my $foo;
471
472open (FDISK, "$fdisk -l $device |") || die "Unable to read from $fdisk";
473while (<FDISK>) {
474 print if (($_ !~ /^\/dev\//) and (not (defined $wpart)) and ($verbose == 1));
475 if ($_ =~ /^Units/) {
476 ($foo, $un , $foo) = split /=/;
477 $un =~ s/[A-z\s=]//g;
478 $un = eval($un);
479 }
480}
481close(FDISK);
482print FLOG "get_un returns $un\n";
483return($un);
484}
485
486#
487# Parted gives info in MB
488#
489sub get_parted {
490
491my $device = shift;
492my $start = shift;
493my $end = shift;
494my $type = shift;
495my $flags = shift;
496my $d;
497my $n;
498
499open (PARTED, "$parted -s $device print |") || die "Unable to read from $parted";
500# Skip 3 first lines
501$d = <PARTED>;
502$d = <PARTED>;
503$d = <PARTED>;
504print FLOG "Got from parted: \n";
505print FLOG "Minor Start End Filesystem Flags\n";
506# Get info from each partition line
507while (($n,$d) = split(/\s/, <PARTED>,2)) {
508 chomp($d);
509 next if ($n !~ /^[1-9]/);
510 $d =~ s/^\s*//;
511 $d =~ s/\s+/ /g;
512 ($$start{$n},$$end{$n},$$type{$n},$$flags{$n}) = split(/ /,$d);
513 $$start{$n} = "" if (not defined $$start{$n});
514 $$end{$n} = "" if (not defined $$end{$n});
515 $$type{$n} = "" if (not defined $$type{$n});
516 $$flags{$n} = "" if (not defined $$flags{$n});
517 print FLOG "$n $$start{$n} $$end{$n} $$type{$n} $$flags{$n}\n";
518}
519close(PARTED);
520}
521
522# Based on Version 2.4 27-Sep-1996 Charles Bailey bailey@genetics.upenn.edu
523# in Basename.pm
524
525sub basename {
526
527my($fullname) = shift;
528
529my($dirpath,$basename);
530
531($dirpath,$basename) = ($fullname =~ m#^(.*/)?(.*)#s);
532
533return($basename);
534}
535
536sub myexit {
537
538my $val=shift;
539
540close(FLOG);
541exit($val);
542}
543
544sub which_type {
545
546my $device = shift;
547my $type = "";
548
549open (FDISK, "$fdisk -l $device |") || die "Unable to read from $fdisk";
550while (<FDISK>) {
551 if ($_ =~ /EFI GPT/) {
552 $type= "gpt";
553 print FLOG "Found a GPT partition format\n";
554 last;
555 }
556}
557close(FDISK);
558open (PARTED, "$parted -s $device print|") || die "Unable to read from $fdisk";
559while (<PARTED>) {
560 if ($_ =~ /Disk label type: msdos/) {
561 $type= "msdos";
562 print FLOG "Found a msdos partition format\n";
563 last;
564 }
565}
566close(FDISK);
567return ($type);
568}
569
570sub mysyn {
571 print "Syntax: $0 [-l] device | [-s] partition\n";
572 myexit(-1);
573}
Note: See TracBrowser for help on using the repository browser.