[prev in list] [next in list] [prev in thread] [next in thread] 

List:       info-cyrus
Subject:    [PATCH, sorta]  Daemonization of master.c
From:       Henrique de Moraes Holschuh <hmh () debian ! org>
Date:       2002-02-27 20:13:47
[Download RAW message or body]

The following hunks should do it. The last one isn't a diff hunk, just
insert it somewhere apropriate in configure.in.

Do remember to run acconfig and autoconf to regenerate the GNU autotools
chain.

The rlimit stuff is a fix for linux kernels 2.4 won't bother to get out of
the patch. If you don't want it, clean it up...

I actually think the email with these patchs I sent the last time (2.0.x)
should apply cleanly, though. And it was better prepared (I am sort of in a
hurry right now), so one might want to search for it in the archives, and
try with that instead.

-- 
  "One disk to rule them all, One disk to find them. One disk to bring
  them all and in the darkness grind them. In the Land of Redmond
  where the shadows lie." -- The Silicon Valley Tarot
  Henrique Holschuh


Index: Makefile.in
===================================================================
RCS file: /home/cvs/debian/cyrus21-imapd/master/Makefile.in,v
retrieving revision 1.1.1.2
retrieving revision 1.3
diff -u -r1.1.1.2 -r1.3
--- Makefile.in	27 Nov 2001 02:25:04 -0000	1.1.1.2
+++ Makefile.in	13 Feb 2002 10:53:00 -0000	1.3
@@ -53,8 +53,10 @@
 CYRUS_GROUP=@cyrus_group@
 
 DEFS = @DEFS@ @LOCALDEFS@
+#CPPFLAGS = -I. -I.. -I$(srcdir) -I$(srcdir)/../lib @CPPFLAGS@ @COM_ERR_CPPFLAGS@
+DEPLIBS = ../lib/libcyrus.a @DEPLIBS@
 CPPFLAGS = -I. -I.. -I../lib -I$(srcdir) @CPPFLAGS@ @COM_ERR_CPPFLAGS@
-DEPLIBS = @DEPLIBS@
+#DEPLIBS = @DEPLIBS@
 
 CFLAGS = @CFLAGS@
 LDFLAGS = @LDFLAGS@ @CFLAGS@ @COM_ERR_LDFLAGS@
Index: master.c
===================================================================
RCS file: /home/cvs/debian/cyrus21-imapd/master/master.c,v
retrieving revision 1.1.1.4
diff -u -r1.1.1.4 master.c
--- master.c	19 Feb 2002 18:50:15 -0000	1.1.1.4
+++ master.c	27 Feb 2002 19:57:01 -0000
@@ -93,6 +93,7 @@
 
 #include "master.h"
 #include "service.h"
+#include "lock.h"
 
 enum {
     become_cyrus_early = 1,
@@ -183,6 +184,70 @@
     return result;
 }
 
+#ifdef ENABLE_DAEMON_MODE
+void acquire_daemon_lock(int closeflag)
+/* Copyright 1988,1990,1993,1994 by Paul Vixie
+ * All rights reserved
+ *
+ * Distribute freely, except: don't remove my name from the source or
+ * documentation (don't take credit for my work), mark your changes (don't
+ * get me blamed for your possible bugs), don't alter or remove this
+ * notice.  May be sold if buildable source is provided to buyer.  No
+ * warrantee of any kind, express or implied, is included with this
+ * software; use at your own risk, responsibility for damages (if any) to
+ * anyone resulting from the use of this software rests entirely with the
+ * user.
+ *
+ * Changelog: 
+ *   2001-11-18 (hmh@debian.org): 
+ *       Got acquire_daemonlock (and above copyright notice) from Paul Vixie's
+ *       cron, as packaged by the Debian project.  Modified acquire_daemon_lock 
+ *       to adequate it for Cyrus IMAPd needs. Applied it to cyrus master the
+ *       same proven way it is used in Vixie cron.  Basically, call it with
+ *       a zero to update the pidfile, and with a 1 at every fork() of a 
+ *       worker process.
+ */
+{
+	static	FILE	*fp = NULL;
+	int fdflags;
+
+	if (closeflag && fp) {
+		fclose(fp);
+		fp = NULL;
+		return;
+	}
+
+	if (!fp) {
+		int	fd;
+
+		if ((-1 == (fd = open(MASTER_PIDFILE, O_RDWR|O_CREAT, 0644)))
+		    || (NULL == (fp = fdopen(fd, "r+")))
+		    ) {
+			fatal("couldn't open or create pidfile " MASTER_PIDFILE ": %m",1);
+		}
+
+		if (lock_nonblocking(fd)) {
+			fatal("failed to acquire pidfile lock", 1);
+		}
+		fdflags =  fcntl(fd, F_GETFD, 0);
+		if (fdflags != -1) fdflags = fcntl(fd, F_SETFD, 
+						fdflags | FD_CLOEXEC);
+		if (fdflags == -1) {
+			fatal("unable to set close-on-exec for pidfile: %m", 1);
+		}
+	}
+
+	rewind(fp);
+	fprintf(fp, "%d\n", getpid());
+	fflush(fp);
+	(void) ftruncate(fileno(fp), ftell(fp));
+
+	/* abandon fd and fp even though the file is open. we need to
+	 * keep it open and locked, but we don't need the handles elsewhere.
+	 */
+}
+#endif /* ENABLE_DAEMON_MODE */
+
 void get_prog(char *path, char *const *cmd)
 {
     if (cmd[0][0] == '/') strcpy(path, cmd[0]);
@@ -429,6 +494,10 @@
 	break;
 	
     case 0:
+#ifdef ENABLE_DAEMON_MODE
+    	acquire_daemon_lock(1);
+#endif
+    
 	if (become_cyrus() != 0) {
 	    syslog(LOG_ERR, "can't change to the cyrus user");
 	    exit(1);
@@ -485,6 +554,9 @@
 
     case 0:
 	/* child */
+#ifdef ENABLE_DAEMON_MODE
+	acquire_daemon_lock(1);
+#endif
 	if (become_cyrus() != 0) {
 	    syslog(LOG_ERR, "can't change to the cyrus user");
 	    exit(1);
@@ -585,6 +657,9 @@
 	    break;
 
 	case 0:
+#ifdef ENABLE_DAEMON_MODE
+	    acquire_daemon_lock(1);
+#endif
 	    if (become_cyrus() != 0) {
 		syslog(LOG_ERR, "can't change to the cyrus user");
 		exit(1);
@@ -956,16 +1031,14 @@
 void limit_fds(rlim_t x)
 {
     struct rlimit rl;
-    int r;
 
     rl.rlim_cur = x;
     rl.rlim_max = x;
-    if (setrlimit(RLIMIT_NUMFDS, &rl) < 0) {
+    if (setrlimit(RLIMIT_NUMFDS, &rl) < 0 && x != RLIM_INFINITY) {
 	syslog(LOG_ERR, "setrlimit: Unable to set file descriptors limit to %ld: %m", x);
     }
 
-    if (verbose > 1) {
-	r = getrlimit(RLIMIT_NUMFDS, &rl);
+    if (verbose > 1 && getrlimit(RLIMIT_NUMFDS, &rl) >= 0) {
 	syslog(LOG_DEBUG, "set maximum file descriptors to %ld/%ld", rl.rlim_cur,
 	       rl.rlim_max);
     }
@@ -1083,7 +1156,33 @@
 
     limit_fds(RLIM_INFINITY);
 
+#ifdef ENABLE_DAEMON_MODE
+    /* lock pidfile (and create it while we're root) */
+    acquire_daemon_lock(0);
+#endif
+
     masterconf_init("master");
+
+#ifdef ENABLE_DAEMON_MODE
+    /* go daemon, if not in debug mode */
+    if (close_std) {
+#ifdef HAVE_UNISTD_H
+        if (daemon(0, 0)) fatal("could not enter daemon mode: %m", 2);
+#else
+	switch (fork()) {
+		case -1:
+			fatal("could not fork to background: %m", 2);
+		case 0: /* child */
+			break;
+		default: /* parent */
+			exit(0);
+	}
+	setsid();
+#endif /* HAVE_UNISTD_H */
+        acquire_daemon_lock(0);
+    }
+#endif
+
     syslog(LOG_NOTICE, "process started");
 
 #ifdef HAVE_UCDSNMP


Index: acconfig.h
===================================================================
RCS file: /home/cvs/debian/cyrus21-imapd/acconfig.h,v
retrieving revision 1.1.1.3
retrieving revision 1.5
diff -u -r1.1.1.3 -r1.5
--- acconfig.h	18 Feb 2002 20:04:16 -0000	1.1.1.3
+++ acconfig.h	22 Feb 2002 21:24:48 -0000	1.5
@@ -131,6 +134,12 @@
 
 /* do we have rlim_t? */
 #undef HAVE_RLIM_T
+
+/* do we want master to run in daemon mode? */
+#undef ENABLE_DAEMON_MODE
+
+/* path to pid lockfile for master */
+#undef MASTER_PIDFILE
 
 @BOTTOM@
 


dnl
dnl Enable/disable daemon support, set pidfile location
dnl
AC_ARG_ENABLE(pidfile,[  --enable-pidfile[=PATH]     Enable daemon mode, with pidfile \
set to PATH (/var/run/cyrus-master.pid)],  [MASTERPIDFILE="$enableval"],
	[MASTERPIDFILE="/var/run/cyrus-master.pid"])
if test "yes" = "$MASTERPIDFILE" ; then
	MASTERPIDFILE="/var/run/cyrus-master.pid"
fi
if test "$MASTERPIDFILE" != "no" ; then
	AC_DEFINE(ENABLE_DAEMON_MODE)
	MASTERPIDFILE="\"$MASTERPIDFILE\""
	AC_DEFINE_UNQUOTED(MASTER_PIDFILE, $MASTERPIDFILE)
fi



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic