File Coverage

blib/lib/StorageDisplay/Data/LVM.pm
Criterion Covered Total %
statement 143 166 86.1
branch 12 16 75.0
condition n/a
subroutine 39 43 90.7
pod 0 15 0.0
total 194 240 80.8


line stmt bran cond sub pod time code
1             #
2             # This file is part of StorageDisplay
3             #
4             # This software is copyright (c) 2014-2023 by Vincent Danjean.
5             #
6             # This is free software; you can redistribute it and/or modify it under
7             # the same terms as the Perl 5 programming language system itself.
8             #
9 9     9   65 use strict;
  9         22  
  9         3626  
10 9     9   55 use warnings;
  9         23  
  9         1031  
11              
12             package StorageDisplay::Data::LVM;
13             # ABSTRACT: Handle LVM data for StorageDisplay
14              
15             our $VERSION = '2.06'; # VERSION
16              
17             1;
18              
19             ##################################################################
20             package StorageDisplay::Data::LVM::Group;
21              
22 9     9   66 use Moose;
  9         22  
  9         81  
23 9     9   75661 use namespace::sweep;
  9         21  
  9         123  
24             extends 'StorageDisplay::Data::Elem';
25              
26             with ('StorageDisplay::Role::Style::IsSubGraph');
27              
28             has 'vg' => (
29             is => 'ro',
30             isa => 'StorageDisplay::Block',
31             required => 1,
32             );
33              
34             has 'vgname' => (
35             is => 'ro',
36             isa => 'Str',
37             required => 1,
38             init_arg => undef,
39             lazy => 1,
40             default => sub {
41             my $self = shift;
42             return $self->vg->name;
43             },
44             );
45              
46             has 'pvs' => (
47             is => 'ro',
48             isa => 'StorageDisplay::Data::LVM::PVs::Base',
49             writer => '_pvs',
50             required => 0,
51             );
52              
53             sub dname {
54 18     18 0 71 my $self=shift;
55 18         694 return 'LVM VG: '.$self->name;
56             }
57              
58             sub dotLabel {
59 18     18 0 76 my $self = shift;
60 18         868 return 'LVM: '.$self->vgname;
61             }
62              
63             sub _xv {
64 96     96   219 my $self = shift;
65 96         186 my $kind = shift;
66 96         182 my $name = shift;
67              
68 96         4161 my $it = $self->$kind->iterator(recurse => 0);
69 96         167690 while (defined(my $e=$it->next)) {
70 817 100       44315 return $e if $e->lvmname eq $name;
71             }
72             #print STDERR "E: no $kind with name $name\n";
73 0         0 return;
74             }
75              
76 9     9   9169 use StorageDisplay::Moose::Cached;
  9         169  
  9         192  
77              
78             has 'pv' => (
79             cached_hash => "StorageDisplay::Data::LVM::VG::PVs::PV",
80             compute => sub {
81             my $self = shift;
82             my $name = shift;
83             return $self->_xv("pvs", $name);
84             },
85             );
86              
87             ##################################################################
88             package StorageDisplay::Data::LVM::UnassignedPVs;
89              
90 9     9   228 use Moose;
  9         47  
  9         242  
91 9     9   89778 use namespace::sweep;
  9         47  
  9         244  
92             extends 'StorageDisplay::Data::LVM::Group';
93              
94             with (
95             'StorageDisplay::Role::Style::Grey',
96             'StorageDisplay::Role::Elem::Kind'
97             => { kind => "Unassigned PVs" }
98             );
99              
100             around BUILDARGS => sub {
101             my $orig = shift;
102             my $class = shift;
103             my $vgname = shift;
104             my $st = shift;
105              
106             $st->log({level=>1}, 'Unassigned PVs');
107              
108             my $vgblock = StorageDisplay::Block::NoSystem->new(
109             'name' => $class,
110             );
111              
112             my $info = $st->get_info('lvm', $vgname);
113              
114             return $class->$orig(
115             'ignore_name' => 1,
116             'vg' => $vgblock,
117             'consume' => [],
118             'lvm-info' => $info,
119             'st' => $st,
120             @_
121             );
122             };
123              
124             sub BUILD {
125 0     0 0 0 my $self=shift;
126 0         0 my $args=shift;
127 0         0 my $st = $args->{st};
128              
129             $self->_pvs($self->newChild('LVM::UnassignedPVs::PVs',
130 0         0 $self, $st, $args->{'lvm-info'}));
131 0         0 return $self;
132             };
133              
134             sub dotLabel {
135 0     0 0 0 my $self = shift;
136 0         0 return ('LVM: unassigned PVs');
137             }
138              
139             1;
140              
141             ##################################################################
142             package StorageDisplay::Data::LVM::VG;
143              
144 9     9   3974 use Moose;
  9         40  
  9         83  
145 9     9   71695 use namespace::sweep;
  9         49  
  9         86  
146             extends 'StorageDisplay::Data::LVM::Group';
147              
148             with (
149             'StorageDisplay::Role::Style::WithFree',
150             );
151              
152             has 'lvs' => (
153             is => 'ro',
154             isa => 'StorageDisplay::Data::LVM::VG::LVs',
155             writer => '_lvs',
156             required => 0,
157             );
158              
159             has '_pv_lv_links' => (
160             traits => [ 'Array' ],
161             is => 'ro',
162             isa => "ArrayRef",
163             required => 1,
164             default => sub { return []; },
165             handles => {
166             '_add_link' => 'push',
167             'internal_links' => 'elements',
168             }
169             );
170              
171             around BUILDARGS => sub {
172             my $orig = shift;
173             my $class = shift;
174             my $vgname = shift;
175             my $st = shift;
176              
177             $st->log({level=>1}, 'VG '.$vgname);
178              
179             my $vgblock = StorageDisplay::Block::NoSystem->new(
180             'name' => $vgname,
181             );
182              
183             my $info = $st->get_info('lvm', $vgname);
184              
185             return $class->$orig(
186             'name' => $vgname,
187             'vg' => $vgblock,
188             'consume' => [],
189             'lvm-info' => $info,
190             'st' => $st,
191             'size' => ($info->{'vgs-vg'}->{'vg_size'} =~ s/B$//r),
192             'free' => ($info->{'vgs-vg'}->{'vg_free'} =~ s/B$//r),
193             @_
194             );
195             };
196              
197             sub BUILD {
198 9     9 0 29772 my $self=shift;
199 9         25 my $args=shift;
200 9         26 my $st = $args->{st};
201              
202             $self->_pvs($self->newChild('LVM::VG::PVs', $self, $st,
203 9         125 $args->{'lvm-info'}));
204 9 50       52 if ($args->{'name'} ne '') {
205             #print STDERR "name: ", $args->{'name'}, "\n";
206             $self->_lvs($self->newChild('LVM::VG::LVs', $self, $st,
207 9         54 $args->{'lvm-info'}));
208             #my $links = $args->{'lvm-info'}->{'pvs'};
209             #foreach my $l (@{$links}) {
210             # if ($l->{segtype} ne "free"
211             # && $l->{lv_role} ne "private,pool,spare"
212             # && $l->{lv_role} ne "private,thin,pool,metadata"
213             # && $l->{lv_role} ne "private,thin,pool,data") {
214             # $self->_add_link({pv => $l->{pv_name},
215             # lv => $l->{lv_name}});
216             # }
217             #}
218 9         46 my $links = $args->{'lvm-info'}->{'lvs'};
219 9         20 foreach my $l (@{$links}) {
  9         32  
220 86 100       296 if ($l->{'pool_lv'} ne '') {
221             $self->_add_link({source_name => $l->{'pool_lv'},
222             source_type => 'lv',
223 1         65 lv => $l->{lv_name}});
224             }
225 86 100       213 if ($l->{'lv_parent'} ne '') {
226             $self->_add_link({source_name => $l->{lv_name},
227             source_type => 'lv',
228 2         168 lv => $l->{lv_parent}});
229             }
230 86         323 foreach my $devpos (split(/,/, $l->{'seg_le_ranges'})) {
231 85 50       419 if ($devpos !~ m/^(.*):[0-9]+-[0-9]+$/) {
232 0         0 $st->warn("Cannot parse seg_le_ranges $devpos for ".$l->{lv_name});
233             } else {
234 85         219 my $source_name = $1;
235             #$st->warn("Parsing seg_pe_ranges $devpos for ".$l->{lv_name});
236 85         145 my $type = 'pv';
237 85 100       247 if (index($l->{'seg_pe_ranges'},$devpos) == -1) {
238 1         2 $type = 'lv';
239             #$st->warn("switching to LV for $devpos for ".$l->{lv_name});
240             #} else {
241             # $st->warn("ok : $devpos in ".$l->{'seg_pe_ranges'});
242             }
243             $self->_add_link({source_name => $source_name,
244             source_type => $type,
245 85         5031 lv => $l->{lv_name}});
246             }
247             }
248             }
249             }
250 9         65 return $self;
251             };
252              
253 9     9   7537 use StorageDisplay::Moose::Cached;
  9         110  
  9         135  
254              
255             has 'lv' => (
256             cached_hash => "StorageDisplay::Data::LVM::VG::LVs::LV",
257             compute => sub {
258             my $self = shift;
259             my $name = shift;
260             return $self->_xv("lvs", $name);
261             },
262             );
263              
264             sub dotLinks {
265 9     9 0 61 my $self = shift;
266             my $source = sub {
267 88     88   210 my $name = shift;
268 88         163 my $type = shift;
269 88         550 my $source = $self->$type($name);
270 88 50       262 if (defined($source)) {
271 88         462 return $source->linkname;
272             }
273 0         0 print STDERR "E: FIXME: No source for $name ($type)\n";
274 0         0 return "''";
275 9         66 };
276             return map {
277 9         702 $source->($_->{source_name}, $_->{source_type}).' -> '.$self->lv($_->{lv})->linkname
  88         443  
278             } $self->internal_links;
279             }
280              
281             1;
282              
283             ##################################################################
284             package StorageDisplay::Data::LVM::Elem;
285              
286 9     9   71 use Moose;
  9         59  
  9         86  
287 9     9   68043 use namespace::sweep;
  9         758  
  9         89  
288             extends 'StorageDisplay::Data::Elem';
289              
290             has 'vg' => (
291             is => 'ro',
292             isa => 'StorageDisplay::Data::LVM::Group',
293             required => 1,
294             );
295              
296             around BUILDARGS => sub {
297             my $orig = shift;
298             my $class = shift;
299             my $vg = shift;
300             my $st = shift;
301             my $info = shift;
302              
303             return $class->$orig(
304             'vg' => $vg,
305             'st' => $st,
306             'lvm-info' => $info,
307             @_
308             );
309             };
310              
311             1;
312              
313             ##################################################################
314             package StorageDisplay::Data::LVM::PVs::Base;
315              
316 9     9   1938 use Moose;
  9         31  
  9         83  
317 9     9   74908 use namespace::sweep;
  9         31  
  9         80  
318             extends 'StorageDisplay::Data::LVM::Elem';
319              
320             with (
321             'StorageDisplay::Role::Style::IsSubGraph',
322             'StorageDisplay::Role::Style::SubInternal',
323             );
324              
325             1;
326              
327             ##################################################################
328             package StorageDisplay::Data::LVM::VG::PVs;
329              
330 9     9   2621 use Moose;
  9         32  
  9         77  
331 9     9   67293 use namespace::sweep;
  9         35  
  9         101  
332             extends 'StorageDisplay::Data::LVM::PVs::Base';
333              
334             around BUILDARGS => sub {
335             my $orig = shift;
336             my $class = shift;
337             my $vg = shift;
338              
339             return $class->$orig(
340             $vg,
341             @_,
342             'ignore_name' => 1,
343             'consume' => [],
344             );
345             };
346              
347             sub BUILD {
348 9     9 0 18260 my $self=shift;
349 9         28 my $args=shift;
350 9         23 my @pvnames = sort keys %{$args->{'lvm-info'}->{'vgs-pv'}};
  9         117  
351 9 50       58 if (scalar(@pvnames) == 0) {
352             # PV without a VG
353 0         0 @pvnames = map { $_->{'pv_name'} } @{$args->{'lvm-info'}->{'pvs'}};
  0         0  
  0         0  
354             }
355 9         25 foreach my $pv_name (sort keys %{$args->{'lvm-info'}->{'vgs-pv'}}) {
  9         40  
356             $self->newChild('LVM::VG::PVs::PV', $pv_name, $self->vg, $args->{st},
357 21         937 $args->{'lvm-info'});
358             }
359 9         74 return $self;
360             };
361              
362             sub dotLabel {
363 18     18 0 40 my $self = shift;
364 18         853 return ($self->vg->vgname.'\'s PVs');
365             }
366              
367             1;
368              
369             ##################################################################
370             package StorageDisplay::Data::LVM::UnassignedPVs::PVs;
371              
372 9     9   3690 use Moose;
  9         41  
  9         259  
373 9     9   70763 use namespace::sweep;
  9         215  
  9         72  
374             extends 'StorageDisplay::Data::LVM::PVs::Base';
375              
376             around BUILDARGS => sub {
377             my $orig = shift;
378             my $class = shift;
379             my $vg = shift;
380              
381             return $class->$orig(
382             $vg,
383             @_,
384             'ignore_name' => 1,
385             'consume' => [],
386             );
387             };
388              
389             sub BUILD {
390 0     0 0 0 my $self=shift;
391 0         0 my $args=shift;
392 0         0 foreach my $pv_name (sort map { $_->{'pv_name'} } @{$args->{'lvm-info'}->{'pvs'}}) {
  0         0  
  0         0  
393             $self->newChild('LVM::VG::PVs::PV', $pv_name, $self->vg,
394 0         0 $args->{st}, $args->{'lvm-info'});
395             }
396 0         0 return $self;
397             };
398              
399             sub dotLabel {
400 0     0 0 0 my $self = shift;
401 0         0 return ();
402             }
403              
404             1;
405              
406             ##################################################################
407             package StorageDisplay::Data::LVM::VG::LVs;
408              
409 9     9   3202 use Moose;
  9         43  
  9         62  
410 9     9   70074 use namespace::sweep;
  9         40  
  9         170  
411             extends 'StorageDisplay::Data::LVM::Elem';
412              
413             with (
414             'StorageDisplay::Role::Style::IsSubGraph',
415             'StorageDisplay::Role::Style::SubInternal',
416             );
417              
418             around BUILDARGS => sub {
419             my $orig = shift;
420             my $class = shift;
421             my $vg = shift;
422              
423             return $class->$orig(
424             $vg,
425             @_,
426             'ignore_name' => 1,
427             'consume' => [],
428             );
429             };
430              
431             sub BUILD {
432 9     9 0 22700 my $self=shift;
433 9         26 my $args=shift;
434              
435 9         27 foreach my $lv_name (sort keys %{$args->{'lvm-info'}->{'vgs-lv'}}) {
  9         106  
436             $self->newChild('LVM::VG::LVs::LV', $lv_name, $self->vg,
437 75         3627 $args->{st}, $args->{'lvm-info'});
438             }
439 9         72 return $self;
440             };
441              
442             sub dotLabel {
443 18     18 0 64 my $self = shift;
444 18         830 return ($self->vg->vgname.'\'s LVs');
445             }
446             1;
447              
448             ##################################################################
449             package StorageDisplay::Data::LVM::XV;
450              
451 9     9   3391 use Moose;
  9         23  
  9         77  
452 9     9   71960 use namespace::sweep;
  9         37  
  9         92  
453             extends 'StorageDisplay::Data::LVM::Elem';
454              
455             with (
456             'StorageDisplay::Role::HasBlock',
457             );
458              
459             has 'lvmname' => (
460             is => 'ro',
461             isa => 'Str',
462             required => 1,
463             );
464              
465             around BUILDARGS => sub {
466             my $orig = shift;
467             my $class = shift;
468             my $vg = shift;
469             my $st = shift;
470             my $info = shift;
471             my $lvmname = shift;
472             my $block = shift;
473              
474             return $class->$orig(
475             $vg, $st, $info,
476             'lvmname' => $lvmname,
477             'block' => $block,
478             @_
479             );
480             };
481              
482             1;
483              
484             ##################################################################
485             package StorageDisplay::Data::LVM::VG::PVs::PV;
486              
487 9     9   2222 use Moose;
  9         28  
  9         70  
488 9     9   69614 use namespace::sweep;
  9         30  
  9         69  
489             extends 'StorageDisplay::Data::LVM::XV';
490              
491             with (
492             'StorageDisplay::Role::Style::WithUsed',
493             );
494              
495             around BUILDARGS => sub {
496             my $orig = shift;
497             my $class = shift;
498             my $pvblockname = shift;
499             my $vg = shift;
500             my $st = shift;
501             my $info = shift;
502              
503             my $pvblock = $st->block($pvblockname);
504              
505             my $pvinfo = $info->{'vgs-pv'}->{$pvblockname};
506              
507             if (not defined($pvinfo)) {
508             # only PV, no assigned VG
509             my @pv = grep { $_->{'pv_name'} eq $pvblockname } @{$info->{'pvs'}};
510             $pvinfo = $pv[0];
511             }
512              
513             return $class->$orig(
514             $vg, $st, $info, $pvblockname, $pvblock,
515             'name' => $pvblock->name,
516             'consume' => [$pvblock],
517             'size' => ($pvinfo->{'pv_size'} =~ s/B$//r),
518             'free' => ($pvinfo->{'pv_free'} =~ s/B$//r),
519             'used' => ($pvinfo->{'pv_used'} =~ s/B$//r),
520             @_
521             );
522             };
523              
524             sub dotLabel {
525 42     42 0 99 my $self = shift;
526 42         1884 return ('PV: '.$self->block->dname);
527             }
528              
529             1;
530              
531             ##################################################################
532             package StorageDisplay::Data::LVM::VG::LVs::LV;
533              
534 9     9   4273 use Moose;
  9         28  
  9         72  
535 9     9   66907 use namespace::sweep;
  9         23  
  9         71  
536             extends 'StorageDisplay::Data::LVM::XV';
537              
538             with (
539             'StorageDisplay::Role::Style::WithSize',
540             'StorageDisplay::Role::Style::FromBlockState',
541             );
542              
543             around BUILDARGS => sub {
544             my $orig = shift;
545             my $class = shift;
546             my $lvname = shift;
547             my $vg = shift;
548             my $st = shift;
549             my $info = shift;
550              
551             my $lvblock = $st->block($vg->vgname.'/'.$lvname);
552              
553             my $lvinfo = $info->{'vgs-lv'}->{$lvname};
554              
555             return $class->$orig(
556             $vg, $st, $info, $lvname, $lvblock,
557             'name' => $lvname,
558             'consume' => [],
559             'size' => ($lvinfo->{'lv_size'} =~ s/B$//r),
560             @_
561             );
562             };
563              
564             sub BUILD {
565 75     75 0 192207 my $self = shift;
566 75         4276 $self->provideBlock($self->block);
567             }
568              
569             sub dotLabel {
570 150     150 0 345 my $self = shift;
571 150         7150 return ('LV: '.$self->lvmname);
572             }
573              
574             1;
575              
576             __END__
577              
578             =pod
579              
580             =encoding UTF-8
581              
582             =head1 NAME
583              
584             StorageDisplay::Data::LVM - Handle LVM data for StorageDisplay
585              
586             =head1 VERSION
587              
588             version 2.06
589              
590             =head1 AUTHOR
591              
592             Vincent Danjean <Vincent.Danjean@ens-lyon.org>
593              
594             =head1 COPYRIGHT AND LICENSE
595              
596             This software is copyright (c) 2014-2023 by Vincent Danjean.
597              
598             This is free software; you can redistribute it and/or modify it under
599             the same terms as the Perl 5 programming language system itself.
600              
601             =cut