Several fixes & changes:

* qtime and stime computed correctly
* Interactive mode and changing groups doesn't fail
* Interactive mode no longer uses a file to gather samples.
This commit is contained in:
Brian Fraser
2012-01-30 17:44:18 -03:00
parent ad552756b2
commit 73c1e466d7
12 changed files with 723 additions and 312 deletions

View File

@@ -1602,6 +1602,10 @@ sub new {
WRITTEN_KBS
MS_SPENT_DOING_IO
MS_WEIGHTED
READ_KBS
WRITTEN_KBS
IOS_REQUESTED
IOS_IN_BYTES
)
],
_stats_for => {},
@@ -1617,6 +1621,11 @@ sub new {
return bless $self, $class;
}
sub new_from_object {
my ($self, $class) = @_;
return bless $self, $class;
}
sub active_device {
my ( $self, $dev ) = @_;
@@ -1633,7 +1642,6 @@ sub clear_active_devices {
return $self->{_active_devices} = {};
}
sub automatic_headers {
my ($self) = @_;
return $self->{automatic_headers};
@@ -1774,11 +1782,13 @@ sub set_force_header {
}
sub clear_state {
my ($self) = @_;
my ($self, %args) = @_;
$self->set_force_header(1);
$self->clear_curr_stats();
$self->clear_prev_stats();
$self->clear_first_stats();
if ( $args{force} || !$self->interactive() ) {
$self->clear_first_stats();
$self->clear_prev_stats();
}
$self->clear_ts();
$self->clear_ordered_devs();
}
@@ -1808,6 +1818,11 @@ sub _clear_stats_common {
sub clear_curr_stats {
my ( $self, @args ) = @_;
if ( $self->has_stats() ) {
$self->_save_curr_as_prev();
}
$self->_clear_stats_common( "_stats_for", @args );
}
@@ -1882,7 +1897,6 @@ sub _save_curr_as_first {
map { $_ => [@{$curr->{$_}}] } keys %$curr
};
$self->set_first_ts($self->curr_ts());
$self->{_first} = undef;
}
}
@@ -1995,7 +2009,7 @@ sub parse_from {
elsif ( $args{data} ) {
open( my $fh, "<", ref($args{data}) ? $args{data} : \$args{data} )
or die "Couldn't parse data: $OS_ERROR";
my $lines_read = $self->_parse_from_filehandle(
$lines_read = $self->_parse_from_filehandle(
$fh, $args{sample_callback}
);
close $fh or warn "Cannot close: $OS_ERROR";
@@ -2161,7 +2175,7 @@ sub _calc_misc_stats {
* $delta_for->{ms_spent_doing_io}
/ ( 1000 * $elapsed * $devs_in_group ); # Highlighting failure: /
my $number_of_ios = $stats->{ios_requested};
my $number_of_ios = $delta_for->{ios_requested};
my $total_ms_spent_on_io = $delta_for->{ms_spent_reading}
+ $delta_for->{ms_spent_writing};
@@ -2229,7 +2243,7 @@ sub _mark_if_active {
return unless $curr && $first;
if ( first { $curr->[$_] != $first->[$_] } READS..MS_WEIGHTED ) {
if ( first { $curr->[$_] != $first->[$_] } READS..IOS_IN_BYTES ) {
$self->set_active_device($dev, 1);
return $dev;
}
@@ -2301,9 +2315,9 @@ sub _calc_deltas {
sub force_print_header {
my ($self, @args) = @_;
my $orig = $self->force_header();
$self->force_header(1);
$self->set_force_header(1);
$self->print_header(@args);
$self->force_header($orig);
$self->set_force_header($orig);
return;
}
@@ -2356,7 +2370,9 @@ sub print_deltas {
if ( $self->automatic_headers()
&& !$self->isa("DiskstatsGroupByAll") )
{
local $self->{force_header} = 1;
$header_method = ref($header_method)
? $header_method
: "force_print_header";
$self->$header_method( $header, "#ts", "device" );
}
}
@@ -2443,41 +2459,25 @@ use base qw( Diskstats );
sub group_by {
my ($self, %args) = @_;
$self->clear_state();
$self->clear_state() unless $self->interactive();
if (!$self->interactive()) {
$self->parse_from(
filehandle => $args{filehandle},
filename => $args{filename},
data => $args{data},
sample_callback => sub {
$self->print_deltas(
header_callback => $args{header_callback},
rows_callback => $args{rows_callback},
);
my $header_callback = $args{header_callback}
|| sub {
my ($self, @args) = @_;
$self->print_header(@args);
$self->{_print_header} = 0;
};
$self->parse_from(
filehandle => $args{filehandle},
filename => $args{filename},
data => $args{data},
sample_callback => sub {
$self->print_deltas(
header_callback => $header_callback,
rows_callback => $args{rows_callback},
);
},
);
}
else {
my $orig = tell $args{filehandle} if $args{filehandle};
my $header_callback = $args{header_callback} || sub {
my ($self, @args) = @_;
$self->print_header(@args) if $self->{_print_header};
$self->{_print_header} = 0;
};
$self->parse_from(
filehandle => $args{filehandle},
filename => $args{filename},
data => $args{data},
sample_callback => sub {
$self->print_deltas(
header_callback => $header_callback,
rows_callback => $args{rows_callback},
);
},
);
seek $args{filehandle}, $orig, 0 unless $self->prev_ts();
}
);
return;
}
@@ -2583,8 +2583,6 @@ sub group_by {
},
rows_callback => $args{rows_callback},
);
$self->{_iterations} = -1;
return;
}
}
@@ -2596,11 +2594,6 @@ sub group_by {
);
if ($self->interactive()) {
if ($self->{_iterations} != -1 && defined($original_offset)
&& eof($args{filehandle} || $args{data}) ) {
$self->clear_state;
seek( ($args{filehandle} || $args{data}), $original_offset, 0);
}
return $lines_read;
}
@@ -2707,7 +2700,6 @@ sub group_by {
data => $args{data},
);
$self->clear_state() unless $self->interactive();
return;
}
@@ -2781,7 +2773,7 @@ sub compute_dev {
$devs ||= $self->compute_devs_in_group();
return $devs > 1
? "{" . $devs . "}"
: $self->{ordered_devs}->[0];
: $self->{_ordered_devs}->[0];
}
sub _calc_stats_for_deltas {
@@ -2912,11 +2904,8 @@ my %actions = (
"Enter a disk/device pattern: " ),
'q' => sub { return 'last' },
'p' => sub {
my (@args) = @_;
print "Paused - press any key to continue\n";
pause(@args);
$Diskstats::printed_lines--;
print_header(@args) unless $Diskstats::printed_lines;
pause(@_);
return;
},
' ' => \&print_header,
@@ -2947,34 +2936,57 @@ sub run_interactive {
my ($tmp_fh, $filename, $child_pid, $child_fh);
if ( $filename = $args{filename} ) {
open $tmp_fh, "<", $filename
or die "Cannot open $filename: $OS_ERROR";
if ( ref $filename ) {
$tmp_fh = $filename;
undef $args{filename};
}
else {
open $tmp_fh, "<", $filename
or die "Cannot open $filename: $OS_ERROR";
}
}
else {
($tmp_fh, $filename) = file_to_use( $o->get('save-samples') );
$filename = $o->get('save-samples');
$child_pid = open $child_fh, "|-";
if ( $filename ) {
unlink $filename;
open my $tmp_fh, "+>", $filename
or die "Cannot open $filename: $OS_ERROR";
}
$child_pid = open $child_fh, "-|";
die "Cannot fork: $OS_ERROR" unless defined $child_pid;
if ( !$child_pid ) {
STDOUT->autoflush(1);
local $PROGRAM_NAME = "$PROGRAM_NAME (data-gathering daemon)";
close $tmp_fh;
close $tmp_fh if $tmp_fh;
PTDEBUG && _d("Child is [$PROGRAM_NAME] in ps aux and similar");
gather_samples(
gather_while => sub { getppid() },
samples_to_gather => $o->get('iterations'),
filename => $filename,
);
unlink $filename unless $o->get('save-samples');
if ( $filename ) {
unlink $filename unless $o->get('save-samples');
}
exit(0);
}
else {
PTDEBUG && _d("Forked, child is", $child_pid);
$tmp_fh = $child_fh;
$tmp_fh->blocking(0);
}
}
PTDEBUG && _d("Using filename", $filename);
PTDEBUG && _d(
$filename
? ("Using file", $filename)
: "Not using a file to store samples");
local $SIG{CHLD} = 'IGNORE';
local $SIG{PIPE} = 'IGNORE';
@@ -2995,15 +3007,22 @@ sub run_interactive {
my $header_callback = $o->get("current_group_by_obj")
->can("print_header");
my $redraw = 0;
if ( $args{filename} ) {
PTDEBUG && _d("Passed a file from the command line,",
"rendering from scratch before looping");
$redraw = 1;
group_by(
header_callback => $header_callback,
select_obj => $sel,
OptionParser => $o,
filehandle => $tmp_fh,
input => substr(ucfirst($group_by), 0, 1),
redraw_all => $redraw,
);
if ( !-t STDOUT && !tied *STDIN ) {
PTDEBUG && _d("Not connected to a tty and not in testing. Quitting");
return 0
}
}
@@ -3014,25 +3033,30 @@ sub run_interactive {
while ($run) {
my $refresh_interval = $o->get('refresh-interval');
my $time = scalar Time::HiRes::gettimeofday();
my $sleep = $refresh_interval - fmod( $time, ($refresh_interval + 0.5) );
my $sleep = $refresh_interval - fmod( $time, $refresh_interval );
if ( my $input = read_command_timeout($sel, $sleep ) ) {
if ( my $input = read_command_timeout( $sel, $sleep ) ) {
if ($actions{$input}) {
PTDEBUG && _d("Got [$input] and have an action for it");
my $ret = $actions{$input}->(
select_obj => $sel,
OptionParser => $o,
input => $input,
filehandle => $tmp_fh,
redraw_all => $redraw,
) || '';
last MAIN_LOOP if $ret eq 'last';
if ( $args{filename}
&& !grep { $input eq $_ } qw( A S D ), ' ', "\n" )
{
PTDEBUG && _d("Got a file from the command line, redrawing",
"from the beginning after getting an option");
my $obj = $o->get("current_group_by_obj");
$obj->clear_state();
$obj->clear_state( force => 1 );
local $obj->{force_header} = 1;
group_by(
redraw_all => 1,
select_obj => $sel,
OptionParser => $o,
input => substr(ref($obj), 16, 1),
@@ -3049,18 +3073,20 @@ sub run_interactive {
}
if ( !$args{filename} && $o->get('iterations')
&& waitpid($child_pid, WNOHANG) != 0 ) {
PTDEBUG && _d("Child quit as expected after",
$o->get("iterations"),
"iterations. Quitting.");
$run = 0;
}
}
ReadKeyMini::cooked();
if ( !$args{filename} && !defined $o->get('iterations')
if ( $child_pid && !$args{filename} && !defined $o->get('iterations')
&& kill 0, $child_pid ) {
$child_fh->printflush("End\n");
kill 9, $child_pid;
waitpid $child_pid, 0;
}
close $tmp_fh or die "Cannot close: $OS_ERROR";
return 0; # Exit status
}
@@ -3075,28 +3101,30 @@ sub read_command_timeout {
sub gather_samples {
my (%args) = @_;
my $samples = 0;
my $fh;
STDIN->blocking(0);
my $sel = IO::Select->new(\*STDIN);
my $filename = $args{filename};
if ( my $filename = $args{filename} ) {
open $fh, ">>", $filename
or die "Cannot open $filename for appending: $OS_ERROR";
}
else {
$fh = \*STDOUT;
}
open my $fh, ">>", $filename
or die "Cannot open $filename for appending: $OS_ERROR";
$fh->autoflush(1);
GATHER_DATA:
while ( $args{gather_while}->() ) {
my $time = scalar Time::HiRes::gettimeofday();
my $sleep = 1 - fmod( $time, 1 );
if ( read_command_timeout( $sel, $sleep ) ) {
last GATHER_DATA;
}
my $sleep = 1 - fmod( scalar(Time::HiRes::gettimeofday()), 1 );
Time::HiRes::sleep($sleep);
open my $diskstats_fh, "<", "/proc/diskstats"
or die "Cannot open /proc/diskstats: $OS_ERROR";
my @to_print = timestamp();
push @to_print, <$diskstats_fh>;
$fh->printflush(@to_print);
print { $fh } @to_print;
close $diskstats_fh or die $OS_ERROR;
$samples++;
@@ -3131,55 +3159,58 @@ sub group_by {
}
my ($o, $input) = @args{@required_args};
my $old_obj = $o->get("current_group_by_obj");
if ( ref( $o->get("current_group_by_obj") ) ne $input_to_object{$input} ) {
$o->set("current_group_by_obj", undef);
$o->set("current_group_by_obj",
$input_to_object{$input}->new(
OptionParser => $o,
interactive => 1,
)
);
$o->set( "current_group_by_obj", $input_to_object{$input}->new(OptionParser=>$o, interactive => 1) );
if ( !$args{redraw_all} ) {
print_header(%args);
}
}
seek $args{filehandle}, 0, 0;
for my $obj ( $o->get("current_group_by_obj") ) {
if ( $obj->isa("DiskstatsGroupBySample") ) {
$obj->set_interactive(1);
if ( $args{redraw_all} ) {
seek $args{filehandle}, 0, 0;
if ( $obj->isa("DiskstatsGroupBySample") ) {
$obj->set_interactive(1);
}
else {
$obj->set_interactive(0);
}
my $print_header;
my $header_callback = $args{header_callback} || sub {
my ($self, @args) = @_;
$self->print_header(@args) unless $print_header++
};
$obj->group_by(
filehandle => $args{filehandle},
header_callback => $header_callback,
);
}
else {
$obj->set_interactive(0);
}
my $print_header;
my $header_callback = $args{header_callback} || sub {
my ($self, @args) = @_;
$self->print_header(@args) unless $print_header++
};
$obj->group_by(
filehandle => $args{filehandle},
header_callback => $header_callback,
);
$obj->set_interactive(1);
$obj->set_force_header(0);
}
}
sub help {
my (%args) = @_;
my $obj = $args{OptionParser}->get("current_group_by_obj");
my $mode = substr ref($obj), 16, 1;
my $column_re = $args{OptionParser}->get('columns-regex');
my $device_re = $args{OptionParser}->get('devices-regex');
my $interval = $obj->sample_time() || '(none)';
my $disp_int = $args{OptionParser}->get('refresh-interval');
my $inact_disk = $obj->show_inactive() ? 'no' : 'yes';
my (%args) = @_;
my $obj = $args{OptionParser}->get("current_group_by_obj");
my $mode = substr ref($obj), 16, 1;
my $column_re = $args{OptionParser}->get('columns-regex');
my $device_re = $args{OptionParser}->get('devices-regex');
my $interval = $obj->sample_time() || '(none)';
my $disp_int = $args{OptionParser}->get('refresh-interval');
my $inact_disk = $obj->show_inactive() ? 'no' : 'yes';
for my $re ( $column_re, $device_re ) {
$re ||= '(none)';
}
my $help = <<"HELP";
print <<"HELP";
You can control this program by key presses:
------------------- Key ------------------- ---- Current Setting ----
A, D, S) Set the group-by mode $mode
@@ -3192,54 +3223,11 @@ sub help {
q) Quit the program
------------------- Press any key to continue -----------------------
HELP
print $help;
=begin IGNORE
my $lines = $help =~ tr/\n//;
while ( $lines-- ) {
$Diskstats::printed_lines--;
print_header(%args) unless $Diskstats::printed_lines;
}
=cut
pause(%args);
return;
}
sub file_to_use {
my ( $filename ) = @_;
if ( !$filename ) {
PTDEBUG && _d('No explicit filename passed in,',
'trying to get one from mktemp');
chomp($filename = `mktemp -t pt-diskstats.$PID.XXXXXXXX`);
}
if ( $filename ) {
unlink $filename;
open my $fh, "+>", $filename
or die "Cannot open $filename: $OS_ERROR";
return $fh, $filename;
}
else {
PTDEBUG && _d("mktemp didn't return a filename,",
"trying to use File::Temp");
local $EVAL_ERROR;
if ( !eval { require File::Temp } ) {
die "Can't call mktemp nor load File::Temp.",
" Install either of those, or pass in an explicit",
" filename through --save-samples.";
}
my $dir = File::Temp::tempdir( CLEANUP => 1 );
return File::Temp::tempfile(
"pt-diskstats.$PID.XXXXXXXX",
DIR => $dir,
UNLINK => 1,
OPEN => 1,
);
}
}
sub get_blocking_input {
my ($message) = @_;

View File

@@ -105,6 +105,10 @@ sub new {
WRITTEN_KBS
MS_SPENT_DOING_IO
MS_WEIGHTED
READ_KBS
WRITTEN_KBS
IOS_REQUESTED
IOS_IN_BYTES
)
],
_stats_for => {},
@@ -121,6 +125,11 @@ sub new {
return bless $self, $class;
}
sub new_from_object {
my ($self, $class) = @_;
return bless $self, $class;
}
# The next lot are accessors, plus some convenience functions.
sub active_device {
@@ -138,7 +147,6 @@ sub clear_active_devices {
return $self->{_active_devices} = {};
}
sub automatic_headers {
my ($self) = @_;
return $self->{automatic_headers};
@@ -284,11 +292,13 @@ sub set_force_header {
}
sub clear_state {
my ($self) = @_;
my ($self, %args) = @_;
$self->set_force_header(1);
$self->clear_curr_stats();
$self->clear_prev_stats();
$self->clear_first_stats();
if ( $args{force} || !$self->interactive() ) {
$self->clear_first_stats();
$self->clear_prev_stats();
}
$self->clear_ts();
$self->clear_ordered_devs();
}
@@ -318,6 +328,11 @@ sub _clear_stats_common {
sub clear_curr_stats {
my ( $self, @args ) = @_;
if ( $self->has_stats() ) {
$self->_save_curr_as_prev();
}
$self->_clear_stats_common( "_stats_for", @args );
}
@@ -392,7 +407,6 @@ sub _save_curr_as_first {
map { $_ => [@{$curr->{$_}}] } keys %$curr
};
$self->set_first_ts($self->curr_ts());
$self->{_first} = undef;
}
}
@@ -537,7 +551,7 @@ sub parse_from {
elsif ( $args{data} ) {
open( my $fh, "<", ref($args{data}) ? $args{data} : \$args{data} )
or die "Couldn't parse data: $OS_ERROR";
my $lines_read = $self->_parse_from_filehandle(
$lines_read = $self->_parse_from_filehandle(
$fh, $args{sample_callback}
);
close $fh or warn "Cannot close: $OS_ERROR";
@@ -730,7 +744,7 @@ sub _calc_misc_stats {
* $delta_for->{ms_spent_doing_io}
/ ( 1000 * $elapsed * $devs_in_group ); # Highlighting failure: /
my $number_of_ios = $stats->{ios_requested};
my $number_of_ios = $delta_for->{ios_requested};
my $total_ms_spent_on_io = $delta_for->{ms_spent_reading}
+ $delta_for->{ms_spent_writing};
@@ -814,7 +828,7 @@ sub _mark_if_active {
return unless $curr && $first;
# read 'any' instead of 'first'
if ( first { $curr->[$_] != $first->[$_] } READS..MS_WEIGHTED ) {
if ( first { $curr->[$_] != $first->[$_] } READS..IOS_IN_BYTES ) {
# It's different from the first one. Mark as active and return.
$self->set_active_device($dev, 1);
return $dev;
@@ -890,9 +904,9 @@ sub _calc_deltas {
sub force_print_header {
my ($self, @args) = @_;
my $orig = $self->force_header();
$self->force_header(1);
$self->set_force_header(1);
$self->print_header(@args);
$self->force_header($orig);
$self->set_force_header($orig);
return;
}
@@ -952,7 +966,9 @@ sub print_deltas {
if ( $self->automatic_headers()
&& !$self->isa("DiskstatsGroupByAll") )
{
local $self->{force_header} = 1;
$header_method = ref($header_method)
? $header_method
: "force_print_header";
$self->$header_method( $header, "#ts", "device" );
}
}

View File

@@ -33,41 +33,25 @@ use base qw( Diskstats );
sub group_by {
my ($self, %args) = @_;
$self->clear_state();
$self->clear_state() unless $self->interactive();
if (!$self->interactive()) {
$self->parse_from(
filehandle => $args{filehandle},
filename => $args{filename},
data => $args{data},
sample_callback => sub {
$self->print_deltas(
header_callback => $args{header_callback},
rows_callback => $args{rows_callback},
);
my $header_callback = $args{header_callback}
|| sub {
my ($self, @args) = @_;
$self->print_header(@args);
$self->{_print_header} = 0;
};
$self->parse_from(
filehandle => $args{filehandle},
filename => $args{filename},
data => $args{data},
sample_callback => sub {
$self->print_deltas(
header_callback => $header_callback,
rows_callback => $args{rows_callback},
);
},
);
}
else {
my $orig = tell $args{filehandle} if $args{filehandle};
my $header_callback = $args{header_callback} || sub {
my ($self, @args) = @_;
$self->print_header(@args) if $self->{_print_header};
$self->{_print_header} = 0;
};
$self->parse_from(
filehandle => $args{filehandle},
filename => $args{filename},
data => $args{data},
sample_callback => sub {
$self->print_deltas(
header_callback => $header_callback,
rows_callback => $args{rows_callback},
);
},
);
seek $args{filehandle}, $orig, 0 unless $self->prev_ts();
}
);
return;
}

View File

@@ -73,8 +73,6 @@ sub group_by {
},
rows_callback => $args{rows_callback},
);
$self->{_iterations} = -1;
return;
}
}
@@ -93,11 +91,6 @@ sub group_by {
# where we started, so subsequent attempts (i.e. when
# the file has more data) have greater chances of succeeding,
# and no data goes unreported.
if ($self->{_iterations} != -1 && defined($original_offset)
&& eof($args{filehandle} || $args{data}) ) {
$self->clear_state;
seek( ($args{filehandle} || $args{data}), $original_offset, 0);
}
return $lines_read;
}

View File

@@ -58,7 +58,6 @@ sub group_by {
data => $args{data},
);
$self->clear_state() unless $self->interactive();
return;
}
@@ -138,7 +137,7 @@ sub compute_dev {
$devs ||= $self->compute_devs_in_group();
return $devs > 1
? "{" . $devs . "}"
: $self->{ordered_devs}->[0];
: $self->{_ordered_devs}->[0];
}
# Terrible breach of encapsulation, but it'll have to do for the moment.

View File

@@ -92,39 +92,63 @@ sub run_interactive {
# Here's a big crux of the program. If we have a filename, we don't
# need to fork and create a child, just read from it.
if ( $filename = $args{filename} ) {
open $tmp_fh, "<", $filename
or die "Cannot open $filename: $OS_ERROR";
# INTERNAL: For testing.
if ( ref $filename ) {
$tmp_fh = $filename;
undef $args{filename};
}
else {
open $tmp_fh, "<", $filename
or die "Cannot open $filename: $OS_ERROR";
}
}
else {
($tmp_fh, $filename) = file_to_use( $o->get('save-samples') );
$filename = $o->get('save-samples');
if ( $filename ) {
unlink $filename;
open my $tmp_fh, "+>", $filename
or die "Cannot open $filename: $OS_ERROR";
}
# fork(), but future-proofing it in case we ever need to speak to
# the child
$child_pid = open $child_fh, "|-";
$child_pid = open $child_fh, "-|";
die "Cannot fork: $OS_ERROR" unless defined $child_pid;
if ( !$child_pid ) {
# Child
STDOUT->autoflush(1);
# Bit of helpful magic: Changes how the program's name is displayed,
# so it's easier to track in things like ps.
local $PROGRAM_NAME = "$PROGRAM_NAME (data-gathering daemon)";
close $tmp_fh;
close $tmp_fh if $tmp_fh;
PTDEBUG && _d("Child is [$PROGRAM_NAME] in ps aux and similar");
gather_samples(
gather_while => sub { getppid() },
samples_to_gather => $o->get('iterations'),
filename => $filename,
);
unlink $filename unless $o->get('save-samples');
if ( $filename ) {
unlink $filename unless $o->get('save-samples');
}
exit(0);
}
else {
PTDEBUG && _d("Forked, child is", $child_pid);
$tmp_fh = $child_fh;
$tmp_fh->blocking(0);
}
}
PTDEBUG && _d("Using filename", $filename);
PTDEBUG && _d(
$filename
? ("Using file", $filename)
: "Not using a file to store samples");
# I don't think either of these are needed actually, since piped opens
# are supposed to deal with children on their own, but it doesn't hurt.
@@ -147,18 +171,25 @@ sub run_interactive {
my $header_callback = $o->get("current_group_by_obj")
->can("print_header");
my $redraw = 0;
if ( $args{filename} ) {
PTDEBUG && _d("Passed a file from the command line,",
"rendering from scratch before looping");
$redraw = 1;
group_by(
header_callback => $header_callback,
select_obj => $sel,
OptionParser => $o,
filehandle => $tmp_fh,
input => substr(ucfirst($group_by), 0, 1),
redraw_all => $redraw,
);
if ( !-t STDOUT && !tied *STDIN ) {
# If we were passed down a file but aren't tied to a tty,
# -and- STDIN isn't tied (so we aren't in testing mode),
# then this is the end of the program.
PTDEBUG && _d("Not connected to a tty and not in testing. Quitting");
return 0
}
}
@@ -169,15 +200,17 @@ sub run_interactive {
while ($run) {
my $refresh_interval = $o->get('refresh-interval');
my $time = scalar Time::HiRes::gettimeofday();
my $sleep = $refresh_interval - fmod( $time, ($refresh_interval + 0.5) );
my $sleep = $refresh_interval - fmod( $time, $refresh_interval );
if ( my $input = read_command_timeout($sel, $sleep ) ) {
if ( my $input = read_command_timeout( $sel, $sleep ) ) {
if ($actions{$input}) {
PTDEBUG && _d("Got [$input] and have an action for it");
my $ret = $actions{$input}->(
select_obj => $sel,
OptionParser => $o,
input => $input,
filehandle => $tmp_fh,
redraw_all => $redraw,
) || '';
last MAIN_LOOP if $ret eq 'last';
@@ -187,11 +220,14 @@ sub run_interactive {
if ( $args{filename}
&& !grep { $input eq $_ } qw( A S D ), ' ', "\n" )
{
PTDEBUG && _d("Got a file from the command line, redrawing",
"from the beginning after getting an option");
my $obj = $o->get("current_group_by_obj");
# Force it to print the header
$obj->clear_state();
$obj->clear_state( force => 1 );
local $obj->{force_header} = 1;
group_by(
redraw_all => 1,
select_obj => $sel,
OptionParser => $o,
input => substr(ref($obj), 16, 1),
@@ -217,6 +253,9 @@ sub run_interactive {
# When that happens, we are also done.
if ( !$args{filename} && $o->get('iterations')
&& waitpid($child_pid, WNOHANG) != 0 ) {
PTDEBUG && _d("Child quit as expected after",
$o->get("iterations"),
"iterations. Quitting.");
$run = 0;
}
}
@@ -224,13 +263,15 @@ sub run_interactive {
# If we don't have a filename, the daemon might still be running.
# If it is, ask it nicely to end, then wait.
if ( !$args{filename} && !defined $o->get('iterations')
if ( $child_pid && !$args{filename} && !defined $o->get('iterations')
&& kill 0, $child_pid ) {
$child_fh->printflush("End\n");
#$child_fh->printflush("End\n");
# TODO
kill 9, $child_pid;
waitpid $child_pid, 0;
}
close $tmp_fh or die "Cannot close: $OS_ERROR";
#close $tmp_fh or die "Cannot close: $OS_ERROR";
return 0; # Exit status
}
@@ -245,21 +286,23 @@ sub read_command_timeout {
sub gather_samples {
my (%args) = @_;
my $samples = 0;
my $fh;
STDIN->blocking(0);
my $sel = IO::Select->new(\*STDIN);
my $filename = $args{filename};
if ( my $filename = $args{filename} ) {
open $fh, ">>", $filename
or die "Cannot open $filename for appending: $OS_ERROR";
}
else {
$fh = \*STDOUT;
}
open my $fh, ">>", $filename
or die "Cannot open $filename for appending: $OS_ERROR";
$fh->autoflush(1);
GATHER_DATA:
while ( $args{gather_while}->() ) {
my $time = scalar Time::HiRes::gettimeofday();
my $sleep = 1 - fmod( $time, 1 );
if ( read_command_timeout( $sel, $sleep ) ) {
last GATHER_DATA;
}
my $sleep = 1 - fmod( scalar(Time::HiRes::gettimeofday()), 1 );
Time::HiRes::sleep($sleep);
open my $diskstats_fh, "<", "/proc/diskstats"
or die "Cannot open /proc/diskstats: $OS_ERROR";
@@ -268,7 +311,7 @@ sub gather_samples {
# Lovely little method from IO::Handle: turns on autoflush,
# prints, and then restores the original autoflush state.
$fh->printflush(@to_print);
print { $fh } @to_print;
close $diskstats_fh or die $OS_ERROR;
$samples++;
@@ -303,56 +346,58 @@ sub group_by {
}
my ($o, $input) = @args{@required_args};
my $old_obj = $o->get("current_group_by_obj");
if ( ref( $o->get("current_group_by_obj") ) ne $input_to_object{$input} ) {
# Particularly important! Otherwise we would depend on the
# object's ->new being smart about discarding unrecognized
# values.
$o->set("current_group_by_obj", undef);
# This would fail on a stricter constructor, so it probably
# needs fixing.
$o->set("current_group_by_obj",
$input_to_object{$input}->new(
OptionParser => $o,
interactive => 1,
)
);
#my $new_obj = $old_obj->new_from_object($input_to_object{$input});
$o->set( "current_group_by_obj", $input_to_object{$input}->new(OptionParser=>$o, interactive => 1) );
if ( !$args{redraw_all} ) {
print_header(%args);
}
}
seek $args{filehandle}, 0, 0;
# Just aliasing this for a bit.
for my $obj ( $o->get("current_group_by_obj") ) {
if ( $obj->isa("DiskstatsGroupBySample") ) {
$obj->set_interactive(1);
if ( $args{redraw_all} ) {
seek $args{filehandle}, 0, 0;
if ( $obj->isa("DiskstatsGroupBySample") ) {
$obj->set_interactive(1);
}
else {
$obj->set_interactive(0);
}
my $print_header;
my $header_callback = $args{header_callback} || sub {
my ($self, @args) = @_;
$self->print_header(@args) unless $print_header++
};
$obj->group_by(
filehandle => $args{filehandle},
# Only print the header once, as if in interactive.
header_callback => $header_callback,
);
}
else {
$obj->set_interactive(0);
}
my $print_header;
my $header_callback = $args{header_callback} || sub {
my ($self, @args) = @_;
$self->print_header(@args) unless $print_header++
};
$obj->group_by(
filehandle => $args{filehandle},
# Only print the header once, as if in interactive.
header_callback => $header_callback,
);
$obj->set_interactive(1);
$obj->set_force_header(0);
}
}
sub help {
my (%args) = @_;
my $obj = $args{OptionParser}->get("current_group_by_obj");
my $mode = substr ref($obj), 16, 1;
my $column_re = $args{OptionParser}->get('columns-regex');
my $device_re = $args{OptionParser}->get('devices-regex');
my $interval = $obj->sample_time() || '(none)';
my $disp_int = $args{OptionParser}->get('refresh-interval');
my $inact_disk = $obj->show_inactive() ? 'no' : 'yes';
my (%args) = @_;
my $obj = $args{OptionParser}->get("current_group_by_obj");
my $mode = substr ref($obj), 16, 1;
my $column_re = $args{OptionParser}->get('columns-regex');
my $device_re = $args{OptionParser}->get('devices-regex');
my $interval = $obj->sample_time() || '(none)';
my $disp_int = $args{OptionParser}->get('refresh-interval');
my $inact_disk = $obj->show_inactive() ? 'no' : 'yes';
for my $re ( $column_re, $device_re ) {
$re ||= '(none)';
@@ -376,40 +421,6 @@ HELP
return;
}
sub file_to_use {
my ( $filename ) = @_;
if ( !$filename ) {
PTDEBUG && _d('No explicit filename passed in,',
'trying to get one from mktemp');
chomp($filename = `mktemp -t pt-diskstats.$PID.XXXXXXXX`);
}
if ( $filename ) {
unlink $filename;
open my $fh, "+>", $filename
or die "Cannot open $filename: $OS_ERROR";
return $fh, $filename;
}
else {
PTDEBUG && _d("mktemp didn't return a filename,",
"trying to use File::Temp");
local $EVAL_ERROR;
if ( !eval { require File::Temp } ) {
die "Can't call mktemp nor load File::Temp.",
" Install either of those, or pass in an explicit",
" filename through --save-samples.";
}
my $dir = File::Temp::tempdir( CLEANUP => 1 );
return File::Temp::tempfile(
"pt-diskstats.$PID.XXXXXXXX",
DIR => $dir,
UNLINK => 1,
OPEN => 1,
);
}
}
sub get_blocking_input {
my ($message) = @_;

View File

@@ -379,6 +379,8 @@ is_deeply(
writes_merged => 270,
written_kbs => 1229,
written_sectors => 2458,
ios_in_bytes => 1262080,
ios_requested => 57,
},
"_calc_delta_for works"
);
@@ -441,9 +443,9 @@ is_deeply(
{
busy => '0.6',
line_ts => ' 0.0',
qtime => 0,
qtime => '0.929824561403509',
s_spent_doing_io => '0.053',
stime => 0,
stime => '0.210526315789474',
},
"_calc_misc_stats works"
);

View File

@@ -0,0 +1,50 @@
#ts device qtime stime
1.0 sda 12.5 0.2
1.0 sdb 0.7 0.7
1.0 dm-0 5.1 1.5
1.0 dm-1 12.9 0.2
#ts device qtime stime
2.0 sda 0.0 0.0
2.0 sdb 0.0 0.0
2.0 dm-0 0.0 0.0
2.0 dm-1 0.0 0.0
#ts device qtime stime
2.8 sda 0.0 0.0
2.8 sdb 0.0 0.0
2.8 dm-0 0.0 0.0
2.8 dm-1 0.0 0.0
#ts device qtime stime
3.5 sda 0.0 0.0
3.5 sdb 0.0 0.0
3.5 dm-0 0.0 0.0
3.5 dm-1 0.0 0.0
#ts device qtime stime
4.5 sda 0.7 0.7
4.5 sdb 0.0 0.0
4.5 dm-0 0.0 0.0
4.5 dm-1 0.2 0.2
#ts device qtime stime
6.2 sda 0.8 0.4
6.2 sdb 0.0 1.0
6.2 dm-0 1.0 0.1
6.2 dm-1 0.0 0.0
#ts device qtime stime
6.4 sda 0.0 0.0
6.4 sdb 1.0 0.5
6.4 dm-0 0.0 0.0
6.4 dm-1 0.0 0.0
#ts device qtime stime
7.4 sda 0.0 0.0
7.4 sdb 0.0 0.0
7.4 dm-0 0.2 0.2
7.4 dm-1 0.0 0.0
#ts device qtime stime
8.4 sda 29.1 0.7
8.4 sdb 0.9 0.5
8.4 dm-0 0.0 0.0
8.4 dm-1 23.2 0.5
#ts device qtime stime
9.4 sda 0.0 0.0
9.4 sdb 0.0 0.0
9.4 dm-0 0.0 0.0
9.4 dm-1 0.0 0.0

View File

@@ -0,0 +1,5 @@
#ts device qtime stime
{10} sda 22.7 0.6
{10} sdb 0.8 0.6
{10} dm-0 2.6 0.7
{10} dm-1 21.1 0.4

View File

@@ -0,0 +1,9 @@
#ts device qtime stime
1.0 {4} 11.9 0.3
2.0 {4} 0.0 0.0
3.5 {4} 0.0 0.0
4.5 {4} 0.5 0.5
6.2 {4} 0.8 0.3
7.4 {4} 0.2 0.2
8.4 {4} 25.1 0.6
9.4 {4} 0.0 0.0

View File

@@ -9,7 +9,7 @@ BEGIN {
use strict;
use warnings FATAL => 'all';
use English qw(-no_match_vars);
use Test::More tests => 22;
use Test::More tests => 25;
use File::Temp ();
@@ -22,7 +22,9 @@ require "$trunk/bin/pt-diskstats";
# so that we can fake sending pt-diskstats menu commands via STDIN.
# All we do is send 'q', the command to quit. See the note in the bottom
# of this file about *DATA. Please don't close it.
my $called_seek_on_handle = 0;
{
$TestInteractive::first = 1;
sub TestInteractive::TIEHANDLE {
my ($class, @cmds) = @_;
push @cmds, "q";
@@ -36,9 +38,32 @@ sub TestInteractive::FILENO {
sub TestInteractive::READLINE {
my ($self) = @_;
my $cmd = shift @$self;
print $cmd if $cmd =~ /\n/;
return unless $cmd;
print $cmd if $cmd =~ /\n/ && !-t STDOUT;
if ($cmd =~ /^TS/) {
if ( $TestInteractive::first ) {
$TestInteractive::first = 0;
}
else {
splice @$self, 1, 0, (undef) x 50;
}
}
return $cmd;
}
sub TestInteractive::EOF {
my ($self) = @_;
return @$self ? undef : 1;
}
sub TestInteractive::CLOSE { 1 }
sub TestInteractive::TELL {}
sub TestInteractive::SEEK {
$called_seek_on_handle++;
}
}
sub test_diskstats_file {
@@ -50,6 +75,13 @@ sub test_diskstats_file {
( my $x = $_ ) =~ s/\n/\\n/g;
$x
} @commands;
my @options = $args{options}
? @{ $args{options} }
: (
'--show-inactive',
'--no-automatic-headers',
'--columns-regex','cnc|rt|mb|busy|prg',
);
die "$file does not exist" unless -f $file;
foreach my $groupby ( qw(all disk sample) ) {
ok(
@@ -57,10 +89,8 @@ sub test_diskstats_file {
sub {
tie local *STDIN, TestInteractive => @commands;
pt_diskstats::main(
'--show-inactive',
'--no-automatic-headers',
@options,
'--group-by', $groupby,
'--columns-regex','cnc|rt|mb|busy|prg',
$file);
},
"t/pt-diskstats/expected/${groupby}_int_$args{file}",
@@ -85,6 +115,11 @@ test_diskstats_file(
commands => [ "i", "/", "cciss\n", "q" ]
);
test_diskstats_file(
file => "small.txt",
options => [ '--no-automatic-headers', '--columns-regex','time', ],
);
# ###########################################################################
# --save-samples and --iterations
# ###########################################################################

View File

@@ -0,0 +1,319 @@
TS 1327510177.628000 2012-01-25T10:49:37
1 0 ram0 0 0 0 0 0 0 0 0 0 0 0
1 1 ram1 0 0 0 0 0 0 0 0 0 0 0
1 2 ram2 0 0 0 0 0 0 0 0 0 0 0
1 3 ram3 0 0 0 0 0 0 0 0 0 0 0
1 4 ram4 0 0 0 0 0 0 0 0 0 0 0
1 5 ram5 0 0 0 0 0 0 0 0 0 0 0
1 6 ram6 0 0 0 0 0 0 0 0 0 0 0
1 7 ram7 0 0 0 0 0 0 0 0 0 0 0
1 8 ram8 0 0 0 0 0 0 0 0 0 0 0
1 9 ram9 0 0 0 0 0 0 0 0 0 0 0
1 10 ram10 0 0 0 0 0 0 0 0 0 0 0
1 11 ram11 0 0 0 0 0 0 0 0 0 0 0
1 12 ram12 0 0 0 0 0 0 0 0 0 0 0
1 13 ram13 0 0 0 0 0 0 0 0 0 0 0
1 14 ram14 0 0 0 0 0 0 0 0 0 0 0
1 15 ram15 0 0 0 0 0 0 0 0 0 0 0
8 0 sda 85958345 9208182 2671393219 2437232103 534745383 846485907 11060948316 2055732382 0 545004107 197928245
8 1 sda1 5024 46400 6662 13324
8 2 sda2 23671288 753256530 918679759 3054471032
8 3 sda3 306655 2443289 529697 4237576
8 4 sda4 10 20 0 0
8 5 sda5 71211345 1915333340 462827300 3707258504
8 16 sdb 145329387 10397919 3590114436 2492237855 144339337 483516351 5022900400 109665845 0 699286938 2601866158
8 17 sdb1 155688199 3589800804 627862340 727932176
2 0 fd0 0 0 0 0 0 0 0 0 0 0 0
9 0 md0 0 0 0 0 0 0 0 0 0 0 0
253 0 dm-0 3698313 0 441982922 21577627 73403807 0 591870544 1142786100 0 43867855 1164431937
253 1 dm-1 67512604 0 1473349498 2074313873 389423519 0 3115388152 4250610633 0 349314969 2030031267
TS 1327510178.635000 2012-01-25T10:49:38
1 0 ram0 0 0 0 0 0 0 0 0 0 0 0
1 1 ram1 0 0 0 0 0 0 0 0 0 0 0
1 2 ram2 0 0 0 0 0 0 0 0 0 0 0
1 3 ram3 0 0 0 0 0 0 0 0 0 0 0
1 4 ram4 0 0 0 0 0 0 0 0 0 0 0
1 5 ram5 0 0 0 0 0 0 0 0 0 0 0
1 6 ram6 0 0 0 0 0 0 0 0 0 0 0
1 7 ram7 0 0 0 0 0 0 0 0 0 0 0
1 8 ram8 0 0 0 0 0 0 0 0 0 0 0
1 9 ram9 0 0 0 0 0 0 0 0 0 0 0
1 10 ram10 0 0 0 0 0 0 0 0 0 0 0
1 11 ram11 0 0 0 0 0 0 0 0 0 0 0
1 12 ram12 0 0 0 0 0 0 0 0 0 0 0
1 13 ram13 0 0 0 0 0 0 0 0 0 0 0
1 14 ram14 0 0 0 0 0 0 0 0 0 0 0
1 15 ram15 0 0 0 0 0 0 0 0 0 0 0
8 0 sda 85958345 9208182 2671393219 2437232103 534745448 846485919 11060948932 2055733196 0 545004122 197929059
8 1 sda1 5024 46400 6662 13324
8 2 sda2 23671288 753256530 918679759 3054471032
8 3 sda3 306655 2443289 529697 4237576
8 4 sda4 10 20 0 0
8 5 sda5 71211345 1915333340 462827377 3707259120
8 16 sdb 145329387 10397919 3590114436 2492237855 144339340 483516367 5022900552 109665847 0 699286940 2601866160
8 17 sdb1 155688199 3589800804 627862359 727932328
2 0 fd0 0 0 0 0 0 0 0 0 0 0 0
9 0 md0 0 0 0 0 0 0 0 0 0 0 0
253 0 dm-0 3698313 0 441982922 21577627 73403817 0 591870624 1142786151 0 43867870 1164431988
253 1 dm-1 67512604 0 1473349498 2074313873 389423586 0 3115388688 4250611498 0 349314984 2030032132
TS 1327510179.669000 2012-01-25T10:49:39
1 0 ram0 0 0 0 0 0 0 0 0 0 0 0
1 1 ram1 0 0 0 0 0 0 0 0 0 0 0
1 2 ram2 0 0 0 0 0 0 0 0 0 0 0
1 3 ram3 0 0 0 0 0 0 0 0 0 0 0
1 4 ram4 0 0 0 0 0 0 0 0 0 0 0
1 5 ram5 0 0 0 0 0 0 0 0 0 0 0
1 6 ram6 0 0 0 0 0 0 0 0 0 0 0
1 7 ram7 0 0 0 0 0 0 0 0 0 0 0
1 8 ram8 0 0 0 0 0 0 0 0 0 0 0
1 9 ram9 0 0 0 0 0 0 0 0 0 0 0
1 10 ram10 0 0 0 0 0 0 0 0 0 0 0
1 11 ram11 0 0 0 0 0 0 0 0 0 0 0
1 12 ram12 0 0 0 0 0 0 0 0 0 0 0
1 13 ram13 0 0 0 0 0 0 0 0 0 0 0
1 14 ram14 0 0 0 0 0 0 0 0 0 0 0
1 15 ram15 0 0 0 0 0 0 0 0 0 0 0
8 0 sda 85958345 9208182 2671393219 2437232103 534745448 846485919 11060948932 2055733196 0 545004122 197929059
8 1 sda1 5024 46400 6662 13324
8 2 sda2 23671288 753256530 918679759 3054471032
8 3 sda3 306655 2443289 529697 4237576
8 4 sda4 10 20 0 0
8 5 sda5 71211345 1915333340 462827377 3707259120
8 16 sdb 145329387 10397919 3590114436 2492237855 144339340 483516367 5022900552 109665847 0 699286940 2601866160
8 17 sdb1 155688199 3589800804 627862359 727932328
2 0 fd0 0 0 0 0 0 0 0 0 0 0 0
9 0 md0 0 0 0 0 0 0 0 0 0 0 0
253 0 dm-0 3698313 0 441982922 21577627 73403817 0 591870624 1142786151 0 43867870 1164431988
253 1 dm-1 67512604 0 1473349498 2074313873 389423586 0 3115388688 4250611498 0 349314984 2030032132
TS 1327510180.4705000 2012-01-25T10:49:40
1 0 ram0 0 0 0 0 0 0 0 0 0 0 0
1 1 ram1 0 0 0 0 0 0 0 0 0 0 0
1 2 ram2 0 0 0 0 0 0 0 0 0 0 0
1 3 ram3 0 0 0 0 0 0 0 0 0 0 0
1 4 ram4 0 0 0 0 0 0 0 0 0 0 0
1 5 ram5 0 0 0 0 0 0 0 0 0 0 0
1 6 ram6 0 0 0 0 0 0 0 0 0 0 0
1 7 ram7 0 0 0 0 0 0 0 0 0 0 0
1 8 ram8 0 0 0 0 0 0 0 0 0 0 0
1 9 ram9 0 0 0 0 0 0 0 0 0 0 0
1 10 ram10 0 0 0 0 0 0 0 0 0 0 0
1 11 ram11 0 0 0 0 0 0 0 0 0 0 0
1 12 ram12 0 0 0 0 0 0 0 0 0 0 0
1 13 ram13 0 0 0 0 0 0 0 0 0 0 0
1 14 ram14 0 0 0 0 0 0 0 0 0 0 0
1 15 ram15 0 0 0 0 0 0 0 0 0 0 0
8 0 sda 85958345 9208182 2671393219 2437232103 534745448 846485919 11060948932 2055733196 0 545004122 197929059
8 1 sda1 5024 46400 6662 13324
8 2 sda2 23671288 753256530 918679759 3054471032
8 3 sda3 306655 2443289 529697 4237576
8 4 sda4 10 20 0 0
8 5 sda5 71211345 1915333340 462827377 3707259120
8 16 sdb 145329387 10397919 3590114436 2492237855 144339340 483516367 5022900552 109665847 0 699286940 2601866160
8 17 sdb1 155688199 3589800804 627862359 727932328
2 0 fd0 0 0 0 0 0 0 0 0 0 0 0
9 0 md0 0 0 0 0 0 0 0 0 0 0 0
253 0 dm-0 3698313 0 441982922 21577627 73403817 0 591870624 1142786151 0 43867870 1164431988
253 1 dm-1 67512604 0 1473349498 2074313873 389423586 0 3115388688 4250611498 0 349314984 2030032132
TS 1327510181.1748000 2012-01-25T10:49:41
1 0 ram0 0 0 0 0 0 0 0 0 0 0 0
1 1 ram1 0 0 0 0 0 0 0 0 0 0 0
1 2 ram2 0 0 0 0 0 0 0 0 0 0 0
1 3 ram3 0 0 0 0 0 0 0 0 0 0 0
1 4 ram4 0 0 0 0 0 0 0 0 0 0 0
1 5 ram5 0 0 0 0 0 0 0 0 0 0 0
1 6 ram6 0 0 0 0 0 0 0 0 0 0 0
1 7 ram7 0 0 0 0 0 0 0 0 0 0 0
1 8 ram8 0 0 0 0 0 0 0 0 0 0 0
1 9 ram9 0 0 0 0 0 0 0 0 0 0 0
1 10 ram10 0 0 0 0 0 0 0 0 0 0 0
1 11 ram11 0 0 0 0 0 0 0 0 0 0 0
1 12 ram12 0 0 0 0 0 0 0 0 0 0 0
1 13 ram13 0 0 0 0 0 0 0 0 0 0 0
1 14 ram14 0 0 0 0 0 0 0 0 0 0 0
1 15 ram15 0 0 0 0 0 0 0 0 0 0 0
8 0 sda 85958345 9208182 2671393219 2437232103 534745448 846485919 11060948932 2055733196 0 545004122 197929059
8 1 sda1 5024 46400 6662 13324
8 2 sda2 23671288 753256530 918679759 3054471032
8 3 sda3 306655 2443289 529697 4237576
8 4 sda4 10 20 0 0
8 5 sda5 71211345 1915333340 462827377 3707259120
8 16 sdb 145329387 10397919 3590114436 2492237855 144339340 483516367 5022900552 109665847 0 699286940 2601866160
8 17 sdb1 155688199 3589800804 627862359 727932328
2 0 fd0 0 0 0 0 0 0 0 0 0 0 0
9 0 md0 0 0 0 0 0 0 0 0 0 0 0
253 0 dm-0 3698313 0 441982922 21577627 73403817 0 591870624 1142786151 0 43867870 1164431988
253 1 dm-1 67512604 0 1473349498 2074313873 389423586 0 3115388688 4250611498 0 349314984 2030032132
TS 1327510182.1766000 2012-01-25T10:49:42
1 0 ram0 0 0 0 0 0 0 0 0 0 0 0
1 1 ram1 0 0 0 0 0 0 0 0 0 0 0
1 2 ram2 0 0 0 0 0 0 0 0 0 0 0
1 3 ram3 0 0 0 0 0 0 0 0 0 0 0
1 4 ram4 0 0 0 0 0 0 0 0 0 0 0
1 5 ram5 0 0 0 0 0 0 0 0 0 0 0
1 6 ram6 0 0 0 0 0 0 0 0 0 0 0
1 7 ram7 0 0 0 0 0 0 0 0 0 0 0
1 8 ram8 0 0 0 0 0 0 0 0 0 0 0
1 9 ram9 0 0 0 0 0 0 0 0 0 0 0
1 10 ram10 0 0 0 0 0 0 0 0 0 0 0
1 11 ram11 0 0 0 0 0 0 0 0 0 0 0
1 12 ram12 0 0 0 0 0 0 0 0 0 0 0
1 13 ram13 0 0 0 0 0 0 0 0 0 0 0
1 14 ram14 0 0 0 0 0 0 0 0 0 0 0
1 15 ram15 0 0 0 0 0 0 0 0 0 0 0
8 0 sda 85958345 9208182 2671393219 2437232103 534745454 846485950 11060949228 2055733200 0 545004126 197929063
8 1 sda1 5024 46400 6662 13324
8 2 sda2 23671288 753256530 918679792 3054471296
8 3 sda3 306655 2443289 529697 4237576
8 4 sda4 10 20 0 0
8 5 sda5 71211345 1915333340 462827381 3707259152
8 16 sdb 145329387 10397919 3590114436 2492237855 144339340 483516367 5022900552 109665847 0 699286940 2601866160
8 17 sdb1 155688199 3589800804 627862359 727932328
2 0 fd0 0 0 0 0 0 0 0 0 0 0 0
9 0 md0 0 0 0 0 0 0 0 0 0 0 0
253 0 dm-0 3698313 0 441982922 21577627 73403817 0 591870624 1142786151 0 43867870 1164431988
253 1 dm-1 67512604 0 1473349498 2074313873 389423590 0 3115388720 4250611499 0 349314985 2030032133
TS 1327510183.843000 2012-01-25T10:49:43
1 0 ram0 0 0 0 0 0 0 0 0 0 0 0
1 1 ram1 0 0 0 0 0 0 0 0 0 0 0
1 2 ram2 0 0 0 0 0 0 0 0 0 0 0
1 3 ram3 0 0 0 0 0 0 0 0 0 0 0
1 4 ram4 0 0 0 0 0 0 0 0 0 0 0
1 5 ram5 0 0 0 0 0 0 0 0 0 0 0
1 6 ram6 0 0 0 0 0 0 0 0 0 0 0
1 7 ram7 0 0 0 0 0 0 0 0 0 0 0
1 8 ram8 0 0 0 0 0 0 0 0 0 0 0
1 9 ram9 0 0 0 0 0 0 0 0 0 0 0
1 10 ram10 0 0 0 0 0 0 0 0 0 0 0
1 11 ram11 0 0 0 0 0 0 0 0 0 0 0
1 12 ram12 0 0 0 0 0 0 0 0 0 0 0
1 13 ram13 0 0 0 0 0 0 0 0 0 0 0
1 14 ram14 0 0 0 0 0 0 0 0 0 0 0
1 15 ram15 0 0 0 0 0 0 0 0 0 0 0
8 0 sda 85958345 9208182 2671393219 2437232103 534745472 846486004 11060949804 2055733214 0 545004133 197929077
8 1 sda1 5024 46400 6662 13324
8 2 sda2 23671288 753256530 918679857 3054471816
8 3 sda3 306655 2443289 529697 4237576
8 4 sda4 10 20 0 0
8 5 sda5 71211345 1915333340 462827388 3707259208
8 16 sdb 145329387 10397919 3590114436 2492237855 144339341 483516380 5022900576 109665847 1 699286941 2601866161
8 17 sdb1 155688199 3589800804 627862374 727932448
2 0 fd0 0 0 0 0 0 0 0 0 0 0 0
9 0 md0 0 0 0 0 0 0 0 0 0 0 0
253 0 dm-0 3698313 0 441982922 21577627 73403824 0 591870680 1142786158 0 43867871 1164431995
253 1 dm-1 67512604 0 1473349498 2074313873 389423590 0 3115388720 4250611499 0 349314985 2030032133
TS 1327510183.999864000 2012-01-25T10:49:43
1 0 ram0 0 0 0 0 0 0 0 0 0 0 0
1 1 ram1 0 0 0 0 0 0 0 0 0 0 0
1 2 ram2 0 0 0 0 0 0 0 0 0 0 0
1 3 ram3 0 0 0 0 0 0 0 0 0 0 0
1 4 ram4 0 0 0 0 0 0 0 0 0 0 0
1 5 ram5 0 0 0 0 0 0 0 0 0 0 0
1 6 ram6 0 0 0 0 0 0 0 0 0 0 0
1 7 ram7 0 0 0 0 0 0 0 0 0 0 0
1 8 ram8 0 0 0 0 0 0 0 0 0 0 0
1 9 ram9 0 0 0 0 0 0 0 0 0 0 0
1 10 ram10 0 0 0 0 0 0 0 0 0 0 0
1 11 ram11 0 0 0 0 0 0 0 0 0 0 0
1 12 ram12 0 0 0 0 0 0 0 0 0 0 0
1 13 ram13 0 0 0 0 0 0 0 0 0 0 0
1 14 ram14 0 0 0 0 0 0 0 0 0 0 0
1 15 ram15 0 0 0 0 0 0 0 0 0 0 0
8 0 sda 85958345 9208182 2671393219 2437232103 534745472 846486004 11060949804 2055733214 0 545004133 197929077
8 1 sda1 5024 46400 6662 13324
8 2 sda2 23671288 753256530 918679857 3054471816
8 3 sda3 306655 2443289 529697 4237576
8 4 sda4 10 20 0 0
8 5 sda5 71211345 1915333340 462827388 3707259208
8 16 sdb 145329387 10397919 3590114436 2492237855 144339343 483516380 5022900680 109665849 0 699286942 2601866162
8 17 sdb1 155688199 3589800804 627862375 727932456
2 0 fd0 0 0 0 0 0 0 0 0 0 0 0
9 0 md0 0 0 0 0 0 0 0 0 0 0 0
253 0 dm-0 3698313 0 441982922 21577627 73403824 0 591870680 1142786158 0 43867871 1164431995
253 1 dm-1 67512604 0 1473349498 2074313873 389423590 0 3115388720 4250611499 0 349314985 2030032133
TS 1327510184.999903000 2012-01-25T10:49:44
1 0 ram0 0 0 0 0 0 0 0 0 0 0 0
1 1 ram1 0 0 0 0 0 0 0 0 0 0 0
1 2 ram2 0 0 0 0 0 0 0 0 0 0 0
1 3 ram3 0 0 0 0 0 0 0 0 0 0 0
1 4 ram4 0 0 0 0 0 0 0 0 0 0 0
1 5 ram5 0 0 0 0 0 0 0 0 0 0 0
1 6 ram6 0 0 0 0 0 0 0 0 0 0 0
1 7 ram7 0 0 0 0 0 0 0 0 0 0 0
1 8 ram8 0 0 0 0 0 0 0 0 0 0 0
1 9 ram9 0 0 0 0 0 0 0 0 0 0 0
1 10 ram10 0 0 0 0 0 0 0 0 0 0 0
1 11 ram11 0 0 0 0 0 0 0 0 0 0 0
1 12 ram12 0 0 0 0 0 0 0 0 0 0 0
1 13 ram13 0 0 0 0 0 0 0 0 0 0 0
1 14 ram14 0 0 0 0 0 0 0 0 0 0 0
1 15 ram15 0 0 0 0 0 0 0 0 0 0 0
8 0 sda 85958345 9208182 2671393219 2437232103 534745476 846486006 11060949852 2055733214 0 545004133 197929077
8 1 sda1 5024 46400 6662 13324
8 2 sda2 23671288 753256530 918679857 3054471816
8 3 sda3 306655 2443289 529697 4237576
8 4 sda4 10 20 0 0
8 5 sda5 71211345 1915333340 462827394 3707259256
8 16 sdb 145329387 10397919 3590114436 2492237855 144339343 483516380 5022900680 109665849 0 699286942 2601866162
8 17 sdb1 155688199 3589800804 627862375 727932456
2 0 fd0 0 0 0 0 0 0 0 0 0 0 0
9 0 md0 0 0 0 0 0 0 0 0 0 0 0
253 0 dm-0 3698313 0 441982922 21577627 73403830 0 591870728 1142786159 0 43867872 1164431996
253 1 dm-1 67512604 0 1473349498 2074313873 389423590 0 3115388720 4250611499 0 349314985 2030032133
TS 1327510185.999958000 2012-01-25T10:49:45
1 0 ram0 0 0 0 0 0 0 0 0 0 0 0
1 1 ram1 0 0 0 0 0 0 0 0 0 0 0
1 2 ram2 0 0 0 0 0 0 0 0 0 0 0
1 3 ram3 0 0 0 0 0 0 0 0 0 0 0
1 4 ram4 0 0 0 0 0 0 0 0 0 0 0
1 5 ram5 0 0 0 0 0 0 0 0 0 0 0
1 6 ram6 0 0 0 0 0 0 0 0 0 0 0
1 7 ram7 0 0 0 0 0 0 0 0 0 0 0
1 8 ram8 0 0 0 0 0 0 0 0 0 0 0
1 9 ram9 0 0 0 0 0 0 0 0 0 0 0
1 10 ram10 0 0 0 0 0 0 0 0 0 0 0
1 11 ram11 0 0 0 0 0 0 0 0 0 0 0
1 12 ram12 0 0 0 0 0 0 0 0 0 0 0
1 13 ram13 0 0 0 0 0 0 0 0 0 0 0
1 14 ram14 0 0 0 0 0 0 0 0 0 0 0
1 15 ram15 0 0 0 0 0 0 0 0 0 0 0
8 0 sda 85958350 9208182 2671393259 2437232181 534745670 846486098 11060952148 2055738921 0 545004273 197934862
8 1 sda1 5024 46400 6662 13324
8 2 sda2 23671288 753256530 918679857 3054471816
8 3 sda3 306655 2443289 529697 4237576
8 4 sda4 10 20 0 0
8 5 sda5 71211350 1915333380 462827681 3707261552
8 16 sdb 145329387 10397919 3590114436 2492237855 144339353 483516406 5022900968 109665858 0 699286947 2601866171
8 17 sdb1 155688199 3589800804 627862411 727932744
2 0 fd0 0 0 0 0 0 0 0 0 0 0 0
9 0 md0 0 0 0 0 0 0 0 0 0 0 0
253 0 dm-0 3698313 0 441982922 21577627 73403830 0 591870728 1142786159 0 43867872 1164431996
253 1 dm-1 67512609 0 1473349538 2074313951 389423877 0 3115391016 4250618205 0 349315125 2030038917
TS 1327510186.999984000 2012-01-25T10:49:46
1 0 ram0 0 0 0 0 0 0 0 0 0 0 0
1 1 ram1 0 0 0 0 0 0 0 0 0 0 0
1 2 ram2 0 0 0 0 0 0 0 0 0 0 0
1 3 ram3 0 0 0 0 0 0 0 0 0 0 0
1 4 ram4 0 0 0 0 0 0 0 0 0 0 0
1 5 ram5 0 0 0 0 0 0 0 0 0 0 0
1 6 ram6 0 0 0 0 0 0 0 0 0 0 0
1 7 ram7 0 0 0 0 0 0 0 0 0 0 0
1 8 ram8 0 0 0 0 0 0 0 0 0 0 0
1 9 ram9 0 0 0 0 0 0 0 0 0 0 0
1 10 ram10 0 0 0 0 0 0 0 0 0 0 0
1 11 ram11 0 0 0 0 0 0 0 0 0 0 0
1 12 ram12 0 0 0 0 0 0 0 0 0 0 0
1 13 ram13 0 0 0 0 0 0 0 0 0 0 0
1 14 ram14 0 0 0 0 0 0 0 0 0 0 0
1 15 ram15 0 0 0 0 0 0 0 0 0 0 0
8 0 sda 85958350 9208182 2671393259 2437232181 534745670 846486098 11060952148 2055738921 0 545004273 197934862
8 1 sda1 5024 46400 6662 13324
8 2 sda2 23671288 753256530 918679857 3054471816
8 3 sda3 306655 2443289 529697 4237576
8 4 sda4 10 20 0 0
8 5 sda5 71211350 1915333380 462827681 3707261552
8 16 sdb 145329387 10397919 3590114436 2492237855 144339353 483516406 5022900968 109665858 0 699286947 2601866171
8 17 sdb1 155688199 3589800804 627862411 727932744
2 0 fd0 0 0 0 0 0 0 0 0 0 0 0
9 0 md0 0 0 0 0 0 0 0 0 0 0 0
253 0 dm-0 3698313 0 441982922 21577627 73403830 0 591870728 1142786159 0 43867872 1164431996
253 1 dm-1 67512609 0 1473349538 2074313951 389423877 0 3115391016 4250618205 0 349315125 2030038917