[Dovecot] Dovecot-2.1.14 - pop3 processes always hangs forever - another follow-up

Axel Luttgens AxelLuttgens at swing.be
Mon Feb 18 18:41:24 EET 2013


Le 18 févr. 2013 à 10:28, Axel Luttgens a écrit :

> [...]
> 
> It seems it could be easily back ported to 2.1.x.
> I'll try and report back here.

Hello Timo,

Please find hereafter a proposal based on 2.1.4.
Tested here, no hangs anymore with virtual uids/gids.

I'm just wondering about the call to hostpid_init() at line 364 of master/main.c, the one related to a config reload; since provisions seem to have been made for taking a possible hostname change into account, wouldn't it be needed to unset the environment variables there?

Axel


--- src/lib/hostpid.c.original	2013-02-18 12:46:25.000000000 +0100
+++ src/lib/hostpid.c	2013-02-18 17:18:32.000000000 +0100
@@ -3,9 +3,12 @@
 #include "lib.h"
 #include "hostpid.h"
 
+#include <stdlib.h>
 #include <unistd.h>
 #include <netdb.h>
 
+#define HOSTNAME_DISALLOWED_CHARS "/\r\n\t"
+
 const char *my_hostname = NULL;
 const char *my_pid = NULL;
 
@@ -15,13 +18,19 @@
 {
 	static char hostname[256], pid[MAX_INT_STRLEN];
 
-	if (gethostname(hostname, sizeof(hostname)-1) == -1)
-		i_strocpy(hostname, "unknown", sizeof(hostname));
-	hostname[sizeof(hostname)-1] = '\0';
-	my_hostname = hostname;
+	/* Children should find MY_HOSTNAME_ENV set by master process.	*/
+	/* Only master process should have to call gethostname() once.	*/
+	my_hostname = getenv(MY_HOSTNAME_ENV);
+	if (my_hostname == NULL) {
+		if (gethostname(hostname, sizeof(hostname)-1) < 0)
+			i_fatal("gethostname() failed: %m");
+		hostname[sizeof(hostname)-1] = '\0';
+		my_hostname = hostname;
+	}
 
-	if (strchr(hostname, '/') != NULL)
-		i_fatal("Invalid system hostname: %s", hostname);
+	if (my_hostname[0] == '\0' ||
+			strcspn(my_hostname, HOSTNAME_DISALLOWED_CHARS) != strlen(my_hostname))
+		i_error("Invalid system hostname: '%s'", my_hostname);
 
 	/* allow calling hostpid_init() multiple times to reset hostname */
 	i_free_and_null(my_domain);
@@ -35,12 +44,17 @@
 	struct hostent *hent;
 	const char *name;
 
+	/* Children should find MY_HOSTDOMAIN_ENV set by master process.	*/
+	/* Only master process should have to call gethostbyname() once.	*/
 	if (my_domain == NULL) {
-		hent = gethostbyname(my_hostname);
-		name = hent != NULL ? hent->h_name : NULL;
+		name = getenv(MY_HOSTDOMAIN_ENV);
 		if (name == NULL) {
-			/* failed, use just the hostname */
-			name = my_hostname;
+			hent = gethostbyname(my_hostname);
+			name = hent != NULL ? hent->h_name : NULL;
+			if (name == NULL) {
+				/* failed, use just the hostname */
+				name = my_hostname;
+			}
 		}
 		my_domain = i_strdup(name);
 	}

--- src/lib/hostpid.h.original	2013-02-18 13:13:44.000000000 +0100
+++ src/lib/hostpid.h	2013-02-18 13:21:24.000000000 +0100
@@ -11,5 +11,10 @@
    hostname. */
 const char *my_hostdomain(void);
 
+/* When set, these environments override above my_hostname and static my_domain.	*/
+/* Master process normally sets these to child processes.							*/
+#define MY_HOSTNAME_ENV "DOVECOT_HOSTNAME"
+#define MY_HOSTDOMAIN_ENV "DOVECOT_HOSTDOMAIN"
+
 #endif
 
--- src/master/service-process.c.original	2013-02-18 13:24:23.000000000 +0100
+++ src/master/service-process.c	2013-02-18 13:39:15.000000000 +0100
@@ -234,6 +234,8 @@
 					service->set->service_count));
 	}
 	env_put(t_strdup_printf(MASTER_UID_ENV"=%u", uid));
+	env_put(t_strdup_printf(MY_HOSTNAME_ENV"=%s", my_hostname));
+	env_put(t_strdup_printf(MY_HOSTDOMAIN_ENV"=%s", my_hostdomain()));
 
 	if (!service->set->master_set->version_ignore)
 		env_put(MASTER_DOVECOT_VERSION_ENV"="PACKAGE_VERSION);





More information about the dovecot mailing list