master-service.c revision 08c518f050eb243cd35ad5c10027cf1720edc503
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen/* Copyright (c) 2005-2015 Dovecot authors, see the included COPYING file */
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen#define DEFAULT_CONFIG_FILE_PATH SYSCONFDIR"/dovecot.conf"
63a61b7a739ae0f3f520215137d9c50f94d0f34fTimo Sirainen/* getenv(MASTER_CONFIG_FILE_ENV) provides path to configuration file/socket */
63a61b7a739ae0f3f520215137d9c50f94d0f34fTimo Sirainen/* getenv(MASTER_DOVECOT_VERSION_ENV) provides master's version number */
63a61b7a739ae0f3f520215137d9c50f94d0f34fTimo Sirainen#define MASTER_DOVECOT_VERSION_ENV "DOVECOT_VERSION"
63a61b7a739ae0f3f520215137d9c50f94d0f34fTimo Sirainen/* when we're full of connections, how often to check if login state has
63a61b7a739ae0f3f520215137d9c50f94d0f34fTimo Sirainen changed. we normally notice it immediately because of a signal, so this is
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen just a fallback against race conditions. */
8af07808ba203f8709e2ff9eaf2291e1c4a4d53dTimo Sirainen/* If die callback hasn't managed to stop the service for this many seconds,
992a13add4eea0810e4db0f042a595dddf85536aTimo Sirainen#define MASTER_SERVICE_DIE_TIMEOUT_MSECS (30*1000)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenstatic void master_service_io_listeners_close(struct master_service *service);
7f773564b94e6054a40d3785cb63c29f1e4d4deeTimo Sirainenstatic void master_service_refresh_login_state(struct master_service *service);
7f773564b94e6054a40d3785cb63c29f1e4d4deeTimo Sirainenmaster_status_send(struct master_service *service, bool important_update);
7f773564b94e6054a40d3785cb63c29f1e4d4deeTimo Sirainen return "c:i:ko:OL";
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenstatic void sig_die(const siginfo_t *si, void *context)
01cbf4ac5d44137ab434791be7f838d98d0fcf3bTimo Sirainen /* SIGINT comes either from master process or from keyboard. we don't
01cbf4ac5d44137ab434791be7f838d98d0fcf3bTimo Sirainen want to log it in either case.*/
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen i_warning("Killed with signal %d (by pid=%s uid=%s code=%s)",
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen lib_signal_code_to_str(si->si_signo, si->si_code));
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen } else if ((service->flags & MASTER_SERVICE_FLAG_NO_IDLE_DIE) != 0) {
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen /* never die when idling */
01cbf4ac5d44137ab434791be7f838d98d0fcf3bTimo Sirainen } else if ((service->flags & MASTER_SERVICE_FLAG_STANDALONE) == 0) {
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen /* SIGINT came from master. die only if we're not handling
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen any clients currently. */
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen /* we don't want to die - send a notification to master
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen so it doesn't think we're ignoring it completely. */
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainensig_state_changed(const siginfo_t *si ATTR_UNUSED, void *context)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenstatic void master_service_verify_version_string(struct master_service *service)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen strcmp(service->version_string, PACKAGE_VERSION) != 0) {
992a13add4eea0810e4db0f042a595dddf85536aTimo Sirainen "(if you don't care, set version_ignore=yes)",
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenstatic void master_service_init_socket_listeners(struct master_service *service)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen unsigned int i;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen i_new(struct master_service_listener, service->socket_count);
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen struct master_service_listener *l = &service->listeners[i];
b2ecd50bb98c44816cb07c17aa17fae2b425f941Timo Sirainen value = getenv(t_strdup_printf("SOCKET%u_SETTINGS", i));
18565c69efcd7db003dbf27cf625ed822e889fb1Timo Sirainen const char *const *settings =
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen } else if (strcmp(*settings, "haproxy") == 0) {
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen service->want_ssl_settings = have_ssl_sockets ||
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen (service->flags & MASTER_SERVICE_FLAG_USE_SSL_SETTINGS) != 0;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenmaster_service_init(const char *name, enum master_service_flags flags,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen int *argc, char **argv[], const char *getopt_str)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen unsigned int count;
const char *value;
#ifdef DEBUG
count = 0;
non-setuid/gid binaries..) */
lib_init();
T_BEGIN {
} T_END;
count == 0)
count > 0)
count > 0)
count > 0)
return service;
return FALSE;
return TRUE;
const char *prefix)
int facility;
&facility))
bool set)
void (*callback)(void))
bool (*callback)(void))
which dovecot.conf we even want to read! so we must use the
const char *path;
switch (opt) {
return FALSE;
return TRUE;
service);
void master_service_env_clean(void)
env_clean();
else T_BEGIN {
} T_END;
unsigned int client_limit)
unsigned int used;
unsigned int count)
unsigned int used;
int listen_fd)
void (*callback)(void))
unsigned int current_count;
if (current_count == 0)
if (ret < 0) {
} else if (ret == 0)
switch (state) {
service);
case MASTER_LOGIN_STATE_FULL:
int ret;
if (ret < 0)
lib_deinit();
if (l->haproxy)
return TRUE;
return TRUE;
return FALSE;
} else if (ret >= 0) {
} else if (important_update) {
bool important_update;
used_count));
} T_END;
!important_update) {
service);
unsigned major_version)
unsigned int minor_version;
unsigned major_version,
unsigned int *minor_version_r)
bool ret;
return FALSE;
return FALSE;
T_BEGIN {
if (p == NULL)
} T_END;
return ret;