]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
anvil: Handle crash restarts without failing completely.
authorTimo Sirainen <tss@iki.fi>
Fri, 4 Nov 2011 18:11:39 +0000 (20:11 +0200)
committerTimo Sirainen <tss@iki.fi>
Fri, 4 Nov 2011 18:11:39 +0000 (20:11 +0200)
src/anvil/anvil-connection.c
src/anvil/common.h
src/anvil/main.c
src/master/service-anvil.c
src/master/service-anvil.h
src/master/service-process.c

index 1be5928f87ccd053548806456dfd2b2b3c8fea03..615226a31d0bbe285b8b7a50c4ca3f1e0f5b6171 100644 (file)
@@ -150,8 +150,13 @@ static void anvil_connection_input(void *context)
 
                if (!version_string_verify(line, "anvil",
                                ANVIL_CLIENT_PROTOCOL_MAJOR_VERSION)) {
+                       if (anvil_restarted && (conn->master || conn->fifo)) {
+                               /* old pending data. ignore input until we get
+                                  the handshake. */
+                               return anvil_connection_input(context);
+                       }
                        i_error("Anvil client not compatible with this server "
-                               "(mixed old and new binaries?)");
+                               "(mixed old and new binaries?) %s", line);
                        anvil_connection_destroy(conn);
                        return;
                }
index 2620817b08fb86ca19004adc1fdff37cf6a3e9f3..f9a44bd576d2c265e046025cb6004cd57e856d1c 100644 (file)
@@ -5,5 +5,6 @@
 
 extern struct connect_limit *connect_limit;
 extern struct penalty *penalty;
+extern bool anvil_restarted;
 
 #endif
index cd41b8a9a7c5fa1d01e7515c01be7978298181a2..da0e274cf27872b98b2f0e568291c51876938f77 100644 (file)
 #include "penalty.h"
 #include "anvil-connection.h"
 
+#include <stdlib.h>
 #include <unistd.h>
 
 struct connect_limit *connect_limit;
 struct penalty *penalty;
+bool anvil_restarted;
 static struct io *log_fdpass_io;
 
 static void client_connected(struct master_service_connection *conn)
@@ -65,6 +67,7 @@ int main(int argc, char *argv[])
 
        restrict_access_by_env(NULL, FALSE);
        restrict_access_allow_coredumps(TRUE);
+       anvil_restarted = getenv("ANVIL_RESTARTED") != NULL;
 
        /* delay dying until all of our clients are gone */
        master_service_set_die_with_master(master_service, FALSE);
index 6b38abbd45b4ca40dab723721d4ba9d12029ed3c..a5305efd956c1a7f5ded20e39ac3edd0460a6e3d 100644 (file)
@@ -125,6 +125,7 @@ void service_anvil_process_destroyed(struct service_process *process)
 
        if (service_anvil_global->pid == process->pid)
                service_anvil_global->pid = 0;
+       service_anvil_global->restarted = TRUE;
 }
 
 void service_anvil_send_log_fd(void)
index 9095863dceacf34a54535be5b06305eda24747d7..b749134f62d16eaf811529ae39b9500dad0f7b02 100644 (file)
@@ -17,6 +17,8 @@ struct service_anvil_global {
        struct io *io_blocking, *io_nonblocking;
 
        unsigned int process_count;
+       /* anvil crashed and we're now restarting it */
+       bool restarted;
 };
 
 extern struct service_anvil_global *service_anvil_global;
index 90ad136275537195a86e4e8913b47799ad3056f3..f9ccddde25fee1ba347403f263bcaa651b07dfc0 100644 (file)
@@ -188,6 +188,10 @@ service_process_setup_environment(struct service *service, unsigned int uid)
        master_service_env_clean();
 
        switch (service->type) {
+       case SERVICE_TYPE_ANVIL:
+               if (service_anvil_global->restarted)
+                       env_put("ANVIL_RESTARTED=1");
+               break;
        case SERVICE_TYPE_CONFIG:
                env_put(t_strconcat(MASTER_CONFIG_FILE_ENV"=",
                                    service->config_file_path, NULL));