Changeset 3664


Ignore:
Timestamp:
May 3, 2017, 11:27:15 AM (3 months ago)
Author:
bruno
Message:

Attempts to fix mr-parted2fdisk

  • usage of -m option of parted where possible to ease analysis
  • handle new fdisk formats
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/3.3/mindi/mr-parted2fdisk

    r3663 r3664  
    251251close(CMD);
    252252# More than 1000 is a lot of disks so may triggers the issue
    253 $use_parted = 1 if ($lines >= 1000);
    254 
    255 # Check partition table type
     253my $maxhdd = 1;
     254$use_parted = 1 if ($lines >= $maxhdd);
     255
     256$device = "" if ((not defined $device) || ($device =~ /^-/));
     257pb_log(1,"Called with device: $device\n");
     258
     259# Check partition table type. Works also if no device
    256260$type = mr_disk_type($device);
     261
    257262# Replacement code only for GPT disks
    258263if (((($v == 1) || (($v == 2) && ($maj < 22))) && ($type ne "MBR")) || ($use_parted == 1)) {
    259     pb_log(1,"This distribution uses an old fdisk, activating replacement code for GPT disk label...\n");
     264    if ($use_parted == 1) {
     265        pb_log(1,"Using parted since we detected more than $maxhdd disks...\n");
     266    } else {
     267        pb_log(1,"This distribution uses an old fdisk, activating replacement code for GPT disk label...\n");
     268    }
    260269    my $parted = pb_check_req("parted",0);
    261270    if (defined $opts{'l'}) {
    262         fdisk_list($device,undef,\%start,\%end, 1);
     271        fdisk_list_all($device,undef,\%start,\%end, 1);
    263272    } elsif (defined $opts{'s'}) {
    264273        fdisk_list($device,$wpart,\%start,\%end, 1);
     
    467476open(PART,"/proc/partitions") || die "Unable to open /proc/partitions";
    468477while (<PART>) {
    469     my ($maj,$min,$blocks,$dev) = split(/\s+/);
    470     next if ($dev =~ /^fd|^sr/);
    471     next if ($min != 0);
     478    # Skip first cmt line if present or empty lines
     479    next if (($_ =~ /^maj/) || ($_ =~ /^\s*$/));
     480    my ($void,$maj,$min,$blocks,$dev) = split(/\s+/);
     481    next if ((not defined $dev) || ($dev =~ /^fd|^sr|^ram/));
     482    next if ((not defined $min) || ($min != 0));
    472483    fdisk_list("/dev/$dev",$wpart,$start,$end,$verbose);
    473484}
     
    550561    # so return in MB * 1MB / what represents 1 cyl in B
    551562    $mstart = sprintf("%d",$$start{$n}*$mega/$un);
     563    pb_log(2,"mstart: $mstart\n");
    552564    $mstart = 1 if ($mstart < 1);
    553565    $mstart = $endmax if ($mstart > $endmax);
    554566    $mend = sprintf("%d",$$end{$n}*$mega/$un - 1);
    555567    $mend = $endmax if ($mend > $endmax);
     568    pb_log(2,"mend $mend\n");
    556569    $mend = 1 if ($mend < 1);
    557570    # length is in 1K blocks
     
    559572    $pid = $pid{$type{$n}};
    560573    $cmt = $cmt{$type{$n}};
    561     #print FLOG "$part - $mstart - $mend - $length\n";
     574    pb_log(2,"$part - $mstart - $mend - $length\n");
    562575
    563576    if ($verbose == 1) {
     
    612625    }
    613626}
     627if ($max == 0) {
     628    close(FDISK);
     629    # Try by forcing the cylinders display, not done by default on more recent fdisk
     630    open (FDISK, "$fdisk -u=cylinders -l $device 2>/dev/null |") || die "Unable to read from $fdisk -u=cylinders";
     631    while (<FDISK>) {
     632        if ($_ =~ /heads/) {
     633            chomp;
     634            $max = $_;
     635            $max =~ s/.* ([0-9]+) cylinders/$1/;
     636        }
     637    }
     638}
    614639close(FDISK);
    615640pb_log(2,"get_max returns $max\n");
     
    659684my $size;
    660685my $unit;
     686my $flag;
    661687
    662688my $parted = pb_check_req("parted",0);
     
    670696my ($v,$maj,$min) = split(/\./,$d);
    671697# depending on parted version, information given change:
    672 if ($v == 2) {
     698# parted >= 1.8.0 has support for -m option
     699# Cf: http://git.savannah.gnu.org/cgit/parted.git/commit/?id=30e12276029b0b6c04d2d0edf2b9b00ba797013c
     700if ($v >= 2) {
     701    # RHEL 5 parted 1.8
    673702    # RHEL 6 parted 2.1
     703    # SLES 11 1.8.8
    674704    $mode=2;
    675705} elsif ($v == 1) {
     
    678708        # RHEL 4 parted 1.6.19
    679709        $mode=0;
     710    } elsif ($maj >= 8) {
     711        $mode=2;
    680712    } else {
    681713        # SLES 10 parted >= 1.6.25
     
    687719pb_log(2,"parted mode: $mode\n");
    688720
    689 open(PARTED, "$parted -s $device print |") || die "Unable to read from $parted";
    690 # Skip 3 first lines
    691 $d = <PARTED>;
    692 $d = <PARTED>;
    693 $d = <PARTED>;
     721# Result of parted -m -s /dev/sda print
     722#
     723# On RHEL7:
     724#BYT;
     725#/dev/sda:500GB:scsi:512:512:gpt:HP LOGICAL VOLUME:;
     726#1:1049kB:211MB:210MB:fat16:EFI System Partition:boot;
     727#2:211MB:735MB:524MB:ext4::;
     728#3:735MB:500GB:499GB:::lvm;
     729#
     730# On RHEL6:
     731#BYT;
     732#/dev/sda:500GB:scsi:512:512:gpt:HP LOGICAL VOLUME;
     733#1:1049kB:211MB:210MB:fat16::boot;
     734#2:211MB:735MB:524MB:ext4::;
     735#3:735MB:500GB:499GB:::lvm;
     736#
     737# On Debian 8
     738#
     739#BYT;
     740#/dev/sda:500GB:scsi:512:512:gpt:HP LOGICAL VOLUME:;
     741#1:1049kB:538MB:537MB:fat32::boot, esp;
     742#2:538MB:7538MB:7000MB:ext4::;
     743#3:7538MB:10.5GB:3000MB:ext4::;
     744#4:10.5GB:44.6GB:34.1GB:linux-swap(v1)::;
     745#5:44.6GB:45.0GB:400MB:ext4::;
     746#6:45.0GB:500GB:455GB:ext4::;
    694747
    695748if ($mode == 2) {
     749    # Then use option -m which is available
     750    open(PARTED, "$parted -m -s $device print |") || die "Unable to read from $parted";
     751    # Skip 2 first lines
     752    $d = <PARTED>;
     753    if ($d !~ /^BYT/) {
     754        die "Your $parted command doesn't behave correctly in machine readable mode";
     755    }
     756    # Skip device line for now
     757    $d = <PARTED>;
     758    pb_log(2,"Got from parted: \n");
     759    pb_log(2,"Minor    Start       End     Filesystem\n");
     760    while (<PARTED>) {
     761        ($n,$d) = split(/:/,$_,2);
     762        ($$start{$n},$$end{$n},$size,$$type{$n},$void,$flag) = split(/:/,$d);
     763        # Handles suffixes. Returns MB
     764        $ret = decode_Bsuf($$start{$n},$mega);
     765        $$start{$n} = $ret;
     766        $ret = decode_Bsuf($$end{$n},$mega);
     767        $$end{$n} = $ret;
     768        $$type{$n} =~ s/\(..*\)$//;
     769        pb_log(2,"$n      $$start{$n}      $$end{$n}     $$type{$n}\n");
     770    }
     771} else {
     772    # Maintaned for compatibility with very old distributions now
     773    open(PARTED, "$parted -s $device print |") || die "Unable to read from $parted";
     774    # Skip 3 first lines
    696775    $d = <PARTED>;
    697776    $d = <PARTED>;
    698777    $d = <PARTED>;
    699 }
    700 pb_log(2,"Got from parted: \n");
    701 pb_log(2,"Minor    Start       End     Filesystem\n");
    702 # Get info from each partition line
    703 while (($n,$d) = split(/\s/, <PARTED>,2)) {
    704     chomp($d);
    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 ""));
    709     next if ($n !~ /^[1-9]/);
    710     $d =~ s/^\s*//;
    711     $d =~ s/\s+/ /g;
    712     if ($mode == 0) {
    713         ($$start{$n},$$end{$n},$$type{$n},$void) = split(/ /,$d);
    714         $unit = 1;
    715     } elsif ($mode == 1) {
    716         ($$start{$n},$$end{$n},$size,$$type{$n},$void) = split(/ /,$d);
    717         $unit = $mega;
    718     } elsif ($mode == 2) {
    719         ($$start{$n},$$end{$n},$size,$$type{$n},$void) = split(/ /,$d);
    720         $unit = $mega;
    721     } else {
    722         die "Undefined mode $mode";
    723     }
    724     $$start{$n} = "" if (not defined $$start{$n});
    725     $$end{$n} = "" if (not defined $$end{$n});
    726     $$type{$n} = "" if (not defined $$type{$n});
    727     # Handles potential suffixes in latest parted version. Return MB
    728     $ret = decode_Bsuf($$start{$n},$unit);
    729     $$start{$n} = $ret;
    730     $ret = decode_Bsuf($$end{$n},$unit);
    731     $$end{$n} = $ret;
    732     pb_log(2,"$n      $$start{$n}      $$end{$n}     $$type{$n}\n");
     778
     779    pb_log(2,"Got from parted: \n");
     780    pb_log(2,"Minor    Start       End     Filesystem\n");
     781    # Get info from each partition line
     782    while (($n,$d) = split(/\s/, <PARTED>,2)) {
     783        chomp($d);
     784        next if ($n !~ /^[1-9]/);
     785        $d =~ s/^\s*//;
     786        $d =~ s/\s+/ /g;
     787        if ($mode == 0) {
     788            ($$start{$n},$$end{$n},$$type{$n},$void) = split(/ /,$d);
     789            $unit = 1;
     790        } elsif ($mode == 1) {
     791            ($$start{$n},$$end{$n},$size,$$type{$n},$void) = split(/ /,$d);
     792            $unit = $mega;
     793        } else {
     794            die "Undefined mode $mode";
     795        }
     796        $$start{$n} = "" if (not defined $$start{$n});
     797        $$end{$n} = "" if (not defined $$end{$n});
     798        $$type{$n} = "" if (not defined $$type{$n});
     799        # Handles potential suffixes in latest parted version. Return MB
     800        $ret = decode_Bsuf($$start{$n},$unit);
     801        $$start{$n} = $ret;
     802        $ret = decode_Bsuf($$end{$n},$unit);
     803        $$end{$n} = $ret;
     804        pb_log(2,"$n      $$start{$n}      $$end{$n}     $$type{$n}\n");
     805    }
    733806}
    734807close(PARTED);
     
    740813my $unit  = shift;
    741814my $ret = 0;
     815my $kilo = 1024;
    742816
    743817pb_log(2,"decode_Bsuf input: $size / $unit ");
    744818if ($size =~ /K[B]*$/i) {
    745819    $size =~ s/K[B]*$//i;
    746     $size *= 1024;
     820    $size *= $kilo;
    747821} elsif ($size =~ /M[B]*$/i) {
    748822    $size =~ s/M[B]*$//i;
    749     $size *= 1048576;
     823    $size *= $kilo*$kilo;
    750824} elsif ($size =~ /G[B]*$/i) {
    751825    $size =~ s/G[B]*$//i;
    752     $size *= 1073741824;
     826    $size *= $kilo*$kilo*$kilo;
    753827} elsif ($size =~ /T[B]*$/i) {
    754828    $size =~ s/T[B]*$//i;
    755     $size *= 1099511627776;
     829    $size *= $kilo*$kilo*$kilo*$kilo;
    756830} else {
    757831    # Nothing to do
Note: See TracChangeset for help on using the changeset viewer.