ChorusOS 5.0 Application Developer's Guide

Using the Black Box

At node startup, a specific number of black boxes are allocated. The node will select one of these black boxes to be active. This is performed sufficiently early in the boot process so that all user applications are able to log events to it as soon as they start. Some black box parameters are configurable at node startup time, that is before applications start running.

Before an application component manager launches an application, it prepares to catch the application in case it fails unexpectedly. If the application does fail, the component manager logs information about the failure to the black box, and triggers a freeze of the current black box.

Any application can log events in a black box at any point by calling bb_event. If multiple entities on the node are generating black box events, a specific thread may have fewer events than expected recorded in the black box.

At some point, an event may occur which requires freezing the black box. This is accomplished by calling bb_freeze. When the current black box is frozen, a new black box is chosen (if one is available), and new events are routed into it.

The criteria by which event filtering is performed can be modified dynamically. See "Filtering APIs" for details on the capabilities of the filtering APIs.

A system process can locate a frozen black box, open it, and read its contents to diagnose a failure. After the failure has been diagnosed, the process calls bb_release to allow the system to reselect that black box.

The black box API can also be used to store microkernel-level information. In this case the black box logs exceptions, traps, panics, and failed system calls. To use this feature, the kern.blackbox.kernelLogging tunable must be set to 1.

When the HOT_RESTART feature is selected,persistent memory can be used to store the black box data. To use persistant memory in this way, the BSP must be compiled with the -DBB_PERSISTENT flag.


Note -

When the BSP is compiled with the -DBB_PERSISTENT flag, the total size allocated for the black boxes is fixed and equally distributed for the specified number of black boxes.


Example 14-1 demonstrates the basic use of the black box API in an application.


Example 14-1 Basic Use of the Software Black Box

#include <sys/blackbox.h>

#define SEV_LOW 4 
#define SEV_HIGH 24 
#define SEV_EMERG 31

int main(int argc, char **argv)
{ 
   int fd; 
   
   bb_event("main", SEV_LOW, "Starting with %d args", argc); 
   
   if (argc > 1) { 
   	   bb_event("main", SEV_LOW, "argv[1] = %s", argv[1]);
   } else { 
   	   bb_event("main", SEV_EMERG, "no arguments   exiting");
   	   exit(1);
   } 
   
   if ((fd = open(argv[1], O_RDWR)) ==  1) {
   	   bb_event("main", SEV_HIGH,
   	    "failed to open \"%s\": error %d", argv[1], errno);
   } 
   ... 
}


Note -

Depending on the node's filtering configuration, some of the events in this example may not be added to the black box.