Whamcloud - gitweb
LU-160 Reduce OST size requirement for test 155
[fs/lustre-release.git] / lustre / tests / rename.pl
1 #!/usr/bin/perl -w
2 use strict;
3 $|++;
4
5 $ENV{PATH}="/bin:/usr/bin";
6 $ENV{ENV}="";
7 $ENV{BASH_ENV}="";
8
9 use diagnostics;
10 use Getopt::Long;
11 use POSIX ":sys_wait_h";
12
13 use vars qw(
14             $MAX_THREADS
15             $SCRIPT_NAME
16             );
17  
18 # Don't try to run more than this many threads concurrently.
19 $MAX_THREADS = 16;
20
21 $SCRIPT_NAME = "rename.pl";
22
23 # Initialize variables
24 my $silent = 0;
25 my $create_files = 1; # should we create files or not?
26 my $use_mcreate = 1;  # should we use mcreate or open?
27 my $num_dirs = 3;     # number of directories to create
28 my $num_files = 6;    # number of files to create
29 my $iterations = 1;
30 my $num_threads = 1;
31 my $mountpt;
32 my $num_mounts = -1;
33
34 GetOptions("silent!"=> \$silent,
35            "use_mcreate=i" => \$use_mcreate,
36            "create_files=i" => \$create_files,
37            "use_mcreate=i" => \$use_mcreate,
38            "num_files=i" => \$num_files,
39            "num_dirs=i" => \$num_dirs,
40            "mountpt=s" => \$mountpt,
41            "num_mounts=i" => \$num_mounts,
42            "iterations=i" => \$iterations,
43            "num_threads=i" => \$num_threads,
44            ) || die &usage;
45
46 # Check for mandatory args.
47 if (!$mountpt ||
48     !$num_mounts) {
49     die &usage;
50 }
51
52 if ($num_threads > $MAX_THREADS) {
53     print "\nMAX_THREADS is currently set to $MAX_THREADS.\n\n";
54     print "You will have to change this in the source\n";
55     print "if you really want to run with $num_threads threads.\n\n";
56     exit 1;
57 }
58
59 # Initialize rand() function.
60 srand (time ^ $$ ^ unpack "%L*", `ps axww | gzip`);
61
62 #########################################################################
63 ### MAIN
64
65 my $which = "";
66 if ($num_mounts > 0) {
67     $which = int(rand() * $num_mounts) + 1;
68 }
69
70 # Create files and directories (if necessary)
71 if ($create_files) {
72     for (my $i=1; $i<=$num_threads;$i++) {
73         for (my $j=0; $j<$num_dirs;$j++) {
74             my $path = "${mountpt}${which}/${i}.${j}";
75             mkdir $path, 0755 || die "Can't mkdir $path: $!\n";
76             for (my $k=0; $k<$num_files; $k++) {
77                 my $filepath = "${path}/${k}";
78                 &create_file($filepath);
79                 if (! -e $filepath) {
80                     die "Error creating $filepath\n";
81                 }
82             }
83         }
84     }
85 }
86
87 for (my $i=1; $i<=$num_threads; $i++) {
88     my $status = &fork_and_rename($i);
89     last if ($status != 0);
90 }
91
92 # Wait for all our threads to finish.
93 # Wait for all our threads to finish.
94 my $child = 0;
95 do {
96     $child = waitpid(-1, 0);
97 } until $child > 0;
98 sleep 1;
99
100 # Unlink files and directories (if necessary)
101 if ($create_files) {
102     for (my $i=1; $i<=$num_threads;$i++) {
103         for (my $j=0; $j<$num_dirs;$j++) {
104             my $path = "${mountpt}${which}/${i}.${j}";
105             for (my $k=0; $k<=$num_files; $k++) {
106                 my $filepath = "${path}/${k}";
107                 unlink("$filepath") if (-e $filepath);
108             }
109             my $rc = rmdir $path;
110             print "$SCRIPT_NAME - rmdir $path failed: $!\n" if !$rc;        
111         }
112     }
113 }
114
115 exit 0;
116
117 #########################################################################
118 ### SUBROUTINES
119
120 sub usage () {
121     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";
122     print "\t--silent\tminimal output\n";
123     print "\t--create_files=n\create files at start, default=1 (yes)\n";
124     print "\t--use_mcreate=n\tuse mcreate to create files, default=1 (yes)\n";
125     print "\t--num_dirs=n\tnumber of directories to create per iteration, default=3\n";
126     print "\t--num_files=n\tnumber of files to create per directory, default=6\n";
127     print "\t--iterations=n\tnumber of iterations to perform, default=1\n";
128     print "\t--num_threads=n\tnumber of thread to run, default=1\n";
129     print "\t--mountpt\tlocation of lustre mount\n";
130     print "\t--num_mounts=n\tnumber of lustre mounts to test across, default=-1 (single mount point without numeric suffix)\n\n";
131     print "example: $0 --mountpt=/mnt/lustre --num_mounts=2 --iterations=50\n";
132     print "         will perform 50 interations in /mnt/lustre1 and /mnt/lustre2\n";
133     print "         $0 --mountpt=/mnt/lustre --num_mounts=-1 --iterations=50\n";
134     print "         will perform 50 iterations in /mnt/lustre only\n\n";
135     exit;
136 }
137
138
139 #########################################################################
140 sub create_file ($) {
141     my ($path) = @_;;
142     
143     if (-e $path) {
144         warn "$path already exists!\n";
145         return 1;
146     }
147
148     if ($use_mcreate) {
149         my $tmp = `./mcreate $path`;
150         if ($tmp =~ /.*error: (.*)\n/) {
151             die "Error mcreating $path: $!\n";
152         }
153     } else {
154         open(FH, ">$path") || die "Error opening $path: $!\n";
155         close(FH) || die;
156     }
157     return 0;
158 }
159
160 #########################################################################
161 sub fork_and_rename ($) {
162     my ($thread_num) = @_;
163     
164   FORK: {
165       if (my $pid = fork) {
166           # parent here
167           # child process pid is available in $pid
168           return 0;
169       } elsif (defined $pid) { # $pid is zero here if defined
170           
171           my $current_iteration=1;
172           while ($current_iteration <= $iterations) {
173               for (my $i=0; $i<$num_files; $i++) {
174                   my $which = "";
175                   if ($num_mounts > 0) {
176                       $which = int(rand() * $num_mounts) + 1;
177                   }
178                   
179                   my $d = int(rand() * $num_dirs);
180                   my $f1 = int(rand() * $num_files);
181                   my $f2 = int(rand() * $num_files);
182                   my $path_f1 = "${mountpt}${which}/${thread_num}.${d}/${f1}";
183                   my $path_f2 = "${mountpt}${which}/${thread_num}.${d}/${f2}";
184                   
185                   print "$SCRIPT_NAME - Thread $thread_num: [$$] $path_f1 $path_f2 ...\n" if !$silent;
186                   my $rc = rename $path_f1, $path_f2;
187                   print "$SCRIPT_NAME - Thread $thread_num: [$$] done: $rc\n" if !$silent;
188               }
189               if (($current_iteration) % 100 == 0) {
190                   print "$SCRIPT_NAME - Thread $thread_num: " . $current_iteration . " operations [" . $$ . "]\n";
191                   
192               }
193               $current_iteration++;
194           }
195
196           print "$SCRIPT_NAME - Thread $thread_num: Done.\n";
197
198           exit 0;
199
200       } elsif ($! =~ /No more process/) {
201           # EAGAIN, supposedly recoverable fork error
202           sleep 5;
203           redo FORK;
204       } else {
205           # weird fork error
206           die "Can't fork: $!\n";
207       }
208   }
209     
210 }