Commit 238dce73 authored by Robert Ricci's avatar Robert Ricci

Some big changes to assign, and some related changes to assign_wrapper

and ptopgen.

Add link typing to assign. Each virtual link is given a single type.
Each physical link is given one or more types. A virtual link will
only be mapped to a physical link which can satisfy its type. In both
the top and ptop files, the link types are now mandatory, and they
fall at the end of the mandatory link arguments.

This differers from the 'regular' type system in two ways. First, a
plink is not constrained to filling only one type at a time. If we are
using emulated links, a plink could satisfy, say, an 'ethernet' link
and an 'fxp' link at the same time. This seems to more naturally match
the way we'll use link types.  Second, there are no counts assoicated
with link types, as there are for node types. ie. a link is not an
'ethernet:1' link, it's an 'ethernet' link. Presumably, when
multiplexing virtual links onto a physical one, it's bandwidth that's
the factor that limits the multiplexing.

The link type is now taken into account when constructing pclasses,
and in the mapping precheck.

As a side-effect of these changes, the silly 'count' argument on the
end of link lines in the ptop file, which was used for the fake LAN
nodes, is no longer supported.

The implementation could be a bit more efficient, but that would mean
tossing more of the stuff we do with boost's graph library. I think
this should happen, but today is not the day.

Modify assign_wrapper and ptopgen to spit out top and ptop files in
the new format.

Changed the constant LINK_UKNOWN to LINK_UNMAPPED - the new name more
accurately reflects the way this constant is used.

Add a new '-n' flag that tells assign not to do annealing, just exit
after the type precheck.

Clarify the usage message for the -c flag.

Removed some dead code for dealing with LAN nodes.
parent 297019fb
......@@ -333,7 +333,8 @@ void print_help()
<< endl;
cout << " -u - Print a summary of the solution." << endl;
cout << " -c <float> - Use the 'connected' pnode finding algorithm " <<
"<float>% of the time." << endl;
"<float>*100% of the time." << endl;
cout << " -n - Don't anneal - just do the prechecks." << endl;
exit(EXIT_FATAL);
}
......@@ -386,7 +387,7 @@ int type_precheck() {
}
if (ok) {
cout << "Type preecheck passed." << endl;
cout << "Type precheck passed." << endl;
return 1;
} else {
cout << "Type precheck failed!" << endl;
......@@ -424,12 +425,16 @@ int mapping_precheck() {
// This constitutes a list of the number of ptypes that matched the
// criteria. We use to guess what's wrong with the vnode.
int matched_links = 0;
int matched_bw = 0;
// Keep track of desires had how many 'hits', so that we can tell
// if any simply were not matched
tb_vnode::desires_count_map matched_desires;
// Keep track of which link types had how many 'hits', so that we can
// tell which type(s) caused this node to fail
tb_vnode::link_counts_map matched_link_counts;
map<crope,bool> matched_links;
tb_vclass *vclass = v->vclass;
tb_vclass::members_map::iterator mit;
if (vclass) {
......@@ -452,6 +457,7 @@ int mapping_precheck() {
// Grab the first node of the pclass as a representative sample
tb_pnode *pnode = *((*it)->members[this_type]->L.begin());
#if 0
// Check the number of interfaces - if the pnode is a switch,
// for now, we don't check this, since it can end up with more
// 'interfaces' due to the fact that it can have interswitch
......@@ -462,6 +468,10 @@ int mapping_precheck() {
} else {
potential_match = false;
}
#endif
// Check to see if any of the link that this pnode has are of
// the correct type for the virtual node
// Check bandwidth on emulated links
if (pnode->total_bandwidth >= v->total_bandwidth) {
......@@ -528,6 +538,26 @@ int mapping_precheck() {
}
}
// Check link types
tb_vnode::link_counts_map::iterator vit;
for (vit = v->link_counts.begin(); vit != v->link_counts.end();
vit++) {
crope type = vit->first;
int count = vit->second;
if (pnode->link_counts.find(type) !=
pnode->link_counts.end()) {
// Found at least one link of this type
matched_links[type] = true;
if (pnode->link_counts[type] >= count) {
// Great, there are enough, too
matched_link_counts[type]++;
} else {
potential_match = false;
}
} else {
potential_match = false;
}
}
if (potential_match) {
vec->push_back(*it);
......@@ -553,8 +583,20 @@ int mapping_precheck() {
if (vnode_type_table[v->name].first == 0) {
cout << " *** No possible mapping for " << v->name << endl;
// Make an attempt to figure out why it didn't match
if (!matched_links) {
cout << " Too many links!" << endl;
// Check all of its link types
tb_vnode::link_counts_map::iterator lit;
for (lit = v->link_counts.begin(); lit != v->link_counts.end();
lit++) {
crope type = lit->first;
if (!matched_links[type]) {
cout << " No links of type " << type << " found!" << endl;
} else {
if (!matched_link_counts[type]) {
cout << " Too many links of type " << type << "!"
<< endl;
}
}
}
if (!matched_bw) {
......@@ -612,12 +654,13 @@ int main(int argc,char **argv)
int seed = 0;
crope viz_prefix;
bool scoring_selftest = false;
bool prechecks_only = false;
// Handle command line
char ch;
timelimit = 0.0;
timetarget = 0.0;
while ((ch = getopt(argc,argv,"s:v:l:t:rpPTdH:oguc:")) != -1) {
while ((ch = getopt(argc,argv,"s:v:l:t:rpPTdH:oguc:n")) != -1) {
switch (ch) {
case 's':
if (sscanf(optarg,"%d",&seed) != 1) {
......@@ -674,6 +717,10 @@ int main(int argc,char **argv)
print_help();
}
break;
case 'n':
prechecks_only = true;
cout << "Doing only prechecks, exiting early" << endl;
break;
default:
print_help();
}
......@@ -753,6 +800,11 @@ int main(int argc,char **argv)
exit(EXIT_UNRETRYABLE);
}
// Bomb out early if we're only doing the prechecks
if (prechecks_only) {
exit(EXIT_SUCCESS);
}
#ifdef PER_VNODE_TT
if (prune_pclasses) {
prune_unusable_pclasses();
......
......@@ -178,27 +178,21 @@ int parse_ptop(tb_pgraph &PG, tb_sgraph &SG, istream& i)
pname2vertex[name] = pv;
}
} else if (command.compare("link") == 0) {
if (parsed_line.size() < 7) {
if (parsed_line.size() < 8) {
ptop_error("Bad link line, too few arguments.");
}
int num = 1;
#ifdef PENALIZE_BANDWIDTH
float penalty;
if (parsed_line.size() == 8) {
if (sscanf(parsed_line[7].c_str(),"%f",&penalty) != 1) {
ptop_error("Bad number argument: " << parsed_line[7] << ".");
if (parsed_line.size() == 9) {
if (sscanf(parsed_line[8].c_str(),"%f",&penalty) != 1) {
ptop_error("Bad number argument: " << parsed_line[8] << ".");
penalty=1.0;
}
}
#else
if (parsed_line.size() == 8) {
if (sscanf(parsed_line[7].c_str(),"%d",&num) != 1) {
ptop_error("Bad number argument: " << parsed_line[7] << ".");
num=1;
}
}
#endif
#if 0
#ifdef FIX_PLINK_ENDPOINTS
bool fixends;
#ifdef FIX_PLINKS_DEFAULT
......@@ -206,16 +200,18 @@ int parse_ptop(tb_pgraph &PG, tb_sgraph &SG, istream& i)
#else
fixends = false;
#endif
if (parsed_line.size() == 9) {
if (parsed_line[8].compare("fixends") == 0) {
if (parsed_line.size() == 10) {
if (parsed_line[9].compare("fixends") == 0) {
fixends = true;
}
}
#else
if (parsed_line.size() > 8) {
if (parsed_line.size() > 9) {
ptop_error("Bad link line, too many arguments.");
}
#endif
#endif
crope name = parsed_line[1];
crope src,srcmac;
split_two(parsed_line[2],':',src,srcmac,"(null)");
......@@ -224,6 +220,7 @@ int parse_ptop(tb_pgraph &PG, tb_sgraph &SG, istream& i)
crope bw = parsed_line[4];
crope delay = parsed_line[5];
crope loss = parsed_line[6];
crope link_type = parsed_line[7];
int ibw,idelay;
double gloss;
......@@ -252,14 +249,17 @@ int parse_ptop(tb_pgraph &PG, tb_sgraph &SG, istream& i)
for (int cur = 0;cur<num;++cur) {
pedge pe = (add_edge(srcv,dstv,PG)).first;
tb_plink *pl = new tb_plink(name,tb_plink::PLINK_NORMAL,srcmac,dstmac);
tb_plink *pl = new
tb_plink(name,tb_plink::PLINK_NORMAL,link_type,srcmac,dstmac);
put(pedge_pmap,pe,pl);
pl->delay_info.bandwidth = ibw;
pl->delay_info.delay = idelay;
pl->delay_info.loss = gloss;
#if 0
#ifdef FIX_PLINK_ENDPOINTS
pl->fixends = fixends;
#endif
#endif
#ifdef PENALIZE_BANDWIDTH
pl->penalty = penalty;
#endif
......@@ -275,11 +275,19 @@ int parse_ptop(tb_pgraph &PG, tb_sgraph &SG, istream& i)
tb_slink *sl = new tb_slink();
put(sedge_pmap,swedge,sl);
sl->mate = pe;
pl->type = tb_plink::PLINK_INTERSWITCH;
pl->is_type = tb_plink::PLINK_INTERSWITCH;
}
}
srcnode->total_interfaces++;
dstnode->total_interfaces++;
srcnode->link_counts[link_type]++;
dstnode->link_counts[link_type]++;
for (int i = 8; i < parsed_line.size(); i++) {
crope link_type = parsed_line[i];
pl->types.insert(link_type);
srcnode->link_counts[link_type]++;
dstnode->link_counts[link_type]++;
}
if (ISSWITCH(srcnode) &&
! ISSWITCH(dstnode)) {
dstnode->switches.insert(srcv);
......
......@@ -158,12 +158,13 @@ int parse_top(tb_vgraph &VG, istream& i)
}
}
} else if (command.compare("link") == 0) {
if (parsed_line.size() < 7) {
if (parsed_line.size() < 8) {
top_error("Bad link line, too few arguments.");
} else {
crope name = parsed_line[1];
crope src = parsed_line[2];
crope dst = parsed_line[3];
crope link_type = parsed_line[7];
crope bw,bwunder,bwover;
crope delay,delayunder,delayover;
crope loss,lossunder,lossover;
......@@ -238,6 +239,7 @@ int parse_top(tb_vgraph &VG, istream& i)
tb_vlink *l = new tb_vlink();
l->src = node1;
l->dst = node2;
l->type = link_type;
put(vedge_pmap,e,l);
if ((sscanf(bw.c_str(),"%d",&(l->delay_info.bandwidth)) != 1) ||
......@@ -264,7 +266,7 @@ int parse_top(tb_vgraph &VG, istream& i)
#endif
l->emulated = false;
for (unsigned int i = 7;i < parsed_line.size();++i) {
for (unsigned int i = 8;i < parsed_line.size();++i) {
if (parsed_line[i].compare("nodelay") == 0) {
l->allow_delayed = false;
} else if (parsed_line[i].compare("emulated") == 0) {
......@@ -288,6 +290,8 @@ int parse_top(tb_vgraph &VG, istream& i)
} else {
vnode1->num_links++;
vnode2->num_links++;
vnode1->link_counts[link_type]++;
vnode2->link_counts[link_type]++;
}
#endif
}
......
......@@ -11,7 +11,7 @@
#include <hash_map>
#include <rope>
#include <queue>
#include <slist>
#include <list>
#include <algorithm>
#include <boost/config.hpp>
......@@ -48,26 +48,15 @@ extern pclass_list pclasses;
// length of the array.
extern pclass_types type_table;
typedef pair<pvertex,int> link_info; // dst, bw
struct hashlinkinfo {
size_t operator()(link_info const &A) const {
hashptr<void *> ptrhash;
return ptrhash(A.first)/2+A.second;
}
};
// returns 1 if a and b are equivalent. They are equivalent if the
// type and features information match and if there is a one-to-one
// mapping between links that preserves bw, and destination.
int pclass_equiv(tb_pgraph &PG, tb_pnode *a,tb_pnode *b)
{
typedef hash_multiset<link_info,hashlinkinfo> link_set;
// The unique flag is used to signify that there is some reason that assign
// is not aware of that the node is unique, and shouldn't be put into a
// pclass. The usual reason for doing this is for scoring purposes - ie.
// don't prefer one just because it's the same pclass as another that, in
// don't prefer one just because it's the same pclass over another that, in
// reality, is very different.
if (a->unique || b->unique) {
return 0;
......@@ -129,33 +118,51 @@ int pclass_equiv(tb_pgraph &PG, tb_pnode *a,tb_pnode *b)
}
}
// check links - to do this we first create sets of every link in b.
// we then loop through every link in a, find a match in the set, and
// remove it from the set.
// Check links
pvertex an = pnode2vertex[a];
pvertex bn = pnode2vertex[b];
link_set b_links;
// Make a list of all links for node b
typedef list<pedge> link_list;
link_list b_links;
poedge_iterator eit,eendit;
tie(eit,eendit) = out_edges(bn,PG);
for (;eit != eendit;++eit) {
pvertex dst = target(*eit,PG);
if (dst == bn)
dst = source(*eit,PG);
b_links.insert(link_info(dst,get(pedge_pmap,*eit)->delay_info.bandwidth));
b_links.push_back(*eit);
}
// Go through all of a's links, trying to find matches on node b. If we find
// a match, we remove it from the list
tie(eit,eendit) = out_edges(an,PG);
for (;eit != eendit;++eit) {
pvertex dst = target(*eit,PG);
if (dst == an)
dst = source(*eit,PG);
int bw = get(pedge_pmap,*eit)->delay_info.bandwidth;
link_info tomatch = link_info(dst,bw);
link_set::iterator found = b_links.find(tomatch);
if (found == b_links.end()) return 0;
else b_links.erase(found);
tb_plink *plink_a = get(pedge_pmap,*eit);
pvertex dest_pv_a = target(*eit,PG);
if (dest_pv_a == a)
dest_pv_a = source(*eit,PG);
link_list::iterator bit;
for (bit = b_links.begin(); bit != b_links.end(); bit++) {
tb_plink *plink_b = get(pedge_pmap,*bit);
pvertex dest_pv_b = target(*bit,PG);
if (dest_pv_b == b)
dest_pv_b = source(*bit,PG);
// If links are equivalent, remove this link in b from further
// consideration, and go to the next link in a
if ((dest_pv_a == dest_pv_b) && plink_a->is_equiv(*plink_b)) {
b_links.erase(bit);
break;
}
}
// If we never found a match, these nodes aren't equivalent
if (bit == b_links.end()) {
return 0;
}
}
// Make sure node b has no extra links
if (b_links.size() != 0) return 0;
return 1;
}
......
......@@ -61,6 +61,8 @@ typedef hash_map<svertex,switch_dist_map*>switch_dist_map_map;
typedef list<pedge> pedge_path;
typedef list<pvertex> pvertex_list;
typedef hash_map<crope,int> link_type_count_map;
// Globals, declared in assign.cc
extern tb_pgraph_vertex_pmap pvertex_pmap;
......@@ -156,6 +158,9 @@ public:
bool is_switch; // Indicates whether or not this pnode is a
// switch
//
link_type_count_map link_counts; // Counts how many links of each type this
// node has
bool set_current_type(crope type) {
if (types.find(type) == types.end()) {
......@@ -228,17 +233,22 @@ typedef hash_map<nodepair,int,pairhash<crope> > nodepair_count_map;
class tb_plink {
public:
typedef enum {PLINK_NORMAL,PLINK_INTERSWITCH,PLINK_LAN} plinkType;
typedef hash_set<crope> type_set;
tb_plink(crope _name, plinkType _type, crope _srcmac, crope _dstmac)
: name(_name), srcmac(_srcmac), dstmac(_dstmac), type(_type),
tb_plink(crope _name, plinkType _is_type, crope _type, crope _srcmac, crope
_dstmac)
: name(_name), srcmac(_srcmac), dstmac(_dstmac), is_type(_is_type),
delay_info(), bw_used(0), emulated(0), nonemulated(0),
penalty(0.0), fixends(false), current_endpoints(), current_count(0),
vedge_counts() {;}
vedge_counts() {
types.insert(_type);
}
crope name; // the name
crope srcmac,dstmac; // source and destination MAC addresses.
plinkType type; // type of the link
plinkType is_type; // inter-switch type of the link
type_set types; // type (ie. ethernet) of the link
tb_delay_info delay_info; // the delay characteristics of this link
int bw_used; // how much is used
......@@ -258,7 +268,7 @@ public:
{
o << "tb_plink: " << link.name << " (" << &link << ")" << endl;
o << " type: ";
switch (link.type) {
switch (link.is_type) {
case tb_plink::PLINK_NORMAL:
o << "normal" << endl;
break;
......@@ -276,6 +286,21 @@ public:
o << link.delay_info;
return o;
}
// Return true if the two plinks are equivalent, in terms of type and
// bandwidth.
// NOTE: should probably use a helper function in delay_info, but right now,
// we only care about bandwidth
const bool is_equiv(const tb_plink& link) {
if (types == link.types) {
return false;
}
if (delay_info.bandwidth != link.delay_info.bandwidth) {
return false;
}
return true;
}
};
class tb_slink {
......
This diff is collapsed.
......@@ -49,21 +49,23 @@ void print_solution()
cout << vlink->name;
if (vlink->link_info.type == tb_link_info::LINK_DIRECT) {
if (vlink->link_info.type_used == tb_link_info::LINK_DIRECT) {
// Direct link - just need the source and destination
tb_plink *p = get(pedge_pmap,vlink->link_info.plinks.front());
tb_plink *p2 = get(pedge_pmap,vlink->link_info.plinks.back());
cout << " direct " << p->name << " (" <<
p->srcmac << "," << p->dstmac << ") " <<
p2->name << " (" << p2->srcmac << "," << p2->dstmac << ")";
} else if (vlink->link_info.type == tb_link_info::LINK_INTRASWITCH) {
} else if (vlink->link_info.type_used ==
tb_link_info::LINK_INTRASWITCH) {
// Intraswitch link - need to grab the plinks to both nodes
tb_plink *p = get(pedge_pmap,vlink->link_info.plinks.front());
tb_plink *p2 = get(pedge_pmap,vlink->link_info.plinks.back());
cout << " intraswitch " << p->name << " (" <<
p->srcmac << "," << p->dstmac << ") " <<
p2->name << " (" << p2->srcmac << "," << p2->dstmac << ")";
} else if (vlink->link_info.type == tb_link_info::LINK_INTERSWITCH) {
} else if (vlink->link_info.type_used ==
tb_link_info::LINK_INTERSWITCH) {
// Interswitch link - interate through each intermediate link
cout << " interswitch ";
for (pedge_path::iterator it=vlink->link_info.plinks.begin();
......@@ -72,7 +74,7 @@ void print_solution()
cout << " " << p->name << " (" << p->srcmac << "," <<
p->dstmac << ")";
}
} else if (vlink->link_info.type == tb_link_info::LINK_TRIVIAL) {
} else if (vlink->link_info.type_used == tb_link_info::LINK_TRIVIAL) {
// Trivial link - we really don't have useful information to
// print, but we'll fake a bunch of output here just to make it
// consistent with other (ie. intraswitch) output
......@@ -211,7 +213,7 @@ void pedge_writer::operator()(ostream &out,const pedge &p) const {
out << plink->delay_info.bandwidth << "/" <<
plink->delay_info.delay << "/" << plink->delay_info.loss << "\"";
#endif
if (plink->type == tb_plink::PLINK_INTERSWITCH) {
if (plink->is_type == tb_plink::PLINK_INTERSWITCH) {
out << " style=dashed";
}
tb_pnode *src = get(pvertex_pmap,source(p,PG));
......@@ -259,8 +261,8 @@ void solution_edge_writer::operator()(ostream &out,const vedge &v) const {
crope style;
crope color;
crope label;
switch (linfo.type) {
case tb_link_info::LINK_UNKNOWN: style="dotted";color="red"; break;
switch (linfo.type_used) {
case tb_link_info::LINK_UNMAPPED: style="dotted";color="red"; break;
case tb_link_info::LINK_DIRECT: style="dashed";color="black"; break;
case tb_link_info::LINK_INTRASWITCH:
style="solid";color="black";
......
......@@ -3,9 +3,11 @@ node pa pc:1
node pb pc:1
node pc pc:1
node pd pc:1
link l1 pa S 100 0 0
link l2 pa S 100 0 0
link l3 pb S 100 0 0
link l4 pb S 100 0 0
link l5 pc S 100 0 0
link l6 pc S 100 0 0
link l1 pa S 100 0 0 ethernet
link l2 pa S 100 0 0 ethernet
link l3 pb S 100 0 0 ethernet
link l4 pb S 100 0 0 ethernet
link l5 pc S 100 0 0 ethernet
link l6 pc S 100 0 0 ethernet
link l7 pd S 100 0 0 80211
link l8 pd S 100 0 0 80211
node A pc
node B pc
node C pc
link vl1 A B 100 0 0
link vl2 A C 100 0 0
link vl3 B C 100 0 0
link vl1 A B 100 0 0 ethernet
link vl2 A C 100 0 0 ethernet
link vl3 B C 100 0 0 ethernet
......@@ -30,20 +30,22 @@ typedef graph_traits<tb_vgraph>::vertex_iterator vvertex_iterator;
typedef graph_traits<tb_vgraph>::edge_iterator vedge_iterator;
typedef graph_traits<tb_vgraph>::out_edge_iterator voedge_iterator;
class tb_link_info {
public:
typedef enum {LINK_UNKNOWN, LINK_DIRECT,
typedef enum {LINK_UNMAPPED, LINK_DIRECT,
LINK_INTRASWITCH, LINK_INTERSWITCH,
LINK_TRIVIAL, LINK_DELAYED} linkType;
linkType type;
linkType type_used; // type of physical link used to satisfy this
// virtual link
pedge_path plinks; // the path of pedges
pvertex_list switches; // what switches were used
friend ostream &operator<<(ostream &o, const tb_link_info& link)
{
o << " Type: ";
switch (link.type) {
case LINK_UNKNOWN : o << "LINK_UNKNOWN"; break;
switch (link.type_used) {
case LINK_UNMAPPED : o << "LINK_UNMAPPED"; break;
case LINK_DIRECT : o << "LINK_DIRECT"; break;
case LINK_INTRASWITCH : o << "LINK_INTRASWITCH"; break;
case LINK_INTERSWITCH : o << "LINK_INTERSWITCH"; break;
......@@ -115,6 +117,10 @@ public:
subnode_list subnodes;
crope subnode_of_name;
// Counts how many links of each type this virtual node has
typedef hash_map<crope,int> link_counts_map;
link_counts_map link_counts;
};
class tb_vlink {
......@@ -134,6 +140,7 @@ public:
tb_delay_info delay_info; // the delay characteristics of the link
tb_link_info link_info; // what it's mapped to
crope name; // name
crope type; // type of this link
bool emulated; // is this an emulated link, i.e. can it
// share a plink withouter emulated vlinks
bool no_connection; // true if this link should be satisfied
......
......@@ -3890,7 +3890,8 @@ sub CreateTopFile()
my ($node) = (split(":",$member))[0];
my $bandwidth = &getbandwidth($node, $lan, $bw);
print TOPFILE "link $plink $node fakelan/$lan $bandwidth 0 0\n";
print TOPFILE "link $plink $node fakelan/$lan $bandwidth " .
"0 0 wireless\n";
}
}
elsif ($#members == 1) {
......@@ -3940,7 +3941,7 @@ sub CreateTopFile()
my $plink = "linksimple/$lan/$nodeport0,$nodeport1";
print(TOPFILE "link $plink $node0 $node1 ".
max($bw,$rbw) . " 0 0" .
max($bw,$rbw) . " 0 0 ethernet " .
($emulated ? " emulated" : "") .
($trivial_ok ? " trivial_ok\n" : "\n"));
......@@ -3970,10 +3971,10 @@ sub CreateTopFile()
print TOPFILE "node $delayname delay\n";
print TOPFILE
"link linksdelaysrc/$lan/$nodeport0,$nodeport1 ".
"$node0 $delayname $bandwidth 0 0\n";
"$node0 $delayname $bandwidth 0 0 ethernet\n";
print TOPFILE
"link linksdelaydst/$lan/$nodeport1,$nodeport0 ".
"$node1 $delayname $bandwidth 0 0\n";
"$node1 $delayname $bandwidth 0 0 ethernet\n";
$delaynodes{$delayname} = $delayname;
......@@ -3994,10 +3995,10 @@ sub CreateTopFile()
print TOPFILE "link $plink $node0 $node1";
if ($emulated) {
print TOPFILE " " . max($bw,$rbw) . " 0 0 emulated";
print TOPFILE " " . max($bw,$rbw) . " 0 0 ethernet emulated";
}
else {
print TOPFILE " $bandwidth 0 0";
print TOPFILE " $bandwidth 0 0 ethernet";
}
if ($trivial_ok) {
print TOPFILE " trivial_ok";
......@@ -4061,7 +4062,7 @@ sub CreateTopFile()
$member,$rdelay,$rbw,$rloss,0];
print(TOPFILE "link $plink $node lan/$lan " .
max($bw,$rbw) . " 0 0" .
max($bw,$rbw) . " 0 0 ethernet" .
($emulated ? " emulated" : "") .
($trivial_ok ? " trivial_ok\n" : "\n"));
......@@ -4078,9 +4079,9 @@ sub CreateTopFile()
print TOPFILE "node $delayname delay\n";
print TOPFILE "link linkdelaysrc/$lan/$member" .
" $node $delayname $bandwidth 0 0\n";
" $node $delayname $bandwidth 0 0 ethernet\n";
print TOPFILE "link linkdelaydst/$lan/$member" .
" lan/$lan $delayname $bandwidth 0 0\n";
" lan/$lan $delayname $bandwidth 0 0 ethernet\n";
$delaynodes{$delayname} = $delayname;
......@@ -4098,7 +4099,8 @@ sub CreateTopFile()
else {
my $plink = "linklan/$lan/$member";
print TOPFILE "link $plink $node lan/$lan $bandwidth 0 0";
print TOPFILE "link $plink $node lan/$lan $bandwidth " .
"0 0 ethernet";
if ($emulated) {
print TOPFILE " emulated";
}
......
......@@ -413,6 +413,15 @@ foreach $node (keys(%nodes)) {
# physnode.
#
if ($widearea) {
#
# If we are spposed to exempt a certain eid from being considered down,
# build up a clause to do that - we consider all nodes already used by that
# experiment to be available
#
my $exempt_condition = "0";
if (defined($exempt_eid)) {
$free_condition = "(r.pid='$pid' and r.eid='$exempt_eid')";
}
$result =
DBQueryFatal("select count(a.node_id),a.phys_nodeid,aa.type, ".
" ns.status,m.pid,m.eid,wn.site ".
......@@ -576,7 +585,7 @@ while (($node1,$card1,$port1,$node2,$card2,$port2) =
# !!! - Here we use our knowledge that in the wires table links
# to the switch always come as node2.
print "link link-$node1:$iface1-$node2:$iface2 $node1:$node1/$iface1" .
" $node2:$iface2 $bw 0 0 1\n";
" $node2:$iface2 $bw 0 0 1 ethernet\n";
}
}
}
......@@ -632,7 +641,8 @@ if ($TRACK_INTERSWITCH_BANDWIDTH) {
foreach $interconnect (keys(%interconnects)) {
($src,$dst) = split(":",$interconnect);
print "link link-$interconnect $src $dst $interconnects{$interconnect} 0 0 1\n";
print "link link-$interconnect $src $dst $interconnects{$interconnect} " .
"0 0 1 ethernet\n";
}
#
......@@ -659,7 +669,7 @@ foreach my $switchtype (("80211a", "80211b", "80211g")) {
#print "$node $card $port $type $proto\n";
print "link link-$node:$iface-$switchname:(null) ".
"$node:$node/$iface $switchname:(null) $ifacebw 0 0 1\n";
"$node:$node/$iface $switchname:(null) $ifacebw 0 0 1 80211\n";
}
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment