diff --git a/db/Experiment.pm.in b/db/Experiment.pm.in index 1e9e2743d66cbb14b33fbbab4116453cad044434..d41c01d9979e028fcc98a680019d51419cc31ac8 100644 --- a/db/Experiment.pm.in +++ b/db/Experiment.pm.in @@ -99,6 +99,7 @@ my $EXPT_RESOURCESHOSED = 0; "virt_simnode_attributes", "virt_user_environment", "virt_parameters", + "virt_paths", # vis_nodes is locked during update in prerender, so we # will get a consistent dataset when we backup. "vis_nodes", diff --git a/db/VirtExperiment.pm.in b/db/VirtExperiment.pm.in index 1e917276164c616b4f44dbe2167894902b0a8184..1fa8d511d40b23672cde8c2dcfeeb8a3de19b567 100644 --- a/db/VirtExperiment.pm.in +++ b/db/VirtExperiment.pm.in @@ -72,6 +72,7 @@ my $debug = 0; "elabinelab_attributes" => [ "role", "attrkey", "ordering" ], "virt_tiptunnels" => [ "host", "vnode" ], "virt_parameters" => [ "name", "value" ], + "virt_paths" => [ "pathname", "segmentname"], ); # @@ -1184,5 +1185,10 @@ use vars qw(@ISA); @ISA = "VirtExperiment::VirtTableRow"; use VirtExperiment; +package VirtExperiment::VirtTableRow::virt_paths; +use vars qw(@ISA); +@ISA = "VirtExperiment::VirtTableRow"; +use VirtExperiment; + # _Always_ make sure that this 1 is at the end of the file... 1; diff --git a/db/xmlconvert.in b/db/xmlconvert.in index 78e4754f58661b28ce75e9e583ca31872d4bdba1..7b7d2563aae5bd21a5f194ec55a566cebd5a643f 100644 --- a/db/xmlconvert.in +++ b/db/xmlconvert.in @@ -116,9 +116,12 @@ my %virtual_tables = "virt_tiptunnels" => { rows => undef, tag => "tiptunnels", row => "tiptunnel"}, - "virt_parameters" => { rows => undef, - tag => "parameters", - row => "parameter"}, + "virt_parameters" => { rows => undef, + tag => "parameters", + row => "parameter"}, + "virt_paths" => { rows => undef, + tag => "path_members", + row => "path_member"}, # This is a fake table. See below. If we add more, lets generalize. "external_sourcefiles" => { rows => undef, tag => "nsfiles", diff --git a/sql/database-create.sql b/sql/database-create.sql index 213740530daa4d3b6b79e361562527a5a33e2f75..419d4d3fcba6e515d5fd5314da0cbcfb60b9cda0 100644 --- a/sql/database-create.sql +++ b/sql/database-create.sql @@ -3829,6 +3829,8 @@ CREATE TABLE `virt_lans` ( `trace_db` tinyint(1) NOT NULL default '0', `fixed_iface` varchar(128) default '', `layer` tinyint(4) NOT NULL default '2', + `implemented_by_path` tinytext, + `implemented_by_link` tinytext, PRIMARY KEY (`exptidx`,`vname`,`vnode`,`vport`), UNIQUE KEY `vport` (`pid`,`eid`,`vname`,`vnode`,`vport`), KEY `pid` (`pid`,`eid`,`vname`), @@ -3932,6 +3934,25 @@ CREATE TABLE `virt_parameters` ( UNIQUE KEY `pideid` (`pid`,`eid`,`name`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1; +-- +-- Table structure for table `virt_paths` +-- + +DROP TABLE IF EXISTS `virt_paths`; +CREATE TABLE `virt_paths` ( + `pid` varchar(12) NOT NULL default '', + `eid` varchar(32) NOT NULL default '', + `exptidx` int(11) NOT NULL default '0', + `pathname` varchar(32) NOT NULL default '', + `segmentname` varchar(32) NOT NULL default '', + `segmentindex` tinyint(4) unsigned NOT NULL default '0', + `layer` tinyint(4) NOT NULL default '0', + PRIMARY KEY (`exptidx`,`pathname`,`segmentname`), + UNIQUE KEY `segidx` (`exptidx`,`pathname`,`segmentindex`), + KEY `pid` (`pid`,`eid`,`pathname`), + KEY `pideid` (`pid`,`eid`,`pathname`,`segmentname`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1; + -- -- Table structure for table `virt_programs` -- diff --git a/sql/database-fill.sql b/sql/database-fill.sql index 0606ec7bb4a4fda4cd3c21e46f2eb92937f1a3ab..bd23d33f9575d11219b24b581741b866f706d52f 100644 --- a/sql/database-fill.sql +++ b/sql/database-fill.sql @@ -691,7 +691,7 @@ REPLACE INTO table_regex VALUES ('virt_node_desires','desire','text','regex','^[ REPLACE INTO table_regex VALUES ('virt_node_desires','weight','int','redirect','default:float',0,0,NULL); REPLACE INTO table_regex VALUES ('virt_nodes','pid','text','redirect','projects:pid',0,0,NULL); REPLACE INTO table_regex VALUES ('virt_nodes','eid','text','redirect','experiments:eid',0,0,NULL); -REPLACE INTO table_regex VALUES ('virt_nodes','ips','text','regex','^(\\d{1,2}:\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3} {0,1})*$',0,1024,NULL); +REPLACE INTO table_regex VALUES ('virt_nodes','ips','text','regex','^(\\d{1,2}:\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3} {0,1})*$',0,2048,NULL); REPLACE INTO table_regex VALUES ('virt_nodes','osname','text','redirect','os_info:osname',0,0,NULL); REPLACE INTO table_regex VALUES ('virt_nodes','cmd_line','text','redirect','default:tinytext',0,0,NULL); REPLACE INTO table_regex VALUES ('virt_nodes','rpms','text','regex','^([-\\w\\.\\/\\+:~]+;{0,1})*$',0,4096,NULL); @@ -970,6 +970,14 @@ REPLACE INTO table_regex VALUES ('user_pubkeys','verify','text','redirect','defa REPLACE INTO table_regex VALUES ('user_pubkeys','user','text','redirect','users:uid',0,0,NULL); REPLACE INTO table_regex VALUES ('user_pubkeys','keyfile','text','regex','^[-_\\w\\.\\/:+]*$',1,256,NULL); +REPLACE INTO table_regex VALUES ('virt_paths','pathname','text','redirect','virt_nodes:vname',0,0,NULL); +REPLACE INTO table_regex VALUES ('virt_paths','segmentname','text','redirect','virt_nodes:vname',0,0,NULL); +REPLACE INTO table_regex VALUES ('virt_paths','segmentindex','int','redirect','default:tinyuint',0,0,NULL); +REPLACE INTO table_regex VALUES ('virt_paths','layer','int','redirect','default:tinyint',0,0,NULL); + +REPLACE INTO table_regex VALUES ('virt_lans','implemented_by_path','text','redirect','virt_paths:pathname',1,128,NULL); +REPLACE INTO table_regex VALUES ('virt_lans','implemented_by_link','text','redirect','default:tinytext',0,0,NULL); + REPLACE INTO table_regex VALUES ('elabinelab_attributes','role','text','regex','^(boss|router|ops|fs|node)$',0,0,NULL); REPLACE INTO table_regex VALUES ('elabinelab_attributes','attrkey','text','regex','^[-\\w\\.]+$',1,32,NULL); REPLACE INTO table_regex VALUES ('elabinelab_attributes','attrvalue','text','regex','^[-\\w\\.\\+,\\s\\/]+$',0,255,NULL); diff --git a/sql/updates/4/210 b/sql/updates/4/210 new file mode 100644 index 0000000000000000000000000000000000000000..ae88d571582cd4b419f8c1df04e632b38b19b037 --- /dev/null +++ b/sql/updates/4/210 @@ -0,0 +1,63 @@ +# +# Add virt_paths +# +use strict; +use libdb; + +sub DoUpdate($$$) +{ + my ($dbhandle, $dbname, $version) = @_; + + if (!DBTableExists("virt_paths")) { + DBQueryFatal("CREATE TABLE `virt_paths` ( ". + " `pid` varchar(12) NOT NULL default '', ". + " `eid` varchar(32) NOT NULL default '', ". + " `exptidx` int(11) NOT NULL default '0', ". + " `pathname` varchar(32) NOT NULL default '', ". + " `segmentname` varchar(32) NOT NULL default '', ". + " `segmentindex` tinyint(4) unsigned NOT NULL default '0', ". + " `layer` tinyint(4) NOT NULL default '0', ". + " PRIMARY KEY (`exptidx`,`pathname`,`segmentname`), ". + " UNIQUE KEY `segidx` (`exptidx`,`pathname`,`segmentindex`), ". + " KEY `pid` (`pid`,`eid`,`pathname`), ". + " KEY `pideid` (`pid`,`eid`,`pathname`,`segmentname`) ". + ") ENGINE=MyISAM DEFAULT CHARSET=latin1"); + } + DBQueryFatal("REPLACE INTO table_regex VALUES" . + " ('virt_paths', 'pathname', 'text', 'redirect', ". + " 'virt_nodes:vname', 0,0,NULL)"); + DBQueryFatal("REPLACE INTO table_regex VALUES" . + " ('virt_paths', 'segmentname', 'text', 'redirect', ". + " 'virt_nodes:vname', 0,0,NULL)"); + DBQueryFatal("REPLACE INTO table_regex VALUES" . + " ('virt_paths', 'segmentindex', 'int', 'redirect', ". + " 'default:tinyuint', 0,0,NULL)"); + DBQueryFatal("REPLACE INTO table_regex VALUES" . + " ('virt_paths', 'layer', 'int', 'redirect', ". + " 'default:tinyint', 0,0,NULL)"); + + if (!DBSlotExists("virt_lans", "implemented_by_path")) { + DBQueryFatal("ALTER TABLE virt_lans ADD ". + " `implemented_by_path` tinytext"); + } + if (!DBSlotExists("virt_lans", "implemented_by_link")) { + DBQueryFatal("ALTER TABLE virt_lans ADD ". + " `implemented_by_link` tinytext"); + } + + DBQueryFatal("REPLACE INTO table_regex VALUES" . + " ('virt_lans', 'implemented_by_path', 'text', 'redirect', ". + " 'virt_paths:pathname', 1,128,NULL)"); + DBQueryFatal("REPLACE INTO table_regex VALUES" . + " ('virt_lans', 'implemented_by_link', 'text', 'redirect', ". + " 'default:tinytext', 0,0,NULL)"); + + # Unrelated bug fix. + DBQueryFatal("REPLACE INTO table_regex VALUES ". + " ('virt_nodes','ips','text','regex', ". + " '^(\\d{1,2}:\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3} {0,1})*$',". + " 0,2048,NULL"); + + return 0; +} +1; diff --git a/tbsetup/ns2ir/GNUmakefile.in b/tbsetup/ns2ir/GNUmakefile.in index 8bcab0da99e086223fa660b9d417f186dda13155..9f6803a06a02fa63ccb41300209ee343301f9e62 100644 --- a/tbsetup/ns2ir/GNUmakefile.in +++ b/tbsetup/ns2ir/GNUmakefile.in @@ -1,6 +1,6 @@ # # EMULAB-COPYRIGHT -# Copyright (c) 2000-2006 University of Utah and the Flux Group. +# Copyright (c) 2000-2010 University of Utah and the Flux Group. # All rights reserved. # @@ -19,7 +19,7 @@ LIB_STUFF = lanlink.tcl node.tcl sim.tcl tb_compat.tcl null.tcl \ nsenode.tcl nstb_compat.tcl event.tcl firewall.tcl \ elabinelab.ns elabinelab-withfsnode.ns \ fw.ns timeline.tcl sequence.tcl \ - topography.tcl console.tcl + topography.tcl console.tcl path.tcl BOSSLIBEXEC = parse-ns USERLIBEXEC = parse.proxy diff --git a/tbsetup/ns2ir/lanlink.tcl b/tbsetup/ns2ir/lanlink.tcl index 5229bdc3c9f26c7d1760157d072d601836eac804..566c296c5e06656974e9a4d862dcdeb48891c9b2 100644 --- a/tbsetup/ns2ir/lanlink.tcl +++ b/tbsetup/ns2ir/lanlink.tcl @@ -214,8 +214,9 @@ LanLink instproc init {s nodes bw d type} { # XXX Allow user to set the accesspoint. $self set accesspoint {} - # Optional layer + # Optional layer and implemented-by relationship $self set layer {} + $self set implemented_by {} # A simulated lanlink unless we find otherwise $self set simulated 1 @@ -324,6 +325,37 @@ Link instproc trace {{ttype "header"} {texpr ""}} { $fromqueue trace $ttype $texpr } +# +# A link can be implemented in terms of a path or +# a link at a lower level of the stack. +# +Link instproc implemented_by {impl} { + $self instvar implemented_by + $self instvar layer + + if {[$impl info class] == "Path"} { + set implemented_by $impl + } elseif {[$impl info class] == "Link"} { + if {$layer == {}} { + perror "\[$self implemented_by] no layer set!" + return + } + set impl_layer [$impl set layer] + if {$impl_layer == {}} { + perror "\[$self implemented_by] no layer set in $impl!" + return + } + if {$impl_layer >= $layer} { + perror "\[$self implemented_by] $impl is not at a lower layer!" + return + } + set implemented_by $impl + } else { + perror "\[$self implemented_by] must be a link or a path!" + return + } +} + Lan instproc trace_snaplen {len} { $self instvar nodelist $self instvar linkq @@ -720,6 +752,7 @@ Link instproc updatedb {DB} { $self instvar mustdelay $self instvar fixed_iface $self instvar layer + $self instvar implemented_by $sim spitxml_data "virt_lan_lans" [list "vname"] [list $self] @@ -810,6 +843,13 @@ Link instproc updatedb {DB} { if { $layer != {} } { lappend fields "layer" } + if { $implemented_by != {} } { + if {[$implemented_by info class] == "Path"} { + lappend fields "implemented_by_path" + } else { + lappend fields "implemented_by_link" + } + } set values [list $self $nodeportraw $netmask $delay($nodeport) $rdelay($nodeport) $bandwidth($nodeport) $rbandwidth($nodeport) $backfill($nodeport) $rbackfill($nodeport) $loss($nodeport) $rloss($nodeport) $cost($nodeport) $widearea $emulated $uselinkdelay $nobwshaping $encap $limit_ $maxthresh_ $thresh_ $q_weight_ $linterm_ ${queue-in-bytes_} $bytes_ $mean_pktsize_ $wait_ $setbit_ $droptail_ $red_ $gentle_ $trivial_ok $protocol $node $port $ip $mustdelay] @@ -839,6 +879,9 @@ Link instproc updatedb {DB} { if { $layer != {} } { lappend values $layer } + if { $implemented_by != {} } { + lappend values $implemented_by + } $sim spitxml_data "virt_lans" $fields $values } diff --git a/tbsetup/ns2ir/nstb_compat.tcl b/tbsetup/ns2ir/nstb_compat.tcl index 0bb2239d597d3e113c39d035a63c2e0f62d3bef6..1c157ecf1bb0e19c9a2a3902a36f127b68383cf4 100644 --- a/tbsetup/ns2ir/nstb_compat.tcl +++ b/tbsetup/ns2ir/nstb_compat.tcl @@ -261,6 +261,9 @@ Simulator instproc make-cloud {nodes bw delay args} { return [$self make-lan $nodes $bw $delay] } +Simulator instproc make-path {linklist} { +} + Node instproc program-agent {args} { } @@ -289,5 +292,8 @@ LanNode instproc trace {args} { LanNode instproc trace_endnode {args} { } +LanNode instproc implemented_by {args} { +} + LanNode instproc unknown {m args} { } diff --git a/tbsetup/ns2ir/parse.tcl.in b/tbsetup/ns2ir/parse.tcl.in index eecb09aeaf32b1851e860fc2ec4a417d86a090cf..208ccf4ba2a2c21278bf39521639275ec8e71091 100644 --- a/tbsetup/ns2ir/parse.tcl.in +++ b/tbsetup/ns2ir/parse.tcl.in @@ -364,6 +364,7 @@ namespace eval GLOBALS { source ${GLOBALS::libdir}/nsobject.tcl source ${GLOBALS::libdir}/sim.tcl source ${GLOBALS::libdir}/lanlink.tcl +source ${GLOBALS::libdir}/path.tcl source ${GLOBALS::libdir}/node.tcl source ${GLOBALS::libdir}/null.tcl source ${GLOBALS::libdir}/traffic.tcl diff --git a/tbsetup/ns2ir/path.tcl b/tbsetup/ns2ir/path.tcl new file mode 100644 index 0000000000000000000000000000000000000000..8801ccdc568af9a916025f69467f9c4bf535c561 --- /dev/null +++ b/tbsetup/ns2ir/path.tcl @@ -0,0 +1,50 @@ +# -*- tcl -*- +# +# EMULAB-COPYRIGHT +# Copyright (c) 2000-2010 University of Utah and the Flux Group. +# All rights reserved. +# +###################################################################### +# path.tcl +# +# A path is comprised of a set of links. +###################################################################### + +Class Path -superclass NSObject + +namespace eval GLOBALS { + set new_classes(Path) {} +} + +Path instproc init {s links} { + # This is a list of the links + $self set mylinklist $links + + # The simulator + $self set sim $s +} + +Path instproc rename {old new} { + $self instvar sim + $self instvar mylinklist + + $sim rename_path $old $new +} + +Path instproc updatedb {DB} { + $self instvar mylinklist + var_import ::GLOBALS::pid + var_import ::GLOBALS::eid + $self instvar sim + + set idx 0 + + foreach link $mylinklist { + set fields [list "pathname" "segmentname" "segmentindex"] + set values [list $self $link $idx] + + $sim spitxml_data "virt_paths" $fields $values + + incr idx + } +} diff --git a/tbsetup/ns2ir/sim.tcl.in b/tbsetup/ns2ir/sim.tcl.in index 659bfbfcac2bc767a8930d8d7e884f189566890b..0fb0856b9cf27af035bd6cd39e99c6840813bfbe 100644 --- a/tbsetup/ns2ir/sim.tcl.in +++ b/tbsetup/ns2ir/sim.tcl.in @@ -47,6 +47,8 @@ Simulator instproc init {args} { array set lanlink_list {} $self instvar subnets; # Indexed by IP subnet array set subnets {} + $self instvar path_list; # Indexed by path id + array set path_list {} # link_map is indexed by : and contains the # id of the lanlink connecting them. In the case of @@ -271,6 +273,21 @@ Simulator instproc make-lan {nodelist bw delay args} { return $curlan } +# make-path +Simulator instproc make-path {linklist args} { + var_import ::GLOBALS::last_class + $self instvar id_counter + $self instvar path_list + + set curpath tbpath-path[incr id_counter] + + Path $curpath $self $linklist + set path_list($curpath) {} + set last_class $curpath + + return $curpath +} + Simulator instproc make-cloud {nodelist bw delay args} { $self instvar event_list $self instvar event_count @@ -349,6 +366,7 @@ Simulator instproc event-group {{list {}}} { # method casues the 'ran' variable to be set to 1. Simulator instproc run {} { $self instvar lanlink_list + $self instvar path_list $self instvar node_list $self instvar event_list $self instvar prog_list @@ -580,6 +598,9 @@ Simulator instproc run {} { foreach tg [array names topography_list] { $tg updatedb "sql" } + foreach path [array names path_list] { + $path updatedb "sql" + } set fields [list "mem_usage" "cpu_usage" "forcelinkdelays" "uselinkdelays" "usewatunnels" "uselatestwadata" "wa_delay_solverweight" "wa_bw_solverweight" "wa_plr_solverweight" "encap_style" "allowfixnode"] set values [list $mem_usage $cpu_usage $forcelinkdelays $uselinkdelays $usewatunnels $uselatestwadata $wa_delay_solverweight $wa_bw_solverweight $wa_plr_solverweight $vlink_encapsulate $fix_current_resources] @@ -954,6 +975,12 @@ Simulator instproc rename_topography {old new} { set topography_list($new) {} } +Simulator instproc rename_path {old new} { + $self instvar path_list + unset path_list($old) + set path_list($new) {} +} + # find_link # This is just an accesor to the link_map datastructure. If no # link is known between and the empty list is returned.