Chapter 10. Writing VACM Modules

Table of Contents
Libloose function prototypes
An Example Module

VACM modules are the actual workhorses of VACM. IPC requests from clients are dispatched to the appropriate module via Nexxus. It is up to the module to actually take whatever action may be required to complete and satisfy the request. As management techniques, technologies, and protocols improve or evolve, it will be necessary to provide new or upgraded modules in order to provide services from within VACM. Also, there may be custom features that one installation may require that may not be desirable to another. In any event, a new module may need to be written.

VACM modules are stand alone programs which Nexxus starts upon initialization. The module connects to an AF_UNIX socket maintained by Nexxus for communication with the rest of the system. There is a utility library called libloose which makes communicating with Nexxus a lot easier, and it is reccommended that anyone writing a module use this library to maintain forward compatability with future versions of Nexxus. Once a module has connected and registered with Nexxus, it will receive IPC data relating to the nodes that are available for monitoring. The module will receive data for each node in the VACM nodelist, including any global variables set for that node. When in normal operating state, the module will also receive commands from clients over this Nexxus IPC pipe.

Libloose function prototypes

The libloose module API library is defined and described below. To use, simply include libloose.h and link against libloose.a. This library should be used by ALL modules to maintain future compatability.

int lm_init(void);

  Initialize the library. Must be your first call into the library. Always returns 0.

int lm_nexxus_connect(void);

  Connect to Nexxus via the AF_UNIX socket. Returns 0 on success, -1 with errno set on error.

int lm_nexxus_disconnect(void);

  Disconnect from the Nexxus AF_UNIX socket. Returns 0 on success, -1 if not connected. You should only *ever* disconnect from Nexxus if you are asked by Nexxus to shutdown

int lm_register(char *short_name, char *long_name, char *desc, char *author, char *ipc_tag, int major_version, int minor_version);

  Register the module with Nexxus. This should be called immediatly after connecting. Returns 0 on success, -1 with errno set on error.

int lm_timer_add(int timeout, int (*cb) (void *), void *arg);

  Add a timer that will call function 'cb' with argument 'arg' in 'timeout' seconds. If TRUE is returned from the callback function, the timer will be rescheduled. If FALSE is returned, the timer will be destroyed.

int lm_timer_remove(int tag);

  Removes a timer that was set with lm_timer_add. Returns 0 on success, -1 if timer was not set.

int lm_watch_fd(int fd, void (*cb (int, void *), void *arg);

  Add the file descriptor 'fd' to the libraries async i/o list and call function 'cb' with the FD and argument 'arg' when there is data waiting to be read on the descriptor. Returns 0 on success, -1 if no free FD watchers available.

int lm_unwatch_fd(int fd);

  Remove the file descriptor 'I_fd' from the list of descriptors being watched. Returns 0 on success, -1 if the FD is not being watched.

void lm_main_loop(void (*config_cb) (__uint32_t, int, char *), void (*deinit_cb) (__uint32_t, int, char *), void (*discon_cb) (__uint32_t, int, char *), void (*ipc_cb) (char *, __uint32_t, int, char *));

  Pass control of execution to the libraries main loop. The library will execute timers and FD watchers as required. 'config_cb', is called when configuration information is sent from Nexxus. 'deinit_cb' is called when Nexxus requests that the module
shut down. 'discon_cb' is called when Nexxus sends notification that a client has disconnected. 'ipc_cb' is called whenever Nexxus dispatches an IPC message from a client to be acted on. This function never returns.