Hi,
I'd like to share two quick'n dirty patches for cyrus-imapd. The first one removes the attempt of setting the open file limit to "unlimited", because -- afaik and speaking of linux -- this is simply not supported. The second patch skips setting ip or tcp flags on unix domain sockets. It bugged me that my logs showed "unable to setsocketopt(IP_TOS) service" and "unable to setsocketopt(TCP_KEEPIDLE)" for operations on uds. Checking for SOCK_STREAM is probably not sufficient. Discussons welcome. Kind regards, Philippe
setting the fd limit to "unlimited" is simply not supported in linux --- cyrus-imapd-2.5.2/master/master.c.setrlimit +++ cyrus-imapd-2.5.2/master/master.c @@ -1875,21 +1875,14 @@ static void limit_fds(rlim_t x) { struct rlimit rl; - rl.rlim_cur = x; - rl.rlim_max = x; - if (setrlimit(RLIMIT_NUMFDS, &rl) < 0) { - syslog(LOG_ERR, "setrlimit: Unable to set file descriptors limit to %ld: %m", x); - #ifdef HAVE_GETRLIMIT if (!getrlimit(RLIMIT_NUMFDS, &rl)) { - syslog(LOG_ERR, "retrying with %ld (current max)", rl.rlim_max); rl.rlim_cur = rl.rlim_max; if (setrlimit(RLIMIT_NUMFDS, &rl) < 0) { syslog(LOG_ERR, "setrlimit: Unable to set file descriptors limit to %ld: %m", x); } } - } if (verbose > 1) { @@ -1897,8 +1890,6 @@ static void limit_fds(rlim_t x) syslog(LOG_DEBUG, "set maximum file descriptors to %ld/%ld", rl.rlim_cur, rl.rlim_max); } -#else - } #endif /* HAVE_GETRLIMIT */ } #else
do not set tcp flags on unix domain sockets --- cyrus-imapd-2.5.3/master/master.c.uds +++ cyrus-imapd-2.5.3/master/master.c @@ -586,12 +586,14 @@ static void service_create(struct servic /* set IP ToS if supported */ #if defined(SOL_IP) && defined(IP_TOS) + if (s->family == AF_INET || s->family == AF_INET6) { r = setsockopt(s->socket, SOL_IP, IP_TOS, (void *) &config_qosmarking, sizeof(config_qosmarking)); if (r < 0) { syslog(LOG_WARNING, "unable to setsocketopt(IP_TOS) service %s/%s: %m", s->name, s->familyname); } + } #endif oldumask = umask((mode_t) 0); /* for linux */ --- cyrus-imapd-2.5.3/master/service.c.uds +++ cyrus-imapd-2.5.3/master/service.c @@ -289,6 +289,8 @@ int main(int argc, char **argv, char **e int reuse_timeout = REUSE_TIMEOUT; int soctype; socklen_t typelen = sizeof(soctype); + struct sockaddr socname; + socklen_t sockaddr_len = sizeof(struct sockaddr); strarray_t newargv = STRARRAY_INITIALIZER; int id; char path[PATH_MAX]; @@ -406,6 +408,13 @@ int main(int argc, char **argv, char **e return 1; } + if (getsockname(LISTEN_FD, &socname, &sockaddr_len) < 0) { + syslog(LOG_ERR, "getsockname failed"); + if (MESSAGE_MASTER_ON_EXIT) + notify_master(STATUS_FD, MASTER_SERVICE_UNAVAILABLE); + return 1; + } + /* figure out what sort of socket this is */ if (getsockopt(LISTEN_FD, SOL_SOCKET, SO_TYPE, (char *) &soctype, &typelen) < 0) { @@ -545,7 +554,7 @@ int main(int argc, char **argv, char **e alarm(0); /* tcp only */ - if(soctype == SOCK_STREAM) { + if(soctype == SOCK_STREAM && socname.sa_family != AF_UNIX) { libwrap_init(&request, service); if (!libwrap_ask(&request, fd)) {