Package: cyrus-common-2.4
Version: 2.4.8-7

install-configure.html says we should use QUIT first:

Since a clean shutdown may never finish if a child process is stuck
for some reason the recommended approach is to send a SIGQUIT then loop
on the master process sending a signal 0 every second until either the
master process has gone away or a suitable time has expired (maybe 10
seconds).  You can then send a SIGTERM if the process still exists.

As well imapd.conf says sync_shutdown_file should be used if we're doing replication.

I've attached a first draft of a patch. Please let me know what you think. Thank you.

diff -r c5fdbe96f08d debian/cyrus-common.cyrus-imapd.init
--- a/debian/cyrus-common.cyrus-imapd.init	Thu May 19 08:49:41 2011 -0700
+++ b/debian/cyrus-common.cyrus-imapd.init	Thu May 19 10:23:09 2011 -0700
@@ -128,4 +128,29 @@
 }
 
+sync_stop () {
+	if [ -e /usr/lib/cyrus/bin/sync_client ]; then
+		# Check if the sync file is set
+		SYNCSHUTDOWN=`grep sync_shutdown_file /etc/imapd.conf|awk '{print $2}'`
+		if [ "x${SYNCSHUTDOWN}" = "x" ]; then
+			# Do we want to throw an error if this isn't configured?
+			# Maybe we should add a default sync_shutdown_file to imapd.conf
+			# on installation?
+			return 0
+		else
+			if ! touch $SYNCSHUTDOWN ; then
+				echo Failed to create sync_shutdown_file: $SYNCSHUTDOWN
+				exit 1
+			else
+				# Give sync_client time to exit.
+				sleep 1
+				rm -f "$SYNCSHUTDOWN"
+				return 0
+			fi
+		fi
+	fi
+	return 0
+
+}
+
 case "$1" in
   start)
@@ -175,22 +200,39 @@
   stop)
 	echo -n "Stopping $DESC: "
-	if start-stop-daemon --stop --quiet --pidfile /var/run/$NAME.pid \
-		--name ${NAME} --quiet --startas $DAEMON >/dev/null 2>&1 ; then
-		echo "$NAME."
+	sync_stop
+	set +e
+	# Send STOP
+	start-stop-daemon --stop --signal 3 --quiet --pidfile /var/run/$NAME.pid \
+		--name ${NAME} --quiet --startas $DAEMON >/dev/null 2>&1 
+	set -e
+	# process running?
+	if check_status; then
+		i=0
+		# Wait up to 10 seconds for cyrus to exit
+		until [ "$i" -gt 10 ]; do 
+			if ! check_status; then
+				break
+			fi
+			echo -n "."
+			sleep 1
+			i=$(( $i + 1 ))
+		done
+		# If we're still running, send TERM 
+		if check_status; then
+			set +e
+			start-stop-daemon --stop --quiet --pidfile /var/run/$NAME.pid \
+			--name ${NAME} --quiet --startas $DAEMON >/dev/null 2>&1
+			set -e
+		fi
+	fi
+
+	if check_status; then
+		# Yes, report failure.
+		echo "(failed)."
+		exit 1
+	else
+		echo "$NAME"
 		rm -f ${PIDFILE}
 		exit 0
-	else
-		# process running?
-		if check_status; then
-			# Yes, report failure.
-			echo "(failed)."
-			exit 1
-		else
-			# No, return as if stopped a running process 
-			# successfully.
-			echo "."
-			rm -f ${PIDFILE}
-			exit 0
-		fi
 	fi
 	;;

Reply via email to