root/branches/Orange-Branch/src/apps/admin/pvfs2-genconfig @ 8479

Revision 8479, 48.1 KB (checked in by mtmoore, 3 years ago)

update genconfig to use appropriate PrecreateBatchSize? and PrecreateLowThreshold? values

  • Property svn:executable set to *
Line 
1#!/usr/bin/perl -w
2#
3#  (C) 2001 Clemson University and The University of Chicago
4#
5#  See COPYING in top-level directory.
6#
7# generate a global pvfs2 configuration file based on user input
8#
9use Term::ReadLine;
10use Getopt::Long;
11use Math::BigInt;
12
13# turn on strictness
14use strict 'vars';
15
16# ugly global variables for option parsing
17my $opt_protocol = '';
18my $opt_port = '';
19my $opt_board = '';
20my $opt_tcpport = '';
21my $opt_tcpbindspecific = '0';
22my $opt_gmport = '';
23my $opt_mxboard = '';
24my $opt_mxendpoint = '';
25my $opt_ibport = '';
26my $opt_portal = '';
27my $opt_ioservers = '';
28my $opt_metaservers = '';
29my $opt_logfile = '';
30my $opt_storage = '';
31my $opt_trovesync = '1';
32my $opt_trovemethod = '';
33my $opt_quiet = '';
34my $opt_logging = '';
35my $opt_tracing = '';
36my $opt_logstamp = '';
37my $opt_server_job_timeout = '';
38my $opt_client_job_timeout = '';
39my $opt_first_handle = '';
40my $opt_last_handle = '';
41my $opt_root_handle = '';
42my $opt_fsid = '';
43my $opt_fsname = '';
44my $opt_default_num_dfiles = '';
45my $opt_default_flow_buffer_size = '';
46my $opt_default_flow_buffer_count = '';
47
48my $opt_security = '0';
49my $opt_trusted_port = '';
50my $opt_trusted_network = '';
51my $opt_trusted_netmask = '';
52
53my $opt_iospec = undef;
54my $opt_metaspec = undef;
55
56my %all_endpoints = ();
57
58my $default_storage = undef;
59my $default_meta_storage = undef;
60my $default_logfile = undef;
61
62my $bmi_module = undef;
63
64my $opt_gen_key = 0;
65
66my $META_ENDPOINT = 0x1;
67my $IO_ENDPOINT   = 0x2;
68
69my $OUT = undef;
70my $term = undef;
71
72#$num_unexp_reqs = prompt_num("How many unexpected requests should we be prepared to receive?  ");
73my $num_unexp_reqs = 50;
74
75# sometimes people use ip addresses instead of hostnames.  perl's default sort
76# will sort the ip addresses lexically, not numerically, so we need a slightly
77# smarter sorter
78
79sub get_user_input
80{
81    my($prompt,$res);
82       
83    print $OUT "\n";
84    $prompt = "* $_[0]";
85
86    my $line = $term->readline($prompt);
87    print $OUT "\n";
88    return $line;
89}
90
91sub valid_number
92{
93    my($num, $len, $i, $digit);
94
95    $num = $_[0];
96    $len = length($num);
97
98    for($i = 0; $i < $len; $i++)
99    {
100        $digit = substr($num,$i,1);
101        if (($digit < 0) || ($digit > 9))
102        {
103            return 0;
104        }
105    }
106    return (($len > 0) ? 1 : 0);
107}
108
109sub prompt_num
110{
111    my($prompt,$num,$default);
112    $prompt = $_[0];
113    $default = $_[1];
114    do
115    {
116        $num = get_user_input($prompt);
117        if (length($num) == 0)
118        {
119            return $default;
120        }
121    } while(!valid_number($num));
122    return $num;
123}
124
125sub prompt_word
126{
127    my($prompt,$default,$val);
128    $prompt = $_[0];
129    $default = $_[1];
130
131    $val = get_user_input($prompt);
132    if (length($val) == 0)
133    {
134        $val = $default;
135    }
136    return $val;
137}
138
139sub parse_hostlist
140{
141    my $inputline = shift;
142    my @components = ();
143    my @hosts = ();
144
145    # we want to split the string into components seperated by comma
146    # but we don't want split components that have curly brackets.  For example,
147    # we need to be sure that "hosta{1-4,8-12},hostb,hostc{1,2,3}" splits to
148    # hosta{1-4,8-12}
149    # hostb
150    # hostc{1,2,3}
151    #
152    @components = $inputline =~ /(?:,?[ ]*([^{,]+(?:{[^}]+})?[^,]*))/g;
153    foreach my $comp_ws (@components)
154    {
155        my $comp;
156
157        # Trim leading and trailing whitespace
158        $comp = $comp_ws;
159        $comp =~ s/^\s+//;
160        $comp =~ s/\s+$//;
161
162        # if we've got a component that has {..}, then expand.
163        # match the prefix (hostname) and curly brackets
164        if($comp =~ /([^{]+){([^}]+)}(.*)$/)
165        {
166            my $prefix = $1;
167            my $ranges = $2;
168            my $suffix = $3;
169
170            # split the ranges string on the commas
171            foreach my $r (split(/,/, $ranges))
172            {
173                if($r !~ /-/)
174                {
175                    # only one number, just push it on
176                }
177                else
178                {
179                    # min and max in this range.  Add each of the indexes
180                    my ($s, $f) = $r =~ /([0-9]+)-([0-9]+)/;
181                    for(my $i = $s; $i <= $f; ++$i)
182                    {
183                        push @hosts, "$prefix$i$suffix";
184                    }
185                }
186            }
187        }
188        else {
189            push @hosts, $comp;
190        }
191    }
192    return @hosts;
193}
194
195sub emit_defaults
196{
197    my ($target, $num_unexp, $bmi_module, $logfile,
198        $logging, $tracing, $logstamp, $server_job_timeout, $client_job_timeout) = @_;
199
200    print $target "<Defaults>\n";
201    print $target "\tUnexpectedRequests $num_unexp\n";
202    print $target "\tEventLogging $logging\n";
203    print $target "\tEnableTracing $tracing\n";
204    print $target "\tLogStamp $logstamp\n";
205    print $target "\tBMIModules $bmi_module\n";
206    print $target "\tFlowModules flowproto_multiqueue\n";
207    print $target "\tPerfUpdateInterval 1000\n";
208    print $target "\tServerJobBMITimeoutSecs $server_job_timeout\n";
209    print $target "\tServerJobFlowTimeoutSecs $server_job_timeout\n";
210    print $target "\tClientJobBMITimeoutSecs $client_job_timeout\n";
211    print $target "\tClientJobFlowTimeoutSecs $client_job_timeout\n";
212    print $target "\tClientRetryLimit 5\n";
213    print $target "\tClientRetryDelayMilliSecs 2000\n";
214    print $target "\tPrecreateBatchSize 0,32,512,32,32,32,0\n";
215    print $target "\tPrecreateLowThreshold 0,16,256,16,16,16,0\n";
216
217    if(defined($default_storage))
218    {
219        print $target "\n\tDataStorageSpace " . $default_storage . "\n";
220    }
221
222    if(defined($default_meta_storage))
223    {
224        print $target "\tMetadataStorageSpace " . $default_meta_storage . "\n\n";
225    }
226
227    if(defined($default_logfile))
228    {
229        print $target "\tLogFile " . $default_logfile . "\n";
230    }
231
232    if($opt_tcpbindspecific)
233    {
234        print $target "\tTCPBindSpecific yes\n";
235    }
236
237    print $target "</Defaults>\n";
238}
239
240sub emit_security
241{
242    my ($target, $portlist, $network, $netmask) = @_;
243
244    print $target "<Security>\n";
245    print $target "\tTrustedPorts $portlist\n";
246    print $target "\tTrustedNetwork $network $netmask\n";
247    print $target "</Security>\n";
248}
249
250sub emit_aliases
251{
252    my $target = shift;
253
254    print $target "\n<Aliases>\n";
255    foreach my $alias (sort keys %all_endpoints)
256    {
257        print $target "\tAlias $alias " .
258        get_bmi_endpoint($alias) . "\n";
259    }
260    print $target "</Aliases>\n";
261}
262
263sub emit_filesystem
264{
265    my ($target, $name, $fs_id, $root_handle,
266        $last_handle, $first_handle, $count,
267        $default_num_dfiles, $default_flow_buffer_size, $default_flow_buffer_count) = @_;
268
269    # divide handle range space equally among servers ((2^63)-1 for now)
270    my($total_num_handles_available, $start, $end, $i, $step, $num_ranges, $stuffing);
271    $num_ranges = $count;
272    $total_num_handles_available = $last_handle->copy();
273    $total_num_handles_available->bsub($first_handle);
274    $total_num_handles_available->binc();
275
276    # since meta and data handle ranges must be split, increment
277    # num nodes for calculation purposes below
278    $step = $total_num_handles_available->copy();
279    $step->bdiv($num_ranges);
280
281    print $target "\n<Filesystem>\n";
282    print $target "\tName $name\n";
283    print $target "\tID $fs_id\n";
284    print $target "\tRootHandle $root_handle\n";
285    if($default_num_dfiles > 0)
286    {
287        print $target "\tDefaultNumDFiles $default_num_dfiles\n";
288    }
289
290    # Rules for default stuffing setting: only enable it if every I/O server
291    # is also a metadata server, otherwise we would tend to unbalance by
292    # always stuffing on the subset that does metadata.  User can override
293    # if desired.
294    $stuffing = "yes";
295    foreach my $alias (keys %all_endpoints)
296    {
297        if($all_endpoints{$alias}->{TYPE} & $IO_ENDPOINT)
298        {
299            if(!($all_endpoints{$alias}->{TYPE} & $META_ENDPOINT))
300            {
301                $stuffing = "no";
302            }
303        }
304    }
305    print $target "\tFileStuffing $stuffing\n";
306
307    print $target "\t<MetaHandleRanges>\n";
308    $start = $end = $first_handle->copy();
309    $start->bdec();
310    $end->bdec();
311
312    my @meta_aliases = get_aliases($META_ENDPOINT);
313    @meta_aliases = sort @meta_aliases;
314    foreach my $ma (@meta_aliases)
315    {
316        $start = $end->copy();
317        $start->binc();
318        $end->badd($step);
319        print $target "\t\tRange $ma $start-$end\n";
320    }
321
322    print $target "\t</MetaHandleRanges>\n";
323    print $target "\t<DataHandleRanges>\n";
324
325    my @io_aliases = get_aliases($IO_ENDPOINT);
326    @io_aliases = sort @io_aliases;
327    foreach my $ia (@io_aliases)
328    {
329        $start = $end->copy();
330        $start->binc();
331        $end->badd($step);
332        print $target "\t\tRange $ia $start-$end\n";
333    }
334    print $target "\t</DataHandleRanges>\n";
335
336    print $target "\t<StorageHints>\n";
337
338    # only in special cases would someone want to sync data (failover comes to
339    # mind)  The default thus should be to sync metadata but not sync data. 
340    if ($opt_trovesync == 1) {
341        print $target "\t\tTroveSyncMeta yes\n";
342        print $target "\t\tTroveSyncData no\n";
343    } else {
344        print $target "\t\tTroveSyncMeta no\n";
345        print $target "\t\tTroveSyncData no\n";
346        print $target "\t\tCoalescingHighWatermark infinity\n";
347        print $target "\t\tCoalescingLowWatermark 1\n";
348    }
349
350    if($opt_trovemethod ne "")
351    {
352        print $target "\t\tTroveMethod $opt_trovemethod\n";
353    }
354    else
355    {
356        print $target "\t\tTroveMethod alt-aio\n";
357    }
358
359    print $target "\t</StorageHints>\n";
360
361    if($opt_gen_key ne "0")
362    {
363        emit_fs_key($target);
364    }
365
366    if($default_flow_buffer_size > 0)
367    {
368        print $target "\tFlowBufferSizeBytes $default_flow_buffer_size\n";
369    }
370 
371    if($default_flow_buffer_count > 0)
372    {
373        print $target "\tFlowBuffersPerFlow $default_flow_buffer_count\n";
374    }
375
376    print $target "</Filesystem>\n";
377}
378
379sub emit_serveropts
380{
381    my $target = shift;
382
383    foreach my $alias (sort keys %all_endpoints)
384    {
385        my $endpoint = $all_endpoints{$alias};
386        print $target "\n<ServerOptions>\n";
387        print $target "\tServer $alias\n";
388        print $target "\tDataStorageSpace $endpoint->{STORAGE}\n";
389        print $target "\tMetadataStorageSpace $endpoint->{METASTORAGE}\n";
390        print $target "\tLogFile $endpoint->{LOGFILE}\n";
391        print $target "</ServerOptions>\n";
392    }
393}
394
395
396sub emit_server_conf
397{
398    my($target, $node, $storage, $metastorage, $logfile) = @_;
399
400    print $target "DataStorageSpace $storage\n";
401    print $target "MetadataStorageSpace $metastorage\n";
402    print $target "HostID \"" . get_bmi_endpoint($node) . "\"\n";
403    print $target "LogFile $logfile\n";
404}
405
406sub emit_fs_key
407{
408    my ($target, @path, $openssl_cmd, $b64_rand);
409
410    $target = $_[0];
411
412    $openssl_cmd = undef;
413
414    @path = split(/:/, $ENV{PATH});
415    for my $p (@path)
416    {
417        if( -x "$p/openssl" )
418        {
419            $openssl_cmd = "$p/openssl";
420        }
421    }
422
423    if(!defined($openssl_cmd))
424    {
425        print STDERR "\n\nFailed to find openssl executable in PATH\n\n";
426        exit 1;
427    }
428
429    $b64_rand = `$openssl_cmd rand -base64 20 2> /dev/null`;
430    chomp($b64_rand);
431    print $target "\tSecretKey $b64_rand\n";
432}
433
434sub confirm
435{
436    my($prompt, $char, $valid_char);
437    $prompt = shift;
438    $valid_char = 0;
439    do
440    {
441        $char = prompt_word($prompt,"-");
442        if (($char eq 'y') || ($char eq 'n'))
443        {
444            $valid_char = 1;
445        }
446    } while($valid_char == 0);
447
448    return (($char eq 'y') ? 1 : 0);
449}
450
451sub specusage
452{
453    print $OUT <<"THIS"                               
454               
455  The -iospec and -metaspec options allow a wide variaty of configurations
456  to be specified, including multiple endpoints on the same node (different
457  ports), different storage locations for endpoints on the same node, etc.
458
459  Both the -iospec and -metaspec options take strings as arguments.
460  The format of the strings are comma separated endpoints, where
461  each endpoint is formatted as:
462               
463    [<proto>://]<host>:<port>[:<storage>][:<logfile>]
464
465  The protocol, storage, and logfile are all optional.
466  The port can be a range of the format {#-#,#,#-#,..}.
467  If the logfile is specified, the storage path must be as well.
468               
469  Examples:
470
471    myhosta:3334,myhostb:{3334-3338}
472    myhosta:{3334-3338}
473    ib://myhosta:3335:/psto,tcp://myhostb:3334:/psto
474
475  Multiple protocols for the same endpoint may also be specified.  The
476  format for this type of endpoint is:
477
478    [<proto1>://<host>:<port1>,<proto2>://<host>:<port2>,...]
479
480  In this case, the [] delineate the single endpoint (with multiple protocols)
481  from the rest of the spec.  While the protocols and ports are different, the
482  host for each uri must be the same.  For example:
483
484    --metaspec="[ib://myhosta:3335,gm://myhosta:6,mx://myhosta:0:3]:/psto,tcp://myhostb:3334"
485
486  This specifies that one endpoint is at myhosta with the infiniband and myrinet
487  protocols enabled, and the other endpoint is at myhostb with tcp enabled.
488
489  Note that the --iospec and --metaspec options cannot be used with enumerated
490  hosts.  Each endpoint must be a single host.  I.e. tcp://myhost{1-4}:3334
491  is not allowed.  This does not preclude multiple endpoints from being
492  on the same host, such as tcp://myhost1:{3334-3338}
493
494THIS
495    ;;
496}
497
498sub usage
499{
500
501# dump usage with a single HERE document rather than seperate print
502# statements
503    print $OUT <<"THIS";   
504Usage: pvfs2-genconfig [OPTIONS] <fs.conf>
505
506  The pvfs2-genconfig utility creates configuration files for the
507  PVFS2 file system.  The <fs.conf> argument is
508  manditory and specify the name of the configuration file that will
509  be written.  This utility will create the fs.conf file. 
510
511  EXAMPLE: 'pvfs2-genconfig /tmp/fs.conf' will
512  generate a file called /tmp/fs.conf
513  NOTE: If pvfs2-genconfig is executed with a single argument of "-",
514  then all output is directed to stdout and no files are written.
515
516  All other arguments are optional.  If run without any optional
517  arguments, then pvfs2-genconfig will prompt interactively for required
518  parameters.
519
520  pvfs2-genconfig can also be executed non-interactively with --quiet
521  and one of the two [] grouped options below:
522
523     [
524       --protocol    <PROTO>[,<PROTO>..] protocol(s) to use (tcp,gm,mx,ib,portals)
525       --ioservers   <STRING>   hostnames of data servers.  Can be
526                                <prefix>{#-#,#,#-#,...}
527       --metaservers <STRING>   hostnames of meta servers.
528     ]
529  or
530     [
531       --iospec      <STRING>   endpoints of data servers. See --spec-usage
532       --metaspec    <STRING>   endpoints of meta servers. See --spec-usage
533     ]
534
535  The following arguments are entirely optional, whether your intention is
536  to run pvfs2-genconfig in interactive or non-interactive mode:
537
538     --tcpport     <NUM>               TCP port to use (default: 3334)
539     --tcpbindspecific                 Bind TCP only to specific interfaces
540     --gmport      <NUM>               GM port to use (default: 6)
541     --mxboard     <NUM>               MX board to use (default is 0)
542     --mxendpoint  <NUM>               MX endpoint to use (default is 3)
543     --ibport      <NUM>               IB port to use (default is 3335)
544     --portal      <NUM>               Portals index for
545                                       listening server (default is 5)
546     --logging     <STRING>            debugging mask for log messages
547     --tracing                         Enable event tracing in the server
548     --logstamp    <STRING>            timestamp type for log messages
549                                       ('none','usec', or 'datetime' are valid)
550     --storage <STRING>                path to pvfs storage directory.
551     --logfile <STRING>                file to place server logging.
552     --notrovesync                     sync metadata only upon request
553     --server-job-timeout <NUM>        server job timeout value (seconds)
554     --client-job-timeout <NUM>        server job timeout value (seconds)
555     --trove-method <STRING>           specify a trove method
556     --first-handle <NUM>              first handle value to reserve
557     --last-handle  <NUM>              last handle value to reserve
558     --root-handle  <NUM>              handle value to reserve for root object
559     --fsid         <NUM>              fs identifier value
560     --fsname <STRING>                 fs name
561     --default-num-dfiles <NUM>        number of datafiles to use per file
562                                       (defaults to number of I/O servers)
563     --flow-buffer-size <NUM>          set flowbuffersize in bytes           
564     --flow-buffer-count <NUM>         set flow buffers per flow
565     --trusted      <0|1>              indicate whether trusted connection options need to be emitted
566     --genkey                          optionally generates a secret key for the
567                                       filesystem(s).
568
569     --help                            This message
570     --spec-usage                      Show the usage info for --iospec
571                                       and --metaspec options
572THIS
573
574}
575
576sub print_welcome
577{
578    if (!$opt_quiet) {
579        print $OUT <<"WELCOMEMSG"
580**********************************************************************
581    Welcome to the PVFS2 Configuration Generator:
582
583This interactive script will generate configuration files suitable
584for use with a new PVFS2 file system.  Please see the PVFS2 quickstart
585guide for details.
586
587**********************************************************************
588WELCOMEMSG
589        ;;
590    }
591}
592
593sub get_portlist
594{
595    my $type;
596
597    if (!$opt_quiet) {
598        print $OUT <<"PORTLIST"
599
600You must enter the trusted port ranges that your file system will accept
601This must be of the form <port1 - port2>
602PORTLIST
603        ;;
604        $type = prompt_word("Enter port list [Default is 0-65535]: ","0-65535");
605    }
606    return $type;
607}
608
609sub get_network
610{
611    my $type;
612
613    if (!$opt_quiet) {
614        print $OUT <<"NETWORK"
615You must enter the network address and network mask to identify list of trusted hosts
616This must be of the form <network>, <netmask>
617NETWORK
618        ;;
619    }
620    $type = prompt_word("Enter network address, network mask [Default is 0.0.0.0, 0.0.0.0]: ", "0.0.0.0, 0.0.0.0");
621    return $type;
622}
623
624sub get_protocol
625{
626    my $type;
627    my %port;
628
629    if ($opt_protocol) {
630        $type = $opt_protocol;
631    } else {
632        if (!$opt_quiet) {
633            # get network type
634            print $OUT <<"PROTOCOL"
635You must first select the network protocol that your file system will use.
636The only currently supported options are \"tcp\", \"gm\", \"mx\", \"ib\", and \"portals\".
637(For multi-homed configurations, use e.g. \"ib,tcp\".)
638PROTOCOL
639            ;;
640        }
641        $type = prompt_word("Enter protocol type [Default is tcp]: ","tcp");
642    }
643
644    foreach (split(',', $type)) {
645        if ($_ eq "tcp") {
646            $port{'tcp'} = tcp_get_port();
647            if ($opt_security == 1)
648            {
649                $opt_trusted_port = get_portlist();
650                my $str = get_network();
651                my $cnt = 0;
652                foreach (split(',', $str)) {
653                    $_ =~ s/\s/ /g;
654                    $_ =~ s/ +/ /g;
655                    $_ =~ s/^ +//;
656                    $_ =~ s/ +$//;
657                    if ($cnt == 0)
658                    {
659                        $opt_trusted_network = "tcp://" . $_;
660                    }
661                    else
662                    {
663                        $opt_trusted_netmask = "tcp://" . $_;
664                    }
665                    $cnt = $cnt + 1;
666                }
667            }
668        } elsif ($_ eq "gm") {
669            $port{'gm'} = gm_get_port();
670        } elsif ($_ eq "mx") {
671            $port{'mx'} = mx_get_endpoint();
672        } elsif ($_ eq "ib") {
673            $port{'ib'} = ib_get_port();
674        } elsif ($_ eq "portals") {
675            $port{'portals'} = portals_get_portal();
676        } else {
677            die "Sorry.  At this time, only the tcp, gm, mx, ib, and portals protocols are available\nfor use with this configuration utility.\n";
678        }
679    }
680
681    return \%port;
682}
683
684sub get_logging
685{
686    my $logging;
687    if ($opt_logging) {
688        $logging = $opt_logging;
689    } else {
690        $logging = "none";
691    }
692    return $logging;
693}
694
695sub get_tracing
696{
697    my $tracing;
698    if ($opt_tracing) {
699        $tracing = "yes";
700    } else {
701        $tracing = "no";
702    }
703    return $tracing;
704}
705
706sub get_logstamp
707{
708    my $logstamp;
709    if ($opt_logstamp) {
710        $logstamp = $opt_logstamp;
711    } else {
712        $logstamp = "datetime";
713    }
714    return $logstamp;
715}
716
717sub get_root_handle
718{
719    my $root_handle;
720    if ($opt_root_handle) {
721        $root_handle = $opt_root_handle;
722    } else {
723        $root_handle = 1048576;
724    }
725    return $root_handle;
726}
727
728sub get_fsid
729{
730    my $fsid;
731    if ($opt_fsid) {
732        $fsid = $opt_fsid;
733    } else {
734        # compute a psuedo-random 32 bit file system ID
735        $fsid = int((rand() * 2147483647));
736    }
737    return $fsid;
738}
739
740sub get_fsname
741{
742    my $fsname;
743    if ($opt_fsname) {
744        $fsname = $opt_fsname;
745    } else {
746        $fsname = "pvfs2-fs";
747    }
748    return $fsname;
749}
750
751sub get_last_handle
752{
753    my $last_handle;
754    if ($opt_last_handle) {
755        $last_handle = Math::BigInt->new($opt_last_handle);
756    } else {
757        $last_handle = Math::BigInt->new('0x7FFFFFFFFFFFFFFF');  # 2^63
758    }
759    return $last_handle;
760}
761
762sub get_default_num_dfiles
763{
764    my $default_num_dfiles;
765    if ($opt_default_num_dfiles) {
766        $default_num_dfiles = $opt_default_num_dfiles;
767    } else {
768        $default_num_dfiles = -1;
769    }
770    return $default_num_dfiles;
771}
772
773sub get_default_flow_buffer_size
774{
775    my $default_flow_buffer_size;
776    if($opt_default_flow_buffer_size ne '') {
777        $default_flow_buffer_size = $opt_default_flow_buffer_size;
778    } else {
779        $default_flow_buffer_size = -1;
780    }
781    return $default_flow_buffer_size;
782}
783
784sub get_default_flow_buffer_count
785{
786    my $default_flow_buffer_count;
787    if($opt_default_flow_buffer_count ne '') {
788        $default_flow_buffer_count = $opt_default_flow_buffer_count;
789    } else {
790        $default_flow_buffer_count = -1;
791    }
792    return $default_flow_buffer_count;
793}
794
795sub get_first_handle
796{
797    my $first_handle;
798    if ($opt_first_handle) {
799        $first_handle = Math::BigInt->new($opt_first_handle);
800    } else {
801        $first_handle = Math::BigInt->new(4);
802    }
803    return $first_handle;
804}
805
806sub get_server_job_timeout
807{
808    my $server_job_timeout;
809    if ($opt_server_job_timeout) {
810        $server_job_timeout = $opt_server_job_timeout;
811    } else {
812        $server_job_timeout = 30;
813    }
814    return $server_job_timeout;
815}
816
817sub get_client_job_timeout
818{
819    my $client_job_timeout;
820    if ($opt_client_job_timeout) {
821        $client_job_timeout = $opt_client_job_timeout;
822    } else {
823        $client_job_timeout = 300;
824    }
825    return $client_job_timeout;
826}
827
828sub get_logfile
829{
830    my $logfile = "/tmp/pvfs2-server.log";
831    if ($opt_logfile) {
832        $logfile = $opt_logfile;
833    } elsif (!$opt_quiet) {
834            print $OUT "Choose a file for each server to write log messages to.\n";
835            $logfile = prompt_word("Enter log file location [Default is /tmp/pvfs2-server.log]: ","/tmp/pvfs2-server.log");
836    }
837    return $logfile;
838}
839
840sub get_storage
841{
842    my $storage = "/pvfs2-storage-space";
843    if ($opt_storage) {
844        $storage = $opt_storage;
845    } elsif (!$opt_quiet) {
846            print $OUT "Choose a directory for each server to store data in.\n";
847            $storage = prompt_word("Enter directory name: [Default is /pvfs2-storage-space]: ","/pvfs2-storage-space");
848    }
849    return $storage;
850}
851
852sub get_meta_storage
853{
854    my $metastorage = "/pvfs2-storage-space";
855    if ($opt_storage) {
856        $metastorage = $opt_storage;
857    } elsif (!$opt_quiet) {
858            print $OUT "Choose a directory for each server to store metadata in.\n";
859            $metastorage = prompt_word("Enter directory name: [Default is /pvfs2-storage-space]: ","/pvfs2-storage-space");
860    }
861    return $metastorage;
862}
863
864# get host port
865sub tcp_get_port
866{
867    my $port = 3334;
868    if ($opt_tcpport) {
869        $port = $opt_tcpport;
870    } elsif (!$opt_iospec) {
871        if (!$opt_quiet) {
872            print $OUT "Choose a TCP/IP port for the servers to listen on.  Note that this\n";
873            print $OUT "script assumes that all servers will use the same port number.\n";
874            $port = prompt_num("Enter port number [Default is 3334]: ","3334");
875        }
876    }
877    return  $port;
878}
879
880sub gm_get_port
881{
882    my $port = 6;
883    if ($opt_gmport) {
884        $port = $opt_gmport;
885    } elsif (!$opt_iospec) {
886        if (!$opt_quiet) {
887            print $OUT "Choose a GM port (in the range of 0 to 7) for the servers to listen on. \n";
888            print $OUT "This script assumes that all servers will use the same port number.\n";
889            $port = prompt_num("Enter port number [Default is 6]: ","6");
890        }
891    }
892    # every myrinet card i've seen has 8 ports.  If myricom makes a card
893    # with more than that, we'll have to adapt
894    ($port < 8) or die "GM ports must be in the range 0 to 7";
895
896    return  $port;
897}
898
899sub mx_get_endpoint
900{
901    my $port = 3;
902    my $board = 0;
903
904    if ($opt_mxboard) {
905        $board = $opt_mxboard;
906    } elsif (!$opt_iospec) {
907        if (!$opt_quiet) {
908            print $OUT "Choose a MX board (in the range of 0 to 4) for the servers to listen on. \n";
909            print $OUT "This script assumes that all servers will use the same board number.\n";
910            $board = prompt_num("Enter board number [Default is 0]: ","0");
911        }
912    }
913    # The number of boards is only limited by the number of PCI-X or PCI-Express
914    # slots in the machine. This is reasonable maximum.
915    ($board < 8) or die "MX board must be in the range 0 to 7";
916
917    if ($opt_mxendpoint) {
918        $port = $opt_mxendpoint;
919    } elsif (!$opt_iospec) {
920        if (!$opt_quiet) {
921            print $OUT "Choose a MX endpoint (in the range of 0 to 7) for the servers to listen on. \n";
922            print $OUT "This script assumes that all servers will use the same port number.\n";
923            $port = prompt_num("Enter port number [Default is 3]: ","3");
924        }
925    }
926    # The number of endpoints in MX is configurable. The default value is 4
927    # but may be changing to 8. It can be higher, but this is reasonable.
928    ($port < 8) or die "MX endpoint must be in the range 0 to 7";
929
930    $port = $board . ":" . $port;
931    return  $port;
932}
933
934sub ib_get_port
935{
936    my $port = 3335;
937    if ($opt_ibport) {
938        $port = $opt_ibport;
939    } elsif(!$opt_iospec) {
940        if (!$opt_quiet) {
941            print $OUT "Choose a TCP/IP port for the servers to listen on for IB communications.  Note that this\n";
942            print $OUT "script assumes that all servers will use the same port number.\n";
943            $port = prompt_num("Enter port number [Default is 3335]: ","3335");
944        }
945    }
946    return  $port;
947}
948
949sub portals_get_portal
950{
951    my $port = 5;
952    if ($opt_portal) {
953        $port = $opt_portal;
954    } elsif(!$opt_iospec) {
955        if (!$opt_quiet) {
956            print $OUT "Choose a portal index for the servers to listen on for communications.  Note that this\n";
957            print $OUT "script assumes that all servers will use the same portal index.\n";
958            $port = prompt_num("Enter portal index [Default is 5]: ","5");
959        }
960    }
961    return $port;
962}
963
964sub get_ionames
965{
966    my $portmap = shift;
967    my $storage = shift;
968    my $metastorage = shift;
969    my $logfile = shift;
970    my $ioline = '';
971    if ($opt_ioservers) {
972        $ioline = $opt_ioservers;
973    } else {
974        print $OUT "Next you must list the hostnames of " .
975                   "the machines that will act as\n";
976        print $OUT "I/O servers.  Acceptable syntax is " .
977                   "\"node1, node2, ...\" or \"node{#-#,#,#}\".\n";
978        $ioline = prompt_word(
979            "Enter hostnames [Default is localhost]: ",
980            "localhost");
981    }
982
983    my @io_hosts = parse_hostlist($ioline);
984    foreach my $io_host (@io_hosts)
985    {
986        if(exists $all_endpoints{$io_host})
987        {
988            $all_endpoints{$io_host}->{TYPE} |= $IO_ENDPOINT;
989        }
990        else
991        {
992
993            $all_endpoints{$io_host} = {
994                ALIAS => $io_host,
995                TYPE => $IO_ENDPOINT,
996                HOSTNAME => $io_host,
997                PORTMAP => $portmap,
998                STORAGE => $storage,
999                METASTORAGE => $metastorage,
1000                LOGFILE => $logfile};
1001        }
1002    }
1003}
1004
1005sub get_metanames
1006{
1007    my $portmap = shift;
1008    my $storage = shift;
1009    my $metastorage = shift;
1010    my $logfile = shift;
1011    my $metaline = '';
1012    my @meta_hosts;
1013    if ($opt_metaservers) {
1014        $metaline = $opt_metaservers;
1015        @meta_hosts = parse_hostlist($metaline);
1016    }
1017    else
1018    {
1019        print $OUT "Use same servers for metadata? (recommended)\n";
1020        $metaline = prompt_word(
1021            "Enter yes or no [Default is yes]: ",
1022            "yes");
1023        if($metaline =~ /^yes$/i)
1024        {
1025            foreach my $alias (keys %all_endpoints)
1026            {
1027                $all_endpoints{$alias}->{TYPE} |= $META_ENDPOINT;
1028            }
1029        }
1030        else
1031        {
1032            print $OUT "Now list the hostnames of the machines that will act as " .
1033                       "Metadata\nservers.  This list may or may not overlap " .
1034                       "with the I/O server list.\n";
1035            $metaline = prompt_word(
1036                "Enter hostnames [Default is localhost]: ",
1037                "localhost");
1038            @meta_hosts = parse_hostlist($metaline);
1039        }
1040    }
1041
1042    foreach my $meta_host (@meta_hosts)
1043    {
1044        if(exists $all_endpoints{$meta_host})
1045        {
1046            $all_endpoints{$meta_host}->{TYPE} |= $META_ENDPOINT;
1047        }
1048        else
1049        {
1050            $all_endpoints{$meta_host} = {
1051                ALIAS => $meta_host,
1052                TYPE => $META_ENDPOINT,
1053                HOSTNAME => $meta_host,
1054                PORTMAP => $portmap,
1055                STORAGE => $storage,
1056                METASTORAGE => $metastorage,
1057                LOGFILE => $logfile};
1058        }
1059    }
1060}
1061
1062sub get_specs
1063{
1064    my $type = shift;
1065    my $line = shift;
1066
1067    # we need to split the spec string into individual components that
1068    # specify different endpoints.  The endpoints are separated by commas,
1069    # but so are the protocols inside square brackets [] and the port ranges
1070    # inside curly brackets {}, so its a bit tricky to get what we actually
1071    # want.  Hence the long regex. 
1072    #
1073    # The (?: ...) groups a pattern without
1074    # putting the matched text in the result variables ($1, $2, ..).  The
1075    # regex tries to match everything that's not a comma, skipping over
1076    # the [] and {} bits that may contain commas.  The global flag at the
1077    # end allows it to keep matching until no more matches can be made.
1078    #
1079    my @endpoints =
1080        $line =~ /(?:,?[ ]*((?:\[[^\]]+\])|[^\[{,]+(?:{[^}]+})?[^\[{,]*))/g;
1081
1082    foreach my $ep (@endpoints)
1083    {
1084        my $stor = undef;
1085        my $mstor = undef;
1086        my $logf = undef;
1087        my $proto = undef;
1088        my $hostname = undef;
1089        my $portn = undef;
1090        my $boardn = undef;
1091        if($ep =~ /^\[/)
1092        {
1093            # the string must have multiple protocols specified for the same
1094            # endpoint.  We want to match on [...]:storage:logfile
1095            # and place the stuff between the [] in $1, and optionally
1096            # place the matched storage path and meta path in $2 and $3,
1097            # logfile is in $4
1098            #
1099            $ep =~ /\[([^\]]+)\](?::([^:]+))?(?::([^:]+))?/;
1100
1101            $stor = $2;
1102            $mstor = $3;
1103            $logf = $4;
1104
1105            if(!defined($1))
1106            {
1107                print STDERR "Invalid spec option format: Missing endpoints\n" .
1108                             "between brackets.\n\n";
1109                exit(1);
1110            }
1111
1112            my @multiproto = split(/,/, $1);
1113            my $alias_suffix = "";
1114            my %port = ();
1115            foreach my $prothost (@multiproto)
1116            {
1117                $prothost =~ /([a-z]+):\/\/([^:]+):([0-9]+)/;
1118                $proto = $1;
1119                my $hn = $2;
1120
1121                # special casing for mx
1122                if($proto =~ /mx/)
1123                {
1124                    $boardn = $3;
1125                    $portn = $4;
1126                }
1127                else
1128                {
1129                    $portn = $3;
1130                }
1131
1132                if(!defined($hostname))
1133                {
1134                    $hostname = $hn;
1135                }
1136                elsif($hostname ne $hn)
1137                {
1138                    print STDERR "Invalid spec option format: multiple" . 
1139                                 "protocols specified between [] must\n" .
1140                                 "specify the same host ($hostname != $hn)\n\n";
1141                    exit(1);
1142                }
1143
1144                $port{$proto} = "$boardn:$portn";
1145                $alias_suffix .= "_" . $proto . $boardn . "_" . $portn;
1146            }
1147
1148            my $alias = $hostname . $alias_suffix;
1149            $all_endpoints{$alias} = {
1150                ALIAS => $alias,
1151                TYPE => $type,
1152                HOSTNAME => $hostname,
1153                PORTMAP => \%port,
1154                STORAGE => $stor,
1155                METASTORAGE => $mstor,
1156                LOGFILE => $logf};
1157        }
1158        else
1159        {
1160            # I'll probably forget what this does in a day or two, hence the
1161            # comment.  The (?: ...) pattern allows for grouping without
1162            # putting the matched string in the result variables ($1, $2, ..).
1163            # The first (?: ...) pattern optionally looks for the protocol.
1164            # There's a subgroup that matches the actual protocol name and puts
1165            # it in $1 if it exists.
1166            # The grouped pattern following that looks for the hostname, and
1167            # the one after that looks for the port, putting the results
1168            # in $2 and $3 respectively.  The next two (?: ...) optionally
1169            # match the storage and logfile respectively, with subgroups that
1170            # put the actual strings into $4 and $5.
1171            #
1172            my $count =
1173                $ep =~ /(?:([a-z]+):\/\/)?([^:]+):([^:]+)(?::([^:]+))?(?::([^:]+))?(?::([^:]+))?/;
1174            if(!defined($1))
1175            {
1176                # assume tcp for now
1177                $proto = "tcp";
1178            }
1179            else
1180            {
1181                $proto = $1;
1182            }
1183
1184            if(!defined($2))
1185            {
1186                print STDERR "Invalid spec option format: endpoint: $ep\n" .
1187                "requires a port number\n";
1188                exit(1);
1189            }
1190            $hostname = $2;
1191
1192            if(!defined($3))
1193            {
1194                print STDERR "Invalid spec option format: endpoint\n" .
1195                "requires a port number\n";
1196                exit(1);
1197            }
1198
1199            my $branges = $3;
1200            my $pranges = $4;
1201            $stor = $5;
1202            $mstor = $6;
1203            $logf = $7;
1204
1205            if($proto !~ /mx/)
1206            {
1207                $logf = $stor;
1208                $stor = $mstor;
1209                $mstor = $pranges;
1210                $pranges = $branges;
1211                $branges = undef;
1212            }
1213
1214            my ($s, $e);
1215
1216            foreach my $r (split(/,/, $pranges))
1217            {
1218                if($r !~ /-/)
1219                {
1220                    $s = $r;
1221                    $e = $r;
1222                }
1223                else
1224                {
1225                    if($r =~ /([0-9]+)-([0-9]+)/)
1226                    {
1227                        $s = $1;
1228                        $e = $2;
1229                    }
1230                }
1231
1232                for(my $i = $s; $i <= $e; ++$i)
1233                {
1234                    if($proto !~ /mx/)
1235                    {
1236                        my $portmap = {$proto => $i};
1237                        my $alias = $hostname . "_" . $proto . $i;
1238
1239                        if(exists $all_endpoints{$alias})
1240                        {
1241                            $all_endpoints{$alias}->{TYPE} |= $type;
1242                        }
1243                        else
1244                        {
1245                            $all_endpoints{$alias} = {
1246                                ALIAS => $alias,
1247                                TYPE => $type,
1248                                HOSTNAME => $hostname,
1249                                PORTMAP => $portmap,
1250                                STORAGE => $stor,
1251                                METASTORAGE => $mstor,
1252                                LOGFILE => $logf};
1253                        }
1254                    }
1255                    else
1256                    {
1257                        if(!defined($branges))
1258                        {
1259                            my $portmap = {$proto => "$branges:$i"};
1260                            my $alias = $hostname . "_" . $proto . $branges . "_" . $i;
1261                            if(exists $all_endpoints{$alias})
1262                            {
1263                                $all_endpoints{$alias}->{TYPE} |= $type;
1264                            }
1265                            else
1266                            {
1267                                $all_endpoints{$alias} = {
1268                                    ALIAS => $alias,
1269                                    TYPE => $type,
1270                                    HOSTNAME => $hostname,
1271                                    PORTMAP => $portmap,
1272                                    STORAGE => $stor,
1273                                    METASTORAGE => $mstor,
1274                                    LOGFILE => $logf};
1275                            }
1276                        }
1277
1278                        my ($bs, $be);
1279
1280                        foreach my $br (split(/,/, $branges))
1281                        {
1282                            if($br !~ /-/)
1283                            {
1284                                $bs = $br;
1285                                $be = $br;
1286                            }
1287                            else
1288                            {
1289                                if($br =~ /([0-9]+)-([0-9]+)/)
1290                                {
1291                                    $bs = $1;
1292                                    $be = $2;
1293                                }
1294                            }
1295
1296                            for(my $bi = $bs; $bi <= $be; ++$bi)
1297                            {
1298                                my $portmap = {$proto => "$bi:$i"};
1299                                my $alias = $hostname . "_" . $proto . $bi . "_" . $i;
1300                                if(exists $all_endpoints{$alias})
1301                                {
1302                                    $all_endpoints{$alias}->{TYPE} |= $type;
1303                                }
1304                                else
1305                                {
1306                                    $all_endpoints{$alias} = {
1307                                        ALIAS => $alias,
1308                                        TYPE => $type,
1309                                        HOSTNAME => $hostname,
1310                                        PORTMAP => $portmap,
1311                                        STORAGE => $stor,
1312                                        METASTORAGE => $mstor,
1313                                        LOGFILE => $logf};
1314                                }
1315                            }
1316                        }
1317                    }
1318                }
1319            }
1320        }
1321    }
1322}
1323
1324sub get_aliases
1325{
1326    my $type = shift;
1327    my @aliases = ();
1328    foreach my $ep (values %all_endpoints)
1329    {
1330        if($ep->{TYPE} & $type)
1331        {
1332            push @aliases, $ep->{ALIAS};
1333        }
1334    }
1335    return @aliases;
1336}
1337
1338sub get_bmi_endpoint
1339{
1340    my $alias = shift;
1341    my $endpoint = $all_endpoints{$alias};
1342    my @bmi_list = ();
1343
1344    foreach my $proto (keys %{$endpoint->{PORTMAP}})
1345    {
1346        my $tmpstr = $proto . "://" . $endpoint->{HOSTNAME} . ":" .
1347        $endpoint->{PORTMAP}->{$proto};
1348        push(@bmi_list, $tmpstr);
1349    }
1350    return join(",", @bmi_list);
1351}
1352
1353sub get_all_protocols
1354{
1355    my %protos = ();
1356    foreach my $ep (keys %all_endpoints)
1357    {
1358        my $portmap = $all_endpoints{$ep}->{PORTMAP};
1359
1360        foreach my $prot (keys %{$all_endpoints{$ep}->{PORTMAP}})
1361        {
1362            if(!exists $protos{$prot})
1363            {
1364                $protos{$prot} = 1;
1365            }
1366        }
1367    }
1368    return keys %protos;
1369}
1370
1371sub needs_default_value
1372{
1373    my $paramname = shift;
1374
1375    foreach my $ep (keys %all_endpoints)
1376    {
1377        if(!defined($all_endpoints{$ep}->{$paramname}))
1378        {
1379            return 1;
1380        }
1381    }
1382    return 0;
1383}
1384
1385sub set_default_value
1386{
1387    my $paramname = shift;
1388    my $val = shift;
1389
1390    foreach my $ep (keys %all_endpoints)
1391    {
1392        if(!defined($all_endpoints{$ep}->{$paramname}))
1393        {
1394            $all_endpoints{$ep}->{$paramname} = $val . "-" . $ep;
1395        }
1396    }
1397}
1398
1399# ---------------------
1400# entry point of script
1401# ---------------------
1402
1403my $using_stdout = 0;
1404my $show_help = '';
1405my $show_specusage = '';
1406
1407$opt_quiet = 0;
1408GetOptions('protocol=s'    => \$opt_protocol,
1409    'tcpport=i'     => \$opt_tcpport,
1410    'tcpbindspecific'  => \$opt_tcpbindspecific,
1411    'gmport=i'      => \$opt_gmport,
1412    'mxboard=i'     => \$opt_mxboard,
1413    'mxendpoint=i'  => \$opt_mxendpoint,
1414    'ibport=i'      => \$opt_ibport,
1415    'portal=i'      => \$opt_portal,
1416    'ioservers=s'   => \$opt_ioservers,
1417    'metaservers=s' => \$opt_metaservers,
1418    'logfile=s'     => \$opt_logfile,
1419    'logging=s'     => \$opt_logging,
1420    'tracing'       => \$opt_tracing,
1421    'logstamp=s'    => \$opt_logstamp,
1422    'first-handle=i' => \$opt_first_handle,
1423    'last-handle=i' => \$opt_last_handle,
1424    'default-num-dfiles=i' => \$opt_default_num_dfiles,
1425    'flow-buffer-size=i' => \$opt_default_flow_buffer_size,
1426    'flow-buffer-count=i'=> \$opt_default_flow_buffer_count,
1427    'root-handle=i' => \$opt_root_handle,
1428    'fsid=i'        => \$opt_fsid,
1429    'fsname=s'      => \$opt_fsname,
1430    'trusted=i'        => \$opt_security,
1431    'server-job-timeout=i' => \$opt_server_job_timeout,
1432    'client-job-timeout=i' => \$opt_client_job_timeout,
1433    'storage=s'     => \$opt_storage,
1434    'help'          => \$show_help,
1435    'quiet!'        => \$opt_quiet,
1436    'trovesync!'    => \$opt_trovesync,
1437    'trove-method=s' => \$opt_trovemethod,
1438    'iospec=s'     => \$opt_iospec,
1439    'metaspec=s'   => \$opt_metaspec,
1440    'spec-usage!'  => \$show_specusage,
1441    'genkey!'       => \$opt_gen_key,
1442    '-'           => \$using_stdout)
1443    or die "Could not parse arguments.  See -h for help.\n";
1444
1445if($opt_quiet)
1446{
1447    if(
1448        !($opt_protocol && $opt_ioservers && $opt_metaservers)
1449        &&
1450        !($opt_iospec && $opt_metaspec)
1451    )
1452    {
1453        # quiet requires full specification of server addresses somehow
1454        die "Invalid arguments for --quiet usage.  See -h for help\n";
1455    }
1456}
1457else
1458{
1459
1460    $term = new Term::ReadLine 'pvfs2-genconfig';
1461    if(!defined($term))
1462    {
1463        print STDERR "Failed to open ReadLine terminal\n";
1464        exit(1);
1465    }
1466}
1467
1468if($term && $term->OUT)
1469{
1470    $OUT = $term->OUT;
1471}
1472else
1473{
1474    $OUT = \*STDOUT;
1475}
1476
1477if($show_help) {
1478    usage();
1479    exit;
1480}
1481
1482if($show_specusage) {
1483    specusage();
1484    exit;
1485}
1486
1487my $output_target = undef;
1488if ($using_stdout) {
1489    $output_target = \*STDOUT;
1490}
1491elsif (@ARGV != 1)
1492{
1493    die "Bad arguments.  See -h for help.\n";
1494}
1495else
1496{
1497    unless (open(FILEOUT, ">", $ARGV[0]))
1498    {
1499        die "Can't open specified file $ARGV[0]: $!\n";
1500    }
1501    $output_target = \*FILEOUT;
1502}
1503
1504die "-port not allowed with -iospec or -metaspec."
1505if($opt_port ne '' && defined($opt_iospec) && defined($opt_metaspec));
1506die "-iospec requires -metaspec."
1507if(defined($opt_iospec) && !defined($opt_metaspec));
1508die "-metaspec requires -iospec."
1509if(defined($opt_metaspec) && !defined($opt_iospec));
1510
1511# only open the terminal for reading input if options specified
1512# on the command line are not enough to gather necessary information
1513
1514print_welcome();
1515
1516if($opt_metaspec)
1517{
1518    get_specs($IO_ENDPOINT, $opt_iospec);
1519    get_specs($META_ENDPOINT, $opt_metaspec);
1520
1521    $bmi_module = join(',', (map { "bmi_" . $_ } get_all_protocols()));
1522}
1523else
1524{
1525    my $portmap = get_protocol();
1526    $bmi_module = join(',', map("bmi_" . $_, keys (%{$portmap})));
1527
1528    $default_storage = get_storage();
1529    $default_meta_storage = get_meta_storage();
1530    $default_logfile = get_logfile();
1531
1532    get_ionames($portmap, $default_storage, $default_logfile);
1533    get_metanames($portmap, $default_meta_storage, $default_logfile);
1534}
1535
1536# find out if any of the storage or logfile entries in the endpoints
1537# are undefined, in which case we need to find the default
1538
1539if(needs_default_value(STORAGE))
1540{
1541    if(!defined($default_storage))
1542    {
1543        $default_storage = get_storage();
1544    }
1545    set_default_value(STORAGE, $default_storage);
1546    set_default_value(STORAGE, $default_storage);
1547}
1548
1549if(needs_default_value(METASTORAGE))
1550{
1551    if(!defined($default_meta_storage))
1552    {
1553        $default_meta_storage = get_meta_storage();
1554    }
1555    set_default_value(METASTORAGE, $default_meta_storage);
1556    set_default_value(METASTORAGE, $default_meta_storage);
1557}
1558
1559if(needs_default_value(LOGFILE))
1560{
1561    if(!defined($default_logfile))
1562    {
1563        $default_logfile = get_logfile();
1564    }
1565
1566    set_default_value(LOGFILE, $default_logfile);
1567    set_default_value(LOGFILE, $default_logfile);
1568}
1569
1570my $count = scalar(keys %all_endpoints);
1571my $io_count = scalar(get_aliases($IO_ENDPOINT));
1572my $meta_count = scalar(get_aliases($META_ENDPOINT));
1573
1574if (!$opt_quiet) {
1575    print $OUT <<"FINI"
1576Configured a total of $count servers:
1577$io_count of them are I/O servers.
1578$meta_count of them are Metadata servers.
1579FINI
1580    ;;
1581
1582    if ($opt_security == 1)
1583    {
1584        print $OUT "Configured trusted connection settings\n";
1585        print $OUT "Trusted port list : ", $opt_trusted_port, "\n";
1586        print $OUT "Trusted network,netmask : ",
1587        $opt_trusted_network, ",", $opt_trusted_netmask, "\n";
1588    }
1589}
1590
1591if (!$opt_quiet) {
1592
1593    my $verify_svr_flag = prompt_word("Would you like to verify server list (y/n) [Default is n]? ","n");
1594
1595    if($verify_svr_flag eq "y" or $verify_svr_flag eq "yes")
1596    {
1597        print $OUT "****** I/O servers:\n";
1598        foreach my $ios (get_aliases($IO_ENDPOINT))
1599        {
1600            print "$ios\n";
1601        }
1602        print $OUT "\n****** Metadata servers:\n";
1603        foreach my $mos (get_aliases($META_ENDPOINT))
1604        {
1605            print $OUT "$mos\n";
1606        }
1607        my $ok_flag = prompt_word("Does this look ok (y/n) [Default is y]? ","y");
1608        if(!($ok_flag eq "y" or $ok_flag eq "yes"))
1609        {
1610            die "Aborting...\n";
1611        }
1612    }
1613}
1614
1615
1616my $logging = get_logging();
1617my $tracing = get_tracing();
1618my $logstamp = get_logstamp();
1619my $first_handle = get_first_handle();
1620my $last_handle = get_last_handle();
1621my $default_num_dfiles = get_default_num_dfiles();
1622my $default_flow_buffer_size = get_default_flow_buffer_size();
1623my $default_flow_buffer_count = get_default_flow_buffer_count();
1624my $root_handle = get_root_handle();
1625my $fsid = get_fsid();
1626my $fsname = get_fsname();
1627my $server_job_timeout = get_server_job_timeout();
1628my $client_job_timeout = get_client_job_timeout();
1629
1630# ----------------------------------------------------------
1631# now that we have all the info, emit the configuration data
1632# ----------------------------------------------------------
1633
1634# NOTE: we assume that server_aliases and server_addrs
1635# arrays are properly populated from above
1636
1637if (!$opt_quiet) {
1638    print $OUT "Writing fs config file... ";
1639}
1640
1641emit_defaults($output_target, $num_unexp_reqs,
1642    $bmi_module, $default_logfile, $logging, $tracing,
1643    $logstamp, $server_job_timeout, $client_job_timeout);
1644if ($opt_security == 1)
1645{
1646    emit_security($output_target, $opt_trusted_port,
1647        $opt_trusted_network, $opt_trusted_netmask);
1648}
1649emit_aliases($output_target);
1650emit_filesystem($output_target, $fsname , $fsid, $root_handle,
1651    $last_handle, $first_handle, $meta_count + $io_count, $default_num_dfiles, $default_flow_buffer_size, $default_flow_buffer_count);
1652
1653if ($opt_metaspec) {
1654    emit_serveropts($output_target);
1655}
1656
1657# close fs.conf
1658if ($using_stdout == 0)
1659{
1660    close($output_target);
1661
1662    my $req_limit = 65536;
1663
1664    if(-s $ARGV[0] > $req_limit)
1665    {
1666        my $size = (-s $ARGV[0]);
1667        print STDERR
1668"Warning: Generated config file: " . $ARGV[0] . "\n" .
1669"has size: $size, which is larger than the current PVFS request: $req_limit\n" .
1670"Increase the value of PVFS_REQ_LIMIT_CONFIG_FILE_BYTES in src/proto/pvfs2-req-proto.h\n";
1671    }
1672}
1673
1674if (!$opt_quiet) {
1675    print $OUT "done\n";
1676}
1677
1678# Local variables:
1679#  c-indent-level: 4
1680#  c-basic-offset: 4
1681# End:
1682
1683# vim: ts=8 sts=4 sw=4 expandtab
1684
1685
Note: See TracBrowser for help on using the browser.