File Coverage

blib/lib/Lustre/Info/OST.pm
Criterion Covered Total %
statement 9 79 11.3
branch 0 28 0.0
condition 0 9 0.0
subroutine 3 17 17.6
pod 11 13 84.6
total 23 146 15.7


line stmt bran cond sub pod time code
1             #
2             # Lustre OST/OSS subclass
3             #
4             # (C) 2010 Adrian Ulrich -
5             #
6             # This program is free software; you can redistribute it and/or
7             # modify it under the same terms as Perl itself.
8             #
9             #
10             package Lustre::Info::OST;
11 1     1   4 use strict;
  1         2  
  1         61  
12 1     1   4 use warnings;
  1         1  
  1         36  
13 1     1   3 use constant PROCFS_OBDFILTER => '/proc/fs/lustre/obdfilter';
  1         2  
  1         1192  
14              
15             my @TRACK_FIELDS = qw(write_bytes read_bytes create destroy setattr ping preprw);
16              
17             sub new {
18 0     0 0   my($classname, %args) = @_;
19 0           my $self = { super=>$args{super}, ostname=>$args{ostname}, procpath=>PROCFS_OBDFILTER."/$args{ostname}", ost_stats=> [ {}, {} ], client_stats=>{} };
20 0           bless($self,$classname);
21 0 0         return ( -d $self->{procpath} ? $self : undef );
22             }
23              
24              
25             ##########################################################################
26             # Return name of OST
27             sub get_name {
28 0     0 1   my($self) = @_;
29 0           return $self->{ostname};
30             }
31              
32             ##########################################################################
33             # Return the size of this OST
34 0     0 1   sub get_kbytes_total { return $_[0]->_rint('kbytestotal'); }
35              
36             ##########################################################################
37             # Return how much space is free
38 0     0 1   sub get_kbytes_free { return $_[0]->_rint('kbytesfree'); }
39              
40             ##########################################################################
41             # # of pre-allocated inodes (at mkfs.lustre runtime)
42 0     0 1   sub get_files_total { return $_[0]->_rint('filestotal'); }
43              
44             ##########################################################################
45             # How many files/inodes are free
46 0     0 1   sub get_files_free { return $_[0]->_rint('filesfree'); }
47              
48             ##########################################################################
49             # Returns the name of the hosting blockdevice
50 0     0 0   sub get_blockdevice { return $_[0]->_rint('mntdev'); }
51              
52             ##########################################################################
53             # Parse and return information about the last recovery procedure
54             sub get_recovery_info {
55 0     0 1   my($self) = @_;
56 0           return $self->{super}->_parse_generic_file($self->{procpath}."/recovery_status");
57             }
58              
59             ##########################################################################
60             # Update stats of this OST
61             sub collect_ost_stats {
62 0     0 1   my($self) = @_;
63 0           my $data = $self->{super}->_parse_stats_file($self->{procpath}."/stats");
64 0           my $stats = $self->{ost_stats};
65 0           shift(@$stats);
66 0           push(@{$stats}, $data);
  0            
67 0           return $stats;
68             }
69              
70             ##########################################################################
71             # Return stats for this OST
72             sub get_ost_stats {
73 0     0 1   my($self) = @_;
74            
75 0           my $a = $self->{ost_stats}->[0];
76 0           my $b = $self->{ost_stats}->[1];
77 0           my $r = {};
78 0 0         return undef if !exists($a->{data}); # not enough data
79 0 0         return undef if !exists($b->{data});
80            
81 0           $r->{_slice} = $b->{timestamp} - $a->{timestamp};
82 0           foreach my $k (@TRACK_FIELDS) {
83 0 0 0       $r->{$k} = $b->{data}->{$k}->{count} - $a->{data}->{$k}->{count} if
84             exists($a->{data}->{$k}) && exists($b->{data}->{$k});
85             }
86 0           return $r;
87             }
88              
89              
90             ##########################################################################
91             # Collect statistics for ALL connected clients of this OST. This is expensive!
92             sub collect_client_stats {
93 0     0 1   my($self, $clist) = @_;
94            
95 0 0         $clist = $self->get_exports if !$clist;
96            
97 0           foreach my $eid (@$clist) {
98 0 0         my $data = $self->{super}->_parse_stats_file($self->{procpath}."/exports/$eid/stats") or next;
99 0 0         if(!exists($self->{client_stats}->{$eid})) {
100 0           $self->{client_stats}->{$eid} = [ {}, {} ]; # init empty struct on first run
101             }
102            
103 0           my $ref = $self->{client_stats}->{$eid};
104 0           shift(@$ref);
105 0           push(@$ref, $data);
106             }
107 0           return $self->{client_stats}; # return most recent entry.
108             }
109              
110             ##########################################################################
111             # Returns statistics for all clients on this OST
112             sub get_client_stats {
113 0     0 1   my($self) = @_;
114            
115 0           my $r = {};
116 0           foreach my $eid (keys(%{$self->{client_stats}})) {
  0            
117 0           my $this_ref = $self->{client_stats}->{$eid}; # holds: [ {timestamp=>0, data=>{}}, {timestamp=>0, data=>{}} ]
118 0           my $a = $this_ref->[0];
119 0           my $b = $this_ref->[1];
120 0 0 0       next if !exists($a->{data}) or !exists($b->{data}); # all zero or not enough data;
121            
122 0           $r->{$eid}->{_slice} = $b->{timestamp} - $a->{timestamp};
123 0           map { $r->{$eid}->{$_} = 0 } @TRACK_FIELDS;
  0            
124            
125 0           foreach my $k (@TRACK_FIELDS) {
126 0 0 0       $r->{$eid}->{$k} = $b->{data}->{$k}->{count} - $a->{data}->{$k}->{count} if
127             exists($a->{data}->{$k}) && exists($b->{data}->{$k});
128             }
129             }
130 0           return $r;
131             }
132              
133             ##########################################################################
134             # Returns a list to all 'known' exports of this OST
135             sub get_exports {
136 0     0 1   my($self) = @_;
137            
138 0           my @list = ();
139 0 0         opendir(PD, $self->{procpath}."/exports/") or return \@list;
140 0           while(defined(my $dirent = readdir(PD))) {
141 0 0         next if $dirent eq '.';
142 0 0         next if $dirent eq '..';
143 0 0         next unless -d $self->{procpath}."/exports/$dirent";
144 0           push(@list,$dirent);
145             }
146 0           closedir(PD);
147 0           return \@list;
148             }
149              
150              
151              
152             ##########################################################################
153             # Return an integer
154             sub _rint {
155 0     0     my($self,$procfile) = @_;
156 0 0         open(PF, $self->{procpath}."/$procfile") or return -1;
157 0           my $num = ; chomp($num);
  0            
158 0           close(PF);
159 0           return $num;
160             }
161              
162              
163             1;
164             __END__