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);