source: MondoRescue/trunk/mindi/parted2fdisk.pl@ 89

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

merge r87:88 of the 2.04_berlios branch
indent some files

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