diff options
| -rw-r--r-- | lib/ManaTools/Module/Disk.pm | 90 | ||||
| -rw-r--r-- | lib/ManaTools/Shared/disk_backend.pm | 263 | ||||
| -rw-r--r-- | lib/ManaTools/Shared/disk_backend/FileSystem.pm | 30 | ||||
| -rw-r--r-- | lib/ManaTools/Shared/disk_backend/IO.pm | 154 | ||||
| -rw-r--r-- | lib/ManaTools/Shared/disk_backend/IOs.pm | 219 | ||||
| -rw-r--r-- | lib/ManaTools/Shared/disk_backend/Part.pm | 158 | ||||
| -rw-r--r-- | lib/ManaTools/Shared/disk_backend/Plugin.pm | 72 | ||||
| -rw-r--r-- | lib/ManaTools/Shared/disk_backend/Plugin/Btrfs.pm | 311 | ||||
| -rw-r--r-- | lib/ManaTools/Shared/disk_backend/Plugin/Disk.pm | 70 | ||||
| -rw-r--r-- | lib/ManaTools/Shared/disk_backend/Plugin/Extfs.pm | 109 | ||||
| -rw-r--r-- | lib/ManaTools/Shared/disk_backend/Plugin/Loop.pm | 30 | ||||
| -rw-r--r-- | lib/ManaTools/Shared/disk_backend/Plugin/Mount.pm | 195 | ||||
| -rw-r--r-- | lib/ManaTools/Shared/disk_backend/Plugin/Partition.pm | 163 | ||||
| -rw-r--r-- | lib/ManaTools/Shared/disk_backend/Plugin/Swap.pm | 40 | ||||
| -rw-r--r-- | lib/test-diskbe.pl | 38 | 
15 files changed, 249 insertions, 1693 deletions
| diff --git a/lib/ManaTools/Module/Disk.pm b/lib/ManaTools/Module/Disk.pm index 9b3b8584..e583230a 100644 --- a/lib/ManaTools/Module/Disk.pm +++ b/lib/ManaTools/Module/Disk.pm @@ -171,7 +171,7 @@ has actionsBox => (      init_arg => undef,  ); -has ioProperties => ( +has partProperties => (      is => 'rw',      isa => 'Maybe[ManaTools::Shared::GUI::Properties]',      default => undef, @@ -183,7 +183,7 @@ has ioProperties => (  has selectedItem => (      is => 'rw', -    isa => 'Maybe[ManaTools::Shared::disk_backend::IO]', +    isa => 'Maybe[ManaTools::Shared::disk_backend::Part]',      default => undef,      init_arg => undef,  ); @@ -236,9 +236,8 @@ sub _selectItem {      return $old unless @_;      my $new = shift; -    my @parts = $new->findin(); -    while (scalar(@parts) > 0) { -    } +    # TODO: find the first child, and then use the first child again +      # if $new has children, get the first one instead      # if $new is an ancestor of $old, we're not gonna change it      return $self->$orig($new); @@ -247,9 +246,9 @@ sub _selectItem {  sub _showSelectedItem {      my $self = shift;      my $module = $self->module(); -    my $io = $self->selectedItem(); -    my $ioProperties = $module->ioProperties(); -    $ioProperties->properties($io); +    my $part = $self->selectedItem(); +    my $partProperties = $module->partProperties(); +    $partProperties->properties($part);      my $propbox = $module->propertiesBox();      # properties @@ -267,28 +266,28 @@ sub _rebuildTab {      my $parent = shift;      my @items = @_;      my $tab = ManaTools::Shared::GUI::ExtTab->new(eventHandler => $eventHandler, parentWidget => $container); -    for my $io (@items) { -        $tab->addSelectorItem($io->label(), $io, sub { +    for my $part (@items) { +        $tab->addSelectorItem($part->label(), $part, sub {              my $self = shift;# tab              my $parent = shift; -            my $io = shift; +            my $part = shift;              my $dialog = $self->parentDialog();              my $module = $dialog->module();              my $factory = $dialog->factory();              # create content              my $vbox = $factory->createVBox($parent); -            $module->_rebuildItem($io, $self->replacepoint(), $vbox); -            #$self->addWidget($io->label() .': button 1', $factory->createPushButton($vbox, $io->label() .': button 1'), sub { my $backendItem = shift; print STDERR "backendItem: ". $backendItem->label() ."::button1\n"; }); -            #$self->addWidget($io->label() .': button 2', $factory->createPushButton($vbox, $io->label() .': button 2'), sub { my $backendItem = shift; print STDERR "backendItem: ". $backendItem->label() ."::button2\n"; }); -            #$self->addWidget($io->label() .': button 3', $factory->createPushButton($vbox, $io->label() .': button 3'), sub { my $backendItem = shift; print STDERR "backendItem: ". $backendItem->label() ."::button3\n"; }); +            $module->_rebuildItem($part, $self->replacepoint(), $vbox); +            #$self->addWidget($part->label() .': button 1', $factory->createPushButton($vbox, $part->label() .': button 1'), sub { my $backendItem = shift; print STDERR "backendItem: ". $backendItem->label() ."::button1\n"; }); +            #$self->addWidget($part->label() .': button 2', $factory->createPushButton($vbox, $part->label() .': button 2'), sub { my $backendItem = shift; print STDERR "backendItem: ". $backendItem->label() ."::button2\n"; }); +            #$self->addWidget($part->label() .': button 3', $factory->createPushButton($vbox, $part->label() .': button 3'), sub { my $backendItem = shift; print STDERR "backendItem: ". $backendItem->label() ."::button3\n"; });              $factory->createHStretch($vbox);              #$factory->createVStretch($vbox);              # update the properties -            my $ioProperties = $module->ioProperties(); -            $ioProperties->properties($io); -            my $db = $io->db(); +            my $partProperties = $module->partProperties(); +            $partProperties->properties($part); +            my $db = $part->db();              my $propbox = $module->propertiesBox();              my $actionbox = $module->actionsBox(); @@ -297,17 +296,17 @@ sub _rebuildTab {              $actionbox->clear();              # loop all connected parts -            my @parts = $db->findin($io); -            for my $part (@parts) { +            my @children = $part->children(); +            for my $child (@children) {                  # add properties for each part in a frame with label -                my $frame = $factory->createFrame($propbox->container(), $part->label() ." properties"); +                my $frame = $factory->createFrame($propbox->container(), $child->label() ." properties");                  my $align = $factory->createLeft($frame); -                ManaTools::Shared::GUI::Properties->new({eventHandler => $propbox, parentWidget => $align, properties => $part}); +                ManaTools::Shared::GUI::Properties->new({eventHandler => $propbox, parentWidget => $align, properties => $child});                  # add actions for each part in a frame with label                  $frame = $factory->createFrame($actionbox->container(), $part->label() ." actions"); -                ManaTools::Shared::GUI::ActionList->new({eventHandler => $actionbox, parentWidget => $frame, actions => $part}); +                ManaTools::Shared::GUI::ActionList->new({eventHandler => $actionbox, parentWidget => $frame, actions => $child});              }              # finalize propbox and actionbox @@ -315,7 +314,8 @@ sub _rebuildTab {              $actionbox->finished();              # stretch vertically if no children are there -            $factory->createVStretch($vbox) if (scalar(@parts) == 0); +            $factory->createVStretch($vbox) if (scalar(@children) == 0); +            # TODO: select logically the item (which should also select it's children if needed)          });      }      $tab->finishedSelectorItems(); @@ -397,12 +397,12 @@ sub _rebuildButtonBox {              $count = $count + 1;              $start = $i->prop('start');          } +        # get the purpose_label()          # get part type (path)          my $label = ''; -        my @p = $i->findin(); -        if (scalar(@p) > 0) { -            $label = join ',', map { ($_->type() eq 'Mount') && $_->prop('path') || $_->type() } @p; -        } +        $self->D("$self: $i (". $i->label() .") does PurposeLabelRole: %s", $i->does('ManaTools::Shared::disk_backend::PurposeLabelRole')); +        $label = $i->purpose_label() if ($i->does('ManaTools::Shared::disk_backend::PurposeLabelRole')); +        $label = '' if !(defined $label);          $self->D("$self: add a button SelectorItem to $buttonbox with label $label and backend $i");          my $item = $buttonbox->addSelectorItem($label, $i, sub {              my $self = shift; @@ -469,16 +469,16 @@ sub _rebuildItems {      my $container = shift;      for my $i (@{$info}) {          if ($i->{type} eq 'tab') { -            return $self->_rebuildTab($eventHandler, $container, $i->{io}, @{$i->{items}}); +            return $self->_rebuildTab($eventHandler, $container, $i->{part}, @{$i->{items}});          }          if ($i->{type} eq 'buttonbox') { -            return $self->_rebuildButtonBox($eventHandler, $container, $i->{io}, @{$i->{items}}); +            return $self->_rebuildButtonBox($eventHandler, $container, $i->{part}, @{$i->{items}});          }          if ($i->{type} eq 'list') { -            return $self->_rebuildList($eventHandler, $container, $i->{io}, @{$i->{items}}); +            return $self->_rebuildList($eventHandler, $container, $i->{part}, @{$i->{items}});          }          if ($i->{type} eq 'tree') { -            return $self->_rebuildTree($eventHandler, $container, $i->{io}, @{$i->{items}}); +            return $self->_rebuildTree($eventHandler, $container, $i->{part}, @{$i->{items}});          }      }      return undef; @@ -486,23 +486,23 @@ sub _rebuildItems {  sub _expandItem {      my $self = shift; -    my $io = shift; +    my $part = shift;      my $infos = [];      my $type = 'list';      my @items;      # get parts -    if (defined $io) { -        @items = $io->findin(); +    if (defined $part) { +        @items = $part->children();      }      else {          my $backend = $self->backend(); -        @items = $backend->findnoin(); +        @items = $backend->findnopart(undef, 'parent');      } -    # merge all outs from these Parts +    # merge all children from these Parts      for my $p (@items) { -        push @{$infos}, {io => $io, part => $p, type => ( $p->type() eq 'Disks' ? 'tab' : $p->type() eq 'PartitionTable' ? 'buttonbox' : $type ), items => [sort {$a->label() cmp $b->label()} $p->out_list()]}; +        push @{$infos}, {parent => $part, part => $p, type => ( $p->type() eq 'Disks' ? 'tab' : $p->type() eq 'PartitionTable' ? 'buttonbox' : $type ), items => [sort {$a->label() cmp $b->label()} $p->children()]};      }      return $infos;  } @@ -655,8 +655,8 @@ sub _adminDiskPanel {              my $propframe = $factory->createFrame($vbox1, $self->loc->N("&Device properties"));              my $vbox3 = $factory->createVBox($propframe);              $align = $factory->createLeft($vbox3); -            # properties from IO first, and then the applicable Parts -            $module->ioProperties(ManaTools::Shared::GUI::Properties->new(eventHandler => $self, parentWidget => $align)); +            # properties from the Part first, and then the ancestors +            $module->partProperties(ManaTools::Shared::GUI::Properties->new(eventHandler => $self, parentWidget => $align));              $replacepoint = ManaTools::Shared::GUI::ReplacePoint->new(eventHandler => $self, parentWidget => $vbox1);              $factory->createVStretch($replacepoint->container());              # don't add children right away @@ -683,15 +683,15 @@ sub _adminDiskPanel {              $backend->probe();              ## fill in info -            # disks has a list of IOs (from Parts without in) -            # unused has a list of IOs not being an in for a Part -            # fs has a list of endpoints and in a tree (mount/swap?): ie: Parts without out +            # disks has a list of Parts without parent +            # unused has a list of Parts without children, maybe specifically BlockDevices ? +            # fs has a list of endpoints and in a tree (mount/swap?): ie: Mount parts with no parentmount and all their childmounts              ## start the info structure              my $info = {                  disks => $module->_expandItem(), -                unused => {type => 'list', items => sort {$a->label() cmp $b->label()} grep {scalar($_->findin()) == 0} values %{$backend->ios()}}, -                fs => {type => 'tree', items => []} +                unused => {type => 'list', items => [sort {$a->label() cmp $b->label()} grep {$_->does('ManaTools::Shared::disk_backend::BlockDevice')} $backend->findnopart(undef, 'child')]}, +                fs => {type => 'tree', items => [grep {!defined($_->parentmount())} $backend->findpart('Mount')]}              };              ## fs Part should be linked to all the mounts (hierarchial) diff --git a/lib/ManaTools/Shared/disk_backend.pm b/lib/ManaTools/Shared/disk_backend.pm index af8f63b9..8753a539 100644 --- a/lib/ManaTools/Shared/disk_backend.pm +++ b/lib/ManaTools/Shared/disk_backend.pm @@ -14,15 +14,9 @@ package ManaTools::Shared::disk_backend;      my $db_man = ManaTools::Shared::disk_backend->new();      $db_man->load();      $db_man->probe(); -    $db_man->findin($io); -    $db_man->findout($io); -    $db_man->findnoin(); -    $db_man->findnoout();      my @parts = $db_man->findpart($type); -    my @ios = $db_man->findioprop($prop, $value);      ...      $db_man->save(); -    $db_man->mkio('Foo', {id => 'foo-id', other => 'value'});      $db_man->mkpart('Foo', {other => 'value'}); @@ -169,14 +163,6 @@ has 'plugins' => (      }  ); -has 'ios' => ( -    is => 'rw', -    isa =>'HashRef[ManaTools::Shared::disk_backend::IO]', -    default => sub { -        return {}; -    } -); -  has 'parts' => (      is => 'rw',      isa =>'ArrayRef[ManaTools::Shared::disk_backend::Part]', @@ -214,63 +200,6 @@ sub _check_dependencies {  #============================================================= -=head2 mkio - -=head3 OUTPUT - -    ManaTools::Shared::disk_backend::IO subclass - -=head3 DESCRIPTION - -    this method creates an IO and adds it to the list if it does not already exists, and returns the IO - -=cut - -#============================================================= -sub mkio { -    my $self = shift; -    my $class = 'ManaTools::Shared::disk_backend::IO::'. shift; -    my $parameters = shift; -    defined($parameters->{'id'}) or die('id is a required parameter when creating IO'); -    my $id = $parameters->{'id'}; -    if (!defined($self->ios->{$id})) { -        $self->ios->{$id} = $class->new(%$parameters); -        $self->ios->{$id}->db($self); -        $self->probeio($self->ios->{$id}); -    } -    return $self->ios->{$id}; -} - -#============================================================= - -=head2 rmio - -=head3 INPUT - -    $io: ManaTools::Shared::disk_backend::IO subclass - -=head3 DESCRIPTION - -    this method removes a IO and returns the IO - -=cut - -#============================================================= -sub rmio { -    my $self = shift; -    my $io = shift; -    my $parts = $self->parts(); -    my $ios = $self->ios(); -    delete $ios->{$io->id()}; -    # walk parts and remove io from ins or outs -    for my $part (@{$parts}) { -        $part->rmio($io); -    } -    return $io; -} - -#============================================================= -  =head2 mkpart  =head3 OUTPUT @@ -458,175 +387,6 @@ sub diff {  #============================================================= -=head2 probeio - -=head3 OUTPUT - -    0 if failed, 1 if success - -=head3 DESCRIPTION - -    this method will call probeio for all plugins and merge results of the probe - -=cut - -#============================================================= -sub probeio { -    my $self = shift; -    my $io = shift; - -    for my $plugin (@{$self->plugins}) { -        $plugin->probeio($io); -    } -    1; -} - -#============================================================= - -=head2 findin - -=head3 INPUT - -    $io: ManaTools::Shared::disk_backend::IO -    $state: ManaTools::Shared::disk_backend::Part::PartState|undef - -=head3 OUTPUT - -    array of Part - -=head3 DESCRIPTION - -    this method will return all Part that match on an in IO - -=cut - -#============================================================= -sub findin { -    my $self = shift; -    my $io = shift; -    my $state = shift; - -    return grep {scalar(grep {$io eq $_} $_->get_ins()) > 0 && (!defined $state || $_->is_state($state))} @{$self->parts}; -} - -#============================================================= - -=head2 findout - -=head3 INPUT - -    $io: ManaTools::Shared::disk_backend::IO -    $state: ManaTools::Shared::disk_backend::Part::PartState|undef - -=head3 OUTPUT - -    array of Part - -=head3 DESCRIPTION - -    this method will return all Part that match on an out IO - -=cut - -#============================================================= -sub findout { -    my $self = shift; -    my $io = shift; -    my $state = shift; - -    return grep {scalar(grep {$io eq $_} $_->get_outs()) > 0 && (!defined $state || $_->is_state($state))} @{$self->parts}; -} - -#============================================================= - -=head2 findnoin - -=head3 OUTPUT - -    array of Part - -=head3 DESCRIPTION - -    this method will return all Part that have no ins - -=cut - -#============================================================= -sub findnoin { -    my $self = shift; -    my $io = shift; - -    return grep {$_->in_length() == 0} @{$self->parts}; -} - -#============================================================= - -=head2 findoutnoin - -=head3 OUTPUT - -    array of Part - -=head3 DESCRIPTION - -    this method will return all Part that have outs, but no ins - -=cut - -#============================================================= -sub findoutnoin { -    my $self = shift; -    my $io = shift; - -    return grep {$_->in_length() == 0 && $_->out_length() > 0} @{$self->parts}; -} - -#============================================================= - -=head2 findnoout - -=head3 OUTPUT - -    array of Part - -=head3 DESCRIPTION - -    this method will return all Part that have no outs - -=cut - -#============================================================= -sub findnoout { -    my $self = shift; -    my $io = shift; - -    return grep {$_->out_length() == 0} @{$self->parts}; -} - -#============================================================= - -=head2 findinnoout - -=head3 OUTPUT - -    array of Part - -=head3 DESCRIPTION - -    this method will return all Part that have ins, but no outs - -=cut - -#============================================================= -sub findinnoout { -    my $self = shift; -    my $io = shift; - -    return grep {$_->out_length() == 0 && $_->in_length() > 0} @{$self->parts}; -} - -#============================================================= -  =head2 findpart  =head3 INPUT @@ -804,29 +564,6 @@ sub walkplugin {  #============================================================= -=head2 findioprop - -=head3 OUTPUT - -    array of IO - -=head3 DESCRIPTION - -    this method will return all IO that matches on a prop value - -=cut - -#============================================================= -sub findioprop { -    my $self = shift; -    my $prop = shift; -    my $value = shift; - -    return grep {$_->has_prop($prop) && $_->prop($prop) eq $value} values %{$self->ios}; -} - -#============================================================= -  =head2 findpartprop  =head3 OUTPUT diff --git a/lib/ManaTools/Shared/disk_backend/FileSystem.pm b/lib/ManaTools/Shared/disk_backend/FileSystem.pm index 682e3a9f..3799686f 100644 --- a/lib/ManaTools/Shared/disk_backend/FileSystem.pm +++ b/lib/ManaTools/Shared/disk_backend/FileSystem.pm @@ -17,7 +17,6 @@ package ManaTools::Shared::disk_backend::FileSystem;      ...      my $f = Foo->new(); -    my $in = $f->fsprobe($io);  =head1 DESCRIPTION @@ -60,29 +59,6 @@ use Moose::Role;  #============================================================= -=head2 fsprobe - -=head3 INPUT - -    $io: ManaTools::Shared::disk_backend::IO - -=head3 OUTPUT - -    ManaTools::Shared::disk_backend::IO or undef - -=head3 DESCRIPTION - -    this method probes the IO to see if it fits for this -    filesystem, if it does, create a new Part with this IO as in. -    also create an IO (linked as the out) and return that one. -    The resulting one can then be used as an in to eg: a Mount Part. - -=cut - -#============================================================= - -requires 'fsprobe'; -  has 'fstypes' => (      is => 'ro',      isa => 'ArrayRef[Str]', @@ -123,17 +99,13 @@ sub has_type {      return 0;  } -package ManaTools::Shared::disk_backend::IOFS; - -use Moose::Role; -  package ManaTools::Shared::disk_backend::FileRole;  use Moose::Role;  has 'fs' => (      is => 'rw', -    does => 'ManaTools::Shared::disk_backend::IOFS', +    does => 'ManaTools::Shared::disk_backend::FileSystem',      required => 1,  ); diff --git a/lib/ManaTools/Shared/disk_backend/IO.pm b/lib/ManaTools/Shared/disk_backend/IO.pm deleted file mode 100644 index f8ea3ee4..00000000 --- a/lib/ManaTools/Shared/disk_backend/IO.pm +++ /dev/null @@ -1,154 +0,0 @@ -# vim: set et ts=4 sw=4: -package ManaTools::Shared::disk_backend::IO; - -#============================================================= -*-perl-*- - -=head1 NAME - -    ManaTools::Shared::disk_backend::IO - IO class - -=head1 SYNOPSIS - -    use ManaTools::Shared::disk_backend::IO; - -    my $db_man = ManaTools::Shared::disk_backend::IO->new($id); -    $db_man->label(); -    $db_man->id(); - - -=head1 DESCRIPTION - -    This is an abstract class for IO in the backend to manadisk - -=head1 SUPPORT - -    You can find documentation for this class with the perldoc command: - -    perldoc ManaTools::Shared::disk_backend::IO - - -=head1 AUTHOR - -    Maarten Vanraes <alien@rmail.be> - -=head1 COPYRIGHT and LICENSE - -Copyright (c) 2015 Maarten Vanraes <alien@rmail.be> - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License version 2, as -published by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -=head1 METHODS - -=cut - -use Moose; - -with 'ManaTools::Shared::PropertiesRole'; - -## Class data -has 'type' => ( -    is => 'ro', -    isa => 'Str', -    init_arg => undef, -    lazy => 1, -    default => 'IO' -); - -## Object vars -has 'db' => ( -    is => 'rw', -    isa => 'ManaTools::Shared::disk_backend', -    init_arg => undef, -    lazy => 1, -    default => undef -); - -has 'id' => ( -    is => 'ro', -    isa => 'Str', -    required => 1 -); - -#============================================================= - -=head2 label - -=head3 OUTPUT - -    label of the IO - -=head3 DESCRIPTION - -    this method returns the label for this IO - -=cut - -#============================================================= -sub label { -    my $self = shift; - -    return $self->type .' '. $self->id; -} - -#============================================================= - -=head2 unhook - -=head3 DESCRIPTION - -    this method returns removes the IO from the parent and Parts - -=cut - -#============================================================= -sub unhook { -    my $self = shift; -    $self->db->rmio($self); -} - -#============================================================= - -=head2 findin - -=head3 DESCRIPTION - -    this method find the Parts it's an in for - -=cut - -#============================================================= -sub findin { -    my $self = shift; -    my $db = $self->db(); -    return $db->findin($self, @_); -} - -#============================================================= - -=head2 findout - -=head3 DESCRIPTION - -    this method find the Parts it's an out for - -=cut - -#============================================================= -sub findout { -    my $self = shift; -    my $db = $self->db(); -    return $db->findout($self, @_); -} - -1; diff --git a/lib/ManaTools/Shared/disk_backend/IOs.pm b/lib/ManaTools/Shared/disk_backend/IOs.pm deleted file mode 100644 index eb562904..00000000 --- a/lib/ManaTools/Shared/disk_backend/IOs.pm +++ /dev/null @@ -1,219 +0,0 @@ -# vim: set et ts=4 sw=4: -package ManaTools::Shared::disk_backend::IOs; - -#============================================================= -*-perl-*- - -=head1 NAME - -    ManaTools::Shared::disk_backend::IOs - list of IOs - -=head1 SYNOPSIS - -    use ManaTools::Shared::disk_backend::IOs; - -    my $db_man = ManaTools::Shared::disk_backend::IOs->new(parent => $self, restriction => $restriction); -    $db_man->append($io); -    $db_man->remove($io); -    $db_man->list(); -    $db_man->length(); - - -=head1 DESCRIPTION - -    This plugin is an collection of IOs in the backend to manadisk - -=head1 SUPPORT - -    You can find documentation for this plugin with the perldoc command: - -    perldoc ManaTools::Shared::disk_backend::IOs - - -=head1 AUTHOR - -    Maarten Vanraes <alien@rmail.be> - -=head1 COPYRIGHT and LICENSE - -Copyright (c) 2015 Maarten Vanraes <alien@rmail.be> - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License version 2, as -published by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -=head1 METHODS - -=cut - -use Moose; - -has 'parent' => ( -    is => 'ro', -    isa => 'ManaTools::Shared::disk_backend::Part', -    required => 1 -); -has 'restriction' => ( -    traits => ['Code'], -    is => 'ro', -    isa => 'CodeRef', -    required => 1, -    handles => { -        check => 'execute' -    } -); -has 'ios' => ( -    is => 'ro', -    isa => 'HashRef[ManaTools::Shared::disk_backend::IO]', -    default => sub {return {};} -); - -#============================================================= - -=head2 length - -=head3 OUTPUT - -    Int - -=head3 DESCRIPTION - -    this method returns the number of IOs - -=cut - -#============================================================= -sub length { -    my $self = shift; - -    return scalar(keys %{$self->ios}); -} - -#============================================================= - -=head2 list - -=head3 OUTPUT - -    array of the IOs - -=head3 DESCRIPTION - -    this method returns a list of IOs - -=cut - -#============================================================= -sub list { -    my $self = shift; - -    return values %{$self->ios}; -} - -#============================================================= - -=head2 is_equal - -=head3 INPUT - -    $ios: ManaTools::Shared::disk_backend::IOs - -=head3 OUTPUT - -    bool - -=head3 DESCRIPTION - -    this method returns true of $self is equal to $ios - -=cut - -#============================================================= -sub is_equal { -    my $self = shift; -    my $ios = shift; - -    return 0 if $self->length() != $ios->length(); -    for my $key (keys %{$self->ios()}) { -        return 0 if $ios->ios()->{$key} != $self->ios()->{$key}; -    } -    return 1; -} - -#============================================================= - -=head2 append - -=head3 INPUT - -    $io: IO to add - -=head3 OUTPUT - -    1 if success, 0 otherwise - -=head3 DESCRIPTION - -    this method appends an IO - -=cut - -#============================================================= -sub append { -    my $self = shift; -    my $io = shift; - -    # check IO with restriction -    if (defined $self->restriction) { -        if (!$self->check($self->parent(), $io)) { -            return 0; -        } -    } - -    $self->ios->{$io->id} = $io; -} - -#============================================================= - -=head2 remove - -=head3 INPUT - -    $io: IO to remove - -=head3 OUTPUT - -    1 if success, 0 otherwise - -=head3 DESCRIPTION - -    this method removes an IO - -=cut - -#============================================================= -sub remove { -    my $self = shift; -    my $io = shift; - -    # check IO with restriction -    if (defined $self->restriction) { -        if (!$self->check($self->parent(), $io, 1)) { -            return 0; -        } -    } - -    # remove the io -    delete $self->ios->{$io->id}; -} - -1; - diff --git a/lib/ManaTools/Shared/disk_backend/Part.pm b/lib/ManaTools/Shared/disk_backend/Part.pm index 941d0b5a..7095fe78 100644 --- a/lib/ManaTools/Shared/disk_backend/Part.pm +++ b/lib/ManaTools/Shared/disk_backend/Part.pm @@ -10,20 +10,39 @@ package ManaTools::Shared::disk_backend::Part;  =head1 SYNOPSIS      package ManaTools::Shared::disk_backend::Part::MBR; -    extend 'ManaTools::Shared::disk_backend::Part'; - -    has '+type', required => 0, default => 'MBR'; -    has '+in_restriction', default => sub { my ($self, $io)=@_; return ($self->in_length() < 1 && $io->type == 'disk');}; -    has '+out_restriction', default => sub { my ($self, $io)=@_; return ($self->out_length() < 4 && $io->type == 'partition');}; +    extends 'ManaTools::Shared::disk_backend::Part'; + +    use MooseX::ClassAttribute; + +    class_has '+type' => ( +        default => 'MBR', +    ); +    class_has '+restrictions' => ( +        default => sub { +            return { +                sibling => sub { +                    my $self = shift; +                    my $part = shift; +                    return 0; +                }, +                parent => sub { +                    my $self = shift; +                    my $part = shift; +                    return $part->does('ManaTools::Shared::disk_backend::BlockDevice'); +                }, +            } +        } +    );      override('label', sub {          my $self = shift;          my $label = super; -        if ($self->in_length < 1) { +        my @children = $self->children(); +        if (scalar(@children) < 1) {              return $label;          } -        my @ins = $self->in_list(); -        return $label .= "(". $ins[0]->id() .")"; +        $label .= "(". $child[0]->label() .")"; +        return $label;      });      1; @@ -32,9 +51,6 @@ package ManaTools::Shared::disk_backend::Part;      my $mbr = ManaTools::Shared::disk_backend::Part::MBR->new();      $mbr->label();  // MBR(/dev/sda) -    $mbr->get_ins(); -    $mbr->get_outs(); -    $mbr->out_add($io);      my $size = $mbr->prop('size');      $mbr->prop('size', '20G');      $mbr->action('format'); @@ -83,8 +99,6 @@ with 'ManaTools::Shared::ActionsRole', 'ManaTools::Shared::PropertiesRole';  use MooseX::ClassAttribute;  use Moose::Util::TypeConstraints qw/subtype as where/; -use ManaTools::Shared::disk_backend::IOs; -  ## Class DATA  subtype 'PartState' @@ -126,24 +140,6 @@ class_has 'order' => (      default => undef,  ); -class_has 'in_restriction' => ( -    is => 'ro', -    init_arg => undef, -    isa => 'Maybe[CodeRef]', -    default => sub { -        sub { return 1; } -    } -); - -class_has 'out_restriction' => ( -    is => 'ro', -    init_arg => undef, -    isa => 'Maybe[CodeRef]', -    default => sub { -        sub { return 1; } -    } -); -  ## Object Variables  has 'loaded' => (      is => 'rw', @@ -548,46 +544,17 @@ sub diff {      return $self->_diff($part, $partstate);  } -has 'ins' => ( -    is => 'ro', -    isa => 'ManaTools::Shared::disk_backend::IOs', -    lazy => 1, -    default => sub { -        my $self = shift; -        return ManaTools::Shared::disk_backend::IOs->new(parent => $self, restriction => $self->in_restriction); -    }, -    handles => { -        in_length => 'length', -        in_list => 'list', -        in_add => 'append' -    } -); -has 'outs' => ( -    is => 'ro', -    isa => 'ManaTools::Shared::disk_backend::IOs', -    lazy => 1, -    default => sub { -        my $self = shift; -        return ManaTools::Shared::disk_backend::IOs->new(parent => $self, restriction => $self->out_restriction); -    }, -    handles => { -        out_length => 'length', -        out_list => 'list', -        out_add => 'append' -    } -); -  #=============================================================  =head2 label  =head3 OUTPUT -    label of the IO +    label of the Part  =head3 DESCRIPTION -    this method returns the label for this IO +    this method returns the label for this Part  =cut @@ -736,73 +703,6 @@ sub check_merge {  #============================================================= -=head2 get_ins - -=head3 OUTPUT - -    array of the in IOs - -=head3 DESCRIPTION - -    this method returns the in IOs - -=cut - -#============================================================= -sub get_ins { -    my $self = shift; - -    return $self->ins->list(); -} - -#============================================================= - -=head2 get_outs - -=head3 OUTPUT - -    array of the out IOs - -=head3 DESCRIPTION - -    this method returns the out IOs - -=cut - -#============================================================= -sub get_outs { -    my $self = shift; - -    return $self->outs->list(); -} - -#============================================================= - -=head2 rmio - -=head3 INPUT - -    $io: ManaTools::Shared::disk_backend::IO - -=head3 DESCRIPTION - -    this method returns removes the IO from the Part - -=cut - -#============================================================= -sub rmio { -    my $self = shift; -    my $io = shift; -    my $ins = $self->ins(); -    my $outs = $self->outs(); -    # remove io from ins and outs -    $ins->remove($io); -    $outs->remove($io); -} - -#============================================================= -  =head2 unhook  =head3 DESCRIPTION diff --git a/lib/ManaTools/Shared/disk_backend/Plugin.pm b/lib/ManaTools/Shared/disk_backend/Plugin.pm index 61dd767a..f8182637 100644 --- a/lib/ManaTools/Shared/disk_backend/Plugin.pm +++ b/lib/ManaTools/Shared/disk_backend/Plugin.pm @@ -26,21 +26,6 @@ package ManaTools::Shared::disk_backend::Plugin;          ...      }); -    override('probeio', sub { -        ... -    }); - -    1; - -    package ManaTools::Shared::disk_backend::IO::Bar; -    use Moose; - -    extend 'ManaTools::Shared::disk_backend::IO'; - -    has '+type', default => 'bar'; - -    ... -      1;      package ManaTools::Shared::disk_backend::Part::Baz; @@ -49,8 +34,7 @@ package ManaTools::Shared::disk_backend::Plugin;      extend 'ManaTools::Shared::disk_backend::Part';      has '+type', default => 'baz'; -    has '+in_restriction', default => sub { ... }; -    has '+out_restriction', default => sub { ... }; +    has '+restrictions', default => sub { ... };      ... @@ -177,7 +161,7 @@ sub save {  =head3 DESCRIPTION -    this is a default method for probing IO's and/or Part's, the idea is to override it if needed +    this is a default method for probing Part's, the idea is to override it if needed  =cut @@ -214,32 +198,6 @@ sub changedpart {  #============================================================= -=head2 loadio - -=head3 INPUT - -    $io: ManaTools::Shared::disk_backend::IO - -=head3 OUTPUT - -    0 if failed, 1 if success - -=head3 DESCRIPTION - -    this is a default method for loading a Part from a specific IO, the idea is to override it if needed - -=cut - -#============================================================= -sub loadio { -    my $self = shift; -    my $io = shift; - -    1; -} - -#============================================================= -  =head2 savepart  =head3 INPUT @@ -266,32 +224,6 @@ sub savepart {  #============================================================= -=head2 probeio - -=head3 INPUT - -    $io: ManaTools::Shared::disk_backend::IO - -=head3 OUTPUT - -    0 if failed, 1 if success - -=head3 DESCRIPTION - -    this is a default method for probing specific a specific IO, the idea is to override it if needed - -=cut - -#============================================================= -sub probeio { -    my $self = shift; -    my $io = shift; - -    1; -} - -#============================================================= -  =head2 tool_exec  =head3 INPUT diff --git a/lib/ManaTools/Shared/disk_backend/Plugin/Btrfs.pm b/lib/ManaTools/Shared/disk_backend/Plugin/Btrfs.pm index fa14d995..a7acdd6d 100644 --- a/lib/ManaTools/Shared/disk_backend/Plugin/Btrfs.pm +++ b/lib/ManaTools/Shared/disk_backend/Plugin/Btrfs.pm @@ -82,48 +82,71 @@ has 'filesystems' => (      default => sub { return {};}  ); -sub get_fsdev { +sub create_subvolume {      my $self = shift; -    my $io = shift; -    my $rio = ref($io); - -    # if it's a reference, it'll be an object, so return the mm property -    return $io->prop('mm') if defined($rio) && $rio; - -    my @stat = stat($io); -    # if it's not a block device, it's no use -    return undef if (($stat[2] >> 12) != 6); - -    # find the device -    my $dev = $stat[6]; -    my $minor = $dev % 256; -    my $major = int (($dev - $minor) / 256); -    return $major .':'. $minor; -} - -sub get_subvolumes { -    my $self = shift; -    my $io = shift; -    my $path = shift; +    my $part = shift; +    my $partstate = shift; +    my $fields = shift; +    my $quotas = shift; +    my $subvolumes = shift; + +    # look or create part for btrfsvol +    my $p = $part->trychild($partstate, sub { +        my $self = shift; +        my $parameters = shift; +        return ($self->uuid() eq $parameters->{uuid}); +    }, 'BtrfsVol', {plugin => $self, fs => $part, mountsourcepath => $fields->{path} =~ s'<FS_TREE>''r, uuid => $fields->{uuid}, loaded => undef, saved => undef}); + +    # set properties +    $p->prop('label', $fields->{path} =~ s'<FS_TREE>/?''r); +    $p->prop('uuid', $fields->{uuid}); +    $p->prop('parent_uuid', $fields->{parent_uuid}); +    $p->prop('subvolid', $fields->{ID}); +    $p->prop('gen', $fields->{gen}); +    $p->prop('cgen', $fields->{cgen}); +    $p->prop('parent', $fields->{parent}); +    $p->prop('top_level', $fields->{top_level}); + +    # set quota information +    if (defined($quotas->{'0/'. $fields->{ID}})) { +        my $item = $quotas->{'0/'. $fields->{ID}}; +        $p->prop('referred', $item->{rfer}); +        $p->prop('exclusive', $item->{excl}); +        $p->prop('quota_referred', $item->{max_rfer}); +        $p->prop('quota_exclusive', $item->{max_excl}); +    } -    # get the dev numbering -    my $mm = $self->get_fsdev($io); +    # trace parenting and fill in subvolumes in all the BtrfsVol Parts +    # create missing parents too! -    # no device, get out now -    return undef if !defined($mm); +    $self->D("$self: trigger changepart for BTRFS Volume $p: ". $p->mountsourcepath()); +    $p->changedpart($partstate); -    my $fs = $self->filesystems(); -    # no filesystem, get out now -    return undef if !defined($fs->{$mm}); +    # if it has a mount point, get readonly state +    # find Mount child (for subvolumes, might need to check the parent and base the path from there) +    my $path = $p->find_path($partstate); +    if (defined($path)) { +        # if it's mounted, we can get readonly status with properties +        my %fields = $self->tool_fields('btrfs', '=', 'property', 'get', "'$path'"); +        $p->prop('readonly', $fields{ro} eq 'true'); +    } -    # this is the filesystem part -    my $btrfs = $fs->{$mm}; +    # set up children subvolumes +    for my $id (keys %{$fields->{subvolumes}}) { +        if (defined($subvolumes->{$id})) { +            # TODO: add childvol tag for this one +            $p->add_taglink($subvolumes->{$id}, 'childsubvol'); +        } +    } -    my $vols = $btrfs->subvolumes(); +    if (defined($subvolumes->{$p->prop('parent')})) { +        # add a parent link +        $p->add_taglink($subvolumes->{$p->prop('parent')}, 'parentsubvol'); +    } -    $vols = $btrfs->refresh($path) if scalar(@{$vols}) == 0; +    $subvolumes->{$p->prop('subvolid')} = $p; -    return $vols; +    return $p;  }  #============================================================= @@ -153,23 +176,6 @@ override ('probe', sub {          $part->prop_from_file('used', "$fs/allocation/data/disk_used");          $part->prop_from_file('total', "$fs/allocation/data/disk_total");          $part->prop_from_file('flags', "$fs/allocation/data/flags"); -        # create an io for out -        my $io = $self->parent->mkio('Btrfs', {id => $fs =~ s'^.+/''r}); -        $io->prop('uuid', $fs =~ s'^.+/''r); -        $part->out_add($io); - -        # TODO: find the in devices (create if needed?) -        for my $df (glob("$fs/devices/*")) { -            open F, '<'. $df .'/dev'; -            my $value = <F>; -            close F; -            chomp($value); -            my @ios = $self->parent->findioprop('dev', $value); -            if (scalar(@ios) > 0) { -                $part->in_add($ios[0]); -                $fss->{$ios[0]->prop('dev')} = $part; -            } -        }          # TODO: find base mount point in order to find volumes          # TODO: quotas ...? pathbased? @@ -179,64 +185,6 @@ override ('probe', sub {  #============================================================= -=head2 fsprobe - -=head3 INPUT - -    $io: ManaTools::Shared::disk_backend::IO | Str -    $mount: ManaTools::Shared::disk_backend::Part::Mount - -=head3 OUTPUT - -    ManaTools::Shared::disk_backend::IO or undef - -=head3 DESCRIPTION - -    this method probes the IO to see if it fits for this -    filesystem, if it does, create a new Part with this IO as in. -    also create an IO (linked as the out) and return that one. -    The resulting one can then be used as an in to eg: a Mount Part. - -=cut - -#============================================================= -sub fsprobe { -    my $self = shift; -    my $io = shift; -    my $mount = shift; -    my $vols = $self->get_subvolumes($io, $mount->path()); -    # return undef if there are not subvolumes -    return undef if !defined($vols); - -    for my $vol (@{$vols}) { -        # return when we find the one with the correct srcpath -        return $vol if ($vol->prop('srcpath') eq $mount->prop('srcdevpath')); -    } -    return undef; -} - -package ManaTools::Shared::disk_backend::IO::Btrfs; - -use Moose; - -extends 'ManaTools::Shared::disk_backend::IO'; - -has '+type' => ( -    default => 'Btrfs' -); - -package ManaTools::Shared::disk_backend::IO::BtrfsVol; - -use Moose; - -extends 'ManaTools::Shared::disk_backend::IO'; - -with 'ManaTools::Shared::disk_backend::IOFS'; - -has '+type' => ( -    default => 'BtrfsVol' -); -  package ManaTools::Shared::disk_backend::Part::Btrfs; @@ -268,93 +216,6 @@ has 'subvolumes' => (      default => sub { return [];},  ); -class_has '+in_restriction' => ( -    default => sub { -        return sub { -            my $self = shift; -            my $io = shift; -            my $del = shift; -            if (defined $del && !$del) { -                return ($self->in_length() > 0); -            } -            # multiple device allowed -            return $io->does('ManaTools::Shared::disk_backend::BlockDevice'); -        }; -    } -); - -class_has '+out_restriction' => ( -    default => sub { -        return sub { -            my $self = shift; -            my $io = shift; -            my $del = shift; -            if (!defined $del) { -                $del = 0; -            } -            if ($del != 0) { -                return ($self->in_length() > 0); -            } -            return ($self->in_length() == 0 && ref($io) eq 'ManaTools::Shared::disk_backend::IO::Btrfs'); -        }; -    } -); - -sub refresh { -    my $self = shift; -    my $path = shift; -    my $subvols = $self->subvolumes(); - -    # first, clean up all Volume stuff -    my @parts = $self->db->findpart('BtrfsVol'); -    for my $part (@parts) { -        $part->unhook(); -    } -    # loop all BtrfsVol IO and remove safely -    for my $vol (@{$subvols}) { -        # this should also unhook from any Part -        $vol->unhook(); -    } -    # clear subvols from list -    @{$subvols} = (); - -    # find the IO::Btrfs -    my @outs = $self->get_outs(); -    if (scalar(@outs) == 0) { -        # make an IO::Btrfs for this one -        @outs = ($self->db->mkio('Btrfs', {id => $self->uuid()})); -    } - -    return $subvols if !defined($path) || !$path; - -    # btrfs subvolume list / -agcpuq -    # ID 264 gen 1090157 cgen 255 parent 5 top level 5 parent_uuid - uuid ab6d48f8-6d65-6b43-b792-dd31d93018be path <FS_TREE>/backup-@ -    my @lines = $self->tool_lines('btrfs', 'subvolume', 'list', "'$path'", '-agcpuq'); -    for my $line (@lines) { -        # top level is 2 strings, so combine them, so that the fields can be nicely splitted -        my %fields = split(/[ \t\r\n]+/, $line =~ s'top level'top_level'r); -        # create the volume part -        my $part = $self->db->mkpart('BtrfsVol', {fs => $self, uuid => $fields{uuid}, plugin => $self->plugin()}); -        # add the IO::Btrfs filesystem -        $part->in_add($outs[0]); -        # create a IO::BtrfsVol -        my $vol = $self->db->mkio('BtrfsVol', {id => $fields{ID}}); -        # TODO: trace parenting and fill in subvolumes in all the BtrfsVol Parts -        # set properties -        $vol->prop('srcpath', $fields{path} =~ s'<FS_TREE>''r); -        $vol->prop('uuid', $fields{uuid}); -        $vol->prop('parent_uuid', $fields{parent_uuid}); -        $vol->prop('gen', $fields{gen}); -        $vol->prop('cgen', $fields{cgen}); -        $vol->prop('parent', $fields{parent}); -        $vol->prop('top_level', $fields{top_level}); -        $part->out_add($vol); -        push @{$subvols}, $vol; -    } -    return $subvols; -} - -  package ManaTools::Shared::disk_backend::Part::BtrfsVol;  use Moose; @@ -391,39 +252,37 @@ has 'subvolumes' => (      default => sub { return [];},  ); -class_has '+in_restriction' => ( +class_has '+restrictions' => (      default => sub { -        return sub { -            my $self = shift; -            my $io = shift; -            my $del = shift; -            if (!defined $del) { -                $del = 0; -            } -            if ($del != 0) { -                return ($self->in_length() > 0); -            } -            return ($self->in_length() == 0 && ref($io) eq 'ManaTools::Shared::disk_backend::IO::Btrfs'); -        }; +        return { +            sibling => sub { +                my $self = shift; +                my $part = shift; +                return $part->isa('ManaTools::Shared::disk_backend::Part::BtrfsVol');; +            }, +            parentsubvol => sub { +                my $self = shift; +                my $part = shift; +                return $part->isa('ManaTools::Shared::disk_backend::Part::BtrfsVol'); +            }, +            childsubvol => sub { +                my $self = shift; +                my $part = shift; +                return $part->isa('ManaTools::Shared::disk_backend::Part::BtrfsVol'); +            }, +            parent => sub { +                my $self = shift; +                my $part = shift; +                return $part->isa('ManaTools::Shared::disk_backend::Part::Btrfs'); +            }, +            child => sub { +                my $self = shift; +                my $part = shift; +                return $part->isa('ManaTools::Shared::disk_backend::Part::Mount'); +            }, +        }      }  ); -class_has '+out_restriction' => ( -    default => sub { -        return sub { -            my $self = shift; -            my $io = shift; -            my $del = shift; -            if (!defined $del) { -                $del = 0; -            } -            if ($del != 0) { -                return ($self->in_length() > 0); -            } -            # multiple device allowed -            return (ref($io) eq 'ManaTools::Shared::disk_backend::IO::BtrfsVol'); -        }; -    } -);  1; diff --git a/lib/ManaTools/Shared/disk_backend/Plugin/Disk.pm b/lib/ManaTools/Shared/disk_backend/Plugin/Disk.pm index 6d12cfe5..ba47fc63 100644 --- a/lib/ManaTools/Shared/disk_backend/Plugin/Disk.pm +++ b/lib/ManaTools/Shared/disk_backend/Plugin/Disk.pm @@ -97,52 +97,11 @@ override ('probe', sub {              }, 'Disk', {plugin => $self, devicepath => $bdfile, loaded => undef, saved => undef});              # trigger the changedpart              $p->changedpart(ManaTools::Shared::disk_backend::Part->CurrentState); -            # create the IO -            my $io = $self->parent->mkio('Disk', {id => basename($bdfile), devicepath => $bdfile}); -            if (!defined($io) || !$part->out_add($io)) { -                $err = 1; -            }          }      }      return $err == 0;  }); -package ManaTools::Shared::disk_backend::IO::Disk; - -use Moose; - -extends 'ManaTools::Shared::disk_backend::IO'; - -with 'ManaTools::Shared::disk_backend::BlockDevice'; - -has '+type' => ( -    default => 'Disk' -); - -has '+devicepath' => ( -    trigger => sub { -        my $self = shift; -        my $value = shift; -        $self->prop_from_file('ro', $value .'/ro'); -        $self->prop_from_file('removable', $value .'/removable'); -        $self->prop_from_file('size', $value .'/size'); -        $self->prop('present', ($self->prop('removable') == 0 || $self->prop('size') > 0) ? 1 : 0); -        $self->prop_from_file('dev', $value .'/dev'); -        $self->sync_majorminor(); - -        # additional data -        my $dpath = $value =~ s,/[^/]+/[^/]+$,,r; -        $self->prop_from_file('vendor', $dpath .'/vendor'); -        $self->prop_from_file('model', $dpath .'/model'); -        $self->prop_from_file('type', $dpath .'/type'); -    } -); - -sub file { -    my $self = shift; -    return '/dev/'. $self->id(); -} -  package ManaTools::Shared::disk_backend::Part::Disks;  use Moose; @@ -155,20 +114,21 @@ class_has '+type' => (      default => 'Disks'  ); -class_has '+in_restriction' => ( -    default => sub { -        return sub {return 0;}; -    } -); - -class_has '+out_restriction' => ( +class_has '+restrictions' => (      default => sub { -        return sub { -            my $self = shift; -            my $io = shift; -            my $del = shift; -            return ref($io) eq 'ManaTools::Shared::disk_backend::IO::Disk'; -        }; +        return { +            child => sub { +                my $self = shift; +                my $part = shift; +                return $part->isa('ManaTools::Shared::disk_backend::Part::Disk'); +            }, +            parent => sub { +                return 0; +            }, +            sibling => sub { +                return 0; +            }, +        }      }  ); @@ -178,7 +138,7 @@ override('label', sub {      if ($self->out_length() < 1) {          return $label;      } -    return $label .'('. join(',', sort map { $_->id(); } $self->out_list()) .')'; +    return $label .'('. join(',', sort map { $_->label(); } @children) .')';  });  package ManaTools::Shared::disk_backend::Part::Disk; diff --git a/lib/ManaTools/Shared/disk_backend/Plugin/Extfs.pm b/lib/ManaTools/Shared/disk_backend/Plugin/Extfs.pm index 690cb1bd..7087f91a 100644 --- a/lib/ManaTools/Shared/disk_backend/Plugin/Extfs.pm +++ b/lib/ManaTools/Shared/disk_backend/Plugin/Extfs.pm @@ -168,83 +168,6 @@ override ('changedpart', sub {      return 1;  }); -#============================================================= - -=head2 fsprobe - -=head3 INPUT - -    $io: ManaTools::Shared::disk_backend::IO | Str -    $mount: ManaTools::Shared::disk_backend::Part::Mount - -=head3 OUTPUT - -    ManaTools::Shared::disk_backend::IO or undef - -=head3 DESCRIPTION - -    this method probes the IO to see if it fits for this -    filesystem, if it does, create a new Part with this IO as in. -    also create an IO (linked as the out) and return that one. -    The resulting one can then be used as an in to eg: a Mount Part. - -=cut - -#============================================================= -sub fsprobe { -    my $self = shift; -    my $io = shift; -    my $mount = shift; - -    # gather fields from dumpe2fs -    my %fields = $self->tool_fields('dumpe2fs', ':', '-h', '/dev/'. $io->id()); - -    # get uuid -    my $uuid = $fields{'Filesystem UUID'}; - -    return undef if (!defined $uuid || !$uuid); - -    # create part -    # TODO: look or create part -    my $part = $self->parent->mkpart('Extfs', { uuid => $uuid, plugin => $self}); -    $part->prop('label', $fields{'Filesystem volume name'} =~ s'<none>''r); -    $part->prop('features', split(' ', $fields{'Filesystem features'})); -    $part->prop('options', split(' ', $fields{'Default mount options'})); -    $part->prop('state', $fields{'Filesystem state'}); -    $part->prop('block_size', $fields{'Block size'}); -    $part->prop('block_count', $fields{'Block count'}); -    $part->prop('size', $fields{'Block size'} * $fields{'Block count'}); - -    # link in the in IO -    $part->in_add($io); - -    # create the out IO and set properties -    my $fs = $self->parent->mkio('Extfs', {id => $uuid}); -    $fs->prop('label', $fields{'Filesystem volume name'} =~ s'<none>''r); -    $fs->prop('features', split(' ', $fields{'Filesystem features'})); -    $fs->prop('options', split(' ', $fields{'Default mount options'})); -    $fs->prop('state', $fields{'Filesystem state'}); -    $fs->prop('block_size', $fields{'Block size'}); -    $fs->prop('block_count', $fields{'Block count'}); -    $fs->prop('size', $fields{'Block size'} * $fields{'Block count'}); -    $part->out_add($fs); - -    # return $fs to be link as an in IO into $mount Part -    return $fs; -} - -package ManaTools::Shared::disk_backend::IO::Extfs; - -use Moose; - -extends 'ManaTools::Shared::disk_backend::IO'; - -with 'ManaTools::Shared::disk_backend::IOFS'; - -has '+type' => ( -    default => 'Extfs' -); -  package ManaTools::Shared::disk_backend::Part::Extfs;  use Moose; @@ -270,38 +193,6 @@ has 'uuid' => (      }  ); -class_has '+in_restriction' => ( -    default => sub { -        return sub { -            my $self = shift; -            my $io = shift; -            my $del = shift; -            if (defined $del && !$del) { -                return ($self->in_length() > 0); -            } -            # multiple device allowed -            return $io->does('ManaTools::Shared::disk_backend::BlockDevice'); -        }; -    } -); - -class_has '+out_restriction' => ( -    default => sub { -        return sub { -            my $self = shift; -            my $io = shift; -            my $del = shift; -            if (!defined $del) { -                $del = 0; -            } -            if ($del != 0) { -                return ($self->out_length() > 0); -            } -            return ($self->out_length() == 0 && ref($io) eq 'ManaTools::Shared::disk_backend::IO::Extfs'); -        }; -    } -); -  class_has '+restrictions' => (      default => sub {          return { diff --git a/lib/ManaTools/Shared/disk_backend/Plugin/Loop.pm b/lib/ManaTools/Shared/disk_backend/Plugin/Loop.pm index 9086ac80..10e37fc0 100644 --- a/lib/ManaTools/Shared/disk_backend/Plugin/Loop.pm +++ b/lib/ManaTools/Shared/disk_backend/Plugin/Loop.pm @@ -158,19 +158,6 @@ override ('probe', sub {          # TODO: add sibling tags to the other parts          # TODO: parent that is filerole? if parent is create, we can do the child/first/last thing -        # io stuff -        my $io = $self->parent->mkio('Disk', {id => basename($loopfile), path => $bdfile, devicepath => $bdfile}); -        if (!defined($io) || !$part->out_add($io)) { -            $err = 1; -        } -        else { -            $io->prop('sizelimit', $self->_sanitize_string($fields[2])); -            $io->prop('offset', $self->_sanitize_string($fields[3])); -            $io->prop('autoclear', $self->_sanitize_string($fields[4])); -            $io->prop('back-file', $self->_sanitize_string($fields[6])); -            $io->prop('back-dev', $self->_sanitize_string($fields[7])) if (defined $fields[7]); -            $io->prop('back-ino', $self->_sanitize_string($fields[8])) if (defined $fields[8]); -        }      }      # trigger changed parts @@ -192,23 +179,6 @@ class_has '+type' => (      default => 'Loops'  ); -class_has '+in_restriction' => ( -    default => sub { -        return sub {return 0;}; -    } -); - -class_has '+out_restriction' => ( -    default => sub { -        return sub { -            my $self = shift; -            my $io = shift; -            my $del = shift; -            return $io->does('ManaTools::Shared::disk_backend::BlockDevice'); -        }; -    } -); -  package ManaTools::Shared::disk_backend::Part::Loop;  use Moose; diff --git a/lib/ManaTools/Shared/disk_backend/Plugin/Mount.pm b/lib/ManaTools/Shared/disk_backend/Plugin/Mount.pm index b0e02e5c..5b3593b4 100644 --- a/lib/ManaTools/Shared/disk_backend/Plugin/Mount.pm +++ b/lib/ManaTools/Shared/disk_backend/Plugin/Mount.pm @@ -66,6 +66,74 @@ has '+dependencies' => (  #============================================================= +=head2 _makemount + +=head3 INPUT + +    $parent: Part +    $partstate: PartState +    $fields: ArrayRef + +=head3 OUTPUT + +    Part|undef + +=head3 DESCRIPTION + +    this function create a mount Part from the parent and set the properties. + +=cut + +#============================================================= +sub _makemount { +    my $self = shift; +    my $parent = shift; +    my $partstate = shift; +    my $fields = shift; + +    ## from this parent, create the mount point +    # look or create the child with id based on the path +    my $child = $parent->trychild($partstate, sub { +        my $self = shift; +        my $parameters = shift; +        return ($self->path() eq $parameters->{path}); +    },'Mount', {plugin => $self, path => $fields->[4], loaded => undef, saved => undef}); + +    $child->prop('options', $fields->[5]); +    $child->prop('dev', $fields->[2]); +    $child->prop('id', $fields->[0]); +    $child->prop('parent', $fields->[1]); +    $child->prop('srcdevpath', $fields->[3]); +    $child->prop('fstype', $fields->[8]); +    $child->prop('srcmount', $fields->[9]); + +    # add an unmount action +    $child->add_action('unmount', 'Unmount', undef, sub { +        my $self = shift; +        print STDERR "Unmount is not implemented...\n"; +        return 1; +    }); + +    ## take care of family +    # finding parent mount +    if ($fields->[1] != $fields->[0]) { +        # find parent and put into parentmount field +        my @parts = $self->parent->findpartprop('Mount', 'id', $fields->[1]); +        $child->parentmount($parts[0]) if scalar(@parts) > 0; +    } + +    # find missing children Mount Part +    my @parts = $self->parent->findpartprop('Mount', 'parent', $fields->[0]); +    for my $p (@parts) { +        my $pm = $p->parentmount(); +        $p->parentmount($child) if (!defined $pm); +    } + +    return $child; +} + +#============================================================= +  =head2 changedpart  =head3 INPUT @@ -229,82 +297,11 @@ override ('probe', sub {          $fs->prop('fstype', $fields[8]);          ## TODO: check filesystem and sourcepath options to select the actual parent -        # -        ## from this parent, create the mount point -        # look or create the child with id based on the path -        my $child = $fs->trychild(ManaTools::Shared::disk_backend::Part->CurrentState, sub { -            my $self = shift; -            my $parameters = shift; -            return ($self->path() eq $parameters->{path}); -        },'Mount', {plugin => $self, path => $fields[4], loaded => undef, saved => undef}); - -        $child->prop('options', $fields[5]); -        $child->prop('dev', $fields[2]); -        $child->prop('id', $fields[0]); -        $child->prop('parent', $fields[1]); -        $child->prop('srcdevpath', $fields[3]); -        $child->prop('fstype', $fields[8]); -        $child->prop('srcmount', $fields[9]); - -        # add an unmount action -        $child->add_action('unmount', 'Unmount', undef, sub { -            my $self = shift; -            print STDERR "Unmount is not implemented...\n"; -            return 1; -        }); - -        ## take care of family -        # finding parent mount -        if ($fields[1] != $fields[0]) { -            # find parent and put into parentmount field -            my @parts = $self->parent->findpartprop('Mount', 'id', $fields[1]); -            $child->parentmount($parts[0]) if scalar(@parts) > 0; -        } -        # find missing children Mount Part -        @parts = $self->parent->findpartprop('Mount', 'parent', $fields[0]); -        for my $p (@parts) { -            my $pm = $p->parentmount(); -            $p->parentmount($child) if (!defined $pm); -        } - -        ## get the in IO -        # first, track down the device -        my $in = undef; -        my @ios = $self->parent->findioprop('dev', $fields[2]); -        if (scalar(@ios) > 0) { -            $in = $ios[0]; -        } -        else { -            # if major is 0, it's a non-device mount, try fsprobe with srcmount -            if ($fields[2] =~ s':.+$''r eq "0") { -                # just pass on the srcmount string and hope with fsprobe -                $in = $fields[9]; -            } -        } -        # no need to continue trying to parse this one if we can't have an IO -        continue if (!defined $in); - -        ## try to insert filesystem in between, look at fstype -        # first, check the exact filesystem (if it exists) -        my $out = $self->parent->walkplugin(sub { -            my $plugin = shift; -            my $type = shift; -            my $in = shift; -            my $mount = shift; -            return ($plugin->does('ManaTools::Shared::disk_backend::FileSystem') and $plugin->has_type($type) and $plugin->fsprobe($in, $mount)); -        }, $fields[8], $in, $child); - -        if (defined $out) { -            my $res = $child->in_add($out); -        } -        else { -            $child->in_add($in); -        } +        my $child = $self->_makemount($fs, ManaTools::Shared::disk_backend::Part->CurrentState, \@fields);          # TODO: look up device with this          # TODO: find the end of the options, and store them          # TODO: also the super options and mount source (may have UUID or whatnot) -        # TODO: use the filesystem type to connect to the previous IO      }  # 3.5   /proc/<pid>/mountinfo - Information about mounts  # -------------------------------------------------------- @@ -377,29 +374,6 @@ has 'parentmount' => (      default => undef,  ); -class_has '+in_restriction' => ( -    default => sub { -        return sub { -            my $self = shift; -            my $io = shift; -            my $del = shift; -            my $rio = ref($io); -            return 0 if !defined($rio) || !$rio; -            if (defined $del && !$del) { -                return ($self->in_length() > 0); -            } -            # only 1 device allowed -            return $self->in_length() < 1 && ($io->does('ManaTools::Shared::disk_backend::BlockDevice') || $io->does('ManaTools::Shared::disk_backend::IOFS')); -        }; -    } -); - -class_has '+out_restriction' => ( -    default => sub { -        return sub {return 0;}; -    } -); -  class_has '+restrictions' => (      default => sub {          return { @@ -501,36 +475,5 @@ class_has '+restrictions' => (      }  ); -#============================================================= - -=head2 fsprobe - -=head3 INPUT - -    $io: ManaTools::Shared::disk_backend::IO | Str -    $mount: ManaTools::Shared::disk_backend::Part::Mount - -=head3 OUTPUT - -    ManaTools::Shared::disk_backend::IO or undef - -=head3 DESCRIPTION - -    this method probes the IO to see if it fits for this -    filesystem, if it does, create a new Part with this IO as in. -    also create an IO (linked as the out) and return that one. -    The resulting one can then be used as an in to eg: a Mount Part. - -=cut - -#============================================================= -sub fsprobe { -    my $self = shift; -    my $io = shift; -    my $mount = shift; - -    # return $fs to be link as an in IO into $mount Part -    return undef; -}  1; diff --git a/lib/ManaTools/Shared/disk_backend/Plugin/Partition.pm b/lib/ManaTools/Shared/disk_backend/Plugin/Partition.pm index 483f024c..e9a67ab8 100644 --- a/lib/ManaTools/Shared/disk_backend/Plugin/Partition.pm +++ b/lib/ManaTools/Shared/disk_backend/Plugin/Partition.pm @@ -206,135 +206,6 @@ override ('changedpart', sub {      return 1;  }); -#============================================================= - -=head2 load - -=head3 OUTPUT - -    0 if failed, 1 if success or unneeded - -=head3 DESCRIPTION - -    this method will load all disks partition tables - -=cut - -#============================================================= -override ('loadio', sub { -    my $self = shift; -    my $io = shift; -    # get the partition table -    my $pt = ManaTools::Shared::disk_backend::PartitionTable->new(parted => $self->tool('parted'), disk => $io->file()); -    # get partitions and mkio them all -    for my $p (values %{$pt->partitions()}) { -        my @stat = stat($p->{'file'}); -        my $dev = $stat[6]; -        my $minor = $dev % 256; -        my $major = int (($dev - $minor) / 256); -        my $io = $self->parent->mkio('Partition', {id => $p->{'file'} =~ s'^.+/''r}); -        $io->prop('dev', $major .':'. $minor); -        $io->sync_majorminor(); -        $io->prop('start', $p->{'start'}); -        $io->prop('size', $p->{'size'}); -        $io->prop('num', $p->{'num'}); -        # TODO: also create the Part (if it doesn't already exists) and link it -    } -    return 1; -}); - -#============================================================= - -=head2 probeio - -=head3 OUTPUT - -    0 if failed, 1 if success or unneeded - -=head3 DESCRIPTION - -    this method will try to probe the specific disk IO and get partitions - -=cut - -#============================================================= -override ('probeio', sub { -    my $self = shift; -    my $io = shift; -    my $part = undef; -    # return if $io is not the correct type -    if ($io->type() ne 'Disk') { -        return 1; -    } -    if ($io->prop('present') == 0) { -        return 1; -    } -    # find out if the IO already has a part, if not: make a part -    my @parts = $self->parent->findin($io); -    if (scalar(@parts) > 0) { -        $part = $parts[0]; -    } -    else { -        $part = $self->parent->mkpart('PartitionTable', {plugin => $self}); -        if (!defined($part)) { -            return 0; -        } -        # assign this IO to the ins -        if (!$part->in_add($io)) { -            return 0; -        } -        # add properties -        # TODO: partition table type, size and position, logical alignment, etc... -        # default partition is always 1 sector ? -        $part->prop('size', 1); -        # add an action -        $part->add_action('addPartition', 'Add a partition', $part, sub { -            my $self = shift; -            my $part = $self->item(); -            print STDERR "Add partition is not implemented...\n"; -            return 1; -        }, sub { -            my $self = shift; -            my $part = $self->item(); -            return 1; -        }); -    } -    @parts = $self->parent->findin($io); -    my $err =  0; -    my $partitions = 0; -    # find subdevices in /sys/ -    for my $pf (glob($io->devicepath(). "/". $io->id() ."*")) { -        my $io = $self->parent->mkio('Partition', {id => $pf =~ s'^.+/''r, devicepath => $pf}); -        $io->prop_from_file('sectors', $pf . '/size'); -        # sectors are always 512 bytes here! -        $io->prop('size', $io->prop('sectors') * 512); -        $io->prop_from_file('start', $pf . '/start'); -        $io->prop_from_file('ro', $pf . '/ro'); -        $io->prop_from_file('dev', $pf . '/dev'); -        $io->sync_majorminor(); -        $io->prop('num', $pf =~ s/^.+([0-9]+)$/$1/r); -        $partitions = $partitions + 1; -        if (!$part->out_add($io)) { -            $err = 1; -        } -    } -    $part->prop('partitions', $partitions); -    # find out how to differentiate between an empty partition table and no partition table -    return $err == 0; -}); - -package ManaTools::Shared::disk_backend::IO::Partition; - -use Moose; - -extends 'ManaTools::Shared::disk_backend::IO'; - -with 'ManaTools::Shared::disk_backend::BlockDevice'; - -has '+type' => ( -    default => 'Partition' -); -  package ManaTools::Shared::disk_backend::Part::PartitionTable;  use Moose; @@ -367,40 +238,6 @@ class_has '+restrictions' => (      }  ); -class_has '+in_restriction' => ( -    default => sub { -        return sub { -            my $self = shift; -            my $io = shift; -            my $del = shift; -            if (!defined $del) { -                $del = 0; -            } -            if ($del != 0) { -                return ($self->in_length() > 0); -            } -            return ($self->in_length() == 0 && ref($io) eq 'ManaTools::Shared::disk_backend::IO::Disk'); -        }; -    } -); - -class_has '+out_restriction' => ( -    default => sub { -        return sub { -            my $self = shift; -            my $io = shift; -            my $del = shift; -            if (!defined $del) { -                $del = 0; -            } -            if ($del != 0) { -                return ($self->out_length() > 0); -            } -            return ($self->out_length() < 4 && ref($io) eq 'ManaTools::Shared::disk_backend::IO::Partition'); -        }; -    } -); -  package ManaTools::Shared::disk_backend::Part::PartitionElement;  use Moose; diff --git a/lib/ManaTools/Shared/disk_backend/Plugin/Swap.pm b/lib/ManaTools/Shared/disk_backend/Plugin/Swap.pm index 1f3e08a2..3a96036f 100644 --- a/lib/ManaTools/Shared/disk_backend/Plugin/Swap.pm +++ b/lib/ManaTools/Shared/disk_backend/Plugin/Swap.pm @@ -148,25 +148,6 @@ override ('probe', sub {          $part->prop('uuid', defined($labelfields{'UUID'}) ? $labelfields{'UUID'} : '');          $part->prop('label', defined($labelfields{'LABEL'}) ? $labelfields{'LABEL'} : ''); -        # check first if it's a device, then find the define -        my @stat = stat($fields[0]); -        # if device: then... -        if ($stat[2] >> 12 == 6) { -            my $dev = $stat[6]; -            my $minor = $dev % 256; -            my $major = int (($dev - $minor) / 256); -            my @ios = $self->parent->findioprop('dev', $major .':'. $minor); -            if (scalar(@ios) > 0) { -                $part->in_add($ios[0]); -            } -            else { -                # TODO: create the IO ? try to probe parent? or ??? -                # think of XEN where you may have device partition files without an actual disk? -            } -        } -        else { -            # TODO the in should be the mount point containing the filename -        }      }  # /proc/swaps:  # @@ -195,27 +176,6 @@ has 'path' => (      required => 1  ); -class_has '+in_restriction' => ( -    default => sub { -        return sub { -            my $self = shift; -            my $io = shift; -            my $del = shift; -            if (defined $del && !$del) { -                return ($self->in_length() > 0); -            } -            # only 1 device allowed -            return $self->in_length() < 1 && ($io->does('ManaTools::Shared::disk_backend::BlockDevice') || $io->does('ManaTools::Shared::disk_backend::FileRole')); -        }; -    } -); - -class_has '+out_restriction' => ( -    default => sub { -        return sub {return 0;}; -    } -); -  class_has '+order' => (      default => sub {          sub { diff --git a/lib/test-diskbe.pl b/lib/test-diskbe.pl index 380716a9..007f6d6c 100644 --- a/lib/test-diskbe.pl +++ b/lib/test-diskbe.pl @@ -11,25 +11,6 @@ sub sp {  	return "  ". sp($level - 1);  } -sub dumpio { -	my ($db_man, $io, $level) = @_; -	print sp($level) ."- IO(". $io->type() ."): ". $io->label() ."\n"; -	# indent -	$level = $level + 1; - -	print sp($level) ."Properties:\n" if scalar($io->properties()) > 0; -	for my $key (sort $io->properties()) { -		print sp($level) ."- ". $key ." --> ". $io->prop($key) ."\n"; -	} - -	# find parts that contain this -	my @parts = $db_man->findin($io); -	print sp($level) ."Parts:\n" if scalar(@parts) > 0; -	for my $part (sort { $a->label() cmp $b->label() } @parts) { -		dumppart($db_man, $part, $level); -	} -} -  sub dumppart {  	my ($db_man, $part, $level) = @_;  	print sp($level) ."- PART(". $part->type() ."): (". $part->label() .")\n"; @@ -41,11 +22,6 @@ sub dumppart {  		print sp($level) ."- ". $key ." --> ". $part->prop($key) ."\n";  	} -	my @ios = $part->get_outs(); -	print sp($level) ."IOs:\n" if scalar(@ios) > 0; -	for my $io (sort { $a->label() cmp $b->label() } @ios) { -		dumpio($db_man, $io, $level); -	}  	print sp($level) ."PartLinks: '". join("','", map { "(". ( defined $_ ? join(",", @{$_->tags()}) : '' ) .")" } @{$part->links()}) ."'\n" if scalar(@{$part->links()}) > 0;  	my @parts = $part->find_parts(undef, 'child');  	print sp($level) ."Child links:\n" if scalar(@parts) > 0; @@ -81,17 +57,9 @@ if ($mode eq 'fs') {  	}  }  else { -	if ($mode eq 'old') { -		my @parts = $db_man->findoutnoin(); -		for my $part (@parts) { -			dumppart($db_man, $part, 0); -		} -	} -	else { -		my @parts = $db_man->findnopart(undef, 'parent'); -		for my $part (@parts) { -			dumppart($db_man, $part, 0); -		} +	my @parts = $db_man->findnopart(undef, 'parent'); +	for my $part (@parts) { +		dumppart($db_man, $part, 0);  	}  } | 
