]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
imap: imap_client_hibernate() - Return reason string on failure
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Mon, 24 Aug 2020 16:10:43 +0000 (19:10 +0300)
committerTimo Sirainen <timo.sirainen@open-xchange.com>
Mon, 4 Jan 2021 22:59:38 +0000 (00:59 +0200)
This helps writing a unit test for it.

src/imap/cmd-idle.c
src/imap/imap-client-hibernate.c
src/imap/imap-client.h

index 8a05582d0378d218163feaf285a2eac534562f92..2b31dc714e1f23d75a5ca1172a8aef10552bb173 100644 (file)
@@ -175,11 +175,12 @@ static void idle_add_keepalive_timeout(struct cmd_idle_context *ctx)
 static void idle_hibernate_timeout(struct cmd_idle_context *ctx)
 {
        struct client *client = ctx->client;
+       const char *reason;
 
        i_assert(ctx->sync_ctx == NULL);
        i_assert(!ctx->sync_pending);
 
-       if (imap_client_hibernate(&client)) {
+       if (imap_client_hibernate(&client, &reason)) {
                /* client may be destroyed now */
        } else {
                /* failed - don't bother retrying */
index d3451b1bf626e5485bed67e20f36fad4f68690fa..0709e4a244c4e81917478dcdc0599ba06f49d113 100644 (file)
@@ -203,19 +203,23 @@ imap_hibernate_process_send(struct client *client, const buffer_t *state,
        return 0;
 }
 
-bool imap_client_hibernate(struct client **_client)
+bool imap_client_hibernate(struct client **_client, const char **reason_r)
 {
        struct client *client = *_client;
        buffer_t *state;
        const char *error;
        int ret, fd_notify = -1, fd_hibernate = -1;
 
+       *reason_r = NULL;
+
        if (client->fd_in != client->fd_out) {
                /* we won't try to hibernate stdio clients */
+               *reason_r = "stdio clients can't be hibernated";
                return FALSE;
        }
        if (o_stream_get_buffer_used_size(client->output) > 0) {
                /* wait until we've sent the pending output to client */
+               *reason_r = "output pending to client";
                return FALSE;
        }
 
@@ -233,12 +237,14 @@ bool imap_client_hibernate(struct client **_client)
                        "Couldn't export state: %s (mailbox=%s)", error,
                        client->mailbox == NULL ? "" :
                        mailbox_get_vname(client->mailbox));
+               *reason_r = error;
        } else if (ret == 0) {
                e->add_str("error", error);
                e_debug(e->event(), "Couldn't hibernate imap client: "
                        "Couldn't export state: %s (mailbox=%s)", error,
                        client->mailbox == NULL ? "" :
                        mailbox_get_vname(client->mailbox));
+               *reason_r = error;
        }
        if (ret > 0 && client->mailbox != NULL) {
                fd_notify = mailbox_watch_extract_notify_fd(client->mailbox,
@@ -248,6 +254,7 @@ bool imap_client_hibernate(struct client **_client)
                        e_debug(e->event(), "Couldn't hibernate imap client: "
                                "Couldn't extract notifications fd: %s",
                                error);
+                       *reason_r = error;
                        ret = -1;
                }
        }
@@ -257,6 +264,7 @@ bool imap_client_hibernate(struct client **_client)
                        e->add_str("error", error);
                        e_error(e->event(),
                                "Couldn't hibernate imap client: %s", error);
+                       *reason_r = error;
                        ret = -1;
                }
        }
index f2ffe0d7c9163baba56109eb9328a46b96afcd9d..4e591d5c7c1527c44831eb09b2658c58c5ab8aa3 100644 (file)
@@ -323,8 +323,9 @@ enum mailbox_feature client_enabled_mailbox_features(struct client *client);
 const char *const *client_enabled_features(struct client *client);
 
 /* Send client processing to imap-idle process. If successful, returns TRUE
-   and destroys the client. */
-bool imap_client_hibernate(struct client **client);
+   and destroys the client. If hibernation failed, the exact reason is
+   returned (mainly for unit tests). */
+bool imap_client_hibernate(struct client **client, const char **reason_r);
 
 struct imap_search_update *
 client_search_update_lookup(struct client *client, const char *tag,