#!/usr/bin/perl
#testing fs performance with various kernel parameters
#nat@makarevitch.org
#WTFPL (http://sam.zoy.org/wtfpl/)

use strict;
use warnings;

## Parameters  BEGIN

##Beware: ALL combinations values will be tested
my $testset='/home/nat/test1';

#my @iosched_values=qw{ noop deadline cfq };
my @iosched_values=qw{ deadline };
#CFQ: use explicit prioritization!

my @queuedepth_values=qw{254};

#read-ahead: KB, not blocks
#my @ra_values=qw{0 4096 8192 16384};
my @ra_values=qw{2048};

#my @nrreq_values=qw{32 512 2048 8192};
my @nrreq_values=qw{3848 1024 254};

my @maxsec_values=qw{64 32 128};

#my @fifo_values=qw{32 128 256};
my @fifo_values=qw{32 256 768};

#parameters   END

my($fifo,$ra,$nrreq,$max_sec,$iosched,$maxsec,$queuedepth);

my $outputfilename;

sub gosys($) {
  my $str = shift;

  print "Doing $str\n";
  system 'sync';
  system($str);
  system 'sync';
  sleep 2;
}

sub CantPutval($$) {
my $val=shift;
my $where=shift;
my $readval;

open(FIL, "<$where") || die "Can't open $where: $!";
$readval=<FIL>;
chomp($readval);
close(FIL);

#print STDERR "DEBUG CantPutval: $where, target $val, read $readval\n";

return 0 if ($readval eq $val);

gosys("sudo bash -c 'echo $val > $where'");

open(FIL, "<$where") || die "Can't open $where: $!";
$readval=<FIL>;
chomp($readval);
close(FIL);

return 0 if ($readval eq $val);

print STDERR "DEBUG CantPutval: cannot put $val into $where\n";

return 1;
}

#TODO: suboptimal car 'sudos' effectués mm si inutiles, il faudrait ne faire que le strict nécessaire donc
#conserver jeu des anciennes valeurs et ne les écraser 'sudo' que si nécessaire
foreach $iosched (0..$#iosched_values) {

  gosys("sudo bash -c 'echo $iosched_values[$iosched] > /sys/block/sda/queue/scheduler'");

foreach $queuedepth (0..$#queuedepth_values)
{
    next if CantPutval($queuedepth_values[$queuedepth], '/sys/block/sda/device/queue_depth');

foreach $maxsec (0..$#maxsec_values)
{
    next if CantPutval($maxsec_values[$maxsec], '/sys/block/sda/queue/max_sectors_kb');

   foreach $ra (0..$#ra_values) {

#     gosys("sudo /sbin/blockdev --setra $ra_values[$ra] /dev/sda");
    next if CantPutval($ra_values[$ra], '/sys/block/sda/queue/read_ahead_kb');

     foreach $nrreq (0..$#nrreq_values) {

       next if CantPutval($nrreq_values[$nrreq], '/sys/block/sda/queue/nr_requests');

       foreach $fifo (0..$#fifo_values) {

         next if CantPutval($fifo_values[$fifo], '/sys/block/sda/queue/iosched/fifo_batch');

          $outputfilename= $testset . '/sched-' . $iosched_values[$iosched] . '_queuedepth-' . $queuedepth_values[$queuedepth] . '_RA-' . $ra_values[$ra] . '_nrreq-' . $nrreq_values[$nrreq] . '_maxsec-' . $maxsec_values[$maxsec] . '_fifo-' . $fifo_values[$fifo] . '.iotest-result';

#          print "$iosched_values[$iosched], queue depth: $queuedepth_values[$queuedepth], RA: $ra_values[$ra], nr req: $nrreq_values[$nrreq], fifo: $fifo_values[$fifo] ($outputfilename)\n";

          if (-e $outputfilename) {
            print STDERR "$outputfilename already exists.  Skip!\n";
            next;
            }

       system("./test_io >& $outputfilename");
}}}}}}