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
#include
#include
+#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);