Commit be04644b authored by Tarun Prabhu's avatar Tarun Prabhu

Annotations work - well, ok, they haven't been rigorously tested yet, but I...

Annotations work - well, ok, they haven't been rigorously tested yet, but I think they'll hold up. The only thing that is almost certainly broken is the conversion from links with multiple interfaces into the "node + point-to-point" links that assign knows how to deal with.

Mapper now has a flag to determine whether to output the text format or rspec. rspec outputs are named *.ptop.xml and *.vtop.xml for the advertisement and request respectively.
parent 9b62ce75
......@@ -24,31 +24,35 @@ using namespace std;
void annotate::write_annotated_file (const char* filename)
{
// Get the current implementation
DOMImplementation *impl = DOMImplementationRegistry::getDOMImplementation(NULL);
// Construct the DOMWriter
DOMWriter* writer = ((DOMImplementationLS*)impl)->createDOMWriter();
// Make the output look pretty
if (writer->canSetFeature(XMLUni::fgDOMWRTFormatPrettyPrint, true))
writer->setFeature(XMLUni::fgDOMWRTFormatPrettyPrint, true);
// Set the byte-order-mark feature
if (writer->canSetFeature(XMLUni::fgDOMWRTBOM, true))
writer->setFeature(XMLUni::fgDOMWRTBOM, true);
// Construct the LocalFileFormatTarget
XMLFormatTarget *outputFile = new xercesc::LocalFileFormatTarget(filename);
// Serialize a DOMNode to the local file "<some-file-name>.xml"
writer->writeNode(outputFile, *dynamic_cast<DOMNode*>(this->virtual_root));
// Flush the buffer to ensure all contents are written
outputFile->flush();
// Release the memory
writer->release();
// Get the current implementation
DOMImplementation *impl = DOMImplementationRegistry::getDOMImplementation(NULL);
// Construct the DOMWriter
DOMWriter* writer = ((DOMImplementationLS*)impl)->createDOMWriter();
// Make the output look pretty
if (writer->canSetFeature(XMLUni::fgDOMWRTFormatPrettyPrint, true))
writer->setFeature(XMLUni::fgDOMWRTFormatPrettyPrint, true);
// Set the byte-order-mark feature
if (writer->canSetFeature(XMLUni::fgDOMWRTBOM, true))
writer->setFeature(XMLUni::fgDOMWRTBOM, true);
// Set the XML declaration feature
if (writer->canSetFeature(XMLUni::fgDOMXMLDeclaration, true))
writer->setFeature(XMLUni::fgDOMXMLDeclaration, true);
// Construct the LocalFileFormatTarget
XMLFormatTarget *outputFile = new xercesc::LocalFileFormatTarget(filename);
// Serialize a DOMNode to the local file "<some-file-name>.xml"
writer->writeNode(outputFile, *dynamic_cast<DOMNode*>(this->document));
// Flush the buffer to ensure all contents are written
outputFile->flush();
// Release the memory
writer->release();
}
#endif
......@@ -24,7 +24,8 @@
class annotate
{
protected:
//xercesc::DOMDocument* doc;
xercesc::DOMDocument* document;
xercesc::DOMElement* physical_root;
xercesc::DOMElement* virtual_root;
std::map<std::string, xercesc::DOMElement*> *physical_elements;
......
This diff is collapsed.
This diff is collapsed.
......@@ -31,6 +31,9 @@ class annotate_rspec_v2 : public annotate_rspec
// is an interface to a link end point
enum endpoint_interface_enum { NEITHER, SOURCE, DESTINATION, BOTH };
std::map< std::string, std::set<std::string> > lan_links_map;
std::map< std::string, std::string >* vInterfaceMap;
std::map< std::string, std::string >* pInterfaceMap;
public:
annotate_rspec_v2 ();
......@@ -75,12 +78,6 @@ class annotate_rspec_v2 : public annotate_rspec
// Returns the hop element that was created
xercesc::DOMElement* create_component_hop (xercesc::DOMElement* vlink);
// If the interface is the end point of a link/path,
// add two additional attributes to it
void set_interface_as_link_endpoint (xercesc::DOMElement* interface,
const char* virtual_node_id,
const char* virtual_interface_id);
// Finds the next link in the path returned by assign
xercesc::DOMElement* find_next_link_in_path
(xercesc::DOMElement *prev,
......@@ -107,6 +104,15 @@ class annotate_rspec_v2 : public annotate_rspec
bool is_generated_element (const char* tag,
const char* attr_name,
const char* attr_value);
// Given an interface Id, returns the node on which the interface is present
std::string lookupIface (std::map<std::string, std::string>* map,
std::string ifaceId, bool&);
// Returns the interface on the physical link
// which is declared on the physical node with component_id, physNodeId
const xercesc::DOMElement*
getIfaceOnNode(const xercesc::DOMElement* plink, std::string physNodeId);
};
#endif //for __ANNOTATE_RSPEC_H
......
......@@ -128,8 +128,6 @@ struct vclass emulab_extensions_parser::readVClass (const DOMElement* tag)
// the types and present it to assign, we will have to change the code
// in libvtop
string physNodeName = this->getAttribute(physNode, "name");
cerr << "Converted vclass name to "
<< rspec_parser_helper::convertType(physNodeName) << endl;
physTypes.push_back(rspec_parser_helper::convertType(physNodeName));
}
......
......@@ -58,8 +58,10 @@ extern name_vclass_map vclass_map;
// This is a hash map of the entire physical topology
// because it takes far too long for it to search the XML DOM tree.
map<string, DOMElement*>* advertisement_elements
= new map<string, DOMElement*>();
map<string,DOMElement*>* advertisement_elements= new map<string,DOMElement*>();
map<string, string>* pIfacesMap = new map<string, string>();
DOMElement* advt_root = NULL;
/*
......@@ -117,7 +119,7 @@ int parse_advertisement(tb_pgraph &pg, tb_sgraph &sg, char *filename) {
*/
if (errHandler->sawError()) {
cerr << "There were " << domParser -> getErrorCount ()
<< " errors in your file. " << endl;
<< " errors in " << filename << endl;
exit(EXIT_FATAL);
}
else {
......@@ -147,10 +149,10 @@ int parse_advertisement(tb_pgraph &pg, tb_sgraph &sg, char *filename) {
bool is_physical;
XStr type (advt_root->getAttribute(XStr("type").x()));
if (strcmp(type.c(), "advertisement") == 0)
is_physical = true;
else if (strcmp(type.c(), "request") == 0)
is_physical = false;
if (strcmp(type.c(), "advertisement") != 0) {
cerr << "*** Rspec type must be \"advertisement\" in " << filename
<< " (found " << type.c() << ")" << endl;
}
// XXX: Not sure about datetimes, so they are strings for now
XStr generated (advt_root->getAttribute(XStr("generated").x()));
......@@ -205,7 +207,6 @@ bool populate_nodes(DOMElement *root,
DOMNodeList *nodes = root->getElementsByTagName(XStr("node").x());
int nodeCount = nodes->getLength();
XMLDEBUG("Found " << nodeCount << " nodes in rspec" << endl);
clock_t times [nodeCount];
int availableCount = 0;
int counter = 0;
......@@ -484,10 +485,6 @@ bool populate_links(DOMElement *root, tb_pgraph &pg, tb_sgraph &sg,
continue;
}
/* NOTE: In a request, we assume that each link has only two interfaces
* Although the order is immaterial, assign expects a source first
* and a destination second and we assume the same
*/
string src_node = interfaces[0].physicalNodeId;
string src_iface = interfaces[0].physicalIfaceId;
string dst_node = interfaces[1].physicalNodeId;
......@@ -508,6 +505,9 @@ bool populate_links(DOMElement *root, tb_pgraph &pg, tb_sgraph &sg,
continue;
}
pIfacesMap->insert(pair<string, string>(src_iface, src_node));
pIfacesMap->insert(pair<string, string>(dst_iface, dst_node));
if( unavailable.count( src_node ) ||
unavailable.count( dst_node ) )
//one or both of the endpoints are unavailable; silently
......
......@@ -59,6 +59,8 @@ extern name_vclass_map vclass_map;
DOMElement* request_root = NULL;
DOMDocument* doc = NULL;
map<string, string>* vIfacesMap = new map<string, string>();
int rspec_version = -1;
int bind_ptop_subnodes(tb_pgraph &pg);
......@@ -122,7 +124,7 @@ int parse_request(tb_vgraph &vg, char *filename) {
*/
if (errHandler->sawError()) {
cerr << "*** There were " << domParser -> getErrorCount ()
<< " errors in your file. " << endl;
<< " errors in " << filename << endl;
exit(EXIT_FATAL);
}
else {
......@@ -136,7 +138,8 @@ int parse_request(tb_vgraph &vg, char *filename) {
bool is_physical;
XStr type (request_root->getAttribute(XStr("type").x()));
if (strcmp(type.c(), "request") != 0) {
cerr << "*** RSpec type must be \"request\"" << endl;
cerr << "*** RSpec type must be \"request\" in " << filename
<< " (found " << type.c() << ")" << endl;
exit (EXIT_FATAL);
}
......@@ -161,8 +164,10 @@ int parse_request(tb_vgraph &vg, char *filename) {
}
XMLDEBUG("Found rspec ver. " << rspecVersion << endl);
// Set global variable for annotating
rspec_version = rspecVersion;
map< pair<string, string>, pair<string, string> > fixed_interfaces;
/*
* These three calls do the real work of populating the assign data
* structures
......@@ -266,8 +271,6 @@ bool populate_node(DOMElement* elt,
bool isUnlimited = (typeSlots == 1000);
cerr << "Found req type " << typeName << endl;
/*
* Make a tb_ptype structure for this guy - or just add this node to
* it if it already exists
......@@ -614,6 +617,9 @@ bool populate_link (DOMElement* elt,
<< ", non-existent destination node " << dstNode << endl;
return false;
}
vIfacesMap->insert(pair<string, string>(srcIface, srcNode));
vIfacesMap->insert(pair<string, string>(dstIface, dstNode));
vvertex v_src_vertex = vname2vertex[srcNode.c_str()];
vvertex v_dst_vertex = vname2vertex[dstNode.c_str()];
......@@ -728,8 +734,6 @@ bool populate_vclass (struct vclass vclass, tb_vgraph& vg)
const char* name = vclass.name.c_str();
// We don't have support for hard vclasses yet
if (vclass.type.type == SOFT_VCLASS) {
cerr << "Soft vclass " << name << " with weight "
<< vclass.type.weight << endl;
v = new tb_vclass (XStr(name).f(), vclass.type.weight);
if (v == NULL) {
cerr << "*** Could not create vclass " << vclass.name << endl;
......@@ -740,7 +744,6 @@ bool populate_vclass (struct vclass vclass, tb_vgraph& vg)
for (int i = 0; i < vclass.physicalTypes.size(); i++) {
fstring physType = XStr(vclass.physicalTypes[i].c_str()).f();
cerr << "vclass physType: " << physType << endl;
v->add_type(physType);
vclasses[name].push_back(physType);
}
......
......@@ -86,9 +86,11 @@ void print_solution(const solution &s) {
const char* assigned_to
= XStr (get(pvertex_pmap,s.get_assignment(*vit))->name).c() ;
if (both_inputs_rspec) {
// rspec_annotater->annotate_element(node_name, assigned_to);
// if (rspec_annotater->is_generated_element("node","virtual_id",node_name))
// continue;
rspec_annotater->annotate_element(node_name, assigned_to);
if (rspec_annotater->is_generated_element("node",
"virtual_id",
node_name))
continue;
}
else if (both_inputs_xml) {
vtop_annotater->annotate_element(node_name, assigned_to);
......@@ -111,8 +113,8 @@ void print_solution(const solution &s) {
#ifdef WITH_XML
if (both_inputs_rspec) {
// is_generated = rspec_annotater->is_generated_element
// ("link", "virtual_id", (vlink->name).c_str());
is_generated = rspec_annotater->is_generated_element
("link", "virtual_id", (vlink->name).c_str());
if (!is_generated)
cout << vlink->name;
}
......@@ -128,17 +130,18 @@ void print_solution(const solution &s) {
// 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());
// XXX: This is not correct because it contradicts the comment earlier
// It seems that it will work because the front and back of the list will have the same node
// But it needs to be checked anyway.
// XXX: This is not correct because it contradicts the comment earlier
// It seems that it will work because the front and back of the list will have the same node
// But it needs to be checked anyway.
#ifdef WITH_XML
if (both_inputs_rspec) {
// rspec_annotater->annotate_element((vlink->name).c_str(), (p->name).c_str());
rspec_annotater->annotate_element((vlink->name).c_str(),
(p->name).c_str());
if (is_generated)
continue;
}
else if (both_inputs_xml == true) {
// annotate_vtop((vlink->name).c_str(), (p->name).c_str());
// annotate_vtop((vlink->name).c_str(), (p->name).c_str());
}
#endif
cout << " direct " << p->name << " (" <<
......@@ -153,7 +156,7 @@ void print_solution(const solution &s) {
links.push_back((p->name).c_str());
links.push_back((p2->name).c_str());
if (both_inputs_rspec) {
// rspec_annotater->annotate_element((vlink->name).c_str(), &links);
rspec_annotater->annotate_element((vlink->name).c_str(), &links);
if (is_generated)
continue;
}
......@@ -184,7 +187,7 @@ void print_solution(const solution &s) {
}
#ifdef WITH_XML
if (both_inputs_rspec) {
// rspec_annotater->annotate_element((vlink->name).c_str(), &links);
rspec_annotater->annotate_element((vlink->name).c_str(), &links);
}
else if (both_inputs_xml) {
vtop_annotater->annotate_element((vlink->name).c_str(), &links);
......@@ -200,7 +203,7 @@ void print_solution(const solution &s) {
tb_pnode *pnode = get(pvertex_pmap,pv);
#ifdef WITH_XML
if (both_inputs_rspec) {
// rspec_annotater->annotate_element((vlink->name).c_str());
rspec_annotater->annotate_element((vlink->name).c_str());
if (is_generated)
continue;
}
......@@ -234,7 +237,7 @@ void print_solution (const solution &s, const char* output_filename)
// and the objects have been created there
if (both_inputs_rspec == true) {
cout << "Writing annotated rspec to " << output_filename << endl;
// rspec_annotater->write_annotated_file (output_filename);
rspec_annotater->write_annotated_file (output_filename);
}
else if (both_inputs_xml == true) {
cout << "Writing annotated xml to " << output_filename << endl;
......
......@@ -2357,12 +2357,17 @@ sub GenVirtLans($)
#
if ($self->virtlan_use_linkdelay($vlan, $shaped)) {
my $plink = "linksimple/$vname/$member0,$member1";
my $others = {};
if ($emulated) {
$others->{'emulated'} = 1;
}
if ($trivial_ok) {
$others->{'trivial_ok'} = 1;
}
$self->createLink($plink, $cmid, $vname0, $vname1,
($top_bw == 0 ? "*" :
max($top_bw, $top_rbw)), $protocol,
{ 'emulated' => "1",
'trivial_ok' => "1" });
$others);
# $self->addlink("$plink $vname0 $vname1 ".
# ($top_bw == 0 ? "*" :
......
......@@ -48,9 +48,10 @@ sub usage ()
print STDERR " -m - Set the multiplex factor; overrides experiment.\n";
print STDERR " -p - Do a precheck for mapability on an empty testbed - ".
"implies -n\n";
print STDERR " -l - Use rspec v2 instead of the text file format\n";
exit($WRAPPER_FAILED);
}
my $optlist = "dvunfprqczxm:ko:a";
my $optlist = "dvunfprqczxm:ko:al";
my $verbose = 0;
my $debug = 0;
my $fixmode = 0;
......@@ -70,6 +71,7 @@ my $clear = 0;
my $warnings = 0;
my $maxrun = 3; # Maximum number of times we run assign.
my $gotlock = 0;
my $userspec = 0;
my $vtop;
#
......@@ -182,6 +184,9 @@ if (defined($options{"q"})) {
if (defined($options{"c"})) {
$clear = 1;
}
if (defined($options{"l"})) {
$userspec = 1;
}
my $pid = $ARGV[0];
my $eid = $ARGV[1];
......@@ -408,6 +413,10 @@ sub RunAssign($$)
my $typelimitfile = $prefix .".limits";
my $ptopfile = $prefix . ".ptop";
my $vtopfile = $prefix . ".vtop";
if ($userspec) {
$ptopfile .= ".xml";
$vtopfile .= ".xml";
}
my $assignexitcode = 0;
# Debugging hack for regression mode. Avoid really long assign runs.
......@@ -472,7 +481,9 @@ sub RunAssign($$)
if ($precheck);
$ptopargs .= "-c " . $experiment->delay_capacity() . " "
if (defined($experiment->delay_capacity()));
$ptopargs .= "-x -g 2 ";
if ($userspec == 1) {
$ptopargs .= "-x -g 2 ";
}
$ptopargs .= "-l $typelimitfile";
chat("ptopargs: '$ptopargs'\n");
......@@ -491,8 +502,14 @@ sub RunAssign($$)
tberror("Could not open $vtopfile: $!\n");
return -1;
}
# if ($vtop->PrintTop(*VTOPFILE) != 0) {
if ($vtop->PrintRspec(*VTOPFILE) != 0) {
my $reslibvtop;
if ($userspec == 1) {
$reslibvtop = $vtop->PrintRspec(*VTOPFILE);
}
else {
$reslibvtop = $vtop->PrintTop(*VTOPFILE);
}
if ($reslibvtop != 0) {
tberror("Could not print vtop file for $experiment\n");
return -1;
}
......@@ -509,7 +526,12 @@ sub RunAssign($$)
# Run assign
my $cmd = "assign";
my $args = "-f rspec $ptopfile $vtopfile";
my $args = "";
$args .= "-f rspec "
if ($userspec == 1);
$args .= "-f text "
if ($userspec == 0);
$args .= "$ptopfile $vtopfile";
$args = "-P $args"
if (!$vtop->sharednodecount());
$args = "-uod -c .75 $args"
......
......@@ -1668,6 +1668,9 @@ sub print_header {
}
sub print_footer {
if (!$do_xml) {
print_type_limits();
}
if ($do_xml && $genimode eq $NO_GENI) {
print "</ptop>\n";
} elsif ($do_xml && $genimode ne $NO_GENI) {
......@@ -1832,11 +1835,18 @@ sub print_type_limits
foreach $line (@typelimits) {
chomp($line);
my ($typeclass, $count) = split(" ", $line);
print "<emulab:set_type_limit ";
print "typeclass=\"$typeclass\" ";
print "count=\"$count\"";
print "/>\n";
if ($genimode eq $NO_GENI) {
print "set-type-limit $typeclass $count\n";
}
else {
if ($genimode eq $V_2) {
print "<emulab:set_type_limit ";
print "typeclass=\"$typeclass\" ";
print "count=\"$count\"";
print "/>\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