X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Ftests%2Frename.pl;h=dd6b5dc15874e06b555571308639a9c4b0faab76;hp=3ba9368489e1a0c75fb7fd9dbceb7be7975a078b;hb=78057a4d3b156ab2902e7b761f9b98cb3542d09e;hpb=93acd158c57c4c5d0fc751d46741231490c04707 diff --git a/lustre/tests/rename.pl b/lustre/tests/rename.pl index 3ba9368..dd6b5dc 100644 --- a/lustre/tests/rename.pl +++ b/lustre/tests/rename.pl @@ -1,78 +1,210 @@ -#!/usr/bin/perl +#!/usr/bin/perl -w use strict; +$|++; + +$ENV{PATH}="/bin:/usr/bin"; +$ENV{ENV}=""; +$ENV{BASH_ENV}=""; + use diagnostics; use Getopt::Long; +use POSIX ":sys_wait_h"; -sub usage () { - print "Usage: $0 \n"; - print "example: $0 --count=2 /mnt/lustre 50\n"; - print " will test in /mnt/lustre1 and /mnt/lustre2\n"; - print " $0 --count=0 /mnt/lustre 50\n"; - print " will test in /mnt/lustre only\n"; - exit; -} -my ($j, $k, $d, $f1, $f2, $path, $silent); -my $count = 0; -my $create = 10; +use vars qw( + $MAX_THREADS + $SCRIPT_NAME + ); + +# Don't try to run more than this many threads concurrently. +$MAX_THREADS = 16; + +$SCRIPT_NAME = "rename.pl"; + +# Initialize variables +my $silent = 0; +my $create_files = 1; # should we create files or not? +my $use_mcreate = 1; # should we use mcreate or open? +my $num_dirs = 3; # number of directories to create +my $num_files = 6; # number of files to create +my $iterations = 1; +my $num_threads = 1; +my $mountpt; +my $num_mounts = -1; GetOptions("silent!"=> \$silent, - "count=i" => \$count, - "create=i" => \$create); + "use_mcreate=i" => \$use_mcreate, + "create_files=i" => \$create_files, + "use_mcreate=i" => \$use_mcreate, + "num_files=i" => \$num_files, + "num_dirs=i" => \$num_dirs, + "mountpt=s" => \$mountpt, + "num_mounts=i" => \$num_mounts, + "iterations=i" => \$iterations, + "num_threads=i" => \$num_threads, + ) || die &usage; -my $mtpt = shift || usage(); -my $i = shift || usage(); -my $total = $i; -my $files = 6; -my $dirs = 3; -my $mcreate = 0; # should we use mcreate or open? +# Check for mandatory args. +if (!$mountpt || + !$num_mounts) { + die &usage; +} -my $which = ""; -if ($count > 0) { - $which = int(rand() * $count) + 1; +if ($num_threads > $MAX_THREADS) { + print "\nMAX_THREADS is currently set to $MAX_THREADS.\n\n"; + print "You will have to change this in the source\n"; + print "if you really want to run with $num_threads threads.\n\n"; + exit 1; } -$k = $dirs; -if ($create == 0) { - $k = 0; +# Initialize rand() function. +srand (time ^ $$ ^ unpack "%L*", `ps axww | gzip`); + +######################################################################### +### MAIN + +my $which = ""; +if ($num_mounts > 0) { + $which = int(rand() * $num_mounts) + 1; } -while ($k--) { - $path = "$mtpt$which/$k"; - my $rc = mkdir $path, 0755; - print "mkdir $path failed: $!\n" if !$rc; - $j = $files; - while ($j--) { - `./mcreate $path/$j`; + +# Create files and directories (if necessary) +if ($create_files) { + for (my $i=1; $i<=$num_threads;$i++) { + for (my $j=0; $j<$num_dirs;$j++) { + my $path = "${mountpt}${which}/${i}.${j}"; + mkdir $path, 0755 || die "Can't mkdir $path: $!\n"; + for (my $k=0; $k<$num_files; $k++) { + my $filepath = "${path}/${k}"; + &create_file($filepath); + if (! -e $filepath) { + die "Error creating $filepath\n"; + } + } + } } } -while ($i--) { - my $which = ""; - if ($count > 0) { - $which = int(rand() * $count) + 1; - } - $d = int(rand() * $dirs); - $f1 = int(rand() * $files); - $f2 = int(rand() * $files); - print "[$$] $mtpt$which/$d/$f1 $mtpt$which/$d/$f2 ...\n" if !$silent; - my $rc = rename "$mtpt$which/$d/$f1", "$mtpt$which/$d/$f2"; - print "[$$] done: $rc\n" if !$silent; - if (($total - $i) % 100 == 0) { - print STDERR "[" . $$ . "]" . ($total - $i) . " operations\n"; +for (my $i=1; $i<=$num_threads; $i++) { + my $status = &fork_and_rename($i); + last if ($status != 0); +} + +# Wait for all our threads to finish. +# Wait for all our threads to finish. +my $child = 0; +do { + $child = waitpid(-1, 0); +} until $child > 0; +sleep 1; + +# Unlink files and directories (if necessary) +if ($create_files) { + for (my $i=1; $i<=$num_threads;$i++) { + for (my $j=0; $j<$num_dirs;$j++) { + my $path = "${mountpt}${which}/${i}.${j}"; + for (my $k=0; $k<=$num_files; $k++) { + my $filepath = "${path}/${k}"; + unlink("$filepath") if (-e $filepath); + } + my $rc = rmdir $path; + print "$SCRIPT_NAME - rmdir $path failed: $!\n" if !$rc; + } } } -$k = $dirs; -if ($create == 0) { - $k = 0; +exit 0; + +######################################################################### +### SUBROUTINES + +sub usage () { + print "\nUsage: $0 [--silent] [--create_files=n] [--use_mcreate=n] [--num_dirs=n] [--num_files=n] [--iterations=n] [--num_threads=n] --num_mounts=n --mountpt=/path/to/lustre/mount\n\n"; + print "\t--silent\tminimal output\n"; + print "\t--create_files=n\create files at start, default=1 (yes)\n"; + print "\t--use_mcreate=n\tuse mcreate to create files, default=1 (yes)\n"; + print "\t--num_dirs=n\tnumber of directories to create per iteration, default=3\n"; + print "\t--num_files=n\tnumber of files to create per directory, default=6\n"; + print "\t--iterations=n\tnumber of iterations to perform, default=1\n"; + print "\t--num_threads=n\tnumber of thread to run, default=1\n"; + print "\t--mountpt\tlocation of lustre mount\n"; + print "\t--num_mounts=n\tnumber of lustre mounts to test across, default=-1 (single mount point without numeric suffix)\n\n"; + print "example: $0 --mountpt=/mnt/lustre --num_mounts=2 --iterations=50\n"; + print " will perform 50 interations in /mnt/lustre1 and /mnt/lustre2\n"; + print " $0 --mountpt=/mnt/lustre --num_mounts=-1 --iterations=50\n"; + print " will perform 50 iterations in /mnt/lustre only\n\n"; + exit; } -while ($k--) { - $path = "$mtpt$which/$k"; - $j = $files; - while ($j--) { - unlink "$path/$j"; + + +######################################################################### +sub create_file ($) { + my ($path) = @_;; + + if (-e $path) { + warn "$path already exists!\n"; + return 1; + } + + if ($use_mcreate) { + my $tmp = `./mcreate $path`; + if ($tmp =~ /.*error: (.*)\n/) { + die "Error mcreating $path: $!\n"; + } + } else { + open(FH, ">$path") || die "Error opening $path: $!\n"; + close(FH) || die; } - my $rc = rmdir $path; - print "rmdir $path failed: $!\n" if !$rc; + return 0; } -print "Done.\n"; +######################################################################### +sub fork_and_rename ($) { + my ($thread_num) = @_; + + FORK: { + if (my $pid = fork) { + # parent here + # child process pid is available in $pid + return 0; + } elsif (defined $pid) { # $pid is zero here if defined + + my $current_iteration=1; + while ($current_iteration <= $iterations) { + for (my $i=0; $i<$num_files; $i++) { + my $which = ""; + if ($num_mounts > 0) { + $which = int(rand() * $num_mounts) + 1; + } + + my $d = int(rand() * $num_dirs); + my $f1 = int(rand() * $num_files); + my $f2 = int(rand() * $num_files); + my $path_f1 = "${mountpt}${which}/${thread_num}.${d}/${f1}"; + my $path_f2 = "${mountpt}${which}/${thread_num}.${d}/${f2}"; + + print "$SCRIPT_NAME - Thread $thread_num: [$$] $path_f1 $path_f2 ...\n" if !$silent; + my $rc = rename $path_f1, $path_f2; + print "$SCRIPT_NAME - Thread $thread_num: [$$] done: $rc\n" if !$silent; + } + if (($current_iteration) % 100 == 0) { + print "$SCRIPT_NAME - Thread $thread_num: " . $current_iteration . " operations [" . $$ . "]\n"; + + } + $current_iteration++; + } + + print "$SCRIPT_NAME - Thread $thread_num: Done.\n"; + + exit 0; + + } elsif ($! =~ /No more process/) { + # EAGAIN, supposedly recoverable fork error + sleep 5; + redo FORK; + } else { + # weird fork error + die "Can't fork: $!\n"; + } + } + +}