[dovecot-cvs] dovecot/src/master mail-process.c, 1.96.2.19, 1.96.2.20

tss at dovecot.org tss at dovecot.org
Thu Mar 22 00:52:19 EET 2007


Update of /var/lib/cvs/dovecot/src/master
In directory talvi:/tmp/cvs-serv25089

Modified Files:
      Tag: branch_1_0
	mail-process.c 
Log Message:
Use alarm() to make sure that chdir() returns in 30 seconds (NFS..). Also if
chdir() failed, we could have used wrong errno in the checks.



Index: mail-process.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/master/mail-process.c,v
retrieving revision 1.96.2.19
retrieving revision 1.96.2.20
diff -u -d -r1.96.2.19 -r1.96.2.20
--- mail-process.c	21 Mar 2007 20:31:11 -0000	1.96.2.19
+++ mail-process.c	21 Mar 2007 22:52:17 -0000	1.96.2.20
@@ -24,6 +24,12 @@
 #  include <sys/resource.h>
 #endif
 
+/* Timeout chdir() completely after this many seconds */
+#define CHDIR_TIMEOUT 30
+/* Give a warning about chdir() taking a while if it took longer than this
+   many seconds to finish. */
+#define CHDIR_WARN_SECS 10
+
 static unsigned int mail_process_count = 0;
 
 static bool validate_uid_gid(struct settings *set, uid_t uid, gid_t gid,
@@ -431,8 +437,8 @@
 	uid_t uid;
 	gid_t gid;
 	array_t ARRAY_DEFINE(extra_args, const char *);
-	unsigned int i, count;
-	int ret, log_fd, nice;
+	unsigned int i, count, left;
+	int ret, log_fd, nice, chdir_errno;
 	bool home_given, nfs_check;
 
 	/* FIXME: per-group? */
@@ -604,7 +610,14 @@
 			if (seteuid(uid) < 0)
 				i_fatal("seteuid(%s) failed: %m", dec2str(uid));
 		}
+
+		alarm(CHDIR_TIMEOUT);
 		ret = chdir(full_home_dir);
+		chdir_errno = errno;
+		if ((left = alarm(0)) < CHDIR_TIMEOUT - CHDIR_WARN_SECS) {
+			i_warning("chdir(%s) blocked for %u secs",
+				  full_home_dir, CHDIR_TIMEOUT - left);
+		}
 
 		/* Change UID back. No need to change GID back, it doesn't
 		   really matter. */
@@ -615,8 +628,9 @@
 		   trying to chroot anywhere, fallback to /tmp as the mails
 		   could be stored elsewhere. The ENOTDIR check is mostly for
 		   /dev/null home directory. */
-		if (ret < 0 && ((errno != ENOENT && errno != ENOTDIR) ||
-				*chroot_dir != '\0')) {
+		if (ret < 0 && (*chroot_dir != '\0' ||
+				!(ENOTFOUND(chdir_errno) ||
+				  chdir_errno == EINTR))) {
 			i_fatal("chdir(%s) failed with uid %s: %m",
 				full_home_dir, dec2str(uid));
 		}



More information about the dovecot-cvs mailing list