How do I start the OAD or OSAgent as a true daemon on UNIX?
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