From: Timo Sirainen Date: Sat, 17 Dec 2022 19:50:45 +0000 (+0200) Subject: lib-master: Keep the config always mmap()ed X-Git-Tag: 2.4.0~3055 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=59d7e9d435662a11a3f9e432cac516dbea31369a;p=thirdparty%2Fdovecot%2Fcore.git lib-master: Keep the config always mmap()ed The config fd is no longer necessary to keep open. --- diff --git a/src/lib-master/master-service-private.h b/src/lib-master/master-service-private.h index 1052370e19..9a3d59fe66 100644 --- a/src/lib-master/master-service-private.h +++ b/src/lib-master/master-service-private.h @@ -38,7 +38,8 @@ struct master_service { const char *version_string; char *config_path; ARRAY_TYPE(const_string) config_overrides; - int config_fd; + void *config_mmap_base; + size_t config_mmap_size; int syslog_facility; data_stack_frame_t datastack_frame_id; diff --git a/src/lib-master/master-service-settings.c b/src/lib-master/master-service-settings.c index 2ffd4d9f5c..45354dcbcd 100644 --- a/src/lib-master/master-service-settings.c +++ b/src/lib-master/master-service-settings.c @@ -548,10 +548,8 @@ int master_service_settings_read(struct master_service *service, i_zero(output_r); output_r->config_fd = -1; - if (service->config_fd != -1 && !input->reload_config) { + if (service->config_mmap_base != NULL && !input->reload_config) { /* config was already read once */ - fd = service->config_fd; - path = ""; } else if ((value = getenv(DOVECOT_CONFIG_FD_ENV)) != NULL) { /* doveconf -F parameter already executed us back. The configuration is in DOVECOT_CONFIG_FD. */ @@ -568,6 +566,27 @@ int master_service_settings_read(struct master_service *service, return -1; } } + if (fd != -1) { + if (service->config_mmap_base != NULL) { + i_assert(input->reload_config); + if (munmap(service->config_mmap_base, + service->config_mmap_size) < 0) + i_error("munmap() failed: %m"); + } + + service->config_mmap_base = + mmap_ro_file(fd, &service->config_mmap_size); + if (service->config_mmap_base == MAP_FAILED) + i_fatal("Failed to read config: mmap(%s) failed: %m", path); + if (service->config_mmap_size == 0) + i_fatal("Failed to read config: %s file size is empty", path); + + if (input->return_config_fd) + output_r->config_fd = fd; + else + i_close_fd(&fd); + env_remove(DOVECOT_CONFIG_FD_ENV); + } if (service->set_pool != NULL) { if (service->set_parser != NULL) @@ -604,46 +623,22 @@ int master_service_settings_read(struct master_service *service, array_front(&all_roots), array_count(&all_roots), SETTINGS_PARSER_FLAG_IGNORE_UNKNOWN_KEYS); - /* fd is unset only if MASTER_SERVICE_FLAG_NO_CONFIG_SETTINGS is used */ - if (fd != -1) { - size_t mmap_size; - void *mmap_base = mmap_ro_file(fd, &mmap_size); - if (mmap_base == MAP_FAILED) - i_fatal("mmap(%s) failed: %m", path); - if (mmap_size == 0) - i_fatal("%s file size is empty", path); - + /* config_mmap_base is NULL only if + MASTER_SERVICE_FLAG_NO_CONFIG_SETTINGS is used */ + if (service->config_mmap_base != NULL) { ret = master_service_settings_read_mmap(parser, event, - mmap_base, mmap_size, - output_r, error_r); - if (munmap(mmap_base, mmap_size) < 0) - i_fatal("munmap(%s) failed: %m", path); + service->config_mmap_base, service->config_mmap_size, + output_r, error_r); if (ret < 0) { if (getenv(DOVECOT_CONFIG_FD_ENV) != NULL) { i_fatal("Failed to parse config from fd %d: %s", fd, *error_r); } - i_close_fd(&fd); settings_parser_unref(&parser); event_unref(&event); return -1; } - - if (input->return_config_fd) { - output_r->config_fd = dup(fd); - if (output_r->config_fd == -1) - i_fatal("dup(%s) failed: %m", path); - } - if (input->config_path == NULL) { - i_assert(service->config_fd == -1 || - service->config_fd == fd); - service->config_fd = fd; - fd_close_on_exec(service->config_fd, TRUE); - } else { - i_close_fd(&fd); - } - env_remove(DOVECOT_CONFIG_FD_ENV); } event_unref(&event); diff --git a/src/lib-master/master-service.c b/src/lib-master/master-service.c index 73f5e327ed..932d10a0f4 100644 --- a/src/lib-master/master-service.c +++ b/src/lib-master/master-service.c @@ -12,6 +12,7 @@ #include "str.h" #include "strescape.h" #include "env-util.h" +#include "mmap-util.h" #include "home-expand.h" #include "process-title.h" #include "time-util.h" @@ -516,7 +517,6 @@ master_service_init(const char *name, enum master_service_flags flags, service->flags = flags; service->ioloop = io_loop_create(); service->service_count_left = UINT_MAX; - service->config_fd = -1; service->datastack_frame_id = datastack_frame_id; service->config_path = i_strdup(getenv(MASTER_CONFIG_FILE_ENV)); @@ -1521,7 +1521,6 @@ static void master_service_deinit_real(struct master_service **_service) if (service->stats_client != NULL) stats_client_deinit(&service->stats_client); - i_close_fd(&service->config_fd); timeout_remove(&service->to_overflow_call); timeout_remove(&service->to_die); timeout_remove(&service->to_overflow_state); @@ -1535,6 +1534,11 @@ static void master_service_deinit_real(struct master_service **_service) settings_parser_unref(&service->set_parser); pool_unref(&service->set_pool); } + if (service->config_mmap_base != NULL) { + if (munmap(service->config_mmap_base, + service->config_mmap_size) < 0) + i_error("munmap() failed: %m"); + } i_free(master_service_category_name); master_service_category.name = NULL; event_unregister_callback(master_service_event_callback);