]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-master: Allow lib_init()/lib_deinit() to be called externally
authorStephan Bosch <stephan.bosch@open-xchange.com>
Thu, 27 Nov 2025 02:08:46 +0000 (03:08 +0100)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Mon, 2 Feb 2026 18:54:43 +0000 (18:54 +0000)
This is needed for using the master service API inside a fuzzer.

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

index 98eedfefcd8089bdf18e009e950bdcd2baf13695..b139990ecf77f19a90cbd9ba2aaced575073a903 100644 (file)
@@ -91,6 +91,7 @@ struct master_service {
        struct master_service_haproxy_conn *haproxy_conns;
        struct event_filter *process_shutdown_filter;
 
+       bool lib_initialized_externally:1;
        bool stopping:1;
        bool keep_environment:1;
        bool options_parsed:1;
index 606f071f8ffdcb4be9b3e6004204219a45af651e..5254b957b98f25de1defa4f2ae9f298c104a4594 100644 (file)
@@ -453,6 +453,7 @@ master_service_init(const char *name, enum master_service_flags flags,
        data_stack_frame_t datastack_frame_id = 0;
        unsigned int count;
        const char *service_configured_name, *value;
+       bool lib_initialized_externally = FALSE;
 
        i_assert(name != NULL);
 
@@ -476,7 +477,10 @@ master_service_init(const char *name, enum master_service_flags flags,
 
        /* NOTE: we start rooted, so keep the code minimal until
           restrict_access_by_env() is called */
-       lib_init();
+       if (lib_is_initialized())
+               lib_initialized_externally = TRUE;
+       else
+               lib_init();
        /* Get the service name from environment. This usually differs from the
           service name parameter if the executable is used for multiple
           services. For example "auth" vs "auth-worker". It can also be a
@@ -501,7 +505,8 @@ master_service_init(const char *name, enum master_service_flags flags,
                datastack_frame_id = t_push("master_service_init");
 
        /* ignore these signals as early as possible */
-       lib_signals_init();
+       if (!lib_initialized_externally)
+               lib_signals_init();
        lib_signals_ignore(SIGPIPE, TRUE);
        lib_signals_ignore(SIGALRM, FALSE);
 
@@ -525,6 +530,7 @@ master_service_init(const char *name, enum master_service_flags flags,
        service->name = i_strdup(name);
        service->configured_name = i_strdup(service_configured_name);
        service->settings_root = settings_root_init();
+       service->lib_initialized_externally = lib_initialized_externally;
 
        master_service_category_name =
                i_strdup_printf("service:%s", service->configured_name);
@@ -1694,16 +1700,20 @@ static void master_service_free(struct master_service **_service)
 void master_service_deinit(struct master_service **_service)
 {
        struct master_service *service = *_service;
+       bool lib_initialized_externally = service->lib_initialized_externally;
 
        master_service_deinit_real(service);
 
-       lib_signals_deinit();
-       /* run atexit callbacks before destroying ioloop */
-       lib_atexit_run();
+       if (!lib_initialized_externally) {
+               lib_signals_deinit();
+               /* run atexit callbacks before destroying ioloop */
+               lib_atexit_run();
+       }
        io_loop_destroy(&service->ioloop);
 
        master_service_free(_service);
-       lib_deinit();
+       if (!lib_initialized_externally)
+               lib_deinit();
 }
 
 void master_service_deinit_forked(struct master_service **_service)