]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-master: Keep the config always mmap()ed
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Sat, 17 Dec 2022 19:50:45 +0000 (21:50 +0200)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Fri, 27 Jan 2023 13:01:47 +0000 (13:01 +0000)
The config fd is no longer necessary to keep open.

src/lib-master/master-service-private.h
src/lib-master/master-service-settings.c
src/lib-master/master-service.c

index 1052370e198a7bf260968652e81bf3fce1b9ae02..9a3d59fe662b3c6363bf69560d8741a87fe330a8 100644 (file)
@@ -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;
 
index 2ffd4d9f5c366d5c2ed548ac77f99f396eabc0ad..45354dcbcda2b744ca191d4d51eb9b70dc4691a9 100644 (file)
@@ -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 = "<config fd>";
        } 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(<config>) 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);
 
index 73f5e327ed70528c3335033d3bfe8579bd30486e..932d10a0f4176e5d4d8c9bc3dfbe5fecb6dfbd07 100644 (file)
@@ -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(<config>) failed: %m");
+       }
        i_free(master_service_category_name);
        master_service_category.name = NULL;
        event_unregister_callback(master_service_event_callback);