Commit b9ba3398 authored by Leigh B. Stoller's avatar Leigh B. Stoller
Browse files

Add new NS program object. This syntax is different than I had

originally anticipated, but I was worried about confusion with the
Agent/Application API that NS provides, and which is substantially
different than this. Anyway, I added support for this syntax:

	set prog0 [$ns program]
	$prog0 set node $nodeA
	$prog0 set command "/bin/ls -lt >& /users/stoller/logs/foo"

Kinda obvious, although whats not obvious is that without events to
start and stop them, these will never run. So, I added support for
this:

	$ns at 10 "$prog0 start"
	$ns at 20 "$prog0 stop"

You can start and stop programs as much as you like, but you cannot
start a program that is already running; you have to stop it first.
You can also issue these dynamically using the same api:

	tevc -e testbed/Tevents now prog0 start \
		"command=/bin/ls -lt / >& /users/stoller/logs/foo"
	tevc -e testbed/Tevents now prog0 stop

Note the quotes when using a multiword command. I also had intened to
support a KILL command so that you could send arbitrary signals to a
process. I added that, but I will not bother to document it yet; since
I invoke /bin/csh to process the command line, the issue of signals is
a little fuzzy. Sending a signal like -HUP to the parent process (the
csh) is not really what we want to do. I think we can support this,
but I need to poke around and see what the right way is.
parent 340fda00
......@@ -160,6 +160,21 @@ namespace eval GLOBALS {
set GLOBALS::DB [sql conn]
sql selectdb ${GLOBALS::DB} @TBDBNAME@
namespace eval GLOBALS {
# A mapping of event objects.
variable objtypes
sql query $DB \
"select idx,type from event_objecttypes"
while {[set row [sql fetchrow $DB]] != ""} {
set idx [lindex $row 0]
set type [lindex $row 1]
set objtypes($type) $idx
}
sql endquery $DB
}
# Load all our classes
source ${GLOBALS::libdir}/nsobject.tcl
source ${GLOBALS::libdir}/sim.tcl
......
......@@ -15,6 +15,7 @@
######################################################################
Class Simulator
Class Program -superclass NSObject
Simulator instproc init {args} {
# A counter for internal ids
......@@ -46,6 +47,10 @@ Simulator instproc init {args} {
# event list is a list of {time vnode vname otype etype args atstring}
$self set event_list {}
$self set event_count 0
# Program list.
$self instvar prog_list;
array set prog_list {}
}
# node
......@@ -142,6 +147,7 @@ Simulator instproc run {} {
$self instvar lanlink_list
$self instvar node_list
$self instvar event_list
$self instvar prog_list
var_import ::GLOBALS::pid
var_import ::GLOBALS::eid
var_import ::GLOBALS::errors
......@@ -210,6 +216,9 @@ Simulator instproc run {} {
foreach vtype [array names vtypes] {
$vtype updatedb $DB
}
foreach prog [array names prog_list] {
$prog updatedb $DB
}
foreach event $event_list {
sql exec $DB "insert into eventlist (pid,eid,time,vnode,vname,objecttype,eventtype,arguments,atstring) values (\"$pid\",\"$eid\",[lindex $event 0],\"[lindex $event 1]\",\"[lindex $event 2]\",$objtypes([lindex $event 3]),$eventtypes([lindex $event 4]),\"[lindex $event 5]\",\"[lindex $event 6]\")"
......@@ -433,6 +442,36 @@ Simulator instproc at {time eventstring} {
set vnode {}
set vname $obj
}
"Program" {
set otype PROGRAM
set vname $obj
set vnode [$obj set node]
switch -- $cmd {
"start" {
set etype START
set arg [$obj set command]
set args "COMMAND=$arg"
}
"stop" {
set etype STOP
}
"kill" {
set etype KILL
if {[llength $event] < 3} {
perror "Wrong number of arguments: at $time $event"
return
}
set arg [lindex $event 2]
set args "SIGNAL=$arg"
}
unknown {
punsup "at $time $event"
return
}
}
set okargs 1
}
"Simulator" {
switch -- $cmd {
"bandwidth" {
......@@ -494,6 +533,12 @@ Simulator instproc rename_node {old new} {
set node_list($new) {}
}
Simulator instproc rename_program {old new} {
$self instvar prog_list
unset prog_list($old)
set prog_list($new) {}
}
# find_link <node1> <node2>
# This is just an accesor to the link_map datastructure. If no
# link is known between <node1> and <node2> the empty list is returned.
......@@ -536,3 +581,50 @@ Simulator instproc use_subnet {subnet} {
$self instvar subnets
set subnets($subnet) {}
}
# program
Simulator instproc program {} {
var_import ::GLOBALS::last_class
$self instvar id_counter
$self instvar prog_list
set id n[incr id_counter]
Program $id $self
set prog_list($id) {}
set last_class $id
return $id
}
Program instproc init {s} {
$self set sim $s
$self set node {}
$self set command {}
}
Program instproc rename {old new} {
[$self set sim] rename_program $old $new
}
# updatedb DB
# This adds rows to the virt_trafgens table corresponding to this agent.
Program instproc updatedb {DB} {
var_import ::GLOBALS::pid
var_import ::GLOBALS::eid
var_import ::GLOBALS::objtypes
$self instvar node
$self instvar command
if {$node == {}} {
perror "\[updatedb] $self has no node."
return
}
if {$command == {}} {
perror "\[updatedb] $self has no command."
return
}
sql exec $DB "insert into virt_agents (pid,eid,vnode,vname,objecttype) values ('$pid','$eid','$node','$self','$objtypes(PROGRAM)')";
}
......@@ -27,6 +27,7 @@ Class Application -superclass NSObject
Class Application/Traffic/CBR -superclass Application
Class Application/FTP -superclass Application
Class Application/Telnet -superclass Application
Class Application/Program -superclass Application
namespace eval GLOBALS {
set new_classes(Agent/UDP) {}
......@@ -89,6 +90,7 @@ Agent instproc rename {old new} {
Agent instproc updatedb {DB} {
var_import ::GLOBALS::pid
var_import ::GLOBALS::eid
var_import ::GLOBALS::objtypes
$self instvar application
$self instvar destination
$self instvar node
......@@ -109,7 +111,7 @@ Agent instproc updatedb {DB} {
set target_port [$destination set port]
if {$role == "sink"} {
set application [$destination set application]
set application $self
set proto [$destination set proto]
}
# set src_link [lindex [$node set portlist] 0]
......@@ -118,6 +120,7 @@ Agent instproc updatedb {DB} {
# Update the DB
sql exec $DB "insert into virt_trafgens (pid,eid,vnode,vname,role,proto,port,target_vnode,target_port,generator) values ('$pid','$eid','$node','$application','$role','$proto', $port,'$target_vnode',$target_port,'$generator')";
sql exec $DB "insert into virt_agents (pid,eid,vnode,vname,objecttype) values ('$pid','$eid','$node','$application','$objtypes(TRAFGEN)')";
}
# get_nseconfig is only defined for subclasses that will be simulated by NSE
......@@ -233,6 +236,7 @@ Agent/TCP/FullTcp instproc listen {} {
Agent/TCP/FullTcp instproc updatedb {DB} {
var_import ::GLOBALS::pid
var_import ::GLOBALS::eid
var_import ::GLOBALS::objtypes
$self instvar application
$self instvar destination
$self instvar node
......@@ -257,7 +261,11 @@ Agent/TCP/FullTcp instproc updatedb {DB} {
# Update the DB
sql exec $DB "insert into virt_trafgens (pid,eid,vnode,vname,role,proto,port,target_vnode,target_port,generator) values ('$pid','$eid','$node','$vname','$role','$proto', $port,'$target_vnode',$target_port,'$generator')";
sql exec $DB "insert into virt_agents (pid,eid,vnode,vname,objecttype) values ('$pid','$eid','$node','$vname','$objtypes(TRAFGEN)')";
if {$application != {}} {
sql exec $DB "insert into virt_agents (pid,eid,vnode,vname,objecttype) values ('$pid','$eid','$node','$application','$objtypes(TRAFGEN)')";
}
}
# Agent/TCP/FullTcp
......@@ -508,3 +516,4 @@ Application/Telnet instproc get_nseconfig {} {
return $nseconfig
}
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