How do I start the OAD or OSAgent as a true daemon on UNIX?

From Support
Jump to: navigation, search

Question:

The osagent on Unix does  not detach from the process group leader, and so signals may be propagated from the process group leader to the osagent.

For example, if the osagent in background under the bourne shell,  and then the operator types a  ^C, the osagent may be terminated when the SIGINT is propagated by the shell process.

Answer:

This behavior will be improved in VBC++ 4.0.   For VBC++ 3.x it is possible to write a small utility which performs the necessary system/library calls to detach from the process group and fork the osagent as a true daemon.

The utility below (startdaemon.C) can be used to start an osagent (or oad) that is disassociated from the  process group and session.

To start and then run the osagent as a background daemon:

startdaemon `which osagent`  [arguments]

or

startdaemon /opt/vbroker/bin/osagent [arguments]

(where the  optional [arguments] can be any  arguments passed to osagent or oad such as  -v).

By default, output messages to stdout and stderr are redirected to /dev/null unless the VBROKER_LOG_FILE environment has been set before running the startdaemon.

This code has only been tested on Solaris 2.5 with VBC++ 3.3. This code is distributed as-is and is unsupported.


startdaemon.C -------------------------------------------------------------

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

main(int argc, char** argv)
{
        int     pid;
        char*   logfile = getenv("VBROKER_LOG_FILE");
        int     fd;
        struct stat     st;

        if( logfile == 0 || *logfile == 0 )
                logfile = "/dev/null";

        fd = open(logfile, O_WRONLY|O_CREAT|O_APPEND);

        if( argc <= 1 ) {
                printf( "Usage:n"
                        "       %s []n", argv[0]);
                exit(1);
        }

        if( stat(argv[1], &st) ) {
                perror("stat");
                exit(1);
        }

        if( st.st_mode & S_IFDIR ) {
                printf("%s is not a directoryn", argv[1]);
                exit(1);
        }

        if( !(st.st_mode & S_IEXEC) ) {
                printf("%s not executablen", argv[1]);
                exit(1);
        }

        pid = fork();

        if( pid == -1 ) {
                perror("fork");
                exit(1);
        }

        if( pid ) {
                printf("run %s as process %dn", argv[1], pid);
                exit(0);
        }

        /* detach from process group */
        setsid();
        umask(0);

        /* redirect log message */
        close(0);
        dup2(fd, 1);
        dup2(fd, 2);

        execv(argv[1], argv + 1);
        perror("execv");
        exit(1);
}

Article originally contributed by