[omniORB] Running a Server Object as Daemon
W. Eliot Kimber
eliot@isogen.com
Thu, 13 Dec 2001 16:36:56 -0600
All,
I don't know if this code will be useful, but a search of the maillist
archive didn't reveal anything like this. And please tell me if there's
a easier way to do this.
I just wanted to be able to start our main server object as a daemon
under linux. Since I'm not a shell script hack, I did it all directly in
Python:
Here is the daemon startup module:
#!/usr/bin/python
#----------------------------------------------------------
#
# Server Daemon Process
#
#
#---------------------------------------------------------
"""
Linux Server Daemon
Usage:
bonnelld [[start] [-n] -ORBInitRef
NameService=corbaname::{nameservername} -ORBpoa_iiop_name_port
{hostname} ]
[stop]
start
Starts the daemon. You must provide the ORBInitRef and
ORBpoa_iiop_name_port parameters, where
{nameservername} is the hostname or IP address of the name server
(e.g., "localhost" if the nameserver
is running on the same machine as the Bonnell daemon), and
{hostname} is the hostname or IP address
that the Bonnell server is running on.
-n Do not run as a daemon but as a foreground process.
stop
Stops a running daemon. Note that the user that stops the process
must have the authority
to kill the process.
"""
import ZODB
from ZODB import FileStorage
import os.path
import sys
if sys.platform[0] != "l": # Lowercase "l" for linux
print "This daemon only works under Linux"
sys.exit(-1)
import daemon
import string
from bonnellcore import BonnellUtils
from bonnellcorba.BonnellServer import BonnellServer
from bonnellcore.BonnellServer import initDB
import CosNaming
from omniORB import CORBA
from zLOG import LOG, TRACE, DEBUG, BLATHER, INFO, PROBLEM, WARNING,
ERROR, PANIC
cwd = BonnellUtils.cwd(globals(), locals())
d = daemon.Daemon(cwd=cwd)
runAsDaemon = 1
cmd = "START"
if len(sys.argv) > 1:
for opt in sys.argv[1:]:
if opt == "-n":
runAsDaemon = 0
sys.argv.remove(opt)
if string.upper(opt) in ("START", "STOP", "SHUTDOWN", "HALT"):
cmd = string.upper(opt)
sys.argv.remove(opt)
if cmd in ("STOP", "SHUTDOWN", "HALT"):
if not d.isRunning():
print "Daemon is not running, %s request ignored" % cmd
sys.exit(0)
LOG("bonnelld.%s" % __name__, TRACE, \
"Attempting to kill daemon process")
try:
d.killMyself()
print "Bonnell daemon killed"
sys.exit(0)
except daemon.KillFailedError, exc:
print "Unable to kill process ID %s" % exc
sys.exit(-1)
# Otherwise, just start up:
if runAsDaemon:
try:
LOG("bonnelld.%s" % __name__, TRACE, \
"About to go into daemon mode")
d.runAsDaemon()
LOG("bonnelld.%s" % __name__, TRACE, \
"Now running as a daemon, pid=%s" % os.getpid())
except daemon.DaemonIsRunning:
print "Daemon is already running, quiting"
sys.exit(0)
dataFS = os.path.join(cwd, "data.fs")
LOG("bonnelld.%s" % __name__, TRACE, \
"Got a data.fs file")
storage = ZODB.FileStorage.FileStorage(dataFS)
db = ZODB.DB(storage)
initDB(db)
#test CORBA objects
bServ = BonnellServer(storage)
LOG("bonnelld.%s" % __name__, TRACE, \
"Got a bServ object")
bServObj = bServ._this()
orb = CORBA.ORB_init(sys.argv, CORBA.ORB_ID)
LOG("bonnelld.%s" % __name__, TRACE, \
"Got an ORB")
try:
ns = orb.resolve_initial_references("NameService")
ns = ns._narrow(CosNaming.NamingContext)
LOG("bonnelld.%s" % __name__, TRACE, \
"Got a naming service object")
name = [CosNaming.NameComponent("BonnellServer", "")]
ns.rebind(name, bServObj)
LOG("bonnelld.%s" % __name__, TRACE, \
"Starting orb.run()")
orb.run()
except Exception, exc:
LOG("bonnelld.%s" % __name__, TRACE, \
"Got exception %s" % exc)
if not runAsDaemon:
import traceback
trackback.print_exc()
# End of script
--
Here is the daemon module, which is generic:
#-------------------------------------------------------
#
# Daemon startup module.
#
# Based on code posted by Ben Caradoc-Davies <bmcd@es.co.nz>, June 1999
# to comp.lang.python.
#
#--------------------------------------------------------
import os
import sys
def fork_and_die():
r = os.fork()
if r == -1:
raise OSError, "Couldn't fork()."
elif r > 0: # I'm the parent
sys.exit(0)
elif r < 0:
raise OSError, "Something bizarre happened while trying to
fork()."
# now only r = 0 (the child) survives.
class Daemon:
"""
Turns the current Python process into a daemon running in the
background.
Usage:
Just create a Daemon object and call the runAsDaemon() method to go
into Daemon mode.
Creates a file with the daemon's PID that can be used to kill this
process
from a script and to prevent second instances from starting.
"""
def __init__(self, umask=077, chdir="/", pidfile = None ):
self.umask = umask
self.chdir = chdir
self.pdifile = pidfile
def runAsDaemon(self):
fork_and_die()
os.setsid()
fork_and_die()
os.chdir(self.chdir)
os.umask(self.umask)
sys.stdin.close()
sys.stdout.close()
sys.stderr.close()
# End of module
. . . . . . . . . . . . . . . . . . . . . . . .
W. Eliot Kimber | Lead Brain
1016 La Posada Dr. | Suite 240 | Austin TX 78752
T 512.656.4139 | F 512.419.1860 | eliot@isogen.com
w w w . d a t a c h a n n e l . c o m