1 5184 ek110237 #!/usr/bin/perl 2 5184 ek110237 # 3 5184 ek110237 # CDDL HEADER START 4 5184 ek110237 # 5 5184 ek110237 # The contents of this file are subject to the terms of the 6 5184 ek110237 # Common Development and Distribution License (the "License"). 7 5184 ek110237 # You may not use this file except in compliance with the License. 8 5184 ek110237 # 9 5184 ek110237 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 5184 ek110237 # or http://www.opensolaris.org/os/licensing. 11 5184 ek110237 # See the License for the specific language governing permissions 12 5184 ek110237 # and limitations under the License. 13 5184 ek110237 # 14 5184 ek110237 # When distributing Covered Code, include this CDDL HEADER in each 15 5184 ek110237 # file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 5184 ek110237 # If applicable, add the following below this CDDL HEADER, with the 17 5184 ek110237 # fields enclosed by brackets "[]" replaced with your own identifying 18 5184 ek110237 # information: Portions Copyright [yyyy] [name of copyright owner] 19 5184 ek110237 # 20 5184 ek110237 # CDDL HEADER END 21 5184 ek110237 # 22 5184 ek110237 # 23 9326 Andrew # Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 5184 ek110237 # Use is subject to license terms. 25 5184 ek110237 # 26 5184 ek110237 27 5184 ek110237 use POSIX; 28 7736 Andrew use Socket; 29 5184 ek110237 30 7736 Andrew my $MULTI_CLIENT = 0; 31 5184 ek110237 my $USE_XANADU = 0; 32 5184 ek110237 my $TIMEOUT = 60; 33 7736 Andrew my $EOL = "\n"; 34 5184 ek110237 my $FILEBENCH = "/usr/benchmarks/filebench"; 35 9513 Andrew my $PROG = "bin/go_filebench"; 36 7736 Andrew my $SHAREDFILEALLOCATOR; 37 7736 Andrew my $TARGETPATH; 38 7736 Andrew my $TARGETDIR; 39 7736 Andrew my $FB_MASTERPATH; 40 7736 Andrew my $STATSBASE; 41 7736 Andrew my $CONFNAME; 42 5184 ek110237 my $FSCRIPT; 43 5184 ek110237 my $SCRIPT_NO; 44 7736 Andrew my @CLIENTLIST = (); 45 7736 Andrew my %CLIENTHASH = (); 46 5184 ek110237 my @CONFLIST; 47 7736 Andrew my %MULTIDATA = (); 48 9513 Andrew my %CMDLINEDATA = (); 49 5184 ek110237 my %DEFDATA = (); 50 5184 ek110237 my %CONFDATA = (); 51 5184 ek110237 my %STATSHASH = (); 52 9513 Andrew my $OPTIONFLAGS = "cleanupstorage dofscheck"; 53 5184 ek110237 @ext_stats=(); 54 5184 ek110237 @file_stats=(); 55 5184 ek110237 @arg_stats=(); 56 5184 ek110237 @pid_arr=(); 57 5184 ek110237 58 5184 ek110237 # The following if test caters for running benchpoint from an alternative path 59 5184 ek110237 #if (-r $ENV{"FILEBENCH") { 60 5184 ek110237 # $FILEBENCH = $ENV{"FILEBENCH"}; 61 5184 ek110237 #} 62 5184 ek110237 63 5184 ek110237 ############################################################################## 64 5184 ek110237 ## Configuration hash data operations 65 5184 ek110237 ############################################################################## 66 5184 ek110237 67 5184 ek110237 # This sub allows a function program to extract the base directory for filebench 68 5184 ek110237 sub get_FILEBENCH { 69 5184 ek110237 return ($FILEBENCH); 70 5184 ek110237 } 71 5184 ek110237 72 5184 ek110237 sub get_STATSBASE { 73 5184 ek110237 return ($STATSBASE); 74 5184 ek110237 } 75 5184 ek110237 76 5184 ek110237 sub get_CONFNAME { 77 5184 ek110237 return ($CONFNAME); 78 5184 ek110237 } 79 5184 ek110237 80 7736 Andrew sub multi_putval { 81 7736 Andrew my ($key) = shift; 82 7736 Andrew my ($val) = shift; 83 7736 Andrew @{MULTIDATA{$key}} = (); 84 7736 Andrew push(@{ $MULTIDATA{$key} }, $val); 85 7736 Andrew } 86 7736 Andrew 87 7736 Andrew sub multi_getval { 88 7736 Andrew my ($key) = shift; 89 7736 Andrew return ("@{$MULTIDATA{$key}}"); 90 7736 Andrew } 91 7736 Andrew 92 7736 Andrew sub multi_exists { 93 7736 Andrew my ($key) = shift; 94 7736 Andrew if (exists($MULTIDATA{$key})) { 95 7736 Andrew return (1); 96 7736 Andrew } 97 7736 Andrew return (0); 98 5184 ek110237 } 99 5184 ek110237 100 5184 ek110237 sub conf_getval { 101 5184 ek110237 my ($key) = shift; 102 5184 ek110237 return ("@{$CONFDATA{$key}}"); 103 5184 ek110237 } 104 5184 ek110237 105 5184 ek110237 sub conf_reqval { 106 5184 ek110237 my ($key) = shift; 107 5184 ek110237 108 5184 ek110237 if (exists($CONFDATA{$key})) { 109 5184 ek110237 return ("@{$CONFDATA{$key}}"); 110 5184 ek110237 } 111 5184 ek110237 print "ERROR: required key \"$key\" missing from configuration\n"; 112 5184 ek110237 exit(1); 113 5184 ek110237 } 114 5184 ek110237 115 5184 ek110237 sub conf_exists { 116 5184 ek110237 my ($key) = shift; 117 5184 ek110237 if (exists($CONFDATA{$key})) { 118 5184 ek110237 return (1); 119 5184 ek110237 } 120 5184 ek110237 return (0); 121 5184 ek110237 } 122 5184 ek110237 123 5184 ek110237 sub conf_hash { 124 5184 ek110237 return(%CONFDATA); 125 5184 ek110237 } 126 5184 ek110237 127 5184 ek110237 ############################################################################## 128 5184 ek110237 ## Filebench Operations 129 5184 ek110237 ############################################################################## 130 5184 ek110237 131 5184 ek110237 sub op_init { 132 5184 ek110237 } 133 5184 ek110237 134 5184 ek110237 sub op_load { 135 5184 ek110237 my ($workload) = shift; 136 7736 Andrew $scriptname = conf_reqval("statsdir") . "/thisrun.f"; 137 7736 Andrew 138 5184 ek110237 if($workload ne '') { 139 7736 Andrew print ("Creating Client Script " . $scriptname . "\n"); 140 7736 Andrew open (FSCRIPT, ">$scriptname"); 141 7736 Andrew chmod (0755, $scriptname); 142 9513 Andrew print FSCRIPT "#!$FILEBENCH/$PROG -f\n\n"; 143 7736 Andrew # Load the df 144 7736 Andrew print FSCRIPT "load $workload\n"; 145 7736 Andrew # Load the user defined defaults 146 7736 Andrew op_load_defaults(); 147 5184 ek110237 148 7736 Andrew # enable multiclient, if needed 149 7736 Andrew if ($MULTI_CLIENT == 1) { 150 7736 Andrew print FSCRIPT "enable multi master=".multi_getval("masterhost").", client=".conf_getval("myname")."\n"; 151 7736 Andrew } 152 9513 Andrew 153 9513 Andrew # Check to see if the path is legal and pointing to the correct FS 154 9513 Andrew if (conf_exists("dofscheck") == 1) { 155 9513 Andrew print FSCRIPT "fscheck path=" . conf_reqval("dir") . " fstype=" . conf_reqval("filesystem") . "\n"; 156 9513 Andrew } 157 9513 Andrew 158 7736 Andrew # Create the associated files and filesets 159 9513 Andrew print FSCRIPT "create filesets\n"; 160 5184 ek110237 } 161 5184 ek110237 $SCRIPT_NO = 1; 162 5184 ek110237 return(0); 163 9513 Andrew } 164 9513 Andrew 165 9513 Andrew sub op_fsflush { 166 9513 Andrew print FSCRIPT "fsflush fstype=" . conf_reqval("filesystem") . "\n"; 167 5184 ek110237 } 168 5184 ek110237 169 5184 ek110237 sub op_set { 170 5184 ek110237 my ($var, $val) = @_; 171 5184 ek110237 if($var eq 'debug') { 172 5184 ek110237 print FSCRIPT "debug $val\n"; 173 5184 ek110237 } elsif($var ne '') { 174 5184 ek110237 print FSCRIPT "set \$$var=$val\n"; 175 5184 ek110237 } 176 5184 ek110237 return(0); 177 5184 ek110237 } 178 5184 ek110237 179 5184 ek110237 sub op_eventrate { 180 5184 ek110237 my ($eventrate) = shift; 181 5184 ek110237 if ($eventrate ne '') { 182 5184 ek110237 print FSCRIPT "eventgen rate=$eventrate\n"; 183 5184 ek110237 return(0); 184 5184 ek110237 } 185 5184 ek110237 } 186 5184 ek110237 187 5184 ek110237 sub op_run { 188 5184 ek110237 my ($time) = shift; 189 5184 ek110237 print FSCRIPT "run $time\n"; 190 5184 ek110237 return(0); 191 5184 ek110237 } 192 5184 ek110237 193 5184 ek110237 sub op_sleep { 194 5184 ek110237 my ($time) = shift; 195 5184 ek110237 print FSCRIPT "sleep $time\n"; 196 5184 ek110237 return(0); 197 5184 ek110237 } 198 5184 ek110237 199 5184 ek110237 sub op_msg { 200 5184 ek110237 my ($msg) = shift; 201 5184 ek110237 print FSCRIPT "echo \"$msg\"\n"; 202 5184 ek110237 return(0); 203 5184 ek110237 } 204 5184 ek110237 205 5184 ek110237 sub op_quit { 206 7736 Andrew # Shutdown the appropriate processes 207 7736 Andrew print FSCRIPT "shutdown processes\n"; 208 9356 Andrew 209 9356 Andrew # remove filesets, if requested 210 9356 Andrew if (conf_exists("cleanupstorage") == 1) { 211 9356 Andrew printf FSCRIPT "shutdown filesets\n"; 212 9356 Andrew } 213 5184 ek110237 214 7736 Andrew # Quit filebench 215 7736 Andrew print FSCRIPT "quit\n"; 216 7736 Andrew close(FSCRIPT); 217 5184 ek110237 } 218 5184 ek110237 219 5184 ek110237 sub op_statsdir { 220 5184 ek110237 print FSCRIPT "stats directory ".conf_reqval("statsdir")."\n"; 221 5184 ek110237 return(0); 222 5184 ek110237 } 223 5184 ek110237 224 5184 ek110237 sub op_indiv_vars { 225 5184 ek110237 my ($ivar) = shift; 226 5184 ek110237 print FSCRIPT "echo \"\$$ivar\"\n"; 227 5184 ek110237 my ($imatch, $ierr, $ibefore, $iafter) = &expect(FSCRIPT, 228 5184 ek110237 $TIMEOUT, "filebench>"); 229 5184 ek110237 230 5184 ek110237 $ibefore =~ /(.*): (.*): (-*\d+)/; 231 5184 ek110237 $imatch = $3; 232 5184 ek110237 $imatch =~ s/^\s+//; 233 5184 ek110237 chomp($imatch); 234 5184 ek110237 return($imatch); 235 5184 ek110237 } 236 5184 ek110237 237 5184 ek110237 sub op_indiv_stats { 238 5184 ek110237 my ($var) = shift; 239 5184 ek110237 print FSCRIPT "echo \"\${stats.$var}\"\n"; 240 5184 ek110237 my ($match, $err, $before, $after) = &expect(FSCRIPT, 241 5184 ek110237 $TIMEOUT, "filebench>"); 242 5184 ek110237 243 5184 ek110237 $before =~ /(.*): (.*): (-*\d+)/; 244 5184 ek110237 $match = $3; 245 5184 ek110237 $match =~ s/^\s+//; 246 5184 ek110237 chomp($match); 247 5184 ek110237 return($match); 248 5184 ek110237 } 249 5184 ek110237 250 5184 ek110237 sub op_stats { 251 5184 ek110237 my ($time) = shift; 252 9326 Andrew my ($warmup) = shift; 253 5184 ek110237 my ($statsfile) = shift; 254 7736 Andrew my $mstrstatsdir = $STATSBASE."/".$CONFNAME; 255 5184 ek110237 256 7736 Andrew if ($MULTI_CLIENT == 1) { 257 7736 Andrew print FSCRIPT "domultisync value=1\n"; 258 7736 Andrew } 259 5184 ek110237 260 7736 Andrew # Create the associated processes and start them running 261 7736 Andrew print FSCRIPT "create processes\n"; 262 9326 Andrew 263 9326 Andrew if ($warmup ne '') { 264 9326 Andrew print FSCRIPT "warmup $warmup\n"; 265 9326 Andrew } 266 5184 ek110237 267 7736 Andrew if (($time ne '') && ($statsfile ne '')) { 268 7736 Andrew # Clear the current statistics buffers 269 7736 Andrew print FSCRIPT "stats clear\n"; 270 7736 Andrew 271 7736 Andrew # Start external statistics collection (if any) 272 7736 Andrew # Note all statistics arrays MUST be the same length ! 273 7736 Andrew if (@ext_stats != ()) { 274 7736 Andrew if (($#ext_stats == $#file_stats) && ($#ext_stats == $#arg_stats)) { 275 7736 Andrew $script = $mstrstatsdir . "/stats$SCRIPT_NO.sh"; 276 7736 Andrew open (RUNSCRIPT, ">$script"); 277 7736 Andrew chmod (0755, $script); 278 7736 Andrew print FSCRIPT "system \"$script\"\n"; 279 7736 Andrew $SCRIPT_NO++; 280 7736 Andrew $index=0; 281 7736 Andrew foreach my $ext (@ext_stats) { 282 7736 Andrew print RUNSCRIPT "$FILEBENCH/scripts/collect_$ext $ext $file_stats[$index] "; 283 7736 Andrew print RUNSCRIPT $mstrstatsdir; 284 7736 Andrew print RUNSCRIPT " $time $FILEBENCH $arg_stats[$index] &\n"; 285 7736 Andrew $index++; 286 5184 ek110237 } 287 5184 ek110237 } 288 7736 Andrew } 289 7736 Andrew close(RUNSCRIPT); 290 5184 ek110237 291 7736 Andrew # Sleep for the run time 292 7736 Andrew print FSCRIPT "sleep $time\n"; 293 5184 ek110237 294 7736 Andrew # Snap the statistics 295 7736 Andrew print FSCRIPT "stats snap\n"; 296 5184 ek110237 297 7736 Andrew # Dump the statistics to a raw file - out required due to filename constraint 298 7736 Andrew if ($MULTI_CLIENT == 1) { 299 7736 Andrew print FSCRIPT "domultisync value=2\n"; 300 7736 Andrew print FSCRIPT "stats multidump \"$statsfile.out\"\n"; 301 7736 Andrew } else { 302 7736 Andrew print FSCRIPT "stats dump \"$statsfile.out\"\n"; 303 7736 Andrew } 304 5184 ek110237 305 7736 Andrew # Statistics reaping occurs here 306 7736 Andrew if (@ext_stats != ()) { 307 7736 Andrew if (($#ext_stats == $#file_stats) && ($#ext_stats == $#arg_stats)) { 308 7736 Andrew $script = $mstrstatsdir . "/stats$SCRIPT_NO.sh"; 309 7736 Andrew open (RUNSCRIPT, ">$script"); 310 7736 Andrew chmod (0755, $script); 311 7736 Andrew print FSCRIPT "system \"$script\"\n"; 312 7736 Andrew $SCRIPT_NO++; 313 7736 Andrew foreach my $ext (@ext_stats) { 314 7736 Andrew print RUNSCRIPT "$FILEBENCH/scripts/kill_stats $ext &\n"; 315 5184 ek110237 } 316 7736 Andrew close(RUNSCRIPT); 317 5184 ek110237 } 318 5184 ek110237 } 319 7736 Andrew 320 7736 Andrew # Dump the statistics to a Xanadu compatible XML file 321 7736 Andrew if ($USE_XANADU) { 322 7736 Andrew op_xmlstats($statsfile); 323 7736 Andrew 324 7736 Andrew $script = $mstrstatsdir . "/stats$SCRIPT_NO.pl"; 325 7736 Andrew open (RUNSCRIPT, ">$script"); 326 7736 Andrew chmod (0755, $script); 327 7736 Andrew print FSCRIPT "system \"$script\"\n"; 328 7736 Andrew $SCRIPT_NO++; 329 7736 Andrew 330 7736 Andrew # The following loop adds the benchpoint run parameters and statistics into the filebench XML file 331 7736 Andrew # We capture the meta data from the start of the filebench xml file 332 7736 Andrew print RUNSCRIPT "#!/usr/bin/perl\n"; 333 7736 Andrew print RUNSCRIPT "\$phase=1;\n"; 334 7736 Andrew print RUNSCRIPT "open(STATSFILE,\"<".$mstrstatsdir."/$statsfile.xml\");\n"; 335 7736 Andrew print RUNSCRIPT "open(OSTATSFILE,\">".$mstrstatsdir."/$statsfile.new.xml\");\n"; 336 7736 Andrew print RUNSCRIPT "while (<STATSFILE>) {\n"; 337 7736 Andrew print RUNSCRIPT "\t\$temp=\$_;\n"; 338 7736 Andrew print RUNSCRIPT "\tif ((!((/.*meta.*/) || (/.*stat_doc.*/))) && (\$phase == 1)) {\n"; 339 7736 Andrew print RUNSCRIPT "\t\topen(XMLFILE,\"<".$mstrstatsdir."/$statsfile.config.xml\");\n"; 340 7736 Andrew print RUNSCRIPT "\t\twhile (<XMLFILE>) {\n"; 341 7736 Andrew print RUNSCRIPT "\t\t\tprint OSTATSFILE \$_;\n"; 342 7736 Andrew print RUNSCRIPT "\t\t}\n"; 343 7736 Andrew print RUNSCRIPT "\t\tclose(XMLFILE);\n"; 344 7736 Andrew print RUNSCRIPT "\t\t\$phase++;\n"; 345 7736 Andrew print RUNSCRIPT "\t}\n"; 346 7736 Andrew print RUNSCRIPT "\tprint OSTATSFILE \$temp;\n"; 347 7736 Andrew print RUNSCRIPT "}\n"; 348 7736 Andrew print RUNSCRIPT "close(STATSFILE);\n"; 349 7736 Andrew print RUNSCRIPT "close(OSTATSFILE);\n"; 350 7736 Andrew print RUNSCRIPT "unlink(\"".$mstrstatsdir."/$statsfile.xml\");\n"; 351 7736 Andrew print RUNSCRIPT "unlink(\"".$mstrstatsdir."/$statsfile.config.xml\");\n"; 352 7736 Andrew print RUNSCRIPT "system(\"mv ".$mstrstatsdir."/$statsfile.new.xml ".$mstrstatsdir."/$statsfile.xml\");\n"; 353 7736 Andrew 354 7736 Andrew $script = $mstrstatsdir . "/stats$SCRIPT_NO.sh"; 355 7736 Andrew open (RUNSCRIPT, ">$script"); 356 7736 Andrew chmod (0755, $script); 357 7736 Andrew print FSCRIPT "system \"$script\"\n"; 358 7736 Andrew $SCRIPT_NO++; 359 7736 Andrew 360 7736 Andrew print RUNSCRIPT "mkdir ".$mstrstatsdir."/xml\n"; 361 7736 Andrew print RUNSCRIPT "mkdir ".$mstrstatsdir."/html\n"; 362 7736 Andrew 363 7736 Andrew print RUNSCRIPT "mv ".$mstrstatsdir."/$statsfile.xml ".$mstrstatsdir."/xml/$statsfile.xml\n"; 364 7736 Andrew 365 7736 Andrew # Process XML file using Xanadu 2 366 7736 Andrew print RUNSCRIPT "$FILEBENCH/xanadu/scripts/xanadu import ".$mstrstatsdir." ".$mstrstatsdir."/xml ".conf_reqval("function")."-".$mstrstatsdir."\n"; 367 7736 Andrew print RUNSCRIPT "$FILEBENCH/xanadu/scripts/xanadu export ".$mstrstatsdir."/xml ".$mstrstatsdir."/html\n"; 368 7736 Andrew close(RUNSCRIPT); 369 7736 Andrew } 370 7736 Andrew } 371 7736 Andrew return(0); 372 5184 ek110237 } 373 5184 ek110237 374 5184 ek110237 sub op_xmlstats { 375 5184 ek110237 my ($statsfile) = shift; 376 7736 Andrew my $mstrstatsdir = $STATSBASE."/".$CONFNAME; 377 7736 Andrew if($statsfile ne '') { 378 7736 Andrew print FSCRIPT "stats xmldump \"$statsfile.xml\"\n"; 379 5184 ek110237 380 7736 Andrew # The following loop adds the benchpoint run parameters and statistics into a temporary XML file 381 7736 Andrew open(OSTATSFILE,">".$mstrstatsdir."/$statsfile.config.xml"); 382 7736 Andrew %CONFHASH = conf_hash(); 383 7736 Andrew # There is no test for whether CONFHASH contains no keys 384 7736 Andrew # The following two lines is to obtain the stats run directory name for xanadu meta data 385 7736 Andrew print OSTATSFILE "<meta name=\"RunId\" value=\"".conf_reqval("function")."-".$mstrstatsdir."\"/>\n"; 386 7736 Andrew print OSTATSFILE "<stat_group name=\"Benchpoint Configuration\">\n"; 387 7736 Andrew print OSTATSFILE "<cell_list>\n"; 388 7736 Andrew foreach $k (keys(%CONFHASH)) { 389 7736 Andrew print OSTATSFILE "<cell>@{ $CONFHASH{$k} }</cell>\n"; 390 7736 Andrew } 391 7736 Andrew print OSTATSFILE "</cell_list>\n"; 392 7736 Andrew print OSTATSFILE "<dim_list>\n"; 393 7736 Andrew print OSTATSFILE "<dim>\n"; 394 7736 Andrew print OSTATSFILE "<dimval>Value</dimval>\n"; 395 7736 Andrew print OSTATSFILE "</dim>\n"; 396 7736 Andrew print OSTATSFILE "<dim>\n"; 397 7736 Andrew foreach $k (keys(%CONFHASH)) { 398 7736 Andrew print OSTATSFILE "<dimval>$k</dimval>\n"; 399 7736 Andrew } 400 7736 Andrew print OSTATSFILE "</dim>\n"; 401 7736 Andrew print OSTATSFILE "</dim_list>\n"; 402 7736 Andrew print OSTATSFILE "</stat_group>\n"; 403 7736 Andrew close(OSTATSFILE); 404 5184 ek110237 405 7736 Andrew return(0); 406 7736 Andrew } 407 7736 Andrew return(1); 408 5184 ek110237 } 409 5184 ek110237 410 5184 ek110237 sub op_command { 411 5184 ek110237 my ($command) = shift; 412 5184 ek110237 if($command ne '') { 413 5184 ek110237 print FSCRIPT "$command\n"; 414 5184 ek110237 } 415 5184 ek110237 return(0); 416 5184 ek110237 } 417 5184 ek110237 418 5184 ek110237 sub op_statshash { 419 5184 ek110237 op_indiv_stats("iocount"); 420 5184 ek110237 $STATSHASH{"iocount"} = op_indiv_stats("iocount"); 421 5184 ek110237 $STATSHASH{"iorate"} = op_indiv_stats("iorate"); 422 5184 ek110237 $STATSHASH{"ioreadrate"} = op_indiv_stats("ioreadrate"); 423 5184 ek110237 $STATSHASH{"iowriterate"} = op_indiv_stats("iowriterate"); 424 5184 ek110237 $STATSHASH{"iobandwidth"} = op_indiv_stats("iobandwidth"); 425 5184 ek110237 $STATSHASH{"iolatency"} = op_indiv_stats("iolatency"); 426 5184 ek110237 $STATSHASH{"iocpu"} = op_indiv_stats("iocpu"); 427 5184 ek110237 $STATSHASH{"oheadcpu"} = op_indiv_stats("oheadcpu"); 428 5184 ek110237 $STATSHASH{"iowait"} = op_indiv_stats("iowait"); 429 5184 ek110237 $STATSHASH{"syscpu"} = op_indiv_stats("syscpu"); 430 5184 ek110237 $STATSHASH{"iocpusys"} = op_indiv_stats("iocpusys"); 431 5184 ek110237 return(%STATSHASH); 432 5184 ek110237 } 433 5184 ek110237 434 5184 ek110237 sub op_load_defaults { 435 5184 ek110237 # The following code causes an intermittent bug - may be fixed at a later date 436 5184 ek110237 # Prevents the capture of filebench default parameters 437 5184 ek110237 # print FSCRIPT "vars\n"; 438 5184 ek110237 # my ($match, $err, $before, $after) = &expect(FSCRIPT, 439 5184 ek110237 # $TIMEOUT, "filebench>"); 440 5184 ek110237 # chomp($before); 441 5184 ek110237 # $before =~ /(.*): (.*): (.*)/; 442 5184 ek110237 # $match = $3; 443 5184 ek110237 # my @vars = split(/ /, $match); 444 5184 ek110237 # my $value = ""; 445 5184 ek110237 # # Cater for the default filebench commands 446 5184 ek110237 # foreach my $var (@vars) { 447 5184 ek110237 # if (!conf_exists($var)) { 448 5184 ek110237 # $var =~ s/ //g; 449 5184 ek110237 # if ($var ne '') { 450 5184 ek110237 # $value = op_indiv_vars($var); 451 5184 ek110237 # push(@{ $CONFDATA{$var} }, $value); 452 5184 ek110237 # } 453 5184 ek110237 # } 454 5184 ek110237 # } 455 5184 ek110237 456 5184 ek110237 # Cater for the user defined defaults 457 5184 ek110237 foreach $var (keys(%CONFDATA)) { 458 5184 ek110237 if (conf_exists($var)) { 459 5184 ek110237 $var =~ s/ //g; 460 5184 ek110237 my $val = conf_getval($var); 461 7736 Andrew 462 7736 Andrew if (($SHAREDFILEALLOCATOR) and ($var eq "sharedprealloc")) { 463 7736 Andrew if (conf_reqval("myname") ne $SHAREDFILEALLOCATOR) { 464 7736 Andrew $val = "0"; 465 7736 Andrew } 466 7736 Andrew } 467 7736 Andrew 468 9356 Andrew if ($val ne "") { 469 9356 Andrew op_set($var, $val); 470 9356 Andrew } 471 5184 ek110237 } 472 5184 ek110237 } 473 5184 ek110237 } 474 5184 ek110237 475 5184 ek110237 ############################################################################## 476 5184 ek110237 ## Local functions 477 5184 ek110237 ############################################################################## 478 5184 ek110237 479 5184 ek110237 sub parse_profile { 480 5184 ek110237 my ($profile) = shift; 481 7736 Andrew my ($config_section, $default_section, $multi_section); 482 5184 ek110237 483 5184 ek110237 open(CFILE, "$profile") or 484 9513 Andrew die "ERROR: couldn't open profile $profile"; 485 5184 ek110237 486 5184 ek110237 while(<CFILE>) { 487 5184 ek110237 my ($line) = $_; 488 5184 ek110237 chomp($line); 489 5184 ek110237 $line =~ s/^\s+//; # Get rid of spaces 490 5184 ek110237 491 5184 ek110237 if($line =~ /^#/ or $line eq "") { 492 5184 ek110237 } else { 493 5184 ek110237 if($line =~ /}/) { 494 7736 Andrew if($multi_section == 1) { 495 7736 Andrew $multi_section = 0; 496 7736 Andrew } 497 5184 ek110237 if($default_section == 1) { 498 5184 ek110237 $default_section = 0; 499 5184 ek110237 } 500 5184 ek110237 if($config_section == 1) { 501 5184 ek110237 $config_section = 0; 502 5184 ek110237 } 503 7736 Andrew } elsif($multi_section) { 504 9513 Andrew $line =~ /([^\s]+)\s*=\s*(.+);/; 505 7736 Andrew my $opt = $1; 506 7736 Andrew my $val = $2; 507 7736 Andrew chomp($opt); 508 7736 Andrew chomp($val); 509 7736 Andrew my @vals = (); 510 7736 Andrew # Check to see if this needs to be a list 511 7736 Andrew if($val =~ /,/) { 512 7736 Andrew push(@vals, $+) while $val =~ 513 7736 Andrew m{"([^\"\\]*(?:\\.[^\"\\]*)*)",? | ([^,]+),? | , }gx; 514 7736 Andrew push(@vals, undef) if substr($val, -1,1) eq ','; 515 7736 Andrew @{ $MULTIDATA{$opt} } = @vals; 516 7736 Andrew } else { 517 7736 Andrew @{MULTIDATA{$opt}} = (); 518 7736 Andrew push(@{ $MULTIDATA{$opt} }, $val); 519 7736 Andrew } 520 5184 ek110237 } elsif($default_section) { 521 9513 Andrew if ($line =~ /([^\s]+)\s*=\s*(.+);/) { 522 9356 Andrew my $opt = $1; 523 9356 Andrew my $val = $2; 524 9356 Andrew chomp($opt); 525 9356 Andrew chomp($val); 526 9356 Andrew my @vals = (); 527 9356 Andrew # Check to see if this needs to be a list 528 9356 Andrew if(($val =~ /,/) && ($val !~ /"/)) { 529 9356 Andrew push(@vals, $+) while $val =~ 530 9356 Andrew m{"([^\"\\]*(?:\\.[^\"\\]*)*)",? | ([^,]+),? | , }gx; 531 9356 Andrew push(@vals, undef) if substr($val, -1,1) eq ','; 532 9356 Andrew @{ $DEFDATA{$opt} } = @vals; 533 9513 Andrew } elsif(exists($CMDLINEDATA{$opt})) { 534 9513 Andrew @{DEFDATA{$opt}} = (); 535 9513 Andrew push(@{ $DEFDATA{$opt} }, @{$CMDLINEDATA{$opt}}); 536 9356 Andrew } else { 537 9356 Andrew @{DEFDATA{$opt}} = (); 538 9356 Andrew push(@{ $DEFDATA{$opt} }, $val); 539 9356 Andrew } 540 5184 ek110237 } else { 541 9513 Andrew if ($line =~ /([^;]+);/) { 542 9513 Andrew my $opt = $1; 543 9513 Andrew if ($OPTIONFLAGS =~ /$opt/) { 544 9513 Andrew @{DEFDATA{$opt}} = (); 545 9513 Andrew push(@{ $DEFDATA{$opt} }, ""); 546 9513 Andrew } 547 9513 Andrew } 548 9356 Andrew } 549 5184 ek110237 } else { 550 5184 ek110237 if($line =~ /^CONFIG /) { 551 5184 ek110237 my $config = $line; 552 9513 Andrew $config =~ s/CONFIG\s+(.+) {/$1/; 553 5184 ek110237 push(@CONFLIST, $config); 554 5184 ek110237 $config_section = 1; 555 9513 Andrew } elsif($line =~ /MULTICLIENT\s{/) { 556 7736 Andrew $multi_section = 1; 557 7736 Andrew $MULTI_CLIENT = 1; 558 9513 Andrew } elsif($line =~ /DEFAULTS\s{/) { 559 5184 ek110237 $default_section = 1; 560 5184 ek110237 } 561 5184 ek110237 } 562 5184 ek110237 } 563 5184 ek110237 } 564 5184 ek110237 } 565 5184 ek110237 566 5184 ek110237 567 5184 ek110237 # 568 5184 ek110237 # Parse the configuration file 569 5184 ek110237 # 570 5184 ek110237 sub parse_config { 571 5184 ek110237 my ($config) = shift; 572 5184 ek110237 573 5184 ek110237 my $config_section = 0; 574 5184 ek110237 575 5184 ek110237 print "parsing profile for config: $config\n"; 576 5184 ek110237 577 5184 ek110237 # Howdy 578 5184 ek110237 seek(CFILE, 0, 0); 579 5184 ek110237 580 5184 ek110237 while(<CFILE>) { 581 5184 ek110237 # Read in the line and chomp...munch...chomp 582 5184 ek110237 my ($line) = $_; 583 5184 ek110237 chomp($line); 584 5184 ek110237 $line =~ s/^\s+//; # Get rid of spaces 585 5184 ek110237 586 5184 ek110237 # look for our stuff 587 5184 ek110237 if ($line =~ /CONFIG $config /) { 588 5184 ek110237 $config_section = 1; 589 5184 ek110237 } 590 5184 ek110237 591 5184 ek110237 if($line =~ /}/) { 592 5184 ek110237 $config_section = 0; 593 5184 ek110237 } 594 5184 ek110237 595 5184 ek110237 # Skip until our config is found 596 5184 ek110237 next if (!$config_section); 597 5184 ek110237 598 5184 ek110237 next if ($line =~ /^#/ or $line eq ""); 599 5184 ek110237 600 9513 Andrew if ($line =~ /([^\s]+)\s*=\s*(.+);/) { 601 9356 Andrew my $opt = $1; 602 9356 Andrew my $val = $2; 603 9356 Andrew chomp($opt); 604 9356 Andrew chomp($val); 605 9356 Andrew my @vals = (); 606 9356 Andrew # Check to see if this needs to be a list 607 9356 Andrew if(($val =~ /,/) && ($val !~ /"/)) { 608 9356 Andrew push(@vals, $+) while $val =~ 609 9356 Andrew m{"([^\"\\]*(?:\\.[^\"\\]*)*)",? | ([^,]+),? | , }gx; 610 9356 Andrew push(@vals, undef) if substr($val, -1,1) eq ','; 611 5184 ek110237 @{ $CONFDATA{$opt} } = @vals; 612 9356 Andrew } else { 613 9356 Andrew @{CONFDATA{$opt}} = (); 614 9356 Andrew push(@{ $CONFDATA{$opt} }, $val); 615 9356 Andrew } 616 5184 ek110237 } else { 617 9356 Andrew $line =~ /($OPTIONFLAGS);/; 618 9356 Andrew my $opt = $1; 619 9356 Andrew chomp($opt); 620 5184 ek110237 @{CONFDATA{$opt}} = (); 621 9356 Andrew push(@{ $CONFDATA{$opt} }, ""); 622 5184 ek110237 } 623 5184 ek110237 } 624 5184 ek110237 625 5184 ek110237 # Bye, bye 626 5184 ek110237 #close(CFILE) or die "ERROR: config file closing difficulties"; 627 7736 Andrew return \%confdata; 628 7736 Andrew } 629 7736 Andrew 630 7736 Andrew sub build_run 631 7736 Andrew { 632 7736 Andrew # The following function is taken from the user's function file 633 7736 Andrew pre_run(); 634 7736 Andrew 635 7736 Andrew # Set the global statistics directory for this run 636 7736 Andrew op_statsdir(); 637 7736 Andrew 638 7736 Andrew # The following function is taken from the user's function file 639 7736 Andrew bm_run(); 640 7736 Andrew 641 7736 Andrew # Finish and close the .f script 642 7736 Andrew op_quit(); 643 7736 Andrew } 644 7736 Andrew 645 7736 Andrew # statistics aggregation section 646 7736 Andrew my %FLOWOPVALS; 647 7736 Andrew my @SUMMARYVALS; 648 7736 Andrew 649 7736 Andrew sub init_combined_stats 650 7736 Andrew { 651 7736 Andrew %FLOWOPVALS = (); 652 7736 Andrew @SUMMARYVALS = (0,0,0,0,0,0); 653 7736 Andrew } 654 7736 Andrew 655 7736 Andrew sub add_2combstats 656 7736 Andrew { 657 7736 Andrew my ($confname) = shift; 658 7736 Andrew my ($thisclient) = shift; 659 7736 Andrew my $clstatdir; 660 7736 Andrew my $flowopmode = 0; 661 7736 Andrew my $summarymode = 0; 662 7736 Andrew 663 7736 Andrew print "adding in stats for client: $thisclient, configuration: $confname\n"; 664 7736 Andrew 665 7736 Andrew $clstatdir = multi_getval("masterpath")."/".$thisclient; 666 7736 Andrew 667 7736 Andrew print "from: ".$clstatdir."/stats.".$confname.".out\n"; 668 7736 Andrew open (CLSTATS, $clstatdir."/stats.".$confname.".out"); 669 7736 Andrew while(<CLSTATS>) { 670 7736 Andrew my ($line) = $_; 671 7736 Andrew chomp($line); 672 7736 Andrew if (($flowopmode == 0) and ($summarymode == 0)) { 673 7736 Andrew if ($line =~ /^Flowop totals:/) { 674 7736 Andrew $flowopmode = 1; 675 7736 Andrew next; 676 7736 Andrew } 677 7736 Andrew if ($line =~ /^IO Summary:/) { 678 7736 Andrew $summarymode = 1; 679 7736 Andrew next; 680 7736 Andrew } 681 7736 Andrew } 682 7736 Andrew if ($line eq "") { 683 7736 Andrew $flowopmode = 0; 684 7736 Andrew $summarymode = 0; 685 7736 Andrew next; 686 7736 Andrew } 687 7736 Andrew 688 7736 Andrew # get the good stuff 689 7736 Andrew if ($flowopmode == 1) { 690 7736 Andrew my @elementlist; 691 7736 Andrew my @valuelist; 692 7736 Andrew my $flkey; 693 7736 Andrew my $vallistref = []; 694 7736 Andrew 695 7736 Andrew @elementlist = split(' ', $line); 696 7736 Andrew $flkey = $elementlist[0]; 697 7736 Andrew @valuelist = @elementlist[1..$#elementlist]; 698 7736 Andrew 699 7736 Andrew if (exists($FLOWOPVALS{$flkey})) { 700 7736 Andrew my $numvals; 701 7736 Andrew 702 7736 Andrew $vallistref = $FLOWOPVALS{$flkey}; 703 7736 Andrew $numvals = @{$vallistref}; 704 7736 Andrew for (my $idx = 0; $idx < $numvals; $idx++) { 705 7736 Andrew $vallistref->[$idx] += $valuelist[$idx]; 706 7736 Andrew } 707 7736 Andrew } else { 708 7736 Andrew # newly found flowop name 709 7736 Andrew $vallistref = [@valuelist]; 710 7736 Andrew $FLOWOPVALS{$flkey} = $vallistref; 711 7736 Andrew } 712 7736 Andrew next; 713 7736 Andrew } 714 7736 Andrew 715 7736 Andrew # get final totals 716 7736 Andrew if ($summarymode == 1) { 717 7736 Andrew my @valuelist; 718 7736 Andrew 719 7736 Andrew @valuelist = split(' ', $line); 720 7736 Andrew 721 7736 Andrew for (my $idx = 0; $idx <= $#valuelist; $idx++) { 722 7736 Andrew $SUMMARYVALS[$idx] += $valuelist[$idx]; 723 7736 Andrew } 724 7736 Andrew next; 725 7736 Andrew } 726 7736 Andrew } 727 7736 Andrew close (CLSTATS); 728 5184 ek110237 } 729 5184 ek110237 730 5184 ek110237 sub print_usage 731 5184 ek110237 { 732 9513 Andrew print "Usage:\n\tfilebench -c <stat_dir>\n"; 733 9513 Andrew print "\tfilebench [-b <base_path>] "; 734 9513 Andrew print "[-D[ ]<variable name>[ |=| = ]<value>]... <profile name>\n"; 735 7736 Andrew } 736 7736 Andrew 737 7736 Andrew sub dump_combined_stats 738 7736 Andrew { 739 7736 Andrew my ($confname) = shift; 740 7736 Andrew my $totvalsref = []; 741 7736 Andrew my $flkey; 742 7736 Andrew use FileHandle; 743 7736 Andrew 744 7736 Andrew ## set up output formating info 745 7736 Andrew format flowoplinefrm = 746 7736 Andrew @<<<<<<<<<<<<<<<<<<< @#######ops/s @###.#mb/s @#####.#ms/op @#######us/op-cpu 747 7736 Andrew $flkey, $totvalsref->[0], $totvalsref->[1], $totvalsref->[2]/$#CLIENTLIST, $totvalsref->[3]/$#CLIENTLIST 748 7736 Andrew . 749 7736 Andrew 750 7736 Andrew format summarylinefrm = 751 7736 Andrew 752 7736 Andrew IO Summary: @#######ops, @#####.#ops/s, (@####/@#### r/w) @#####.#mb/s, @######us cpu/op, @####.#ms latency 753 7736 Andrew $SUMMARYVALS[0], $SUMMARYVALS[1], $SUMMARYVALS[2], $SUMMARYVALS[3], $SUMMARYVALS[4], $SUMMARYVALS[5], $SUMMARYVALS[6] 754 7736 Andrew . 755 7736 Andrew 756 7736 Andrew open (SUMSTATS, ">$STATSBASE/$confname/stats.$confname.out"); 757 7736 Andrew print "Per-Operation Breakdown:\n"; 758 7736 Andrew print SUMSTATS "Per-Operation Breakdown:\n"; 759 7736 Andrew 760 7736 Andrew format_name STDOUT "flowoplinefrm"; 761 7736 Andrew format_name SUMSTATS "flowoplinefrm"; 762 7736 Andrew 763 7736 Andrew foreach $flkey (keys %FLOWOPVALS) { 764 7736 Andrew 765 7736 Andrew $totvalsref = $FLOWOPVALS{$flkey}; 766 7736 Andrew 767 7736 Andrew write STDOUT; 768 7736 Andrew write SUMSTATS; 769 7736 Andrew } 770 7736 Andrew 771 7736 Andrew format_name STDOUT "summarylinefrm"; 772 7736 Andrew format_name SUMSTATS "summarylinefrm"; 773 7736 Andrew 774 7736 Andrew write STDOUT; 775 7736 Andrew write SUMSTATS; 776 7736 Andrew close (SUMSTATS); 777 7736 Andrew } 778 7736 Andrew 779 7736 Andrew # 780 7736 Andrew # polls the synchronization socket for each client in turn every 5 seconds, 781 7736 Andrew # then sends synch responses once all clients have "checked in". The 782 7736 Andrew # sample number in the received sync requests must match the sequence 783 7736 Andrew # number supplied with the call. 784 7736 Andrew # 785 7736 Andrew sub sync_receive 786 7736 Andrew { 787 7736 Andrew my $seqnum = shift; 788 7736 Andrew # my @cl_list; 789 7736 Andrew my %cl_hash = (); 790 7736 Andrew %cl_hash = %CLIENTHASH; 791 7736 Andrew 792 7736 Andrew my $count = @CLIENTLIST; 793 7736 Andrew print "waiting for sync message: $seqnum from $count clients\n"; 794 7736 Andrew while ($count > 0) { 795 7736 Andrew my $rcv_str = ""; 796 7736 Andrew 797 7736 Andrew sleep 5; 798 7736 Andrew 799 7736 Andrew foreach my $client_name (keys %cl_hash) 800 7736 Andrew { 801 7736 Andrew my $clientdata = $CLIENTHASH{$client_name}; 802 7736 Andrew my $client_hndl = $$clientdata[0]; 803 7736 Andrew print "recv sync: $client_name undefined handle\n" unless defined($client_hndl); 804 7736 Andrew my $client_iaddr = $$clientdata[1]; 805 7736 Andrew my $sn = $$clientdata[2]; 806 7736 Andrew my $rtn = 0; 807 7736 Andrew 808 7736 Andrew do { 809 7736 Andrew my $tmp_str; 810 7736 Andrew $rtn = recv($client_hndl, $tmp_str, 80, MSG_DONTWAIT); 811 7736 Andrew if (defined($rtn)) { 812 7736 Andrew $rcv_str = $rcv_str.$tmp_str; 813 7736 Andrew } 814 7736 Andrew } until (!defined($rtn) || ($rcv_str =~ /$EOL/s )); 815 7736 Andrew 816 7736 Andrew if (defined($rtn)) { 817 7736 Andrew my %ophash = (); 818 7736 Andrew my $ok; 819 7736 Andrew 820 7736 Andrew my @oplist = split /,/,$rcv_str; 821 7736 Andrew foreach my $opent (@oplist) 822 7736 Andrew { 823 7736 Andrew my ($op, $val) = split /=/,$opent; 824 7736 Andrew $ophash{$op} = $val; 825 7736 Andrew } 826 7736 Andrew $ok = ($sn == $seqnum); 827 7736 Andrew $ok &&= defined((my $cmd_val = $ophash{"cmd"})); 828 7736 Andrew $ok &&= defined((my $samp_val = $ophash{"sample"})); 829 7736 Andrew if ($ok && ($cmd_val eq "SYNC") && ($samp_val == $seqnum)) 830 7736 Andrew { 831 7736 Andrew delete $cl_hash{$client_name}; 832 7736 Andrew $count--; 833 7736 Andrew print "received a sync request from $client_name\n"; 834 7736 Andrew ${$CLIENTHASH{$client_name}}[2] = ($sn + 1); 835 7736 Andrew } else { 836 7736 Andrew print "received invalid sync request string [".rcv_str."] from client $client_name\n"; 837 7736 Andrew } 838 7736 Andrew } 839 7736 Andrew } 840 7736 Andrew } 841 7736 Andrew print "received all sync requests for seq $seqnum, sending responses\n"; 842 7736 Andrew foreach my $client_name (@CLIENTLIST) 843 7736 Andrew { 844 7736 Andrew my $clientdata = $CLIENTHASH{$client_name}; 845 7736 Andrew my $client_hndl = $$clientdata[0]; 846 7736 Andrew print "send resp: $client_name undefined handle\n" unless defined($client_hndl); 847 7736 Andrew 848 7736 Andrew send ($client_hndl, "rsp=PASS,sample=$seqnum\n", 0); 849 7736 Andrew } 850 7736 Andrew } 851 7736 Andrew 852 7736 Andrew # 853 7736 Andrew # waits for all known clients to connect, then calls sync_recieve(1) to 854 7736 Andrew # sync_receive(N) to wait for N sync requests for designated sync points 855 7736 Andrew # 1..N. 856 7736 Andrew # 857 7736 Andrew sub sync_server 858 7736 Andrew { 859 7736 Andrew my $port = shift || 8001; 860 7736 Andrew my $proto = getprotobyname('tcp'); 861 7736 Andrew my $paddr; 862 7736 Andrew my $count; 863 7736 Andrew 864 7736 Andrew socket(Server, PF_INET, SOCK_STREAM, $proto) || die "socket: $!"; 865 7736 Andrew setsockopt(Server, SOL_SOCKET, SO_REUSEADDR, 866 7736 Andrew pack("l", 1)) || die "setsockopt: $1"; 867 7736 Andrew bind(Server, sockaddr_in($port, INADDR_ANY)) || die "bind: $1"; 868 7736 Andrew listen(Server, SOMAXCONN) || die "listen: $1"; 869 7736 Andrew 870 7736 Andrew # wait for connection requests from clients 871 7736 Andrew print "sync: Waiting for ".@CLIENTLIST." Clients\n"; 872 7736 Andrew for ($count = @CLIENTLIST; $count > 0; $count--) { 873 7736 Andrew $paddr = accept(my $client_hndl, Server); 874 7736 Andrew die "bad socket address" unless $paddr; 875 7736 Andrew 876 7736 Andrew my ($port, $iaddr) = sockaddr_in($paddr); 877 7736 Andrew my $cl_name = gethostbyaddr($iaddr, AF_INET); 878 7736 Andrew 879 7736 Andrew if (!exists($CLIENTHASH{$cl_name})) { 880 7736 Andrew die "sync from unknown client $cl_name"; 881 7736 Andrew } 882 7736 Andrew 883 7736 Andrew print "received sync connection from client: $cl_name\n"; 884 7736 Andrew ${$CLIENTHASH{$cl_name}}[0] = $client_hndl; 885 7736 Andrew ${$CLIENTHASH{$cl_name}}[1] = $iaddr; 886 7736 Andrew } 887 7736 Andrew 888 7736 Andrew # indicate that all clients have checked in 889 7736 Andrew sync_receive(1); 890 7736 Andrew if (conf_exists("runtime") == 1) { 891 7736 Andrew my $runtime = conf_getval("runtime"); 892 7736 Andrew sleep $runtime; 893 7736 Andrew } 894 7736 Andrew sync_receive(2); 895 5184 ek110237 } 896 5184 ek110237 897 5184 ek110237 ############################################################################## 898 5184 ek110237 ## Main program 899 5184 ek110237 ############################################################################## 900 5184 ek110237 901 5184 ek110237 ## Make sure arguments are okay 902 5184 ek110237 $numargs = $#ARGV + 1; 903 5184 ek110237 904 5184 ek110237 if($numargs < 1) { 905 5184 ek110237 print_usage(); 906 5184 ek110237 exit(2); 907 5184 ek110237 } 908 5184 ek110237 909 9513 Andrew for (my $idx = 0; $idx < $numargs;) { 910 9513 Andrew my $cur_argv = $ARGV[$idx++]; 911 9513 Andrew my $cmdvar = ""; 912 9513 Andrew my $cmddata = ""; 913 9513 Andrew 914 9513 Andrew # See if filebench_compare should be run 915 9513 Andrew if($cur_argv eq "-c") { 916 9513 Andrew if($numargs < ($idx + 1)) { 917 9513 Andrew print_usage(); 918 9513 Andrew exit(2); 919 9513 Andrew } 920 9513 Andrew # next argument variable is path to results files 921 9513 Andrew exec("$FILEBENCH/scripts/filebench_compare", $ARGV[$idx++]); 922 9513 Andrew } 923 9513 Andrew 924 9513 Andrew # Capture specification of an alternate FileBench path 925 9513 Andrew if($cur_argv eq "-b") { 926 9513 Andrew if($numargs < ($idx + 1)) { 927 9513 Andrew print_usage(); 928 9513 Andrew exit(2); 929 9513 Andrew } 930 9513 Andrew # next argument is the base path name 931 9513 Andrew $FILEBENCH = $ARGV[$idx++]; 932 9513 Andrew 933 9513 Andrew # See if Default variable will be supplied. 934 9513 Andrew } elsif($cur_argv =~ /^-D(.*)/) { 935 9513 Andrew my $def_arg = $1; 936 9513 Andrew 937 9513 Andrew # rest of info in separate argvs 938 9513 Andrew if ($def_arg eq "") { 939 9513 Andrew if($numargs < ($idx + 2)) { 940 9513 Andrew print_usage(); 941 9513 Andrew exit(2); 942 9513 Andrew } 943 9513 Andrew 944 9513 Andrew # get next bit 945 9513 Andrew $def_arg = $ARGV[$idx++]; 946 9513 Andrew } 947 9513 Andrew 948 9513 Andrew # with variable name but without "=" or value 949 9513 Andrew if($def_arg =~ /^([^=]+)$/) { 950 9513 Andrew $cmdvar = $1; 951 9513 Andrew if($numargs < ($idx + 2)) { 952 9513 Andrew print_usage(); 953 9513 Andrew exit(2); 954 9513 Andrew } 955 9513 Andrew 956 9513 Andrew # get data from next argument, or next after that if '=' encountered 957 9513 Andrew $cmddata = $ARGV[$idx++]; 958 9513 Andrew if ($cmddata eq "=") { 959 9513 Andrew if($numargs < ($idx + 2)) { 960 9513 Andrew print_usage(); 961 9513 Andrew exit(2); 962 9513 Andrew } 963 9513 Andrew $cmddata = $ARGV[$idx++]; 964 9513 Andrew } else { 965 9513 Andrew $cmddata =~ s/^=//; 966 9513 Andrew } 967 9513 Andrew 968 9513 Andrew # see if variable name and data supplied 969 9513 Andrew } elsif($def_arg =~ /^([^=]+)=(.+)/) { 970 9513 Andrew $cmdvar = $1; 971 9513 Andrew $cmddata = $2; 972 9513 Andrew if($numargs < ($idx + 1)) { 973 9513 Andrew print_usage(); 974 9513 Andrew exit(2); 975 9513 Andrew } 976 9513 Andrew 977 9513 Andrew # see if variable name and '=' but no data supplied 978 9513 Andrew } elsif($def_arg =~ /^([^=]+)=$/) { 979 9513 Andrew $cmdvar = $1; 980 9513 Andrew if($numargs < ($idx + 2)) { 981 9513 Andrew print_usage(); 982 9513 Andrew exit(2); 983 9513 Andrew } 984 9513 Andrew $cmddata = $ARGV[$idx++]; 985 9513 Andrew } 986 9513 Andrew 987 9513 Andrew # push the variable onto the command line hash 988 9513 Andrew $CMDLINEDATA{$cmdvar} = (); 989 9513 Andrew push(@{ $CMDLINEDATA{$cmdvar} }, $cmddata); 990 9513 Andrew 991 9513 Andrew # otherwise argument is the profile name 992 9513 Andrew } else { 993 9513 Andrew $PROFILENAME = $cur_argv; 994 9513 Andrew } 995 9513 Andrew } 996 9513 Andrew 997 5184 ek110237 $PROFILE = $PROFILENAME; 998 5184 ek110237 $PROFILE =~ s/.*\/(.+)$/$1/; 999 5184 ek110237 parse_profile("$PROFILENAME.prof"); 1000 5184 ek110237 1001 5184 ek110237 %CONFDATA = (); 1002 5184 ek110237 %CONFDATA = %DEFDATA; 1003 5184 ek110237 1004 7736 Andrew # get the name of the host this script is running on 1005 5184 ek110237 my $hostname = `hostname`; 1006 5184 ek110237 chomp($hostname); 1007 7736 Andrew 1008 7736 Andrew # Check for Multi-Client operation 1009 7736 Andrew if ($MULTI_CLIENT == 1) { 1010 7736 Andrew 1011 7736 Andrew if (multi_exists("targetpath")) { 1012 7736 Andrew $TARGETPATH = multi_getval("targetpath"); 1013 7736 Andrew } else { 1014 7736 Andrew print "ERROR: Target pathname required for multi-client operation\n"; 1015 7736 Andrew exit(1); 1016 7736 Andrew } 1017 7736 Andrew 1018 7736 Andrew if (multi_exists("clients")) { 1019 7736 Andrew @CLIENTLIST = split(' ',multi_getval("clients")); 1020 7736 Andrew } else { 1021 7736 Andrew print "ERROR: client list required for multi-client operation\n"; 1022 7736 Andrew exit(1); 1023 7736 Andrew } 1024 7736 Andrew 1025 7736 Andrew if (multi_exists("sharefiles")) { 1026 7736 Andrew $SHAREDFILEALLOCATOR = multi_getval("sharefiles"); 1027 7736 Andrew } else { 1028 7736 Andrew $SHAREDFILEALLOCATOR = ""; 1029 7736 Andrew } 1030 7736 Andrew 1031 7736 Andrew $TARGETDIR = $TARGETPATH.conf_getval("dir"); 1032 7736 Andrew 1033 7736 Andrew # Setup the multi client statistics base directory 1034 7736 Andrew $STATSBASE = $TARGETPATH.conf_reqval("stats"); 1035 7736 Andrew 1036 7736 Andrew multi_putval("masterhost", $hostname) unless multi_exists("masterhost"); 1037 7736 Andrew multi_putval("masterpath", $STATSBASE) unless multi_exists("masterpath"); 1038 7736 Andrew 1039 7736 Andrew # create a path for filebench.pl to use to access the master directory 1040 7736 Andrew $FB_MASTERPATH = multi_getval("masterpath"); 1041 7736 Andrew 1042 7736 Andrew print "Target PathName = $TARGETPATH, path = ".multi_getval("masterpath")."\n"; 1043 7736 Andrew 1044 7736 Andrew } else { 1045 7736 Andrew # Setup the single client statistics base directory 1046 7736 Andrew $STATSBASE = conf_reqval("stats"); 1047 7736 Andrew } 1048 7736 Andrew 1049 7736 Andrew my $filesystem = conf_reqval("filesystem"); 1050 5184 ek110237 $STATSBASE = $STATSBASE . "/$hostname-$filesystem-$PROFILENAME-"; 1051 5184 ek110237 my $timestamp = strftime "%b_%e_%Y-%Hh_%Mm_%Ss", localtime; 1052 5184 ek110237 $timestamp =~ s/ //; 1053 5184 ek110237 $STATSBASE = $STATSBASE . $timestamp; 1054 5184 ek110237 1055 7736 Andrew foreach $config_name (@CONFLIST) 1056 7736 Andrew { 1057 5184 ek110237 %CONFDATA = (); 1058 5184 ek110237 %CONFDATA = %DEFDATA; 1059 7736 Andrew $CONFNAME = $config_name; 1060 7736 Andrew parse_config("$config_name"); 1061 5184 ek110237 my $function = conf_reqval("function"); 1062 7736 Andrew my $statsdir; 1063 7736 Andrew 1064 5184 ek110237 if (-f "$function.func") { 1065 5184 ek110237 require "$function.func"; 1066 5184 ek110237 } else { 1067 5184 ek110237 require "$FILEBENCH/config/$function.func"; 1068 5184 ek110237 } 1069 5184 ek110237 1070 7736 Andrew # Setup the final statistics directory 1071 7736 Andrew system("mkdir -p $STATSBASE"); 1072 5184 ek110237 1073 5184 ek110237 # Leave a log of the run info 1074 5184 ek110237 open (RUNLOG, ">$STATSBASE/thisrun.prof"); 1075 5184 ek110237 print RUNLOG "# " . conf_reqval("description") . "\n"; 1076 5184 ek110237 close (RUNLOG); 1077 5184 ek110237 1078 7736 Andrew system ("cat $PROFILENAME.prof >>".$STATSBASE."/thisrun.prof"); 1079 5184 ek110237 1080 7736 Andrew $statsdir = $STATSBASE . "/" . $config_name; 1081 7736 Andrew system("mkdir -p $statsdir"); 1082 7736 Andrew system("chmod a+w $statsdir"); 1083 5184 ek110237 1084 7736 Andrew if ($MULTI_CLIENT == 1) { 1085 7736 Andrew my @pidlist; 1086 7736 Andrew my %multi_confdata; 1087 7736 Andrew my $procpid; 1088 7736 Andrew my $syncclients = ""; 1089 7736 Andrew 1090 7736 Andrew %multi_confdata = %CONFDATA; 1091 7736 Andrew 1092 7736 Andrew foreach my $thisclient (@CLIENTLIST) { 1093 7736 Andrew my $tmpdir; 1094 7736 Andrew my $tmpstatdir; 1095 7736 Andrew my @clientdata; 1096 7736 Andrew 1097 7736 Andrew %CONFDATA = (); 1098 7736 Andrew %CONFDATA = %multi_confdata; 1099 7736 Andrew printf "building client: " . $thisclient . "\n"; 1100 7736 Andrew 1101 7736 Andrew # Setup the statistics directory for each client 1102 7736 Andrew $tmpstatdir = multi_getval("masterpath")."/".$thisclient; 1103 7736 Andrew 1104 7736 Andrew if ($SHAREDFILEALLOCATOR) { 1105 7736 Andrew $tmpdir = $TARGETDIR; 1106 7736 Andrew } else { 1107 7736 Andrew $tmpdir = $TARGETDIR."/".$thisclient; 1108 7736 Andrew } 1109 7736 Andrew 1110 7736 Andrew # add info to client hash 1111 7736 Andrew @clientdata = (); 1112 7736 Andrew $clientdata[2] = 1; 1113 7736 Andrew $CLIENTHASH{$thisclient} = \@clientdata; 1114 7736 Andrew $syncclients = $syncclients." --client ".$thisclient; 1115 7736 Andrew 1116 7736 Andrew push(@{ $CONFDATA{"myname"} }, $thisclient); 1117 7736 Andrew push(@{ $CONFDATA{"statsdir"} }, $tmpstatdir); 1118 7736 Andrew system("mkdir -p ".$FB_MASTERPATH."/".$thisclient); 1119 7736 Andrew system("chmod 0777 ".$FB_MASTERPATH."/".$thisclient); 1120 7736 Andrew 1121 7736 Andrew # modify dir config variable for multiclient 1122 7736 Andrew if (conf_exists("dir")) { 1123 7736 Andrew @{$CONFDATA{"dir"}} = ($tmpdir); 1124 7736 Andrew } 1125 7736 Andrew build_run(); 1126 7736 Andrew } 1127 7736 Andrew 1128 7736 Andrew # Begin the RUN!!! 1129 7736 Andrew print "Running " . $STATSBASE . "\n"; 1130 7736 Andrew 1131 7736 Andrew #spawn the synchronization server 1132 7736 Andrew print "Starting sync server on host ".$hostname."\n"; 1133 7736 Andrew if ($procpid = fork) { 1134 7736 Andrew push(@pidlist, $procpid); 1135 7736 Andrew } else { 1136 7736 Andrew sync_server(); 1137 7736 Andrew exit(0); 1138 7736 Andrew } 1139 7736 Andrew 1140 7736 Andrew sleep(3); 1141 7736 Andrew 1142 7736 Andrew # remotely execute the run on each client 1143 7736 Andrew foreach $thisclient (@CLIENTLIST) { 1144 7736 Andrew if($procpid = fork) { 1145 7736 Andrew push(@pidlist, $procpid); 1146 7736 Andrew } else { 1147 7736 Andrew if ($thisclient eq $hostname) { 1148 7736 Andrew print "Starting local client: $thisclient\n"; 1149 7736 Andrew system(multi_getval("masterpath")."/".$thisclient."/thisrun.f"); 1150 7736 Andrew } else { 1151 7736 Andrew print "Starting remote client: $thisclient\n"; 1152 7736 Andrew system("ssh ".$thisclient." ".multi_getval("masterpath")."/".$thisclient."/thisrun.f >> ".multi_getval("masterpath")."/".$thisclient."/runs.out"); 1153 7736 Andrew } 1154 7736 Andrew exit(0); 1155 7736 Andrew } 1156 7736 Andrew } 1157 7736 Andrew 1158 7736 Andrew # wait for all of them to finish 1159 7736 Andrew foreach $procpid (@pidlist) { 1160 7736 Andrew waitpid($procpid, 0); 1161 7736 Andrew } 1162 7736 Andrew 1163 7736 Andrew init_combined_stats(); 1164 7736 Andrew 1165 7736 Andrew foreach $thisclient (@CLIENTLIST) { 1166 7736 Andrew add_2combstats($config_name, $thisclient); 1167 7736 Andrew } 1168 7736 Andrew 1169 7736 Andrew # dump the combined client stats 1170 7736 Andrew dump_combined_stats($config_name); 1171 7736 Andrew 1172 7736 Andrew } else { 1173 7736 Andrew push(@{ $CONFDATA{"statsdir"} }, $statsdir); 1174 7736 Andrew 1175 7736 Andrew build_run(); 1176 7736 Andrew 1177 7736 Andrew # Execute the run 1178 7736 Andrew print "Running " . conf_reqval("statsdir") . "/thisrun.f\n"; 1179 7736 Andrew system ($statsdir."/thisrun.f"); 1180 7736 Andrew 1181 7736 Andrew 1182 7736 Andrew } 1183 7736 Andrew 1184 5184 ek110237 } 1185 7736 Andrew 1186 7736 Andrew # The following function is taken from the user's function file 1187 7736 Andrew post_run(); 1188 7736 Andrew 1189 7736 Andrew print "\n"; 1190