--- Begin Message ---
On Tue, Mar 27, 2007 at 11:53:42PM +0200, Jeroen van Wolffelaar wrote:
> On Tue, Mar 27, 2007 at 10:54:58PM +0200, José Luis Tallón wrote:
> > Jeroen van Wolffelaar wrote:
> > > Package: imapproxy
> > > Version: 1.2.4-10
> > > Severity: important
> > >
> > > The pid-handling of imapproxy is pretty fragile, as documented in
> > > #369020 amongst others. The current workaround of writing a new pidfile
> > > after start based on 'ps ax' output is, eh, fragile at best, and
> > > actually pretty bad.
> > >
> > > The proper solution would be to patch imapproxy so that it writes out a
> > > pidfile itself, like proper daemons should.
> > Fixed. Will submit the patch ASAP
>
> Why didn't you attach it? I'm pretty busy tomorrow, and want to get this
> fixed ASAP. I mean, the plan is to release this weekend...
NMU'd, based on your patch. See attachment for diff.
--Jeroen
--
Jeroen van Wolffelaar
[EMAIL PROTECTED] (also for Jabber & MSN; ICQ: 33944357)
http://Jeroen.A-Eskwadraat.nl
diff -u up-imapproxy-1.2.4/include/imapproxy.h up-imapproxy-1.2.4/include/imapproxy.h
--- up-imapproxy-1.2.4/include/imapproxy.h
+++ up-imapproxy-1.2.4/include/imapproxy.h
@@ -172,6 +172,10 @@
#define DEFAULT_CONFIG_FILE "/etc/imapproxy.conf"
#endif
+#ifndef DEFAULT_PID_FILE
+#define DEFAULT_PID_FILE "/var/run/imapproxy.pid"
+#endif
+
#define LITERAL_PASSWORD 1
#define NON_LITERAL_PASSWORD 0
#define UNSELECT_SUPPORTED 1
diff -u up-imapproxy-1.2.4/src/main.c up-imapproxy-1.2.4/src/main.c
--- up-imapproxy-1.2.4/src/main.c
+++ up-imapproxy-1.2.4/src/main.c
@@ -242,6 +242,7 @@
static int ParseBannerAndCapability( char *, unsigned int,
char *, unsigned int );
static void ServerInit( void );
+static void Daemonize( const char* );
static void Usage( void );
@@ -265,13 +266,13 @@
pthread_attr_t attr; /* generic thread attribute struct */
int rc, i, fd;
unsigned int ui;
- pid_t pid; /* used just for a fork call */
struct linger lingerstruct; /* for the socket reuse stuff */
int flag; /* for the socket reuse stuff */
ICC_Struct *ICC_tptr;
extern char *optarg;
extern int optind;
char ConfigFile[ MAXPATHLEN ]; /* path to our config file */
+ char PidFile[ MAXPATHLEN ]; /* path to our pidfile */
#ifdef HAVE_LIBWRAP
struct request_info r; /* request struct for libwrap */
#endif
@@ -279,6 +280,9 @@
flag = 1;
ConfigFile[0] = '\0';
+ /* initialize to default */
+ strncpy( PidFile, DEFAULT_PID_FILE, sizeof PidFile -1 );
+
/*
* Ignore signals we don't want to die from but we don't care enough
* about to catch.
@@ -287,7 +291,7 @@
signal( SIGHUP, SIG_IGN );
- while (( i = getopt( argc, argv, "f:h" ) ) != EOF )
+ while (( i = getopt( argc, argv, "f:p:h" ) ) != EOF )
{
switch( i )
{
@@ -298,7 +302,14 @@
syslog( LOG_INFO, "%s: Using configuration file '%s'",
fn, ConfigFile );
break;
-
+ case 'p':
+ /* user specified a pidfile */
+ strncpy( PidFile, optarg, sizeof PidFile -1 );
+ PidFile[ sizeof PidFile - 1 ] = '\0';
+ syslog( LOG_INFO, "%s: Using pidfile '%s'",
+ fn, PidFile );
+ break;
+
case 'h':
Usage();
exit( 0 );
@@ -403,58 +414,7 @@
ServerInit();
- /* detach from our parent if necessary */
- if (! (getppid() == 1) && ( ! PC_Struct.foreground_mode ) )
- {
- syslog( LOG_INFO, "%s: Configured to run in background mode.", fn );
-
- if ( (pid = fork()) < 0)
- {
- syslog(LOG_ERR, "%s: initial call to fork() failed: %s", fn, strerror(errno));
- exit( 1 );
- }
- else if ( pid > 0)
- {
- exit( 0 );
- }
-
- if (setsid() == -1)
- {
- syslog(LOG_WARNING, "%s: setsid() failed: %s",
- fn, strerror(errno));
- }
- if ( (pid = fork()) < 0)
- {
- syslog(LOG_ERR, "%s: secondary call to fork() failed: %s", fn,
- strerror(errno));
- exit( 1 );
- }
- else if ( pid > 0)
- {
- exit( 0 );
- }
- if( chdir("/") < 0 )
- {
- syslog(LOG_ERR, "%s: chdir(\"/\") failed: %s", fn,
- strerror(errno));
- exit( 1 );
- }
- if( (i=open("/dev/null",O_RDWR)) < 0 )
- {
- syslog(LOG_ERR, "%s: open(\"/dev/null\") failed: %s", fn,
- strerror(errno));
- exit( 1 );
- }
- close(2); dup(i);
- close(1); dup(i);
- close(0); dup(i);
- close(i);
- }
- else
- {
- syslog( LOG_INFO, "%s: Configured to run in foreground mode.", fn );
- }
-
+ Daemonize( PidFile );
SetBannerAndCapability();
@@ -723,7 +683,96 @@
* Function definitions.
*/
+/*++
+ * Function: Daemonize
+ *
+ * Purpose: Daemonize, closing all unneeded descriptors.
+ * Write the daemon's PID into 'pidfile'
+ *
+ * Parameters: pidfile -- where to write our PID.
+ *
+ * Returns: nada -- exits on error
+ *
+ * Authors: Jose Luis Tallon <[EMAIL PROTECTED]>
+ *
+ * Notes:
+ *--
+ */
+void Daemonize( const char* pidfile )
+{
+ const char* fn="Daemonize()";
+ FILE* fp=NULL;
+ pid_t pid; /* used just for a fork call */
+ int i;
+
+ if ( PC_Struct.foreground_mode ) {
+ syslog( LOG_INFO, "%s: Configured to run in foreground mode.", fn );
+ return;
+ }
+
+ /* detach from our parent */
+ syslog( LOG_INFO, "%s: Configured to run in background mode.", fn );
+ if (getppid() == 1) {
+ syslog( LOG_INFO, "%s: Forking unneeded, continuing in foreground mode anyway", fn );
+ } else {
+
+ if ( (pid = fork()) < 0)
+ {
+ syslog(LOG_ERR, "%s: initial call to fork() failed: %s", fn, strerror(errno));
+ exit( 1 );
+ }
+ else if ( pid > 0)
+ {
+ exit( 0 );
+ }
+
+ if (setsid() == -1)
+ {
+ syslog(LOG_WARNING, "%s: setsid() failed: %s",
+ fn, strerror(errno));
+ }
+ if ( (pid = fork()) < 0)
+ {
+ syslog(LOG_ERR, "%s: secondary call to fork() failed: %s", fn,
+ strerror(errno));
+ exit( 1 );
+ }
+ else if ( pid > 0)
+ {
+ exit( 0 );
+ }
+ }
+ if ( (fp=fopen(pidfile,"wt")) == NULL )
+ {
+ syslog(LOG_ERR, "%s: creating pidfile '%s' failed: %s", fn,
+ pidfile, strerror(errno));
+ exit(1);
+ }
+ if( fprintf(fp, "%u\n", (unsigned)getpid()) < 0 )
+ {
+ syslog(LOG_ERR, "%s: fprintf on pidfile failed: %s", fn,
+ strerror(errno));
+ exit(1);
+ }
+ fclose(fp);
+ if( chdir("/") < 0 )
+ {
+ syslog(LOG_ERR, "%s: chdir(\"/\") failed: %s", fn,
+ strerror(errno));
+ exit( 1 );
+ }
+ if( (i=open("/dev/null",O_RDWR)) < 0 )
+ {
+ syslog(LOG_ERR, "%s: open(\"/dev/null\") failed: %s", fn,
+ strerror(errno));
+ exit( 1 );
+ }
+ close(2); dup(i);
+ close(1); dup(i);
+ close(0); dup(i);
+ close(i);
+}
/*++
* Function: Usage
@@ -741,7 +790,7 @@
*/
void Usage( void )
{
- printf("Usage: %s [-f config filename] [-h]\n", PGM );
+ printf("Usage: %s [-f config filename] [-p pidfile] [-h]\n", PGM );
return;
}
diff -u up-imapproxy-1.2.4/debian/manpages/imapproxyd.8 up-imapproxy-1.2.4/debian/manpages/imapproxyd.8
--- up-imapproxy-1.2.4/debian/manpages/imapproxyd.8
+++ up-imapproxy-1.2.4/debian/manpages/imapproxyd.8
@@ -15,6 +15,11 @@
.B -f
.RI
<config file name> ]
+.RI
+[
+.B -p
+.RI
+<pidfile name> ]
.br
.SH DESCRIPTION
This manual page documents briefly the
@@ -41,6 +46,12 @@
This can be changed by using the
.I -f
option
+.PP
+Unless foreground_mode has been enabled, UP-ImapProxy will write its PID to to
+a PID-file. It defaults to /var/run/imapproxy.pid, but can be overridden with
+the
+.I -p
+option
.SH SEE ALSO
.BR pimpstat (8),
.br
@@ -53 +64 @@
-
\ No newline at end of file
+
diff -u up-imapproxy-1.2.4/debian/changelog up-imapproxy-1.2.4/debian/changelog
--- up-imapproxy-1.2.4/debian/changelog
+++ up-imapproxy-1.2.4/debian/changelog
@@ -1,3 +1,20 @@
+up-imapproxy (1.2.4-10.1) unstable; urgency=high
+
+ * NMU to fix RC bug
+
+ [ Jose Luis Tallon ]
+ * Re-starting imapproxy failed when it was already running.
+ - Fixed imapproxy to write a pidfile itself
+ Start-stop-daemon can now interact with it properly (Closes: #415954)
+
+ [ Jeroen van Wolffelaar ]
+ * Document -p in manpage
+ * Patch cleanup
+ * Add code to initscript to not attempt to start a second version if already
+ running, and to not fail if imapproxy is no longer running (also #415954)
+
+ -- Jeroen van Wolffelaar <[EMAIL PROTECTED]> Wed, 28 Mar 2007 04:04:55 +0200
+
up-imapproxy (1.2.4-10) unstable; urgency=high
* Bashism in initscript made upgrade sequence fail when sh was not bash
diff -u up-imapproxy-1.2.4/debian/imapproxy.init.d up-imapproxy-1.2.4/debian/imapproxy.init.d
--- up-imapproxy-1.2.4/debian/imapproxy.init.d
+++ up-imapproxy-1.2.4/debian/imapproxy.init.d
@@ -43,59 +43,41 @@
exit 0;
fi
-check_running ()
-{
- proc_cmdline="/proc/`cat $PIDFILE`/cmdline"
-
- if [ -r $proc_cmdline ]; then
- grep -q $DAEMON $proc_cmdline >/dev/null \
- && return 0
- else
- sleep 1
- psline="`ps ax | grep imapproxyd | grep -v grep`"
- if [ -n $psline ]; then
- echo `echo $psline | cut -d ' ' -f 1` > $PIDFILE
- return 0
- else
- return 1
- fi
- fi
- return 1
-}
case "$1" in
start)
+ if [ -f $PIDFILE ] && [ -e /proc/`cat $PIDFILE`/status ]; then
+ echo "Already started: $NAME."
+ exit 0
+ fi
echo -n "Starting $DESC: "
- start-stop-daemon --start --quiet --background \
- --make-pidfile --pidfile=$PIDFILE \
+ start-stop-daemon --start --quiet --pidfile=$PIDFILE \
--exec $DAEMON -- $ARGS
- ssd_ret=$?
sleep 1
- if [ $ssd_ret==0 ] && check_running ; then
- echo "$NAME."
- else
- echo "Failed to start $NAME. Check logs for details."
- exit 1
- fi
+ echo "$NAME."
;;
-
+
stop)
+ if [ ! -f $PIDFILE ]; then
+ echo "Not running: $NAME."
+ exit 0
+ fi
+ if [ ! -e /proc/`cat $PIDFILE`/status ]; then
+ rm -f $PIDFILE
+ echo "Not running: $NAME."
+ exit 0
+ fi
echo -n "Stopping $DESC: "
start-stop-daemon --oknodo --stop --quiet --pidfile=$PIDFILE \
--exec $DAEMON -- $ARGS 2>&1 | grep warning || true > /dev/null
- sleep 1
- if [ -n "`ps ax | grep imapproxyd | grep -v grep`" ]; then
- test -r $PIDFILE && kill -15 `cat $PIDFILE` 2>&1 \
- && rm -f $PIDFILE
- fi
- echo "$NAME."
-
+ rm -f $PIDFILE
+ echo "$NAME."
;;
restart|force-reload)
echo "Restarting $DESC: "
$0 stop
- sleep 1
+ sleep 2 # not gratuituous
$0 start
;;
*)
--- End Message ---