root/branches/Orange-Elaine-Distr-Dir-Branch/src/apps/admin/pvfs2-genconfig @ 8648

Revision 8648, 48.1 KB (checked in by shuangy, 2 years ago)

1. add >InitNumDirdataHandles?< field to fs_config and default value set to 2. 2. add command line options >-n, --init-num-dirdata< to pvfs2-mkdir to set initial number of dirdata handles for a directory. (not yet applied to kernel module.)

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