node.tcl 5.19 KB
Newer Older
Leigh B. Stoller's avatar
Leigh B. Stoller committed
1 2 3 4 5 6 7 8 9 10 11 12
######################################################################
# node.tcl
#
# This defines the Node class.  Instances of this class are created by
# the 'node' method of Simulator.  A Node is connected to a number of
# LanLinks.  Each such connection is associated with a virtual port,
# an integer.  Each virtual port also has an IP address.  Virtual
# ports start at 0 and go up continuously.  Besides the port
# information each node also has a variety of strings.  These strings
# are set by tb-* commands and dumped to the DB but are otherwise
# uninterpreted.
######################################################################
Mac Newbold's avatar
Mac Newbold committed
13

Leigh B. Stoller's avatar
Leigh B. Stoller committed
14
Class Node -superclass NSObject
Mac Newbold's avatar
Mac Newbold committed
15

Leigh B. Stoller's avatar
Leigh B. Stoller committed
16 17
Node instproc init {s} {
    $self set sim $s
Mac Newbold's avatar
Mac Newbold committed
18

Leigh B. Stoller's avatar
Leigh B. Stoller committed
19 20 21 22 23
    # portlist is a list of connections for the node.  It is sorted
    # by portnumber.  I.e. the ith element of portlist is the connection
    # on port i.
    $self set portlist {}

24 25 26 27 28 29 30
    # A list of agents attached to this node.
    $self set agentlist {}

    # A counter for udp/tcp portnumbers. Assign them in an increasing
    # fashion as agents are assigned to the node.
    $self set next_portnumber_ 5000

Leigh B. Stoller's avatar
Leigh B. Stoller committed
31 32 33 34 35
    # iplist, like portlist, is supported by portnumber.  An entry of
    # {} indicates an unassigned IP address for that port.
    $self set iplist {}

    # The type of the node.
36
    $self set type "pc" 
Leigh B. Stoller's avatar
Leigh B. Stoller committed
37 38 39 40 41 42 43 44 45 46 47 48

    # If osid remains blank when updatedb is called it is changed
    # to the default OS based on it's type (taken from node_types
    # table).
    $self set osid ""

    # These are just various strings that we pass through to the DB.
    $self set cmdline ""
    $self set rpms ""
    $self set startup ""
    $self set deltas ""
    $self set tarfiles ""
49
    $self set failureaction "fatal"
50
    $self set fixed ""
Leigh B. Stoller's avatar
Leigh B. Stoller committed
51 52 53 54 55 56 57
}

# The following procs support renaming (see README)
Node instproc rename {old new} {
    $self instvar portlist
    foreach object $portlist {
	$object rename_node $old $new
Mac Newbold's avatar
Mac Newbold committed
58
    }
Leigh B. Stoller's avatar
Leigh B. Stoller committed
59 60 61 62 63 64 65 66 67 68
    [$self set sim] rename_node $old $new
}

Node instproc rename_lanlink {old new} {
    $self instvar portlist
    set newportlist {}
    foreach node $portlist {
	if {$node == $old} {
	    lappend newportlist $new
	} else {
69
	    lappend newportlist $node
Leigh B. Stoller's avatar
Leigh B. Stoller committed
70
	}
Mac Newbold's avatar
Mac Newbold committed
71
    }
Leigh B. Stoller's avatar
Leigh B. Stoller committed
72
    set portlist $newportlist
Mac Newbold's avatar
Mac Newbold committed
73 74
}

Leigh B. Stoller's avatar
Leigh B. Stoller committed
75 76 77 78 79 80 81 82 83 84 85 86
# updatedb DB
# This adds a row to the virt_nodes table corresponding to this node.
Node instproc updatedb {DB} {
    $self instvar portlist
    $self instvar type
    $self instvar osid
    $self instvar cmdline
    $self instvar rpms
    $self instvar startup
    $self instvar deltas
    $self instvar iplist
    $self instvar tarfiles
87
    $self instvar failureaction
88
    $self instvar routertype
89
    $self instvar fixed
90
    $self instvar agentlist
Leigh B. Stoller's avatar
Leigh B. Stoller committed
91 92
    var_import ::GLOBALS::pid
    var_import ::GLOBALS::eid
93
    var_import ::GLOBALS::default_ip_routing_type
Mac Newbold's avatar
Mac Newbold committed
94

Leigh B. Stoller's avatar
Leigh B. Stoller committed
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
    # If we haven't specified a osid so far then we should fill it
    # with the id from the node_types table now.
    if {$osid == {}} {
	sql query $DB "select osid from node_types where type = \"$type\""
	set osid [sql fetchrow $DB]
	sql endquery $DB
    }

    # We need to generate the IP column from our iplist.
    set ipraw {}
    set i 0
    foreach ip $iplist {
	lappend ipraw $i:$ip
	incr i
    }
Mac Newbold's avatar
Mac Newbold committed
110

111
    set nseconfig ""
112 113
    foreach agent $agentlist {
	$agent updatedb $DB
114 115

        append nseconfig [$agent get_nseconfig]
116
    }
Leigh B. Stoller's avatar
Leigh B. Stoller committed
117
    if {$nseconfig != {}} {
118 119 120
        # update the per-node nseconfigs table in the DB
        sql exec $DB "insert into nseconfigs (pid,eid,vname,nseconfig) values ('$pid','$eid','$self','$nseconfig')";
    }
121

Leigh B. Stoller's avatar
Leigh B. Stoller committed
122
    # Update the DB
123
    sql exec $DB "insert into virt_nodes (pid,eid,vname,type,ips,osname,cmd_line,rpms,deltas,startupcmd,tarfiles,failureaction,routertype,fixed) values (\"$pid\",\"$eid\",\"$self\",\"$type\",\"$ipraw\",\"$osid\",\"$cmdline\",\"$rpms\",\"$deltas\",\"$startup\",\"$tarfiles\",\"$failureaction\",\"$default_ip_routing_type\",\"$fixed\")";
Mac Newbold's avatar
Mac Newbold committed
124
}
125

Leigh B. Stoller's avatar
Leigh B. Stoller committed
126 127 128 129 130 131 132 133 134 135
# add_lanlink lanlink
# This creates a new virtual port and connects the specified LanLink to it.
# The port number is returned.
Node instproc add_lanlink {lanlink} {
    $self instvar portlist
    $self instvar iplist
    lappend portlist $lanlink
    lappend iplist ""
    return [expr [llength $portlist] - 1]
}
136

Leigh B. Stoller's avatar
Leigh B. Stoller committed
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
# ip port
# ip port ip
# In the first form this returns the IP address associated with the port.
# In the second from this sets the IP address of a port.
Node instproc ip {port args} {
    $self instvar iplist
    $self instvar sim
    if {$args == {}} {
	return [lindex $iplist $port]
    } else {
	set ip [lindex $args 0]
	set subnet [join [lrange [split $ip .] 0 2] .]
	set iplist [lreplace $iplist $port $port $ip]
	$sim use_subnet $subnet
    }    
152 153
}

Leigh B. Stoller's avatar
Leigh B. Stoller committed
154 155 156 157 158 159
# find_port lanlink
# This takes a lanlink and returns the port it is connected to or 
# -1 if there is no connection.
Node instproc find_port {lanlink} {
    return [lsearch [$self set portlist] $lanlink]
}
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177

# Attach an agent to a node. This mainly a bookkeeping device so
# that the we can update the DB at the end.
Node instproc attach-agent {agent} {
    $self instvar agentlist

    lappend agentlist $agent
    $agent set_node $self
}

#
# Return and bump next agent portnumber,
Node instproc next_portnumber {} {
    $self instvar next_portnumber_
    
    set next_port [incr next_portnumber_]
    return $next_port
}