]> 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>
Fri, 6 Nov 2020 15:08:05 +0000 (17:08 +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 328d951b3bc3df9e858871ca6ac49108c695e248..e5783c2a0d7e7a7cf308fda1fd7661580f98fc59 100644 (file)
@@ -179,11 +179,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 a68ac3cdbde5c012e960d215732afebdafd2c9ce..cb56eb31036ca6a72d7577425b883548833793cf 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 150ad5d1b8fdf48eac81d2ba7fa2eae5f23908b2..868436352c6f367db58b84a339f2371ce8dc0656 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,