NetSpec Daemon HOWTO

NetSpec provides a template which can be used a starting point to build a custom test or measurement daemon. The template provides the skeleton of functions needed in the communication protocol used by the NetSpec controler. This document describe the step-by-step procedure of writing your own NetSpec daemon.

  1. Copy the contents of template directory to a new directory. This new directory will contains files specific to the new daemon. For example we want to create a foo daemon.
    1. cp -R template foo 
  2. Change directory to the new directory. You should see the following files: Makefile, daemon.h, ident.h, command.c, parms.c, parms.h, par.y, and par.l.
  3. Edit the ident.h file and change the IDENT constant to reflect the version of the daemon that you are working on.
    1.  #define IDENT "@(#)NetSpec Version 3.0 FOO alpha 1"
  4. Edit the daemon.h file and replace the string constant DAEMONNAME with the new daemon name. The IDENT and DAEMONNAME strings will be used as identification in the header of a NetSpec report.
    1.  #define DAEMONNAME "foo"
  5. Next, write the parser for the script understood by the daemon. There are two files that you need to modify for this step: par.l is a lex file where you can define the tokens; and par.y where you define the grammar of the script. The common approach is to define data structures for the parameters of the experiment, and store the values as the parameters are being parsed.
  6. At this point, we are ready to fill in the protocol routines. When a NetSpec controller creates a measurement or test daemon, it will pass the portion of the script intended for the daemon. Then the daemon waits for protocol messages from the controller. During its life cycle a daemon will generally go through the following phases: initialize, setup, open, run, finish, close, report, teardown, and kill. However, it is not mandatory to fill in all the routines for each phase. Consult the following table when deciding which phases are required by your daemon.



    initialize ??
    setup Use this phase to initialize variables, set default values, or set up other resources needed
    open This phase is mainly used by test daemons to opens up the connections.
    run This is the main phase where the daemon performs the required task.
    finish Use this phase to clean up after performing the task, e.g. close all file descriptors, post-process the data, etc.
    close If you open any connections during the open phase, close them here.
    report Use this phase to generate report of the experiments. To send the report to the controller, enclose the report within calls to rcipsStartReport() and rcipsFinishReport(). Anything that you print to stdout will be written to the socket connected to the controller.
    teardown Frees up the resources allocated in the setup phase.
    kill The last chance to do anything before the daemon is killed by the controller.
    The appropriate routines in file command.c will be called for each type of protocol message received from the controller. You will need to fill in these routines with the specific tasks that your daemon needs to do at each phase. After finishing each phase, the daemon must send an acknowledgement to the controller. Be sure that the following acknowledgement call is the last thing that you do in each routine.
    1.  rcipAcknowledge(""); 
  7. The remaining two files, parms.c and parms.h are used to declare any global declarations needed by both the parser and command modules. You can create any number of additional files to put the routines specific to your daemon.
  8. Now we are ready to compile the daemon. Replace the macros EXEC with your daemon name. Also, include all additional files that you define in the OBJS macro. You can also modify install directories or other paths to suit your environment. Make sure that NSLIB points to the appropriate NetSpec common library, common.a, for the current architecture. When you are ready, all you need to do is to type make all.
  9. The final step is to add your new daemon to the collection of NetSpec daemons. You can directly put your daemon under NetSpec framework if you are confident that it will work properly. Otherwise, see the note under Testing and Debugging Your Daemon section to find help on running the daemon in stand alone mode.
    You have to edit the netspecd configuration file (usually located at /etc/netspec.conf) and add a new line to point to your new daemon. For example, if you installed the daemon at /usr/local/bin/nsfoo then add the following line to the configuration file:
      foo   UserId	/usr/local/bin/nsfoo nsfoo 
    After you do this, when the NetSpec controller sees the string "foo" in the script, it will create an instant of nsfoo daemon and pass the experiment parameters.

Testing and Debugging Your Daemon

Probably the best way to test your daemon is to run it as a standalone daemon. To do this, run your daemon with -f, -s, -p, and -d options as follows:
    nsfoo -f -s -p 42010 -d 5
where 42010 is the port number it listens to, and 5 is the debugging level (higher debugging level gives you more debugging information).
You have to specify the port number in your NetSpec script so that the controller will contact the daemon attached to that particular port. For example:
    cluster {
         foo localhost:42010 {
If you need to print debugging information, remember not to print it to stdout because it is already attached to the socket connected to the controller. Instead, you should direct it to either stderr or other opened files.

Last modified: Tue Jul 29 17:27:50 CDT 1997