Whamcloud - gitweb
LU-5810 tests: add client hostname to lctl mark
[fs/lustre-release.git] / lustre / tests / create.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 use POSIX ":sys_wait_h";
9
10 use diagnostics;
11 use Getopt::Long;
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 = "create.pl";
22
23 # Initialize variables
24 my $silent = 0;
25 my $use_mcreate = 1; # should we use mcreate or open?
26 my $num_files = 5;   # number of files to create
27 my $iterations = 1;
28 my $num_threads = 1;
29 my $mountpt;
30 my $num_mounts = -1;
31
32 # Get options from the command line.
33 GetOptions("silent!" => \$silent,
34            "use_mcreate=i" => \$use_mcreate,
35            "num_files=i" => \$num_files,
36            "mountpt=s" => \$mountpt,
37            "num_mounts=i" => \$num_mounts,
38            "iterations=i" => \$iterations,
39            "num_threads=i" => \$num_threads,
40            ) || die &usage;
41
42 # Check for mandatory args.
43 if (!$mountpt || 
44     !$num_mounts) {
45     die &usage;
46 }
47
48 if ($num_threads > $MAX_THREADS) {
49     print "\nMAX_THREADS is currently set to $MAX_THREADS.\n\n";
50     print "You will have to change this in the source\n";
51     print "if you really want to run with $num_threads threads.\n\n";
52     exit 1;
53 }
54
55 # Initialize rand() function.
56 srand (time ^ $$ ^ unpack "%L*", `ps axww | gzip`);
57
58 #########################################################################
59 ### MAIN
60
61 for (my $i=1; $i<=$num_threads; $i++) {
62     my $status = &fork_and_create($i);
63     last if ($status != 0);
64 }
65
66 # Wait for all our threads to finish.
67 my $child = 0;
68 do {
69     $child = waitpid(-1, WNOHANG);
70 } until $child > 0;
71 sleep 1;
72
73 exit 0;
74
75 #########################################################################
76 ### SUBROUTINES
77
78 sub usage () {
79     print "\nUsage: $0 [--silent] [--use_mcreate=n] [--num_files=n] [--iterations=n] [--num_threads=n] --mountpt=/path/to/lustre/mount --num_mounts=n\n\n";
80     print "\t--silent\tminimal output\n";
81     print "\t--use_mcreate=n\tuse mcreate to create files, default=1 (yes)\n";
82     print "\t--num_files=n\tnumber of files to create per iteration, default=5\n";
83     print "\t--iterations=n\tnumber of iterations to perform, default=1\n";
84     print "\t--num_threads=n\tnumber of thread to run, default=1\n";
85     print "\t--mountpt\tlocation of lustre mount\n";
86     print "\t--num_mounts=n\tnumber of lustre mounts to test across, default=-1 (single mount point without numeric suffix)\n\n";
87     print "example: $0 --mountpt=/mnt/lustre --num_mounts=2 --iterations=50\n";
88         print "         will perform 50 iterations in /mnt/lustre1 and /mnt/lustre2\n";
89     print "         $0 --mountpt=/mnt/lustre --num_mounts=-1 --iterations=50\n";
90     print "         will perform 50 iterations in /mnt/lustre only\n\n";
91     exit;
92 }
93
94 #########################################################################
95 sub fork_and_create ($) {
96     my ($thread_num) = @_;
97     
98   FORK: {
99       if (my $pid = fork) {
100           # parent here
101           # child process pid is available in $pid
102           return 0;
103       } elsif (defined $pid) { # $pid is zero here if defined
104           my $current_iteration=1;
105           while ($current_iteration <= $iterations) {
106               for (my $i=1; $i<=$num_files; $i++) {
107                   my $which = "";
108                   if ($num_mounts > 0) {
109                       $which = int(rand() * $num_mounts) + 1;
110                   }
111                   my $d = int(rand() * $num_files);
112                   do_open("${mountpt}${which}/thread${thread_num}.${d}");
113                   
114                   if ($num_mounts > 0) {
115                       $which = int(rand() * $num_mounts) + 1;
116                   }
117                   $d = int(rand() * $num_files);
118                   my $path = "${mountpt}${which}/thread${thread_num}.${d}";
119                   print  "$SCRIPT_NAME - Thread $thread_num: Unlink $path start [" . $$."]...\n" if !$silent;
120                   if (unlink($path)) {
121                       print "$SCRIPT_NAME - Thread $thread_num: Unlink done [$$] $path: Success\n" if !$silent;
122                   } else {
123                       print "$SCRIPT_NAME - Thread $thread_num: Unlink done [$$] $path: $!\n"if !$silent;
124                   }
125               }
126               if (($current_iteration) % 100 == 0) {
127                   print "$SCRIPT_NAME - Thread $thread_num: " . $current_iteration . " operations [" . $$ . "]\n";
128               }
129               $current_iteration++;
130           }
131           
132           my $which = "";
133           if ($num_mounts > 0) {
134               $which = int(rand() * $num_mounts) + 1;
135           }
136           for (my $d = 0; $d < $num_files; $d++) {
137               my $path = "${mountpt}${which}/thread${thread_num}.${d}";
138               unlink("$path") if (-e $path);
139           }
140           
141           print "$SCRIPT_NAME - Thread $thread_num: Done.\n";
142           
143           exit 0;
144
145       } elsif ($! =~ /No more process/) {
146           # EAGAIN, supposedly recoverable fork error
147           sleep 5;
148           redo FORK;
149       } else {
150           # weird fork error
151           die "Can't fork: $!\n";
152       }
153   }
154
155 }
156
157 #########################################################################
158
159 sub do_open ($) {
160     my ($path) = @_;;
161
162     if ($use_mcreate) {
163         my $tmp = `./mcreate $path`;
164         if ($tmp) {
165             print  "$SCRIPT_NAME - Creating $path [" . $$."]...\n" if !$silent;
166             $tmp =~ /.*error: (.*)\n/;
167             print  "$SCRIPT_NAME - Create done [$$] $path: $!\n" if !$silent;
168         } else {
169             print  "$SCRIPT_NAME - Create done [$$] $path: Success\n"if !$silent;
170         }
171     } else {
172         print  "$SCRIPT_NAME - Opening $path [" . $$."]...\n"if !$silent;
173         open(FH, ">$path") || die "open($path: $!";
174         print  "$SCRIPT_NAME - Open done [$$] $path: Success\n"if !$silent;
175         close(FH) || die;
176     }
177 }
178