[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[minion-cvs] Run in a reasonable daemon mode; fork less; lock a litt...
Update of /home/minion/cvsroot/src/minion/lib/mixminion/server
In directory moria.mit.edu:/tmp/cvs-serv27308/lib/mixminion/server
Modified Files:
Queue.py ServerConfig.py ServerMain.py
Log Message:
Run in a reasonable daemon mode; fork less; lock a little; be less verbose when we are not verbose.
Index: Queue.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/server/Queue.py,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- Queue.py 12 Dec 2002 19:56:47 -0000 1.2
+++ Queue.py 15 Dec 2002 05:55:30 -0000 1.3
@@ -245,7 +245,7 @@
if s[stat.ST_MTIME] < allowedTime:
self.__changeState(m[4:], "inp", "rmv")
rmv.append(os.path.join(self.dir, m))
- _secureDelete_bg(rmv, cleanFile)
+ secureDelete(rmv, blocking=1)
return 0
def __changeState(self, handle, s1, s2):
@@ -463,7 +463,11 @@
def _secureDelete_bg(files, cleanFile):
"""Helper method: delete files in another thread, removing 'cleanFile'
- once we're done."""
+ once we're done.
+
+ XXXX No longer used: cleanup is a lot faster than it once was, now
+ XXXX that we no longer overwrite repeatedly. If we reinstate it,
+ XXXX it should be a separate process, not a frequent forker."""
pid = os.fork()
if pid != 0:
Index: ServerConfig.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/server/ServerConfig.py,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- ServerConfig.py 12 Dec 2002 19:56:47 -0000 1.1
+++ ServerConfig.py 15 Dec 2002 05:55:30 -0000 1.2
@@ -32,6 +32,13 @@
mixminion.Config._ConfigFile.__init__(self, fname, string)
def validate(self, sections, entries, lines, contents):
+ # Pre-emptively configure the log before validation, so we don't
+ # write to the terminal if we've been asked not to.
+ if not sections['Server'].get("EchoMessages", 0):
+ LOG.handlers = []
+ # ???? This can't be the best way to do this.
+
+ # Now, validate the host section.
mixminion.Config._validateHostSection(sections.get('Host', {}))
# Server section
server = sections['Server']
@@ -86,6 +93,7 @@
'LogFile' : ('ALLOW', None, None),
'LogLevel' : ('ALLOW', C._parseSeverity, "WARN"),
'EchoMessages' : ('ALLOW', C._parseBoolean, "no"),
+ 'NoDaemon' : ('ALLOW', C._parseBoolean, "no"),
'EncryptIdentityKey' : ('REQUIRE', C._parseBoolean, "yes"),
'IdentityKeyBits': ('ALLOW', C._parseInt, "2048"),
'PublicKeyLifetime' : ('ALLOW', C._parseInterval,
Index: ServerMain.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/server/ServerMain.py,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- ServerMain.py 15 Dec 2002 04:15:38 -0000 1.3
+++ ServerMain.py 15 Dec 2002 05:55:30 -0000 1.4
@@ -10,6 +10,7 @@
__all__ = [ 'MixminonServer' ]
+import fcntl
import getopt
import os
import sys
@@ -24,8 +25,8 @@
import mixminion.server.ServerConfig
import mixminion.server.ServerKeys
-from mixminion.Common import LOG, MixError, MixFatalError, ceilDiv, \
- formatBase64, formatTime, waitForChildren
+from mixminion.Common import LOG, LogStream, MixError, MixFatalError, ceilDiv,\
+ createPrivateDir, formatBase64, formatTime, waitForChildren
class IncomingQueue(mixminion.server.Queue.DeliveryQueue):
"""A DeliveryQueue to accept messages from incoming MMTP connections,
@@ -186,6 +187,21 @@
"""Create a new server from a ServerConfig."""
LOG.debug("Initializing server")
self.config = config
+ homeDir = config['Server']['Homedir']
+ createPrivateDir(homeDir)
+
+ # Lock file.
+ # FFFF Refactor this part into common?
+ self.lockFile = os.path.join(homeDir, "lock")
+ self.lockFD = os.open(self.lockFile, os.O_RDWR|os.O_CREAT, 0600)
+ try:
+ fcntl.flock(self.lockFD, fcntl.LOCK_EX|fcntl.LOCK_NB)
+ except IOError:
+ raise MixFatalError("Another server seems to be running.")
+
+ # The pid file.
+ self.pidFile = os.path.join(homeDir, "pid")
+
self.keyring = mixminion.server.ServerKeys.ServerKeyring(config)
if self.keyring._getLiveKey() is None:
LOG.info("Generating a month's worth of keys.")
@@ -208,7 +224,6 @@
self.moduleManager = config.getModuleManager()
self.moduleManager.configure(config)
- homeDir = config['Server']['Homedir']
queueDir = os.path.join(homeDir, 'work', 'queues')
incomingDir = os.path.join(queueDir, "incoming")
@@ -238,10 +253,16 @@
self.mmtpServer.connectQueues(incoming=self.incomingQueue,
outgoing=self.outgoingQueue)
+
def run(self):
"""Run the server; don't return unless we hit an exception."""
# FFFF Use heapq to schedule events? [I don't think so; there are only
# FFFF two events, after all!]
+
+ f = open(self.pidFile, 'wt')
+ f.write("%s\n" % os.getpid())
+ f.close()
+
now = time.time()
MIX_INTERVAL = 20 # FFFF Configurable!
nextMix = now + MIX_INTERVAL
@@ -288,6 +309,13 @@
def close(self):
"""Release all resources; close all files."""
self.packetHandler.close()
+ try:
+ os.unlink(self.lockFile)
+ fcntl.flock(self.lockFD, fcntl.LOCK_UN)
+ os.close(self.lockFD)
+ os.unlink(self.pidFile)
+ except OSError:
+ pass
#----------------------------------------------------------------------
def usageAndExit(cmd):
@@ -331,12 +359,25 @@
mixminion.Crypto.init_crypto(config)
server = MixminionServer(config)
+
except:
LOG.fatal_exc(sys.exc_info(),"Exception while configuring server")
print >>sys.stderr, "Shutting down because of exception"
- #XXXX print stack trace as well as logging?
+ #XXXX001 Print the exception, too.
sys.exit(1)
+ if not config['Server'].get("NoDaemon",0):
+ print >>sys.stderr, "Starting server in the background"
+ # ??? This 'daemonize' logic should go in Common.
+ pid = os.fork()
+ if pid != 0:
+ os._exit(0)
+ sys.stderr.close()
+ sys.stdout.close()
+ sys.stdin.close()
+ sys.stdout = LogStream("STDOUT", "WARN")
+ sys.stderr = LogStream("STDERR", "WARN")
+
LOG.info("Starting server")
try:
server.run()
@@ -344,7 +385,7 @@
pass
except:
LOG.fatal_exc(sys.exc_info(),"Exception while running server")
- #XXXX print stack trace as well as logging?
+ #XXXX001 Print the exception, too.
LOG.info("Server shutting down")
server.close()
LOG.info("Server is shut down")