Emulab Event System Reference

Contents


Introduction

The Emulab event system provides a means for automating your experiments. The event system consists of several types of "agents" that implement some sort of functionality, such as running programs or generating traffic, and a scheduler that triggers the events at the appropriate time. When your experiment is swapped in, any agents specified in your NS file are automatically setup on the experimental nodes and the ops node. A short time after the experiment becomes active, "event time" begins to flow. As event time progresses, any events scheduled in the NS file for a particular time offset are sent to the appropriate agents. Alternatively, events can be sent at runtime using the tevc command from ops or an experimental node. For a detailed walkthrough of using the event system, see the advanced example.

Recently, we have added some experimental extensions to make the event system even more capable. Note that many of these features are subject to change and are only available when using the latest versions of the FBSD410-STD and RHL90-STD disk images. The NS file below gives an example of using these extensions to automate the process of creating disk images. First, it downloads a network traffic analyzer, iftop, then proceeds to build and install the software. Next, the source directory is removed and a snapshot is taken of the node's disk. Finally, after the snapshot completes and the node has finished rebooting, the experiment is swapped out.

 set opt(VERSION) 0.16

 set ns [new Simulator]
 source tb_compat.tcl

 set node [$ns node]
 tb-set-node-tarfiles $node \
     /tmp http://www.ex-parrot.com/~pdw/iftop/download/iftop-$opt(VERSION).tar.gz

 set builder [$node program-agent -dir "/tmp/iftop-$opt(VERSION)"]
 set cleaner [$node program-agent]

 set build [$ns event-sequence {
     $builder run -command "./configure"
     $builder run -command "gmake"
     $builder run -command "sudo gmake install"
 }]

 set clean [$ns event-sequence {
     $cleaner run -command "sudo rm -rf /tmp/iftop-$opt(VERSION)"
 }]

 set doit [$ns event-sequence {
     $build run
     $clean run
     $node snapshot-to RHL90-CUSTOMIZED
     $ns swapout
 }]

 $ns at 0.0 "$doit start"
 $ns run
An example NS file that automates the process of installing software on a node and taking a snapshot of the disk image.

We also have a small package containing a more complicated experiment that runs BitTorrent on a bunch of nodes, collects their output, and generates a simple report on how they performed.

BitTorrent experiment package

The rest of this document is intended as a reference manual for the available set of agents and the events they can handle.


NS "Simulator" Agent

Constructor: new Simulator

The simulator agent provides control over your Emulab experiment as a whole.

The simulator agent listens for the following events:

NS Examples:

 set ns [new Simulator]

 ...

 set doit [$ns event-sequence {
    $ns message "Testing one way, then the other..."
    $thisway run
    $thatway run
    $ns report
 }]
Example 1: Adds some text to the report e-mail, runs an application twice, and then sends a report to the user.

Event Sequence

Constructor: $ns event-sequence [body]

An event sequence agent is an ordered list of events, each of which is sent when the previous event in the list has reported its completion. For example, in a sequence consisting of a pair of events that run programs, the first event will be sent immediately and the second will be sent when the run of the first program completes. While running two programs in a row may be trivial using conventional means, this capability works across machines and can interact with other operations like reloading disks and rebooting machines.

The semantics of when an event "completes" depend on the type of agent and event. Many events complete instantaneously, such as those used to set a property, so the next event in the sequence is sent immediately. Other events that take a variable amount of time to complete, such as running a program. Some agents provide two types of events to support non-blocking and blocking operation, usually called start and run. Whereas the start event completes instantly, the run blocks the sequence until the agent is finished.

Event sequences listen for the following events:

NS Examples:

 set doit [$ns event-sequence {
     $prog0 run -command "setup.sh"
     $node0 reboot
     $prog0 run -command "test.sh"
 }]
Example 1: A sequence that performs some setup on a node, reboots it, and then starts the test.
 set doit [$ns event-sequence {
     $serverprog start; # Start the server,
     $clientprogs run;  # run the clients to completion, then
     $serverprog stop;  # stop the server.
 }]
Example 2: A sequence that asynchronously starts a server, runs some clients, and finally, stops the server.
 set testseq [$ns event-sequence]

 foreach test $tests {
     $testseq append "$prog0 run -command \"$test\""
 }
Example 3: A sequence that is constructed incrementally instead of being fully specified in the constructor.

Event Timeline

Constructor: $ns event-timeline

An event timeline agent sends other events at a relative offset to the overall start time of the timeline. In other words, a timeline is a first class version of the existing "$ns at" syntax.

Event timelines listen for the following events:

NS Examples:

 set tl [$ns event-timeline]

 $tl at 0s "$prog0 start"
 $tl at 15s "$prog0 stop"

 set seq [$ns event-sequence {
     $tl run
     $ns swapout
 }]
Example 1: A timeline that runs a program for 15 seconds and then swaps out the experiment.

Program Agent

Constructor: $node program-agent [-command cmdline] [-dir dir] [-timeout seconds] [-tag string]   [-expected-exit-code code]

Program agents listen for the following events:


Notes on Command Lines

In general, if you have complicated or multiple commands to execute, it is best to put them in a script and specify the script name in -command. But if you insist, here are some things to be aware of.

The command line is executed with "csh -c." Yes, that is the Berkeley C-shell and not the Bourne shell or bash. Sorry, it is an historical thing. So be aware of differences in redirection and expansion syntax (e.g., ">&" and "{}"). When in doubt, put your command in a script and set the command line to "sh -c myscript.sh".

Quoting is fragile and happens at a couple of levels:

  1. Quoting for TCL. Putting curly braces ({...}) or double quotes ("...") around the entire command line will quote the string to TCL (i.e., the NS script parser language). Double quotes allows for TCL variable expansion, curly braces allow no expansion. Thus, these quotes will be stripped off before the command line is given to csh. Use this mechanism if your command line has white space (i.e., arguments to the command), otherwise the Emulab NS parser will flag an error.
  2. Quoting for csh. Recall that the program agent runs a shell to interpret your commands, so you may need additional quoting to get special characters past it. For example, if one of your command arguments has an embedded space, you will need to quote it with single or double quotes. Backslash quoting also works.

A sick example might look like this:

  ... -command {echo arg{1,2} "arg3 has spaces" arg4\ has\ \'\ \'\ too}
where the echo command would have four arguments:
  arg1
  arg2
  arg3 has spaces
  arg4 has ' ' too

To summarize: put your commands in a script.

Other Notes:

  1. Many of the features described here are only available on recent FBSD{410,54,61}-STD, RHL90-STD, and FC4-STD disk images.
  2. This page currently only covers the agent at a high-level, you can find some more detail in the program-agent(8) man page on ops or an experimental node.

NS Examples:

 set prog0 [$node0 program-agent]
 set prog1 [$node0 program-agent -command "/usr/bin/env"]
 set prog2 [$node0 program-agent -command "inf_loop_bug" -timeout 10]
 set prog3 [$node0 program-agent -command "ls" -dir "/foo/bar"]
Example 1: Creates four program agents with different default properties.

Event Group

Constructor: $ns event-group [list-of-agents]

The event group agent is used to broadcast events to a group of agents of the same type. For example, if you wanted to start a program on a large number of nodes at the same time, you can create a group consisting of those program-agents and send a single start event to the group. An event group can also act as a simple synchronization method when used inside an event-sequence. In this case, the next event in the sequence won't be sent until all of the agents in the group have signalled completion.

NS Examples:

 set group [$ns event-group]
 for {set i 0} {$i < 4} {incr i} {
     set nodes($i) [$ns node]
     set progs($i) [$nodes(i) program-agent]
     $group add $progs($i)
 }

 set doit [$ns event-sequence {
     $group run -command "setup.sh"
     $group run -command "client.sh"
 }]
Example 1: Runs the "setup.sh" script on a group of nodes and when they have all completed, runs the "client.sh" script.
 set group [$ns event-group [list $rnode $lnode]]

 set doit [$ns event-sequence {
     $group reboot
     $ns log "Reboot finished"
 }]
Example 2: Reboots a pair of nodes and logs a message with the simulator.

Node Agent

Constructor: $ns node

In addition to allocating an actual machine, the "$ns node" constructor will create a node agent so the node can be controlled from the event system.

Node agents listen for the following events:

Console Agent

Constructor: $node console

Console agents operate on the serial consoles attached to some Emulab nodes. Currently, they only support capturing a slice of the output received on the serial line.

Console agents listen for the following events:

Traffic Generator

Traffic generation agents output network traffic at a constant bit rate over a link. Consult the advanced example for more information and examples of their use.

Traffic generators listen for the following events: