StorageDisplay
view release on metacpan or search on metacpan
lib/StorageDisplay/Collect.pm view on Meta::CPAN
my $self = shift;
my $collector = shift;
die "$collector not a StorageDisplay::Collect::Collector"
if not $collector->isa("StorageDisplay::Collect::Collector");
push @{$self->{_attr_collectors}}, $collector;
foreach my $cn ($collector->provides) {
if (exists($self->{_attr_collectors_by_provide}->{$cn})) {
die "$cn provided by both ".$collector->module." and ".
$self->{_attr_collectors_by_provide}->{$cn}->module;
}
$self->{_attr_collectors_by_provide}->{$cn} = $collector;
}
}
sub open_cmd_pipe {
my $self = shift;
return $self->cmdreader->open_cmd_pipe(@_);
}
sub open_cmd_pipe_root {
my $self = shift;
return $self->cmdreader->open_cmd_pipe_root(@_);
}
sub open_file {
my $self = shift;
return $self->cmdreader->open_file(@_);
}
sub has_file {
my $self = shift;
return $self->cmdreader->has_file(@_);
}
sub cmdreader {
my $self = shift;
return $self->{_attr_cmdreader};
}
my @collectors;
sub new {
my $class = shift;
my $reader = shift // 'Local';
if (ref($reader) eq '') {
my $fullreadername = 'StorageDisplay::Collect::CMD::'.$reader;
$reader = $fullreadername->new(@_);
}
my $self = {
_attr_cmdreader => $reader,
_attr_collectors => [],
_attr_collectors_by_provide => {},
};
bless $self, $class;
foreach my $cdata (@collectors) {
my $cn = $cdata->{name};
$cn->new($cdata, $self);
}
return $self;
}
sub registerCollectorModule {
my $class = shift;
my $collector = shift;
#my $collector = caller 0;
#print STDERR "Registering $collector from ".(caller 0)."\n";
my $info = { name => $collector, @_ };
foreach my $entry (qw(provides requires)) {
next if not exists($info->{$entry});
if (ref($info->{$entry}) eq "") {
$info->{$entry} = [ $info->{$entry} ];
}
}
push @collectors, $info;
}
# Main collect function
#
# It will iterate on the collectors, respecting dependencies.
sub collect {
my $self = shift;
my $req = shift;
my $infos = {};
$infos = $self->cmdreader->data_init($infos);
# 0/undef : not computed
# 1 : computed
# 2 : computing
# 3 : N/A
my $collector_state = {};
my $load;
$load = sub {
my $col = shift;
$collector_state->{$_} = 2 for $col->provides;
foreach my $cname ($col->requires) {
#print STDERR " preloading $cname\n";
my $state = $collector_state->{$cname};
if (not defined($state)) {
my $collector = $self->collector($cname);
die "E: No $cname collector available for ".$col->module."\n"
if not defined($collector);
$load->($collector);
} elsif ($collector_state->{$cname} == 1) {
next
} else {
die "Loop in collectors requires ($cname required in $col->name)";
}
}
# are files present?
my @missing_files =
grep {
not $self->has_file($_);
} $col->depends('files');
if (scalar(@missing_files)) {
lib/StorageDisplay/Collect.pm view on Meta::CPAN
return @devs;
}
sub parse {
my $parser = shift;
my $closure = shift;
my $res = shift // {};
}
my %name = (
'Size (in MB)' => 'size-mb',
'Volume ID' => 'id',
'Volume wwid' => 'wwid',
'Status of volume' => 'status',
);
sub collect {
my $self = shift;
my $infos = shift;
my $dh;
my $lsi={};
my @devs=$self->select($infos);
my $parse_section = sub {
my $self = shift;
my $line = shift;
if ($line eq 'Controller information') {
#$self->push_new_section->($parse_controller, $closure_controller);
} elsif ($line eq 'IR Volume information') {
#return (1, $parse_volumes);
} elsif ($line eq 'Physical device information') {
#return (1, $parse_phydev);
} elsif ($line eq 'Enclosure information') {
#return (1, $parse_phydev);
} elsif ($line =~ /SAS2IRCU:/) {
if ($line eq 'SAS2IRCU: Command DISPLAY Completed Successfully.'
or $line eq 'SAS2IRCU: Utility Completed Successfully.') {
} else {
print STDERR "W: sas2ircu: $line\n";
}
} else {
#if (scalar(keys %$l) != 0) {
# print STDERR "W: sas2ircu: unknown line: $line\n";
#}
}
return 1;
};
foreach my $dev (@devs) {
$dh=$self->open_cmd_pipe_root('sas2ircu', $dev, 'DISPLAY');
my $l={};
my $state = 0;
my $wwid = {};
my $guid = {};
my $data = undef;
my $secdata = undef;
my $closure=sub {} ;
my $subclosure=sub {} ;
while(defined(my $line=<$dh>)) {
chomp($line);
next if $line =~ /^[\s-]*$/;
if ($line =~ /^(Controller) information$/
|| $line =~ /^(Enclosure) information$/) {
my $section = lc($1);
$subclosure->($data);
$closure->($data);
$data = {};
$subclosure = sub {};
$closure = sub {
my $curdata = shift;
if (exists($l->{$section})) {
print STDERR "E: sas2ircu: duplicate section: $line\n";
}
$l->{$section}=$curdata;
return {};
};
$state=10;
} elsif ($line =~ /^IR (Volume) information$/
|| $line =~ /^Physical (device) information$/) {
my $section = lc($1).'s';
$subclosure->($data);
$closure->($data);
$secdata=[];
$subclosure = sub { };
$closure=sub {
my $data = shift;
if (exists($l->{$section})) {
print STDERR "E: sas2ircu: duplicate section: $line\n";
}
$l->{$section}=$secdata;
return
};
} elsif ($line =~ /^IR volume ([^\s])+$/) {
my $name = $1;
$subclosure->($data);
$data = {
name => $name,
};
$subclosure = sub {
my $data = shift;
push @$secdata, $data;
};
} elsif ($line =~ /^Device is a Hard disk$/) {
$subclosure->($data);
$data = {};
$subclosure = sub {
my $data = shift;
push @$secdata, $data;
};
} elsif ($line =~ /^Initiator at ID .*$/) {
} elsif ($line =~ /^SAS2IRCU: .* Completed Successfully.$/) {
} elsif ($line =~ /^[^\s]/) {
if ($state != 0) {
print STDERR "W: sas2ircu: unknown line: $line\n";
}
} elsif ($line =~ /^\s+([^\s][^:]*[^\s])\s*:\s+([^\s].*)$/) {
my $k = $1;
my $v = $2;
if ($k =~ m,^PHY\[([^\]]+)\] Enclosure#/Slot#,) {
my $phy=$1;
my ($e, $s) = split(':', $v);
$data->{PHY}->{$phy} = { enclosure => $e, slot => $s };
next;
} elsif ($k eq 'Size (in MB)/(in sectors)') {
my ($s1, $s2) = split('/', $v);
$data->{'size-mb'}=$s1;
$data->{'size-s'}=$s2;
$data->{'size'}=$s2 * 512;
next;
}
$k = $name{$k} // $k;
$k =~ s/\s*[#]//;
$k = lc($k);
$k =~ s/\s+/-/g;
if ($k eq 'guid') {
$guid->{$v}=1;
} elsif ($k eq 'wwid') {
$wwid->{$v}=1;
}
$data->{$k}=$v;
}
}
$subclosure->($data);
$closure->($data);
close $dh;
$dh=$self->open_cmd_pipe(qw(find /sys/devices -name sas_address));
my @lines=<$dh>;
for my $line (sort @lines) {
chomp($line);
my $dh2 = $self->open_file($line)
or die "Cannot open $line: $!\n";
my $addr=<$dh2>;
close $dh2;
chomp($addr);
$addr =~ s/^0x//;
if (defined($wwid->{$addr})) {
my $dir = $line;
$dir =~ s/sas_address/block/;
my $dh3 = $self->open_cmd_pipe('ls', '-1', $dir);
my @dirs=<$dh3>;
close($dh3);
if (scalar(@dirs) != 1) {
print STDERR "E: sas2ircu: bad number of block devices for $addr\n";
} else {
chomp($l->{wwid}->{$addr} = $dirs[0]);
}
}
}
( run in 0.935 second using v1.01-cache-2.11-cpan-df04353d9ac )