source: MondoRescue/branches/3.3/mindi/mr-parted2fdisk@ 3663

Last change on this file since 3663 was 3663, checked in by Bruno Cornec, 7 years ago

Better handling of -s option for parted2fdisk

  • Property svn:keywords set to Id
File size: 18.7 KB
RevLine 
[1]1#!/usr/bin/perl -w
2#
[88]3# $Id: mr-parted2fdisk 3663 2017-05-03 09:27:14Z bruno $
4#
[3377]5# mr-parted2fdisk: fdisk like interface for parted
[3343]6# [developed for mindi/mondo http://www.mondorescue.org]
[1]7#
8# Aims to be architecture independant (i386/ia64)
[3355]9# Tested on ia64 with RHAS 2.1 - Mandrake 9.0 - RHEL 3.0 - SLES 10 - RHEL 5 -
[1]10#
[3343]11# Copyright B. Cornec 2000-2015
[3143]12# Provided under the GPL v2
[1]13
14use strict;
[3343]15use File::Basename;
[3370]16use Getopt::Long qw(:config auto_abbrev no_ignore_case);
17use Carp qw/confess cluck/;
18use Data::Dumper;
19use English;
[3631]20use FileHandle;
[3370]21use MondoRescue::Version;
22use MondoRescue::Base;
23use MondoRescue::Disk;
24use ProjectBuilder::Base;
[1]25
[3143]26=pod
27
28=head1 NAME
29
[3377]30mr-parted2fdisk is a fdisk like command using parted internally for analysing GPT labelled disks
[3143]31
32=head1 DESCRIPTION
33
[3377]34mr-parted2fdisk behaves like the fdisk command, but dialog internally with parted in order to manipulate partition tables, which allow it to support GPT partition format as well as MBR, contrary to fdisk. It aims at providing compatible external interface with fdisk. Developed initialy for ia64 Linux, it is also useful now on x86 systems using GPT partition format (for large HDDs).
[3143]35
36=head1 SYNOPSIS
37
[3377]38mr-parted2fdisk -s partition
[3370]39
[3377]40mr-parted2fdisk -l [device]
[3370]41
[3377]42mr-parted2fdisk [-n] device
[3143]43
44=head1 OPTIONS
45
46=over 4
47
48=item B<-s>
49
50Print the size (in blocks) of the given partition.
51
[3370]52=item B<-l>
53
54List the partition tables for the specified device (or all if none specified) and then exit.
55
[3143]56=item B<-n>
57
58Fake mode. Doesn't pass the commands just simulate.
59
[3377]60=item B<-v>
61
62Verbose mode. Used to help debugging issues.
63
[3143]64=item B<no option>
65
66Allow the creation and manipulation of partition tables.
67
68=back
69
70=head1 ARGUMENTS
71
72=over 4
73
74=item B<partition>
75
76partition device file (only used with -s option).
77
78=item B<device>
79
80device file to work on.
81
82=back
83
84=head1 WEB SITES
85
86The main Web site of the project is available at L<http://www.mondorescue.org>. Bug reports should be filled using the trac instance of the project at L<http://trac.mondorescue.org/>.
87
88=head1 USER MAILING LIST
89
90For community exchanges around MondoRescue please use the list L<http://sourceforge.net/mailarchive/forum.php?forum_name=mondo-devel>
91
92=head1 AUTHORS
93
94The MondoRescue team lead by Bruno Cornec L<mailto:bruno@mondorescue.org>.
95
96=head1 COPYRIGHT
97
98MondoRescue is distributed under the GPL v2.0 license or later,
99described in the file C<COPYING> included with the distribution.
100
101=cut
102
103
[1]104$ENV{LANG} = "C";
105$ENV{LANGUAGE} = "C";
106$ENV{LC_ALL} = "C";
107
108# Log
[3377]109my $flog = "/var/log/mr-parted2fdisk.log";
[1]110open(FLOG, "> $flog") || die "Unable to open $flog";
111
112my $i;
113my $l;
114my $part;
115my $wpart;
116my $start = "";
117my $end = "";
[90]118my $cylstart;
119my $cylend;
[1]120my %start;
121my %end;
122my %type;
[88]123my $fake = 0;
[1801]124my $mega = 1048576;
[3370]125my %opts;
[1]126
[2163]127# Immediate flushing to avoids read error from mondorestore in log files
128$| = 1;
129
[1]130#
[3343]131# We always use fdisk except with GPT types of
[1]132# partition tables where we need parted
133# All should return fdisk like format so that callers
134# think they have called fdisk directly
135#
136my $un;
137my $type;
[3370]138my $device;
[88]139my $endmax = "";
[3377]140my $appname = "mr-parted2fdisk";
[3370]141my ($mrver,$mrrev) = mr_version_init();
[1]142
[3370]143pb_syntax_init("$appname Version $mrver-$mrrev\n");
144
[1]145if ($#ARGV < 0) {
[3370]146 pb_syntax(-1,0);
[1]147}
148
[3370]149GetOptions("help|?|h+" => \$opts{'h'},
150 "device|d|s=s" => \$opts{'s'},
151 "list|l" => \$opts{'l'},
152 "Log-File|L=s" => \$opts{'L'},
153 "man" => \$opts{'man'},
154 "noop|n" => \$opts{'n'},
155 "quiet|q" => \$opts{'q'},
156 "version|V=s" => \$opts{'V'},
157 "verbose|v+" => \$opts{'v'},
158 "stop-on-error!" => \$Global::pb_stop_on_error,
159) || pb_syntax(-1,0);
160
161if (defined $opts{'L'}) {
162 open(pbLOG,"> $opts{'L'}") || die "Unable to log to $opts{'L'}: $!";
163 $pbLOG = \*pbLOG;
164 }
165pb_log_init($opts{'v'}, $pbLOG);
166
167# We support at most one option and one device
168if ((defined $opts{'l'}) && (defined $opts{'s'})) {
169 pb_syntax(-1,0);
170}
171
[3647]172# Create a device var which will be the device or partition on which to work
[3370]173# whatever the option used.
174$device = $ARGV[0] if (defined $opts{'l'});
175$device = $ARGV[0] if (defined $ARGV[0]);
176
177# -s takes a partition as arg
178# so create a correct device from that
179if (defined $opts{'s'}) {
[3663]180 $device = $opts{'s'};
[3370]181 $wpart = $device;
182 # To support dev like cciss/c0d0p1
183 if ($device =~ /([0-9]+)p[0-9]+$/) {
184 $device =~ s/([0-9]+)p[0-9]+$/$1/;
185 } else {
186 $device =~ s/[0-9]+$//;
187 }
188}
189
190if (defined $opts{'n'}) {
191 print FLOG "Fake mode. Nothing will be really done\n";
192 $fake = 1;
193}
194
[3343]195# util-linux/fdisk version
[3370]196my $fdisk = pb_check_req("fdisk",0);
[3343]197open(CMD,"$fdisk -v |") || die "Unable to execute $fdisk";
198my $version = <CMD>;
199close(CMD);
200chomp($version);
[3383]201# RHEL 5 has fdisk from util-linux 2.13-pre7
[3355]202# Mageia 4 has fdisk from util-linux 2.24.2
203$version =~ s/[^0-9\.]*([0-9a-z\.-]+)[\)]*$/$1/;
[3343]204my ($v,$maj,$min) = split(/\./,$version);
205
[3355]206# Consider pre version the same as the following for formats
207if ((defined $maj) && ($maj =~ /-pre/)) {
208 $maj =~ s/-pre.*$//;
209 $maj++;
210}
[3576]211# Remove potential remaining letters
212$maj =~ s/[a-z]+//;
213
[3355]214if ((defined $min) && ($min =~ /-pre/)) {
215 $min =~ s/-pre.*$//;
216 $min++;
217}
[3582]218$min =~ s/[a-z]+// if (defined $min);
[3355]219
[3663]220my %pid = ( "FAT" => "6",
221 "fat32" => "b",
222 "fat16" => "e",
223 "ext2" => "83",
224 "ext3" => "83",
225 "ext4" => "83",
226 "xfs" => "83",
227 "btrfs" => "83",
228 "reiserfs" => "83",
229 "linux-swap" => "82",
230 "lvm" => "8e",
231 "raid" => "fd",
232 "" => "",
233 );
234my %pnum;
235
236# Reverse table of pid
237while (($i,$l) = each %pid) {
238 next if ($i eq "ext2");
239 $pnum{$l} = $i;
240}
241
[3647]242# fdisk has a bug when handling more than 1024 disks, seen on RHEL
243# so in that case we want to use parted instead
244# # Cf: http://trac.mondorescue.org/ticket/805
245my $use_parted = 0;
246open(CMD,"LANGUAGE=C $fdisk -l |") || die "Unable to execute $fdisk";
247my $lines = 0;
248while (<CMD>) {
249 $lines++ if ($_ =~ /^Disk \//);
250}
251close(CMD);
252# More than 1000 is a lot of disks so may triggers the issue
253$use_parted = 1 if ($lines >= 1000);
254
[3370]255# Check partition table type
256$type = mr_disk_type($device);
257# Replacement code only for GPT disks
[3647]258if (((($v == 1) || (($v == 2) && ($maj < 22))) && ($type ne "MBR")) || ($use_parted == 1)) {
[3370]259 pb_log(1,"This distribution uses an old fdisk, activating replacement code for GPT disk label...\n");
260 my $parted = pb_check_req("parted",0);
261 if (defined $opts{'l'}) {
262 fdisk_list($device,undef,\%start,\%end, 1);
263 } elsif (defined $opts{'s'}) {
264 fdisk_list($device,$wpart,\%start,\%end, 1);
265 } else {
266 # Read fdisk orders on stdin and pass them to parted
267 # on the command line as parted doesn't read on stdin
268 pb_log(1,"Translating fdisk command to parted\n");
269 while ($i = <STDIN>) {
270 if ($i =~ /^p$/) {
271 fdisk_list($device,undef,\%start,\%end, 1);
272 print "command (m for help) sent back to fake fdisk for mondorestore\n";
273 } elsif ($i =~ /^n$/) {
274 fdisk_list($device,undef,\%start,\%end, 0);
[3553]275 if ($type ne "GPT") {
[3370]276 pb_log(1,"Forcing GPT type of disk label\n");
277 pb_log(1,"mklabel gpt\n");
278 pb_system("$parted -s $device mklabel gpt\n") if ($fake == 0);
[3553]279 $type = "GPT";
[3370]280 }
281 $l = <STDIN>;
282 if (not defined $l) {
283 pb_log(1,"no primary/extended arg given for creation... assuming primary\n");
284 $l = "p";
285 }
286 chomp($l);
287 $part = <STDIN>;
288 if ((not defined $part) || ($part eq "")) {
289 pb_log(1,"no partition given for creation... skipping\n");
290 next;
291 }
292 chomp($part);
293 $cylstart = <STDIN>;
294 chomp($cylstart);
295 if ((not defined $cylstart) || ($cylstart eq "")) {
296 if (defined $start{$part-1}) {
297 # in MB => cyl
298 $cylstart = sprintf("%d",$end{$part-1}*$mega/$un + 1);
[90]299 } else {
[3370]300 $cylstart = 1;
[90]301 }
[3370]302 pb_log(1,"no start cyl given for creation... assuming the following: $cylstart\n");
303 } else {
304 pb_log(1,"start cyl: $cylstart\n");
305 }
306 $cylstart = 1 if ($cylstart < 1);
307 $un = get_un($device, "", 0);
308 # parted needs MB
309 if ($cylstart == 1) {
310 $start = 0.01;
311 } else {
312 $start = $cylstart* $un / $mega + 0.001;
313 }
314 # this is a size in B/KB/MB/GB
[90]315
[3370]316 $endmax = get_max($device);
317 $cylend = <STDIN>;
318 chomp($cylend);
319 if ((not defined $cylend) || ($cylend eq "")) {
320 pb_log(1,"no end cyl given for creation... assuming full disk)\n");
321 $cylend = $endmax;
322 }
323 # Handles end syntaxes (+, K, M, ...)
324 # to give cylinders
325 if ($cylend =~ /^\+/) {
326 $cylend =~ s/^\+//;
327 # Handles suffixes; return bytes
328 $cylend = decode_Bsuf($cylend,1);
329 # This gives the number of cyl
330 $cylend /= $un;
331 $cylend = sprintf("%d",$cylend);
332 $cylend += $cylstart - 0.001;
333 # We now have the end cyl
334 }
335 $cylend = $endmax if ($cylend > $endmax);
336 pb_log(1,"end cyl: $cylend\n");
337 # parted needs MB
338 $end = $cylend * $un / $mega;
339 pb_log(1,"n $l $part $cylstart $cylend => mkpart primary $start $end\n");
340 pb_system("$parted -s $device mkpart primary ext2 $start $end\n") if ($fake == 0);
341 print "command (m for help) sent back to fake fdisk for mondorestore\n";
342 } elsif ($i =~ /^d$/) {
343 $part = <STDIN>;
344 if (not defined $part) {
345 pb_log(1,"no partition given for deletion... skipping\n");
346 next;
347 }
348 chomp($part);
349 pb_log(1,"d $part => rm $part\n");
350 pb_system("$parted -s $device rm $part\n") if ($fake == 0);
351 get_parted($device,undef,\%start,\%end,undef);
352 print "command (m for help) sent back to fake fdisk for mondorestore\n";
353 } elsif ($i =~ /^w$/) {
354 pb_log(1,"w => quit\n");
355 } elsif ($i =~ /^t$/) {
356 $part = <STDIN>;
357 if (not defined $part) {
358 pb_log(1,"no partition given for tagging... skipping\n");
359 next;
360 }
361 chomp($part);
362 # If no partition number given it's 1, and we received the type
363 if ($part !~ /\d+/) {
364 $l = $part;
365 $part = 1
366 } else {
367 $l = <STDIN>;
368 }
369 if (not defined $l) {
370 pb_log(1,"no type given for tagging partition $part... skipping\n");
371 next;
372 }
373 chomp($l);
374 if (not defined $pnum{$l}) {
375 pb_log(1,"no partition number given for $l... please report to the author\n");
376 next;
377 }
[2158]378
[3370]379 if ($pnum{$l} eq "lvm") {
380 # In that case this is a flag set, not a mkfs
381 pb_log(1,"t $part $l => set $part $pnum{$l} on\n");
382 pb_system("$parted -s $device set $part $pnum{$l} on\n") if ($fake == 0);
[2154]383 } else {
[3370]384 pb_log(1,"t $part $l => mkfs $part $pnum{$l}\n");
385 pb_system("$parted -s $device mkfs $part $pnum{$l}\n") if ($fake == 0);
386 }
387 print "command (m for help) sent back to fake fdisk for mondorestore\n";
388 } elsif ($i =~ /^a$/) {
389 $part = <STDIN>;
390 if (not defined $part) {
391 pb_log(1,"no partition given for tagging... skipping\n");
[1]392 next;
393 }
[3370]394 chomp($part);
395
396 # Partition shouldn't be negative or null. Then take the first one.
397 $part = 1 if ($part le 0);
398
399 pb_log(1,"a $part => set $part boot on\n");
400 pb_system("$parted -s $device set $part boot on\n") if ($fake == 0);
401 print "command (m for help) sent back to fake fdisk for mondorestore\n";
402 } elsif ($i =~ /^q$/) {
403 pb_log(1,"q => quit\n");
404 } else {
405 pb_log(1,"Unknown command: $i\n");
406 print "command (m for help) sent back to fake fdisk for mondorestore\n";
407 next;
[1]408 }
[3370]409
[1]410 }
411 }
[3370]412 exit(0);
[1]413}
414
415#
416# Else everything is for fdisk
417#
418# Print only mode
[3370]419local_fdisk(\%opts,$device);
420exit(0);
[3355]421
[3370]422# End of main
423
424
[3355]425sub local_fdisk {
426
[3370]427my $opts=shift;
[3355]428my $device=shift;
429
[3370]430pb_log(1,"Passing everything to the real fdisk with device: $device\n");
431pb_log(1,"and the -s $wpart option\n") if (defined $opts{'s'});
[1]432
[3370]433if ((defined $opts->{'l'}) || (defined $opts->{'s'})) {
434 my $args = "-l $device" if (defined $opts->{'l'});
435 $args = "-s $wpart" if (defined $opts->{'s'});
436 open (FDISK, "$fdisk $args 2>/dev/null |") || die "Unable to read from $fdisk";
[1]437 while (<FDISK>) {
[3344]438 print $_;
[1]439 }
440 close(FDISK);
441} else {
442 # Modification mode
[3370]443 open (FDISK, "| $fdisk $device 2>/dev/null") || die "Unable to modify through $fdisk";
[3591]444 # disable fdisk output buffering
445 autoflush FDISK 1;
[1]446 while (<STDIN>) {
[3344]447 print FDISK $_;
[1]448 }
449 close(FDISK);
450 close(STDIN);
451}
[3355]452return;
453}
[1]454
[3355]455# Unused for now - Kept for reference in case there is a need later on
456sub fdisk_list_all {
[3370]457
[3355]458my $device = shift;
459my $wpart = shift;
460my $start = shift;
461my $end = shift;
462my $verbose = shift;
463
464return fdisk_list($device,$wpart,$start,$end,$verbose) if ((defined $device) && ($device ne ""));
465
466# If no device given loop on the list of devices found in /proc/partitions
467open(PART,"/proc/partitions") || die "Unable to open /proc/partitions";
468while (<PART>) {
469 my ($maj,$min,$blocks,$dev) = split(/\s+/);
470 next if ($dev =~ /^fd|^sr/);
471 next if ($min != 0);
472 fdisk_list("/dev/$dev",$wpart,$start,$end,$verbose);
473}
474close(PART);
475}
476
477
[1]478sub fdisk_list {
479
480my $device = shift;
481my $wpart = shift;
482my $start = shift;
483my $end = shift;
[90]484my $verbose = shift;
[1]485
486my $un;
[88]487my $endmax;
[1]488my $d;
489my $n;
490
491my %cmt = ( "FAT" => "FAT",
492 "ext2" => "Linux",
493 "ext3" => "Linux",
[2087]494 "ext4" => "Linux",
495 "xfs" => "Linux",
[1565]496 "reiserfs" => "Linux",
[1]497 "linux-swap" => "Linux swap",
[2158]498 "lvm" => "Linux LVM",
[3343]499 "raid" => "RAID Linux auto",
[1]500 "fat16" => "fat16",
501 "fat32" => "fat32",
502 "" => "Linux",
503);
504
505my $part;
506my $mstart;
507my $mend;
508my $length;
509my $pid;
510my $cmt;
511format FLOG1 =
[1565]512@<<<<<<<<<<<< @>>>>>>>>>> @>>>>>>>>>> @>>>>>>>>>> @>>> @<<<<<<<<<<<<<<<<<<<<<<<<<<<<
[1]513$part, $mstart, $mend, $length, $pid, $cmt
514.
515format FLOG2 =
516@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
517$part,
[1565]518 @>>>>>>>>>> @>>>>>>>>>> @>>>>>>>>>> @>>> @<<<<<<<<<<<<<<<<<<<<<<<<<<<<
[1]519 $mstart, $mend, $length, $pid, $cmt
520.
521format STDOUT1 =
[1565]522@<<<<<<<<<<<< @>>>>>>>>>> @>>>>>>>>>> @>>>>>>>>>> @>>> @<<<<<<<<<<<<<<<<<<<<<<<<<<<<
[1]523$part, $mstart, $mend, $length, $pid, $cmt
524.
525format STDOUT2 =
526@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
527$part,
[1565]528 @>>>>>>>>>> @>>>>>>>>>> @>>>>>>>>>> @>>> @<<<<<<<<<<<<<<<<<<<<<<<<<<<<
[1]529 $mstart, $mend, $length, $pid, $cmt
530.
[1565]531# Device Boot Start End Blocks Id System
532#/dev/hda1 1 77579 39099374+ ee EFI GPT
[1]533
[1565]534
[1]535#
536# Keep Fdisk headers
537#
[88]538# this will return bytes
[3364]539$un = get_un($device,$wpart,$verbose);
[90]540
[88]541$endmax = get_max($device);
[90]542
[88]543# This will return MB
[3355]544get_parted($device,$start,$end,\%type);
[1]545
546while (($n,$d) = each %type) {
547 # Print infos fdisk like
548 $part = ${device}.$n;
[88]549 # start and end are in cylinder in fdisk format
550 # so return in MB * 1MB / what represents 1 cyl in B
[1801]551 $mstart = sprintf("%d",$$start{$n}*$mega/$un);
[88]552 $mstart = 1 if ($mstart < 1);
[1565]553 $mstart = $endmax if ($mstart > $endmax);
[1801]554 $mend = sprintf("%d",$$end{$n}*$mega/$un - 1);
[88]555 $mend = $endmax if ($mend > $endmax);
[1565]556 $mend = 1 if ($mend < 1);
[88]557 # length is in 1K blocks
558 $length = sprintf("%d",($mend-$mstart+1)*$un/1024);
[1]559 $pid = $pid{$type{$n}};
560 $cmt = $cmt{$type{$n}};
[90]561 #print FLOG "$part - $mstart - $mend - $length\n";
[1]562
[90]563 if ($verbose == 1) {
[3370]564 if (not defined $wpart) {
[90]565 if (length($part) > 13) {
566 open(STDOUT2,">&STDOUT") || die "Unable to open STDOUT2";
567 select(STDOUT2);
568 write;
569 open(FLOG2,">&FLOG") || die "Unable to open FLOG2";
570 select(FLOG2);
571 write;
572 select(STDOUT);
573 close(FLOG2);
574 close(STDOUT2);
575 } else {
576 open(STDOUT1,">&STDOUT") || die "Unable to open STDOUT1";
577 select(STDOUT1);
578 write;
579 open(FLOG1,">&FLOG") || die "Unable to open FLOG1";
580 select(FLOG1);
581 write;
582 select(STDOUT);
583 close(FLOG1);
584 close(STDOUT1);
585 }
[1]586 } else {
[90]587 # manage the -s option of fdisk here
588 print "$length\n" if ($part eq $wpart);
[3370]589 pb_log(1,"$part has $length KBytes\n") if ($part eq $wpart);
[1]590 }
591 }
592}
593close(FDISK);
594close(PARTED);
595}
596
597#
598# Get max size from fdisk
599#
600sub get_max {
601
602my $device = shift;
603my $max = 0;
604my $foo;
605
[1857]606open (FDISK, "$fdisk -l $device 2>/dev/null |") || die "Unable to read from $fdisk";
[1]607while (<FDISK>) {
[88]608 if ($_ =~ /heads/) {
609 chomp;
610 $max = $_;
611 $max =~ s/.* ([0-9]+) cylinders/$1/;
[1]612 }
613}
614close(FDISK);
[3370]615pb_log(2,"get_max returns $max\n");
[1]616return($max);
617}
618
619#
[88]620# Get units from fdisk (cylinder size)
[1]621#
622sub get_un {
623
624my $device = shift;
625my $wpart = shift;
[90]626my $verbose = shift;
[1]627my $un = 0;
628my $foo;
629
[1857]630open (FDISK, "$fdisk -l $device 2>/dev/null |") || die "Unable to read from $fdisk";
[1]631while (<FDISK>) {
[90]632 print if (($_ !~ /^\/dev\//) and (not (defined $wpart)) and ($verbose == 1));
[1]633 if ($_ =~ /^Units/) {
634 ($foo, $un , $foo) = split /=/;
635 $un =~ s/[A-z\s=]//g;
636 $un = eval($un);
637 }
638}
639close(FDISK);
[3370]640pb_log(2,"get_un returns $un\n");
[1]641return($un);
642}
643
[88]644#
645# Parted gives info in MB
[1565]646# (depending on versions - 1.6.25.1 provides suffixes)
[88]647#
[1]648sub get_parted {
649
650my $device = shift;
651my $start = shift;
652my $end = shift;
653my $type = shift;
[1565]654my $void;
[1]655my $d;
656my $n;
[1565]657my $ret;
658my $mode;
659my $size;
[1801]660my $unit;
[1]661
[3370]662my $parted = pb_check_req("parted",0);
[1565]663open (PARTED, "$parted -v |") || die "Unable to read from $parted";
664$d = <PARTED>;
[3370]665pb_log(2,"$d");
[1565]666close(PARTED);
[3343]667chomp($d);
668# parted version
669$d =~ s/[^0-9\.]*([0-9\.]+)$/$1/;
670my ($v,$maj,$min) = split(/\./,$d);
671# depending on parted version, information given change:
672if ($v == 2) {
673 # RHEL 6 parted 2.1
674 $mode=2;
675} elsif ($v == 1) {
676 if (($maj <= 5) || (($maj == 6) && (defined $min) && ($min < 25))) {
677 # RHEL 3 parted 1.6.3
678 # RHEL 4 parted 1.6.19
679 $mode=0;
680 } else {
681 # SLES 10 parted >= 1.6.25
682 $mode=1;
683 }
684} else {
685 $mode=-1;
686}
[3370]687pb_log(2,"parted mode: $mode\n");
[1565]688
[3370]689open(PARTED, "$parted -s $device print |") || die "Unable to read from $parted";
[1]690# Skip 3 first lines
691$d = <PARTED>;
692$d = <PARTED>;
693$d = <PARTED>;
[1565]694
[3343]695if ($mode == 2) {
696 $d = <PARTED>;
697 $d = <PARTED>;
698 $d = <PARTED>;
[1565]699}
[3370]700pb_log(2,"Got from parted: \n");
701pb_log(2,"Minor Start End Filesystem\n");
[1]702# Get info from each partition line
703while (($n,$d) = split(/\s/, <PARTED>,2)) {
704 chomp($d);
[3343]705 # v2 of parted ends with empty line
706 next if (($mode == 2) && ($n eq "") && ($d eq ""));
707 # v2 of parted starts with space potentially
708 ($n,$d) = split(/\s/, $d,2) if (($mode == 2) && ($n eq ""));
[1]709 next if ($n !~ /^[1-9]/);
710 $d =~ s/^\s*//;
711 $d =~ s/\s+/ /g;
[1565]712 if ($mode == 0) {
713 ($$start{$n},$$end{$n},$$type{$n},$void) = split(/ /,$d);
[1801]714 $unit = 1;
[1565]715 } elsif ($mode == 1) {
716 ($$start{$n},$$end{$n},$size,$$type{$n},$void) = split(/ /,$d);
[1801]717 $unit = $mega;
[3343]718 } elsif ($mode == 2) {
719 ($$start{$n},$$end{$n},$size,$$type{$n},$void) = split(/ /,$d);
720 $unit = $mega;
[1565]721 } else {
722 die "Undefined mode $mode";
723 }
[1]724 $$start{$n} = "" if (not defined $$start{$n});
725 $$end{$n} = "" if (not defined $$end{$n});
726 $$type{$n} = "" if (not defined $$type{$n});
[1565]727 # Handles potential suffixes in latest parted version. Return MB
[1801]728 $ret = decode_Bsuf($$start{$n},$unit);
[1565]729 $$start{$n} = $ret;
[1801]730 $ret = decode_Bsuf($$end{$n},$unit);
[1565]731 $$end{$n} = $ret;
[3370]732 pb_log(2,"$n $$start{$n} $$end{$n} $$type{$n}\n");
[1]733}
734close(PARTED);
735}
736
[1565]737sub decode_Bsuf {
738
739my $size = shift;
740my $unit = shift;
741my $ret = 0;
742
[3370]743pb_log(2,"decode_Bsuf input: $size / $unit ");
[1837]744if ($size =~ /K[B]*$/i) {
745 $size =~ s/K[B]*$//i;
[1565]746 $size *= 1024;
[1837]747} elsif ($size =~ /M[B]*$/i) {
748 $size =~ s/M[B]*$//i;
[1565]749 $size *= 1048576;
[1837]750} elsif ($size =~ /G[B]*$/i) {
751 $size =~ s/G[B]*$//i;
[1565]752 $size *= 1073741824;
[1837]753} elsif ($size =~ /T[B]*$/i) {
754 $size =~ s/T[B]*$//i;
[1565]755 $size *= 1099511627776;
756} else {
757 # Nothing to do
758}
759$ret = $size / $unit;
[3370]760pb_log(2," - output : $size => $ret\n");
[1565]761return($ret);
762}
Note: See TracBrowser for help on using the repository browser.