SI/ptable.pm
changeset 13 2e3ad71484ea
parent 12 a1aee1136609
child 15 4e3753b998a9
equal deleted inserted replaced
12:a1aee1136609 13:2e3ad71484ea
     3 use if $ENV{DEBUG} ~~ /ptable|all/ => qw(Smart::Comments);
     3 use if $ENV{DEBUG} ~~ /ptable|all/ => qw(Smart::Comments);
     4 
     4 
     5 use strict;
     5 use strict;
     6 use warnings;
     6 use warnings;
     7 use File::Find;
     7 use File::Find;
       
     8 use File::Basename;
     8 use IO::File;
     9 use IO::File;
     9 
       
    10 
    10 
    11 use SI::tools;
    11 use SI::tools;
    12 $ENV{LC_ALL} = "C";
    12 $ENV{LC_ALL} = "C";
    13 
    13 
    14 sub volumes($\%) {
    14 sub volumes($\%) {
    15     my ($file, $devs) = @_;
    15     my ($file, $devs) = @_;
    16 
    16 
    17     # find the non-removable devices
    17     # find the partition tables of all
       
    18     # non-removable block devices (this may include
       
    19     # LVs (used as disk itself) too)
       
    20     foreach (glob("/sys/block/*")) {
       
    21 	    my $name = basename($_);
       
    22 	    verbose("device $name");
    18 
    23 
    19     my ($current, $of);
    24 	    if (!-e "$_/device") {
    20     foreach (`sfdisk -d 2>/dev/null`) {
    25 		    verbose("skipping (non-dev)\n");
    21         chomp;
    26 		    next;
    22 
    27 	    }
    23 	# new entry, new disk
       
    24         if (my ($device, $name) = /^# partition table .*?(\/\S+\/(\S+))/) {
       
    25 	    verbose("scanning device $device");
       
    26 
       
    27 	    if ((grep { /ATTR{removable}/ } `udevadm info --attribute-walk --name $name`)[0] !~ /==.0./) {
    28 	    if ((grep { /ATTR{removable}/ } `udevadm info --attribute-walk --name $name`)[0] !~ /==.0./) {
    28 		    $current = undef;
       
    29 		    verbose("skipping (removable)\n");
    29 		    verbose("skipping (removable)\n");
    30 		    next;
    30 		    next;
    31 	    }
    31 	    }
       
    32 	    verbose("\n");
    32 
    33 
    33 	    # if it looks like a device mapper, we'll have to remember
    34 	    die "ERR: /dev/$name does not exist. (should not happen)"
    34 	    # this
    35 		if !-e "/dev/$name";
    35 	    if ($device =~ /\/dev\/dm-/) {
    36 
    36 		if (my $alias = find_by_devid("/dev/mapper", (stat $device)[6])) {
    37 	    # now the physical disk -- let's ask for the partition table
    37 		    verbose("(alias $device)");
    38 
    38 		    $devs->{disk}{$alias}{dm} = $device;
    39 	    my @sfdisk = `sfdisk -d /dev/$name 2>/dev/null`;
    39 		    $device = $alias;
    40 
    40 		}
    41 	    my $of = sprintf $file, $name;
       
    42 	    my $oh = new IO::File ">$of" or die "Can't open >$of: $!\n";
       
    43 	    print $oh @sfdisk;
       
    44 
       
    45 	    $devs->{disk}{"/dev/$name"} = { 
       
    46 		pt => \@sfdisk
       
    47 	    };
       
    48 
       
    49 	    push @{$devs->{known}}, "/dev/$name";
       
    50 
       
    51 	    # and let's prepare the volume entries
       
    52 	    foreach (@sfdisk) {
       
    53 		/^(\S+)\s*:.*Id=\s*(\d+)/ or next;
       
    54 		$devs->{volume}{$1} = {
       
    55 			origin => "ptable",
       
    56 			ptable_type => $2,
       
    57 		    };
       
    58 		push @{$devs->{known}}, $1;
    41 	    }
    59 	    }
    42 
       
    43 	    # save in our data structure
       
    44 	    verbose("\n");
       
    45 	    $current = $device;
       
    46 	    push @{$devs->{disk}{$current}{pt}}, $_;
       
    47 
       
    48 	    # and open the outfile
       
    49 	    my $f = sprintf ">$file", $name;
       
    50 	    $of = new IO::File $f or die "ERR: Can't open $f: $!\n";
       
    51 	    print $of "$_\n";
       
    52 
       
    53 	    next;
       
    54         }
       
    55 
       
    56         next if not $current;
       
    57 
       
    58 	push @{$devs->{disk}{$current}{pt}}, $_;
       
    59 	print $of "$_\n";
       
    60 
       
    61 	# if it looks like a partition (volume), then
       
    62 	# save it
       
    63 	if (my ($dev, $id) = /^(\/dev\/\S+)\s*:.*\sId=\s*(\d+)/) {
       
    64 	    if (my $dm = $devs->{disk}{$current}{dm}) {
       
    65 		$dev =~ s/$dm/$current/;
       
    66 	    }
       
    67 	    $devs->{volume}{$dev}{fstype} = $id;
       
    68 	}
       
    69 
       
    70     }
    60     }
    71 
    61 
    72     return;
    62     return;
    73 }
    63 }
    74 1;
    64 1;