SI/ptable.pm
changeset 28 7d7ca3f05f25
parent 27 de0a25512844
child 29 4e40cf0eba95
equal deleted inserted replaced
27:de0a25512844 28:7d7ca3f05f25
     1 package SI::ptable;
       
     2 
       
     3 use if $ENV{DEBUG} ~~ /ptable|all/ => qw(Smart::Comments);
       
     4 
       
     5 use strict;
       
     6 use warnings;
       
     7 use File::Find;
       
     8 use File::Basename;
       
     9 use IO::File;
       
    10 
       
    11 use SI::tools;
       
    12 $ENV{LC_ALL} = "C";
       
    13 
       
    14 sub volumes($\%) {
       
    15     my ($file, $devs) = @_;
       
    16 
       
    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         my $dev  = "/dev/$name";
       
    23 
       
    24         next if !-e "$_/device";
       
    25         next
       
    26           if (grep { /ATTR{removable}/ }
       
    27             `udevadm info --attribute-walk --name $name`)[0] !~ /==.0./;
       
    28         next if (stat $dev)[0] == (stat $0)[0];
       
    29 
       
    30         # exclude the device (stick) we're part of - this HACK is
       
    31         # only useful on KVM - the usb stick doesn't appear as a removeable
       
    32         # device
       
    33         next
       
    34           if (stat $0)[0] ~~ [
       
    35             map   { (stat)[6] }
       
    36               map { "/dev/" . basename(dirname $_) } glob("$_/*/partition")
       
    37           ];
       
    38 
       
    39         verbose("\n");
       
    40         verbose("device $dev\n");
       
    41 
       
    42         die "ERR: $dev does not exist. (should not happen): $!"
       
    43           if !-b $dev;
       
    44 
       
    45         # now the physical disk -- let's ask for the partition table
       
    46 
       
    47         my @sfdisk = `sfdisk -d /dev/$name 2>/dev/null`;
       
    48 
       
    49         my $of = sprintf $file, $name;
       
    50         my $oh = new IO::File ">$of" or die "Can't open >$of: $!\n";
       
    51         print $oh @sfdisk;
       
    52 
       
    53         $devs->{disk}{"/dev/$name"} = { pt => \@sfdisk };
       
    54 
       
    55         # and let's prepare the volume entries
       
    56         foreach (@sfdisk) {
       
    57             /^(\S+)\s*:.*Id=\s*([[:xdigit:]]+)/ or next;
       
    58             $devs->{volume}{$1} = {
       
    59                 origin      => "ptable",
       
    60                 ptable_type => $2,
       
    61             };
       
    62             push @{ $devs->{volumes} }, $1;
       
    63         }
       
    64     }
       
    65 
       
    66     return;
       
    67 }
       
    68 1;
       
    69 
       
    70 # vim:sts=4 sw=4 aw ai si: