mirror of
https://github.com/Telecominfraproject/wlan-lanforge-scripts.git
synced 2025-10-28 17:32:35 +00:00
1065 lines
38 KiB
Perl
Executable File
1065 lines
38 KiB
Perl
Executable File
#!/usr/bin/perl -w
|
|
#
|
|
# This program is used to stress test the LANforge system, and may be used as
|
|
# an example for others who wish to automate LANforge tests.
|
|
|
|
# This script sets up connections of types:
|
|
# lf, lf_udp, lf_tcp, custom_ether, custom_udp, custom_tcp, l4 (http, https, ftp and fileIO)
|
|
# across real ports and MACVLAN ports on one or more machines.
|
|
# It then continously starts and stops the connections.
|
|
package main;
|
|
$| = 1; # Un-buffer output
|
|
|
|
use strict;
|
|
use warnings;
|
|
use Carp;
|
|
use Net::Telnet ();
|
|
$SIG{ __DIE__ } = sub { Carp::confess( @_ ) };
|
|
use Scalar::Util; #::looks_like_number;
|
|
use lib '/home/lanforge/scripts'; # this is pedantic necessity for the following use statements
|
|
use LANforge::Port;
|
|
use LANforge::Utils;
|
|
use LANforge::Endpoint;
|
|
use Net::Telnet ();
|
|
use Net::Ping;
|
|
use Getopt::Long;
|
|
use Time::HiRes ('sleep');
|
|
use Socket;
|
|
|
|
use POSIX;
|
|
## ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
|
|
## package variables below
|
|
use constant NL => "\n";
|
|
use constant NA => "NA";
|
|
use constant AUTO => "AUTO";
|
|
use constant READ => "read";
|
|
use constant WRITE => "write";
|
|
|
|
## ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
|
|
our $report_timer = 8000; # Set report timer for all tests created in ms, i.e. 8 seconds
|
|
our $lfmgr_host = undef;
|
|
our $lfmgr_port = 4001;
|
|
our $resource = 1;
|
|
our $quiet = 1;
|
|
our $group = undef;
|
|
our $tmp_group = undef;
|
|
our $tmp_group_min = 0;
|
|
our $tmp_group_max = 0;
|
|
our $action = undef;
|
|
our $nfs_mnt = undef;
|
|
our $nfs_list = undef;
|
|
our $local_mnt = AUTO;
|
|
our $first_mvlan_ip = undef; #"10.26.1.10";
|
|
our $netmask = "255.255.255.0";
|
|
our $parent_port = undef;
|
|
our $utils = undef;
|
|
our $shelf_num = 1;
|
|
our $DEBUG = 0;
|
|
our $sleep_after_wo = 15; # Second to sleep after starting writers (before starting readers)
|
|
our $D_PAUSE = 3;
|
|
|
|
## ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
|
|
# File-IO configuration constants
|
|
our $quiesce_after_files = 0;
|
|
our $min_rw_size = "512";
|
|
our $max_rw_size = "65536";
|
|
our $use_crc = "yes";
|
|
our $min_read_bps = "1000000"; # 1Mbps
|
|
our $max_read_bps = "2000000"; # 2Mbps
|
|
our $num_files = 2;
|
|
our $min_file_size = 1024 * 1024;
|
|
our $max_file_size = 1024 * 1024 * 2;
|
|
our $min_write_bps = "3000000"; # 3Mbps
|
|
our $max_write_bps = "4000000"; # 4Mbps
|
|
our $mount_options = "NONE";
|
|
our $skip_writers = 0;
|
|
our $skip_readers = 0;
|
|
|
|
## ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
|
|
# below are sorted names and associated endpoints
|
|
# the third argument can be used as the default parent
|
|
# port for the mac-vlans for that group
|
|
our %group_names = (
|
|
#"group1" => [ 1, 20, 'eth1'],
|
|
#"group2" => [ 21, 40, 'eth1'],
|
|
#"group3" => [ 41, 60, 'eth1'],
|
|
#"group4" => [ 1, 1, 'eth1'],
|
|
#"group5" => [ 2, 2, 'eth1']
|
|
);
|
|
our $fast_forward_ep = 0; # set this to 1 to leave exiting file endpoints alone
|
|
## ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
|
|
our %mnt_map = ();
|
|
our %file_endpoints = ();
|
|
our %cross_connects = ();
|
|
our %test_groups = ();
|
|
our %all_file_ep = ();
|
|
our %mac_vlans = ();
|
|
our %vlan_ips = ();
|
|
|
|
# These are set based on group chosen.
|
|
our $qty_mac_vlans = 0;
|
|
our $start = 0; # First idx, inclusive
|
|
our $stop = 0; # Last idx
|
|
|
|
sub ipSummary {
|
|
my $first;
|
|
if((!defined $::first_mvlan_ip ) || ("$::first_mvlan_ip" eq "")) {
|
|
$first = "0.0.0.0";
|
|
}
|
|
else {
|
|
$first = $::first_mvlan_ip;
|
|
}
|
|
my $linestart = " # ";
|
|
my $summary = NL;
|
|
for my $name (sort keys %::group_names) {
|
|
$summary .= $linestart.$name.": ";
|
|
my $a = addrtoint( $first ) + $::group_names{ $name }->[0] -1;
|
|
my $b = addrtoint( $first ) + $::group_names{ $name }->[1] -1;
|
|
$summary .= inttoaddr( $a )." - ".inttoaddr( $b ).NL;
|
|
}
|
|
return $summary;
|
|
}
|
|
|
|
## ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
|
|
## Usage ==
|
|
## ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
|
|
my $first = ($::first_mvlan_ip) ? $::first_mvlan_ip : "0.0.0.0";
|
|
|
|
my $usage = "$0 [--mgr {host-name | IP}]
|
|
[--mgr_port {ip port ($lfmgr_port)}]
|
|
[--resource {resource ($resource)}]
|
|
[--nfs_mnt {[IP|host-name]:/path}]
|
|
# 192.168.1.1:/foo
|
|
# filehost:/home/fileio
|
|
[--nfs_list {local file}]\t# list of nfs mountpoints
|
|
# Will be modulo distributed among groups mac vlans
|
|
# Obviates --nfs_mnt; examples:
|
|
# --nfs_list ./my-list-of-mounts
|
|
# --nfs_list /tmp/mnt-list
|
|
# File format:
|
|
# 10.20.30.40:/a/b/c
|
|
# filehost:/z/y
|
|
[--parent_port {parent eth port}]\t# parent of mac vlans
|
|
[--first-mvlan-ip {ip ($first)}]\t# mvlan ips: ".ipSummary()."
|
|
[--netmask {mask ($netmask)}]\t#mac-vlan netmask
|
|
[--action {list_groups|run_group|stop_group|del_group}]
|
|
# list_groups: list test groups
|
|
# run_group: assemble and start writer then reader group
|
|
# stop_group: quiece writer then reader group
|
|
# del_group: delete reader then writer file endpoints
|
|
[--group {name}] # test group base name, creates:
|
|
# <group>_wo for writers and
|
|
# <group>_ro for readers
|
|
[--min_rw_size ($min_rw_size)]\t# in bytes
|
|
[--max_rw_size ($max_rw_size)]\t# in bytes
|
|
[--use_crc {yes|no}]
|
|
[--min_read_bps ($min_read_bps)]\t# in bps, 2000000 = 1Mbps
|
|
[--max_read_bps ($max_read_bps)]\t# in bps, 2000000 = 2Mbps
|
|
[--num_files ($num_files)]\t# files per writer
|
|
[--quiesce_after_files ($quiesce_after_files)]\t# files to read/write before stopping test.
|
|
O == infinite (default)
|
|
|
|
[--skip_readers ($skip_readers)]\t# Should we not create reader connections: 0 | 1
|
|
[--skip_writers ($skip_readers)]\t# Should we not create writer connections: 0 | 1
|
|
[--min_file_size ($min_file_size)]\t# in bytes
|
|
[--max_file_size ($max_file_size)]\t# in bytes
|
|
[--min_write_bps ($min_write_bps)]\t# in bps, 3000000 = 3Mbps
|
|
[--max_write_bps ($max_write_bps)]\t# in bps, 4000000 = 4Mbps
|
|
[--mount_options ($mount_options)]\t# as per nfs(1)
|
|
[--tmp_group {name}]\t# for specifying ad-hoc group, you will see group <name>
|
|
[--min 1-n]\t first macvlan in tmp group
|
|
[--max 1-n]\t last macvlan in tmp group
|
|
|
|
Examples:
|
|
$0 --mgr 10.0.0.1 --resource 1 --action list_groups
|
|
|
|
$0 --mgr 10.0.0.1 --resource 1 --action run_group --group group1 \\
|
|
--parent_port eth2 --netmask 255.255.0.0 \\
|
|
--nfs_mnt 192.168.99.99:/fire
|
|
|
|
$0 --mgr 10.0.0.1 --resource 1 \\
|
|
--action stop_group --group group1
|
|
|
|
$0 --mgr 10.0.0.1 --resource 1 \\
|
|
--action del_group --group group1
|
|
|
|
$0 --mgr 10.0.0.1 --resource 1 \\
|
|
--action run_group --group group2 --parent_port eth9 \\
|
|
--first_mvlan_ip 172.168.90.1 --netmask 255.255.0.0 \\
|
|
--nfs_list ./nfsexports.txt \\
|
|
--num_files 20 --min_file_size 4096 --max_file_size 524288 \\
|
|
--min_write_bps 1000000 --max_write 900000000
|
|
|
|
$0 --mgr 10.0.0.1 --resource 1 \\
|
|
--action run_group --group group1 \\
|
|
--nfs_mnt 192.168.99.99:/fire \\
|
|
--mount_options sync,hard,timeo=120,retrans=4
|
|
|
|
$0 --mgr 10.0.0.1 --resource 1 --action run_group \\
|
|
--tmp_group lag1 --min 1 --max 2 --parent_port eth1 \\
|
|
--first_mvlan_ip 10.30.0.10 \\
|
|
--nfs_mnt 10.30.0.1:/tmp
|
|
|
|
$0 --mgr 10.0.0.1 --resource 1 \\
|
|
--action stop_group --tmp_group lag1 --min 1 --max 2 --parent_port eth1
|
|
";
|
|
|
|
## ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
|
|
## ip_to_a/a_to_ip
|
|
## ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
|
|
sub addrtoint {
|
|
return( unpack( "N", pack( "C4", split( /[.]/,$_[0]) ) ) );
|
|
};
|
|
sub inttoaddr {
|
|
return( join( ".", unpack( "C4", pack( "N", $_[0] ) ) ) );
|
|
};
|
|
|
|
|
|
## ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
|
|
## Open connection to the LANforge server, configure our utils.
|
|
## ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
|
|
sub init {
|
|
my $conn = new Net::Telnet(Timeout => 20,
|
|
Prompt => '/default\@btbits\>\>/');
|
|
$conn->open(Host => $::lfmgr_host,
|
|
Port => $::lfmgr_port,
|
|
Timeout => 10);
|
|
|
|
$conn->waitfor("/btbits\>\>/");
|
|
$conn->max_buffer_length(1024 * 1024 * 10); # 10M buffer
|
|
|
|
$::utils = new LANforge::Utils();
|
|
$::utils->connect($lfmgr_host, $lfmgr_port);
|
|
|
|
if ($::group && $::group ne "") {
|
|
my $ra_bounds = $::group_names{ $::group };
|
|
$::start = @$ra_bounds[0];
|
|
$::stop = @$ra_bounds[1];
|
|
|
|
$::qty_mac_vlans = ($::stop - $::start) + 1;
|
|
print "group [$group] vlans: $::stop - $::start = $::qty_mac_vlans\n" if($::DEBUG);
|
|
}
|
|
}
|
|
|
|
## ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
|
|
## set a port or mvlan up or down
|
|
## ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
|
|
sub fmt_port_up_down {
|
|
my ($resource, $port_id, $state) = @_;
|
|
|
|
my $cur_flags = 0;
|
|
if ($state eq "down") {
|
|
$cur_flags |= 0x1; # port down
|
|
}
|
|
|
|
# Specify the interest flags so LANforge knows which flag bits to pay attention to.
|
|
my $ist_flags = 0;
|
|
$ist_flags |= 0x2; # check current flags
|
|
$ist_flags |= 0x800000; # port down
|
|
|
|
my $cmd = $::utils->fmt_cmd("set_port", 1, $resource, $port_id, NA,
|
|
NA, NA, NA, "$cur_flags",
|
|
NA, NA, NA, NA, "$ist_flags");
|
|
return $cmd;
|
|
} # ~port up/down
|
|
|
|
|
|
## ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
|
|
## Create mac_vlans if they do not exist.
|
|
## ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
|
|
sub preparePorts {
|
|
do_err_exit("First mac vlan IP is not set. Please set --first_mvlan_ip.")
|
|
unless ((defined $::first_mvlan_ip) && ("$::first_mvlan_ip" ne ""));
|
|
|
|
do_err_exit( "preparePorts: Unnamed parent port. Please set \$parent_port")
|
|
unless((defined $::parent_port) && ("$::parent_port" ne ""));
|
|
|
|
my $sleep_after = 0;
|
|
my %all_ports = ();
|
|
# build list of MAC VLANS
|
|
print "shelf_num $::shelf_num, resource $::resource\n" if ($::DEBUG);
|
|
my @ports = $::utils->getPortListing( 1, $::resource +0);
|
|
|
|
for my $rh_port (@ports) {
|
|
print "added port $rh_port->{'dev'}".NL if($::DEBUG);
|
|
$all_ports{ $rh_port->{'dev'} } = $rh_port;
|
|
next unless ( $rh_port->{'dev'} eq $::parent_port );
|
|
}
|
|
do_err_exit("preparePorts: Failed to populate ports list, please debug.")
|
|
unless (keys %all_ports > 0);
|
|
|
|
my $i;
|
|
my %new_items = ();
|
|
my $ra_bounds = $::group_names{ $group };
|
|
my $start_str = $::first_mvlan_ip;
|
|
my $start_int = addrtoint($start_str);
|
|
my $next_ip;
|
|
|
|
if (($::qty_mac_vlans + $::start) < 1) {
|
|
do_err_exit("preparePorts: expects a positive, non-zero number of mvlans to create. Cannot continue.");
|
|
}
|
|
|
|
for ($i = 0 + $::start; $i < $::qty_mac_vlans + $::start; $i++) {
|
|
my $devname = $::parent_port."#".$i;
|
|
print "start_str[$start_str] start_int[$start_int] i[$i]\n" if ($::DEBUG);
|
|
my $next_ip = inttoaddr( $start_int + $i -1);
|
|
print "next_ip[$next_ip]\n" if ($::DEBUG);
|
|
$::vlan_ips{ $devname } = $next_ip;
|
|
$::mac_vlans{ $devname } = 0;
|
|
if ( defined $all_ports{ $devname }) {
|
|
$::mac_vlans{ $devname } = 1;
|
|
}
|
|
else { # create mac_vlan
|
|
my $mac_addr = mac();
|
|
my $cmd = $::utils->fmt_cmd( "add_mvlan", $::shelf_num,
|
|
$::resource, $::parent_port, $mac_addr, $i);
|
|
print " + ".$cmd.NL if ($::DEBUG);
|
|
$::utils->doCmd($cmd);
|
|
sleep(0.1);
|
|
}
|
|
$new_items{ $devname } = 1;
|
|
$sleep_after++;
|
|
} #~for
|
|
|
|
if ( keys %new_items > 0 ) {
|
|
print "Creating ".(keys %new_items)." new ports:...";
|
|
|
|
# set the port IP
|
|
for my $new_item (keys(%new_items)) {
|
|
my $ip = $::vlan_ips{ $new_item };
|
|
my $cmd_flags = 0x0;
|
|
my $current = 0x0;
|
|
my $interesting = 0x0 | 0x4 | 0x8;
|
|
|
|
my $cmd = $::utils->fmt_cmd("set_port",
|
|
$::shelf_num, $::resource, $new_item, $ip,
|
|
$::netmask, NA, $cmd_flags, $current, NA,
|
|
NA, NA, NA, $interesting,
|
|
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
|
|
NA, NA, NA, NA, NA, NA, NA);
|
|
|
|
if ($::DEBUG) {
|
|
print NL." $new_item $ip: $cmd ";
|
|
}
|
|
else {
|
|
print ".";
|
|
}
|
|
$::utils->doCmd($cmd);
|
|
sleep(0.1);
|
|
$sleep_after++;
|
|
|
|
my @ports = $::utils->getPortListing($::shelf_num, $::resource);
|
|
for my $rh_port (@ports) {
|
|
$::all_ports{ $rh_port->{'dev'} } = $rh_port; #reset ports
|
|
}
|
|
}
|
|
print NL."Created ".(keys %new_items)." new mac vlans".NL;
|
|
}
|
|
if ($sleep_after > 10) {
|
|
$sleep_after = $sleep_after / 2;
|
|
}
|
|
|
|
if ($sleep_after) {
|
|
print "\nSleeping: $sleep_after seconds to allow ports to be created and configured.\n";
|
|
for $i (1..$sleep_after) { sleep(1); print "."; }
|
|
print NL;
|
|
}
|
|
# check that the port is up by trying to run a ping from it
|
|
if ( defined $::nfs_mnt && "$::nfs_mnt" ne "") {
|
|
my ($nfs_name) = split(/:/, $::nfs_mnt );
|
|
print "Emitting one ping from each mvlan reduces failed mounts:";
|
|
|
|
foreach my $name (reverse sort keys %new_items) {
|
|
my $rh_p = $::all_ports{ $name };
|
|
my $ip = $rh_p->{'ip_addr'};
|
|
#my $ping = "ping -n -c1 -w1 -W1 -I $ip $nfs_name";
|
|
print "ping $ip".NL if ($::DEBUG);
|
|
my $ping = Net::Ping->new('tcp', 1);
|
|
$ping->bind($ip);
|
|
$ping->port_number(scalar(getservbyname("nfs", "tcp")));
|
|
my $counter = 5;
|
|
while( $counter > 0 ) {
|
|
if ($ping->ping($nfs_name)) {
|
|
print ".";
|
|
$counter = 0;
|
|
}
|
|
else {
|
|
print "$nfs_name did not ack nfs packet from $ip".NL;
|
|
$counter --;
|
|
sleep(0.2);
|
|
}
|
|
}
|
|
$ping->close();
|
|
undef($ping);
|
|
#$ping->close();
|
|
}
|
|
}
|
|
print NL;
|
|
|
|
} # ~preparePorts
|
|
|
|
sub notBlank {
|
|
my ($name, $value) = @_;
|
|
if((!defined $name) || ("$name" eq "")) {
|
|
print "Name itself is blank, value[$value]".NL;
|
|
}
|
|
if((!defined $value) || ("$value" eq "")) {
|
|
print "Value of $name is blank".NL;
|
|
}
|
|
#die if($::DEBUG);
|
|
}
|
|
|
|
## ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
|
|
## prepareFileEndp - creates requested file endpoints if they do not exist,
|
|
## creates implied FIO endpoints if they dont exist and adds endpoints
|
|
## ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
|
|
sub prepareFileEndpoints {
|
|
do_err_exit("prepareFileEndpoints: Unnamed parent port. Please set \$parent_port")
|
|
unless((defined $::parent_port) && ("$::parent_port" ne ""));
|
|
|
|
do_err_exit("prepareFileEndpoints: Blank all_ports array. Please run preparePorts() first.")
|
|
unless( keys %::all_ports > 1 );
|
|
|
|
do_err_exit("prepareFileEndpoints: Blank mac_vlans array. Please run preparePorts() first.")
|
|
unless( keys %::mac_vlans > 0 );
|
|
|
|
if((defined $::nfs_list) && ("$::nfs_list" ne "")) {
|
|
if((keys %::mnt_map) < 1) {
|
|
do_err_exit("prepareFileEndpoints: empty --nfs_list. Provide mountpoints in [$::nfs_list]");
|
|
}
|
|
}
|
|
elsif((! defined $::nfs_mnt) || ("$::nfs_mnt" eq "")) {
|
|
do_err_exit("prepareFileEndpoints: undefined --nfs_mnt. Please specify --nfs_mnt first");
|
|
}
|
|
|
|
my %all_file_endpoints = ();
|
|
my %all_cross_connects = ();
|
|
my %endpoints_mvlans = ();
|
|
my @new_file_endpoints = ();
|
|
my @new_cross_connects = ();
|
|
|
|
my $ep_name = undef;
|
|
for my $grp (sort(keys %::group_names)) {
|
|
my $ra_bounds = $::group_names{ $grp };
|
|
print "skip_writers[$::skip_writers] skip_readers[$::skip_readers]" if ($::DEBUG);
|
|
sleep(3) if($::DEBUG);
|
|
|
|
for my $i (@$ra_bounds[0]..@$ra_bounds[1]) {
|
|
if (! $::skip_writers) {
|
|
$ep_name = $grp ."_wo_".sprintf( "%03d", $i);
|
|
$all_file_endpoints{ $ep_name } = 0;
|
|
$endpoints_mvlans{ $ep_name } = $::parent_port."#".$i;
|
|
$all_cross_connects{ $ep_name } = 0;
|
|
}
|
|
|
|
if (! $::skip_readers) {
|
|
$ep_name = $grp ."_ro_".sprintf( "%03d", $i);
|
|
$all_file_endpoints{ $ep_name } = 0;
|
|
$endpoints_mvlans{ $ep_name } = $::parent_port."#".$i;
|
|
$all_cross_connects{ $ep_name } = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
print NL."Reading endpoints...";
|
|
my $endpoint_str = $::utils->doCmd("nc_show_endpoints all all");
|
|
my @endpoint_lines = split(/\n/, $endpoint_str);
|
|
|
|
if ($::fast_forward_ep) {
|
|
for my $line (@endpoint_lines) {
|
|
$line =~ m/Endpoint \[(.*?)\]/; # proves this ep exists
|
|
next if(! $1);
|
|
$all_file_endpoints{ $1 } = 1;
|
|
}
|
|
}
|
|
for my $ep_name (sort(keys %all_file_endpoints)) {
|
|
print " $ep_name [".$all_file_endpoints{$ep_name}."] " if ($::DEBUG);
|
|
if ($all_file_endpoints{$ep_name} == 0 ){
|
|
my $begins = $::group."_";
|
|
if( $ep_name =~ /^$begins/ ){
|
|
push( @new_file_endpoints, $ep_name );
|
|
}
|
|
}
|
|
}
|
|
# assert we have sufficient remote_mnt entries
|
|
for my $ep_name (@new_file_endpoints) {
|
|
my $mvlan = $endpoints_mvlans{ $ep_name };
|
|
my $remote_mnt = $::mnt_map{ $mvlan };
|
|
notBlank( $mvlan, $remote_mnt );
|
|
}
|
|
|
|
if (@new_file_endpoints > 0) {
|
|
print "Creating ".@new_file_endpoints." new file endpoints...";
|
|
my $endpoint_type = "lf";
|
|
my $ip_port = "-1";
|
|
my $bursty = "no";
|
|
my $rand_pkt_sz = "no";
|
|
my $remote_mnt = undef;
|
|
|
|
for my $ep_name (@new_file_endpoints) {
|
|
my $mvlan = $endpoints_mvlans{ $ep_name };
|
|
$remote_mnt = $::mnt_map{ $mvlan };
|
|
|
|
my $read_write = ($ep_name =~ /_ro_/)? READ : WRITE;
|
|
my $rw_prefix = $ep_name;
|
|
$rw_prefix =~ s/_ro_/_wo_/;
|
|
my $prefix = ($read_write eq WRITE) ? AUTO : $rw_prefix;
|
|
my $directory = ($read_write eq WRITE) ? AUTO : '/mnt/lf/'.$rw_prefix;
|
|
my $min_write_rt = ($read_write eq READ ) ? "0" : $::min_write_bps;
|
|
my $max_write_rt = ($read_write eq READ ) ? "0" : $::max_write_bps;
|
|
my $min_read_rt = ($read_write eq WRITE ) ? "0" : $::min_read_bps;
|
|
my $max_read_rt = ($read_write eq WRITE ) ? "0" : $::max_read_bps;
|
|
my $pattern = "increasing"; #($read_write eq "read" ) ? NA : "increasing";
|
|
my $mount_retry_nap = 3500;
|
|
my $mount_dir = "NA";
|
|
|
|
# we do not want anything 'blank' in this
|
|
my @names=qw(ep_name ::shelf_num ::resource mvlan min_read_rt max_read_rt min_write_rt max_write_rt pattern directory prefix remote_mnt mount_options mount_dir mount_retry_nap);
|
|
|
|
my @values=($ep_name, $::shelf_num, $::resource, $mvlan, $min_read_rt, $max_read_rt, $min_write_rt, $max_write_rt, $pattern, $directory, $prefix, $remote_mnt, $mount_options, $mount_dir, $mount_retry_nap);
|
|
for (my $i=0; $i<@names; $i++) {
|
|
notBlank($names[$i], $values[$i]);
|
|
}
|
|
|
|
my $cmd = $::utils->fmt_cmd(
|
|
"add_file_endp", $ep_name, $::shelf_num, $::resource, $mvlan,
|
|
'fe_nfs', $min_read_rt , $max_read_rt, $min_write_rt, $max_write_rt,
|
|
$pattern, $directory, $prefix, $remote_mnt, $mount_options,
|
|
"7", $mount_dir, NA, $mount_retry_nap);
|
|
print " + " . $cmd.NL if ($::DEBUG);
|
|
$::utils->doCmd($cmd);
|
|
sleep(0.1); # if ($::DEBUG);
|
|
print ".";
|
|
$cmd = $::utils->fmt_cmd( "set_fe_info", $ep_name,
|
|
$min_rw_size, $max_rw_size, $num_files, $min_file_size, $max_file_size,
|
|
$directory, $prefix, $read_write, $quiesce_after_files);
|
|
print " + " . $cmd.NL if ($::DEBUG);
|
|
|
|
$::utils->doCmd($cmd);
|
|
sleep(0.1); # if ($::DEBUG);
|
|
|
|
print "\bo";
|
|
$::utils->doCmd($::utils->fmt_cmd( "set_endp_quiesce", $ep_name, 5));
|
|
sleep(0.1);
|
|
print "\bO";
|
|
$::utils->doCmd($::utils->fmt_cmd( "set_endp_report_timer", $ep_name, 1000));
|
|
sleep(0.1);
|
|
print "\b*";
|
|
$::utils->doCmd($::utils->fmt_cmd( "set_endp_flag", $ep_name, "ClearPortOnStart", 0));
|
|
sleep(0.1);
|
|
print "\b|";
|
|
my $cx_name = "CX_".$ep_name;
|
|
my $tg_name = $::group.(($read_write eq READ) ? "_ro" : "_wo");
|
|
my $tm_name = "default_tm"; #= $::group.(($read_write eq READ) ? "_ro" : "_wo");
|
|
my $tx_endp = $ep_name;
|
|
my $rx_endp = NA;
|
|
|
|
my $add_cx = $::utils->fmt_cmd( "add_cx", $cx_name, $tm_name, $tx_endp, $rx_endp );
|
|
my $set_cx = $::utils->fmt_cmd( "set_cx_report_timer", $tm_name, $cx_name, "1000", "cxonly");
|
|
my $add_tgcx = $::utils->fmt_cmd( "add_tgcx", $tg_name, $cx_name );
|
|
print $add_tgcx.NL if ($::DEBUG);
|
|
print $add_cx.NL if ($::DEBUG);
|
|
print $set_cx.NL if ($::DEBUG);
|
|
|
|
$::utils->doCmd($add_cx);
|
|
sleep(0.1);
|
|
print "\bi";
|
|
$::utils->doCmd($set_cx);
|
|
sleep(0.1);
|
|
print "\b:";
|
|
$::utils->doCmd($add_tgcx);
|
|
sleep(0.1);
|
|
print "\b.";
|
|
} #~for
|
|
print "\nAdded ".@new_file_endpoints." endpoints to group $::group\n";
|
|
sleep(3);
|
|
} #~if need to create file endpoints
|
|
|
|
} #~prepareFileEndpoints
|
|
|
|
## ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
|
|
## prepareExportList - assemble the list of nfs exports from either
|
|
## the nfs_list resource or the nfs_mnt option
|
|
## ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
|
|
sub prepareExportList {
|
|
|
|
if ((defined $::nfs_list) && ("$::nfs_list" ne "")) {
|
|
open(my $fh, "<", $::nfs_list) or do_err_exit("Unable to open [$::nfs_list]. Cannot continue.");
|
|
my @lines = ();
|
|
while(<$fh>) {
|
|
chomp;
|
|
next if (/^\s*[#;]/);
|
|
next if (/^\s*$/);
|
|
s/^\s+//;
|
|
s/\s+$//;
|
|
if (/[0-9a-zA-Z.-]+:\/.*$/) {
|
|
push( @lines, $_ );
|
|
}
|
|
}
|
|
close($fh);
|
|
if (@lines < 1) {
|
|
do_err_exit("Unable to find lines that look like nfs mount points in [$::nfs_list]. Cannot continue.");
|
|
}
|
|
my $i = 0;
|
|
for my $mvlan (sort keys %::mac_vlans) {
|
|
$::mnt_map{ $mvlan } = $lines[ $i ];
|
|
print " mapping $mvlan => ".$lines[ $i ].NL if($::DEBUG);
|
|
$i = ++$i % @lines;
|
|
}
|
|
}
|
|
elsif ((defined $::nfs_mnt) && ("$::nfs_mnt" ne "")) {
|
|
for my $mvlan (sort keys %::mac_vlans) {
|
|
$::mnt_map{ $mvlan } = $::nfs_mnt;
|
|
}
|
|
}
|
|
else {
|
|
do_err_exit("Niether --nfs_list or --nfs_mnt are specified. Cannot continue.");
|
|
}
|
|
|
|
if ((keys %::mnt_map) < 1) {
|
|
do_err_exit("prepareExportList: unable to build map of mount entries. Cannot continue.");
|
|
}
|
|
}
|
|
## ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
|
|
## prepareGroups - creates requested test group if it does not exist,
|
|
## file-endpoints will be created expecting these refs
|
|
## ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
|
|
sub prepareTestGroups {
|
|
my @new_items = ();
|
|
my $test_group_str = $::utils->doCmd("show_group all");
|
|
my @test_group_lines = split(/\n/, $test_group_str );
|
|
my %test_groups = ();
|
|
|
|
for my $group_name (sort(keys %::group_names)) {
|
|
$test_groups{ $group_name } = 0;
|
|
}
|
|
for my $line ( @test_group_lines) {
|
|
if ($line =~ /TestGroup name: ([^\[]+)\s*\[.*$/) {
|
|
$test_groups{ $1 } = 1;
|
|
}
|
|
}
|
|
for my $group_name (keys %test_groups) {
|
|
if ($test_groups{$group_name} == 0 ) {
|
|
push(@new_items, $group_name);
|
|
}
|
|
}
|
|
if (@new_items > 0 ) {
|
|
sleep(5);
|
|
for my $group_name (@new_items) {
|
|
|
|
$::utils->doCmd($::utils->fmt_cmd("add_group", $group_name."_wo", NA, NA)) if (!$::skip_writers);
|
|
$::utils->doCmd($::utils->fmt_cmd("add_group", $group_name."_ro", NA, NA)) if (!$::skip_readers);
|
|
|
|
#print " + tg $group_name ";
|
|
}
|
|
}
|
|
} # ~prepareTestGroups
|
|
|
|
## ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
|
|
## generates random mac address
|
|
## ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
|
|
sub mac {
|
|
my $rv = "00:";
|
|
for (my $i=0; $i<5; $i++) {
|
|
$rv.=sprintf("%02X",int(rand(255))).(($i<4)?':':'');
|
|
}
|
|
return $rv;
|
|
}
|
|
|
|
|
|
|
|
## ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
|
|
## list ports
|
|
## ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
|
|
sub showGroups {
|
|
my @ports = $::utils->getPortListing($::shelf_num, $::resource);
|
|
print "in show groups, found $#ports ports\n" if ($::DEBUG);
|
|
for my $group_name ( sort(keys(%::group_names))) {
|
|
print "show groups, $group_name _ro\n" if ($::DEBUG);
|
|
my $cmd = $::utils->fmt_cmd("show_group", $group_name."_ro");
|
|
print $::utils->doCmd($cmd);
|
|
|
|
print "show groups, $group_name _wo\n" if ($::DEBUG);
|
|
$cmd = $::utils->fmt_cmd("show_group", $group_name."_wo");
|
|
print $::utils->doCmd($cmd);
|
|
}
|
|
print "\n";
|
|
}
|
|
|
|
## ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
|
|
## start the writers then start the readers
|
|
## ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
|
|
sub runGroup {
|
|
my $cmd;
|
|
if (!$::skip_writers) {
|
|
$cmd = "start_group ".$::group."_wo";
|
|
$::utils->doCmd($cmd);
|
|
print "Starting ".$::group."_wo...";
|
|
for my $i ( 1..$sleep_after_wo ) { sleep(1); print "."; }
|
|
print "...started".NL;
|
|
}
|
|
if (!$::skip_readers) {
|
|
$cmd = "start_group ".$::group."_ro";
|
|
$::utils->doCmd($cmd);
|
|
print "Starting ".$::group."_ro ...";
|
|
for my $i ( 1..3 ) { sleep(1); print "."; }
|
|
print "...started".NL;
|
|
}
|
|
}
|
|
|
|
## ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
|
|
## stop writers then stop readers
|
|
## ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
|
|
sub stopGroup {
|
|
my $cmd;
|
|
if (!($::skip_writers || $skip_readers)) {
|
|
print NL."Quiesceing all connections...";
|
|
$cmd = "quiesce_group all";
|
|
$::utils->doCmd($cmd);
|
|
}
|
|
if (!$::skip_writers) {
|
|
print NL."Quiesceing writers...";
|
|
$cmd = "quiesce_group ".$::group."_wo";
|
|
$::utils->doCmd($cmd);
|
|
}
|
|
if (!$::skip_readers) {
|
|
print NL."Quiesceing readers...";
|
|
$cmd = "quiesce_group ".$::group."_ro";
|
|
$::utils->doCmd($cmd);
|
|
}
|
|
}
|
|
|
|
## ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
|
|
## poll the set of connections to see if they are 'stopped'
|
|
## ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
|
|
sub pollCxForStop {
|
|
my $cmd;
|
|
my $lines;
|
|
my $num_lines = 0;
|
|
my $num_counted = 0;
|
|
my $num_stopped = 0;
|
|
my $upper_limit = 60;
|
|
my $attempts = 0;
|
|
while( $num_counted == 0 || ($num_counted != $num_stopped)) {
|
|
return 0 if ($attempts > $upper_limit);
|
|
sleep(2);
|
|
$attempts++;
|
|
$cmd = $::utils->fmt_cmd("show_cx", "all", "all");
|
|
$lines = $::utils->doCmd($cmd);
|
|
$num_counted = 0;
|
|
$num_stopped = 0;
|
|
for my $line (split(NL, $lines)) {
|
|
next unless ($line =~ /CX_.*?_[wr]o_\d+/);
|
|
$num_counted ++;
|
|
my @h = split(/ +/, $line);
|
|
|
|
$num_stopped += ($h[10] eq "STOPPED") ? 1 : 0;
|
|
print "${h[2]} target:${h[8]} reported:${h[10]} counted:$num_counted stopped:$num_stopped attempts: $attempts".NL if ($::DEBUG);
|
|
}
|
|
print " counted:$num_counted stopped:$num_stopped attempts: $attempts".NL if ($::DEBUG);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
|
|
## ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
|
|
## stop the group,
|
|
## delete the file endpoints from the group,
|
|
## then delete the group
|
|
## ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
|
|
|
|
sub deleteGroup {
|
|
if ((!defined $::group) || ("$::group" eq "")) {
|
|
do_err_exit("Cannot delete group if --group unspecified.");
|
|
}
|
|
my $group_name = undef;
|
|
if( @_ < 1 ) {
|
|
if ( $::skip_readers || $::skip_writers) {
|
|
if (!$::skip_readers) {
|
|
print "send Delete Group $group_name to $::group _ro \n" if ($::DEBUG);
|
|
deleteGroup( $::group."_ro") ;
|
|
}
|
|
if (!$::skip_writers) {
|
|
print "send Delete Group $group_name to $::group _wo \n" if ($::DEBUG);
|
|
deleteGroup( $::group."_wo");
|
|
}
|
|
return;
|
|
}
|
|
$group_name = $::group;
|
|
}
|
|
else {
|
|
($group_name) = @_;
|
|
}
|
|
print "Delete Group $group_name\n" if ($::DEBUG);
|
|
|
|
my %cx_names = ();
|
|
my %endp_names = ();
|
|
my %portlist = ();
|
|
my $cx_prefix = "CX_".$group_name."_";
|
|
my $should_stop_group = 0;
|
|
my $cmd;
|
|
my $resp;
|
|
my $endp_name;
|
|
my $cx_name;
|
|
|
|
if ("$group_name" eq "$::group") {
|
|
$cmd = $::utils->fmt_cmd("show_group", $group_name."_wo");
|
|
$resp = $::utils->doCmd($cmd);
|
|
$cmd = $::utils->fmt_cmd("show_group", $group_name."_ro");
|
|
$resp .= $resp.NL.$::utils->doCmd($cmd);
|
|
}
|
|
else {
|
|
$cmd = $::utils->fmt_cmd("show_group", $group_name);
|
|
$resp = $::utils->doCmd($cmd);
|
|
}
|
|
|
|
# collect cross connect names
|
|
for my $line (split(NL, $resp)) {
|
|
chomp $line;
|
|
$should_stop_group = 1 if ($line =~ /TestGroup name:.*?\[RUNNING/);
|
|
if( $line =~ / $cx_prefix/ ) {
|
|
for my $tg_name_hunk (sort split(/\s+/, $line )) {
|
|
next if ( $tg_name_hunk =~ /^ *$/);
|
|
print "$tg_name_hunk " if ($::DEBUG);
|
|
$cx_names{$tg_name_hunk}++ if ($tg_name_hunk =~ /^CX_/);
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($should_stop_group) {
|
|
stopGroup();
|
|
if (! pollCxForStop()) {
|
|
stopGroup();
|
|
print "Not all connections have stopped. Continuing.".NL;
|
|
}
|
|
}
|
|
|
|
# I'm not getting output here for many seconds after polling for stop
|
|
foreach my $x (1..10) { sleep(1); print "."; }
|
|
print NL;
|
|
|
|
# build endpoint names and find ports
|
|
for $cx_name (reverse sort keys %cx_names) {
|
|
next if( $cx_name !~ /^CX_/);
|
|
my $endp_name = $cx_name;
|
|
$endp_name =~ s/CX_//;
|
|
print "."; sleep(0.2);
|
|
my $lines = $::utils->doCmd("nc_show_endp $endp_name");
|
|
for my $line (split(NL, $lines)) {
|
|
if ($line =~ /Shelf: /) {
|
|
$line =~ s/,//g;
|
|
my @hunks = split(/\s+/, $line);
|
|
my $port = $hunks[2]." ".$hunks[4]." ".$hunks[6];
|
|
#print "PORT: $port\n";
|
|
$portlist{$port}++;
|
|
}
|
|
}
|
|
}
|
|
print NL;
|
|
die "Error making portlist" if (length(keys %portlist) < 1);
|
|
|
|
# remove cross connects and endpoints immediately after each
|
|
print "Removing Cross Connects and endpoints: ";
|
|
for $cx_name (reverse sort keys %cx_names) {
|
|
next if( $cx_name !~ /^CX_/);
|
|
$cmd = $::utils->fmt_cmd("rm_cx", "all", $cx_name);
|
|
print "** $cmd **".NL if ($::DEBUG);
|
|
|
|
$::utils->doCmd($cmd);
|
|
print "0"; #$cx_name ";
|
|
sleep(0.5);
|
|
my $endp_name = $cx_name;
|
|
$endp_name =~ s/CX_//;
|
|
$cmd = $::utils->fmt_cmd("rm_endp", $endp_name);
|
|
$::utils->doCmd($cmd);
|
|
print "o"; #$endp_name ";
|
|
sleep(0.1);
|
|
}
|
|
print NL;
|
|
sleep(1);
|
|
|
|
# remove group
|
|
if ( "$group_name" eq "$::group" ) {
|
|
$cmd = $::utils->fmt_cmd("rm_group", $group_name."_wo");
|
|
print " + $cmd".NL if ($::DEBUG);
|
|
$::utils->doCmd($cmd);
|
|
print "Removed ".$group_name."_wo".NL;
|
|
sleep(0.2);
|
|
$cmd = $::utils->fmt_cmd("rm_group", $group_name."_ro");
|
|
print " + $cmd".NL if ($::DEBUG);
|
|
$::utils->doCmd($cmd);
|
|
print "Removed ".$group_name."_ro".NL;
|
|
sleep(0.2);
|
|
}
|
|
else {
|
|
$cmd = $::utils->fmt_cmd("rm_group", $group_name);
|
|
print " + $cmd".NL if ($::DEBUG);
|
|
$::utils->doCmd($cmd);
|
|
print "Removed ".$group_name.NL;
|
|
}
|
|
sleep(2);
|
|
|
|
# set those vlans admin down
|
|
print "Setting mvlans down: ";
|
|
for my $port (reverse sort keys %portlist) {
|
|
my @h = split(/\s+/, $port);
|
|
$cmd = fmt_port_up_down($h[1], $h[2], "down");
|
|
print "$cmd".NL if ($::DEBUG);
|
|
$::utils->doCmd($cmd);
|
|
print "o"; # $port ";
|
|
sleep(0.4);
|
|
}
|
|
print NL;
|
|
sleep(0.2 * length(keys %portlist));
|
|
# remove macvlans
|
|
print "Removing mvlans ports: ";
|
|
for my $port (reverse sort keys %portlist) {
|
|
$cmd = "rm_vlan $port";
|
|
print "Remove VLAN: $cmd".NL if ($::DEBUG);
|
|
$::utils->doCmd($cmd);
|
|
print "*"; #$port ";
|
|
sleep(0.2);
|
|
}
|
|
print "...done.".NL;
|
|
}
|
|
|
|
## ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
|
|
## use this method to find the user prefix for each ip last octet
|
|
## ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
|
|
sub get_prefix_for_octet {
|
|
my($octet) = @_;
|
|
die "get_prefix_for_octet called without octet as argument" if ((!defined $octet) || ("$octet" eq ""));
|
|
for my $name (sort( keys %::group_names)) {
|
|
my $ra_bounds = $::group_names{ $name };
|
|
if (($octet >= @$ra_bounds[0]) && ($octet <= @$ra_bounds[1])) {
|
|
return $name;
|
|
}
|
|
}
|
|
die "get_prefix_for_octet: no prefix found for octet [$octet]";
|
|
}
|
|
|
|
sub do_err_exit {
|
|
my $msg = shift;
|
|
print $msg.NL;
|
|
exit(1);
|
|
}
|
|
|
|
## ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ==
|
|
## ==
|
|
## M A I N ==
|
|
## ==
|
|
## ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ==
|
|
|
|
GetOptions
|
|
(
|
|
'mgr|m=s' => \$lfmgr_host,
|
|
'mgr_port|mp=i' => \$lfmgr_port,
|
|
'resource|r=i' => \$resource,
|
|
'quiet|q=s' => \$quiet,
|
|
'action|a=s' => \$action,
|
|
'nfs_mnt|h=s' => \$nfs_mnt,
|
|
'nfs_list|e=s' => \$nfs_list,
|
|
'first_mvlan_ip|n=s' => \$first_mvlan_ip,
|
|
'group|g=s' => \$group,
|
|
'debug' => \$DEBUG,
|
|
'dbg_nap|dp=i' => \$D_PAUSE,
|
|
'parent_port|pp=s' => \$parent_port,
|
|
'min_rw_size|nws=i' => \$min_rw_size,
|
|
'max_rw_size|xws=i' => \$max_rw_size,
|
|
'use_crc|crc=s' => \$use_crc,
|
|
'min_read_bps|nrbps=i' => \$min_read_bps,
|
|
'max_read_bps|xrbps=i' => \$max_read_bps,
|
|
'num_files|nf=i' => \$num_files,
|
|
'quiesce_after_files|qaf=i' => \$quiesce_after_files,
|
|
'skip_readers|sr=i' => \$skip_readers,
|
|
'skip_writers|sw=i' => \$skip_writers,
|
|
'min_file_size|nsz=i' => \$min_file_size,
|
|
'max_file_size|xsz=i' => \$max_file_size,
|
|
'min_write_bps|nwbps=i' => \$min_write_bps,
|
|
'max_write_bps|xwbps=i' => \$max_write_bps,
|
|
'mount_options|mo=s' => \$mount_options,
|
|
'netmask|nm=s' => \$netmask,
|
|
'tmp_group|tmp=s' => \$tmp_group,
|
|
'min|ga=i' => \$tmp_group_min,
|
|
'max|gb=i' => \$tmp_group_max,
|
|
) || do_err_exit("$usage");
|
|
|
|
|
|
if ((!defined $action) || ($action eq "")) {
|
|
do_err_exit("Please specify an action to perform.\n$usage");
|
|
}
|
|
|
|
if ( ! ( $action eq "list_groups"
|
|
|| $action eq "run_group"
|
|
|| $action eq "stop_group"
|
|
|| $action eq "del_group" )) {
|
|
do_err_exit("Unknown action $action:\n$usage");
|
|
}
|
|
|
|
if ((defined $tmp_group) && ($tmp_group ne "")) {
|
|
print "Using temporary group [$tmp_group]\n";
|
|
do_err_exit("Please set --min when using tmp_group") if ($tmp_group_min <= 0);
|
|
do_err_exit("Please set --max when using tmp_group") if ($tmp_group_max <= 0);
|
|
$group = $tmp_group;
|
|
}
|
|
elsif ( !(defined $group) || ("$group" eq "")) {
|
|
do_err_exit("Blank or unknown group. Cannot continue.");
|
|
}
|
|
|
|
if ( $group eq $tmp_group ) {
|
|
if ( !defined $parent_port || "$parent_port" eq "" ) {
|
|
do_err_exit("Undefined --parent_port value. Cannot continue.");
|
|
}
|
|
$group_names{ $tmp_group } = [ $tmp_group_min, $tmp_group_max, $parent_port ];
|
|
print "assigned values to group name [$group]\n" if ($::DEBUG);
|
|
my $ra = $group_names{ $tmp_group };
|
|
print "values: [".join(':', @$ra)."]\n" if ($::DEBUG);
|
|
}
|
|
|
|
if ( !defined $parent_port || "$parent_port" eq "" ) {
|
|
$parent_port = $group_names{ $group }[2];
|
|
if ( !defined $parent_port || "$parent_port" eq "" ) {
|
|
do_err_exit("Undefined --parent_port value. Cannot continue.");
|
|
}
|
|
}
|
|
|
|
init();
|
|
|
|
if ( $action eq "list_groups" ) {
|
|
showGroups();
|
|
exit(0);
|
|
}
|
|
|
|
print "checking group name [$group]\n" if ($::DEBUG);
|
|
if ( !defined $group || $group eq "" || ! $group_names{ $group }) {
|
|
$group = "" if ( !defined $group );
|
|
do_err_exit("Blank or unknown group [$group]"
|
|
.NL."Known groups: ".join(', ', sort(keys(%group_names))));
|
|
}
|
|
print "Using group [$group]\n";
|
|
|
|
|
|
if ( $action eq "stop_group" ) {
|
|
stopGroup();
|
|
}
|
|
elsif ( $action eq "run_group" ) {
|
|
prepareTestGroups();
|
|
preparePorts();
|
|
prepareExportList();
|
|
prepareFileEndpoints();
|
|
runGroup();
|
|
}
|
|
elsif ( $action eq "del_group" ) {
|
|
if ( $::skip_readers || $::skip_writers ) {
|
|
deleteGroup();
|
|
}
|
|
else {
|
|
deleteGroup( $::group );
|
|
}
|
|
}
|
|
else {
|
|
die "Unknown action $action:\n$usage";
|
|
}
|
|
|
|
#eof
|