goodnodes.pl 6.21 KB
Newer Older
1 2 3
#!/usr/bin/perl -w
#
# Copyright (c) 2006 University of Utah and the Flux Group.
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
# 
# {{{EMULAB-LICENSE
# 
# This file is part of the Emulab network testbed software.
# 
# This file is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at
# your option) any later version.
# 
# This file is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public
# License for more details.
# 
# You should have received a copy of the GNU Affero General Public License
# along with this file.  If not, see <http://www.gnu.org/licenses/>.
# 
# }}}
23 24 25 26 27 28
#

#
# - Find a set of fully connected nodes from the list of nodes at
#     boss:/proj/tbres/plab-reliable-list
# - Size of desired set given as a parameter
29 30
# - + The sites containing the nodes must have both latency and bw 
#     data in the past XXX hours (XXX<24)
31 32 33
#   + The set will not contain more than one node from a site
# - Run this on ops.

34 35 36 37 38 39 40

#
# TODO:
# - add options for time window
#


41 42
#use diagnostics;
use strict;
43
use English;
44
use Getopt::Std;
45
use lib '/usr/testbed/lib';
46
use libxmlrpc;
47

48
my $allnodeFile = "/share/planetlab/reliable_nodes";
49
my $NLIST = "/usr/testbed/bin/node_list";
50
my $pprefix = "plab";
51 52
my $windowHrsDef = 6;

53 54
# Turn off line buffering on output
$| = 1;
55

56
sub usage {
57
        print "Usage: $0 [-e pid/eid] [-f blacklistfilename] [-t type] [-v] ".
Sachin Goyal's avatar
Sachin Goyal committed
58
            "[-m meastype] [-s searchtype] <numNodes>\n";
59 60 61
        return 1;
}
my ($pid, $eid);
62
my $blacklistfilename;
63
my $type = "";
Sachin Goyal's avatar
Sachin Goyal committed
64 65
my $meastype = "both";
my $searchtype = "maxclique";
66
my $verbose = 0;
67
my ($t0, $t1);
68
my %opt = ();
Sachin Goyal's avatar
Sachin Goyal committed
69
getopts("0:1:e:f:t:vm:s:", \%opt);
70 71 72 73 74
if ($opt{e}) {
    ($pid,$eid) = split('/', $opt{e});
} else {
    $pid = "tbres"; $eid = "pelabbgmon";
}
75
if ($opt{f}) { $blacklistfilename = $opt{f}; }
76
if ($opt{t}) { $type = $opt{t}; }
Sachin Goyal's avatar
Sachin Goyal committed
77 78
if ($opt{m}) { $meastype = $opt{m}; }
if ($opt{s}) { $searchtype = $opt{s}; }
79
if ($opt{v}) { $verbose = 1; }
80 81 82 83
if ($opt{0}) { $t0 = $opt{0}; } else { $t0 = time()-$windowHrsDef*60*60; }
if ($opt{1}) { $t1 = $opt{1}; }
elsif($opt{0}) { $t1 = $t0+$windowHrsDef*60*60; }
else { $t1 = time(); }
84
if (@ARGV !=1) { exit &usage; }
Sachin Goyal's avatar
Sachin Goyal committed
85 86 87 88 89 90 91 92 93 94 95 96
if (($meastype ne 'lat') && ($meastype ne 'bw') && ($meastype ne 'both')) {
    print "Wrong value of meastype (-m option). It can be only".
	  "'lat', 'bw', or 'both' \n";
    exit 1;
}

if (($searchtype ne 'fastfallible') && ($searchtype ne 'maxclique')) {
    print "Wrong value of searchtype (-s option). It can be only".
	  "'fastfallible' or 'maxclique'\n";
    exit 1;
}

97 98 99 100

#
# These are globals
#
101
my $numnodes = $ARGV[0];
102
my @allnodes = ();      #nodes to consider, in order of desirablility (?)
103
my %expnodes = ();  #nodes making up eid/pid
104
my %blacknodes = ();#nodes not allowed to be chosen (deleted from allnodes)
105 106 107 108 109 110 111 112

#
# Get list of possible nodes
#
open FILE, "< $allnodeFile"
    or die "Can't open file";
my @allnodesinfo = <FILE>;
foreach my $nodeinfo (@allnodesinfo){
113
    my @fields = split /\s+/, $nodeinfo;
114 115 116 117
    #we only want the plabxxx value (for now)
    push @allnodes, $fields[0];
    #print "$fields[0]\n";
}
118
close FILE;
119 120 121
if ($verbose) {
    print "Read " . scalar(@allnodes) . " nodes from reliable nodes file\n";
}
122

123 124 125 126 127 128 129 130 131 132 133 134 135 136
#
# get list of blacklisted nodes
#
if( defined $blacklistfilename ){
    open FILE, "< $blacklistfilename"
        or die "Can't open file";
    my @blacklist = <FILE>;
    chomp @blacklist;
    foreach my $node (@blacklist){
        $blacknodes{$node} = 1;
        print "blacknode: $node\n";
    }
    close FILE;
}
137 138 139 140 141 142 143


###############################################################################
# Keep nodes given in pid/eid in hash for quick access.
if( defined($pid) && defined($eid) ){
#    print "reading $pid/$eid nodes\n";
    #add exp nodes to a hash
144
    my @expnodelist = split('\s+', `$NLIST -H -e $pid,$eid`);
145
    chomp(@expnodelist);
146 147 148 149 150 151 152 153 154
    foreach my $node (@expnodelist) {
        if ($node =~ /^(${pprefix}\d+)=([\w,]*)$/) {
            my $pnode = $1;
            my $types = $2;
            my @types = split(/,/,$types);
            if ($type && ! grep(/^$type$/,@types)) {
                #print "Skipping $pnode ($type,$types)\n";
                next;
            }
155 156 157 158 159 160
#            print "$vnode ($pnode)\n";
            $expnodes{$pnode} = 1;  #set this node
        }
    }
    #delete nodes from allnodes not found in given experiment
    for( my $i=0; $i < scalar(@allnodes); $i++ ){
161 162 163
        if( !defined $expnodes{$allnodes[$i]} ||
            defined $blacknodes{$allnodes[$i]})
        {
164 165 166 167 168 169 170
#            print "removing $allnodes[$i] from set\n";
            splice( @allnodes, $i, 1 );
            $i--;
        }else{
#            print "$allnodes[$i]\n";
        }
    }
171
#    chomp @allnodes;
172 173 174 175 176 177 178 179 180 181 182 183
}else{
    #remove blacknodes
    for( my $i=0; $i < scalar(@allnodes); $i++ ){
        if( defined $blacknodes{$allnodes[$i]})
        {
#            print "removing $allnodes[$i] from set\n";
            splice( @allnodes, $i, 1 );
            $i--;
        }else{
#            print "$allnodes[$i]\n";
        }
    }
184 185
}

186 187 188
#print "allnodes[".scalar(@allnodes-1]=$allnodes

#print "%%%%%%\n@allnodes\n%%%%%%%%%%";
189

190

191
#
192
# Send candidate node list to flexlab xmlrpc server.
193 194
#

195
my ($DEF_HOST,$DEF_PORT,$DEF_URL) = ('ops.emulab.net','3993','/');
196

197 198 199
my $xurl = "http://${DEF_HOST}:${DEF_PORT}${DEF_URL}";
my $xargs = { 'size' => $numnodes,
              'nodefilter' => \@allnodes,
Sachin Goyal's avatar
Sachin Goyal committed
200 201
              'meastype' => $meastype,
              'searchtype' => $searchtype,
202 203 204
              'filtertype' => 1 };
my $respref = libxmlrpc::CallMethodHTTP($xurl,'flexlab.getFullyConnectedSet',
    $xargs);
205

206 207 208
if (!defined($respref)) {
    print STDERR "ERROR: did not get response from server!\n";
    exit(3);
209 210
}

211
my %resp = %$respref;
212

213 214 215 216
if (exists($resp{'httpcode'}) && $resp{'httpcode'} != 400) {
    print STDERR "ERROR: http code " . $resp{'httpcode'} . "; http msg '" . 
        $resp{'httpmsg'} . "'\n";
    exit(4);
217 218
}

219 220 221 222
if ($resp{'code'} ne 0) {
    print STDERR "ERROR: xmlrpc code " . $resp{'code'} . ", fault msg '" . 
	$resp{'output'} . "'\n";
    exit(5);
223 224 225
}

#
226
# Must be a success.
227
#
228 229
print "" . join(',',@{$resp{'value'}}). "\n";
exit(0);