changeset 20558:df08a7bc2b0d

lib-storage: Added mail_get_stream_because() and mail_get_hdr_stream_because() With mail_debug=yes each mail access is now logged with a reason. This can be helpful when figuring out why something isn't in dovecot.index.cache.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Mon, 25 Jul 2016 14:16:39 -0400
parents 31d7157aa0b1
children ad24699d4138
files src/lib-storage/index/index-mail.c src/lib-storage/mail-storage-private.h src/lib-storage/mail-storage.h src/lib-storage/mail.c
diffstat 4 files changed, 57 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-storage/index/index-mail.c	Tue Aug 02 21:16:15 2016 +0300
+++ b/src/lib-storage/index/index-mail.c	Mon Jul 25 14:16:39 2016 -0400
@@ -1077,9 +1077,11 @@
 			return;
 	}
 	mail_storage_set_critical(_mail->box->storage,
-		"read(%s) failed: %s (uid=%u, box=%s)",
+		"read(%s) failed: %s (uid=%u, box=%s, read reason=%s)",
 		i_stream_get_name(input), i_stream_get_error(input),
-		_mail->uid, mailbox_get_vname(_mail->box));
+		_mail->uid, mailbox_get_vname(_mail->box),
+		mail->mail.get_stream_reason == NULL ? "" :
+		mail->mail.get_stream_reason);
 }
 
 static int index_mail_parse_body(struct index_mail *mail,
@@ -1142,6 +1144,14 @@
 	bool has_nuls;
 	int ret;
 
+	if (_mail->box->storage->user->mail_debug &&
+	    mail->mail.get_stream_reason != NULL &&
+	    mail->mail.get_stream_reason[0] != '\0') {
+		i_debug("Mailbox %s: Opened mail UID=%u because: %s",
+			_mail->box->vname, _mail->uid,
+			mail->mail.get_stream_reason);
+	}
+
 	if (!data->initialized_wrapper_stream &&
 	    _mail->transaction->stats_track) {
 		input = i_stream_create_mail(_mail, data->stream,
--- a/src/lib-storage/mail-storage-private.h	Tue Aug 02 21:16:15 2016 +0300
+++ b/src/lib-storage/mail-storage-private.h	Mon Jul 25 14:16:39 2016 -0400
@@ -504,6 +504,8 @@
 
 	pool_t pool, data_pool;
 	ARRAY(union mail_module_context *) module_contexts;
+
+	const char *get_stream_reason;
 };
 
 struct mailbox_list_context {
--- a/src/lib-storage/mail-storage.h	Tue Aug 02 21:16:15 2016 +0300
+++ b/src/lib-storage/mail-storage.h	Mon Jul 25 14:16:39 2016 -0400
@@ -857,10 +857,21 @@
 int mail_get_stream(struct mail *mail, struct message_size *hdr_size,
 		    struct message_size *body_size, struct istream **stream_r)
 	ATTR_NULL(2, 3);
+/* Same as mail_get_stream(), but specify a reason why the mail is being read.
+   This can be useful for debugging purposes. */
+int mail_get_stream_because(struct mail *mail, struct message_size *hdr_size,
+			    struct message_size *body_size,
+			    const char *reason, struct istream **stream_r)
+	ATTR_NULL(2, 3);
 /* Similar to mail_get_stream(), but the stream may or may not contain the
    message body. */
 int mail_get_hdr_stream(struct mail *mail, struct message_size *hdr_size,
 			struct istream **stream_r) ATTR_NULL(2);
+/* Same as mail_get_hdr_stream(), but specify a reason why the header is being
+   read. This can be useful for debugging purposes. */
+int mail_get_hdr_stream_because(struct mail *mail,
+				struct message_size *hdr_size,
+				const char *reason, struct istream **stream_r);
 /* Returns the message part's body decoded to 8bit binary. If the
    Content-Transfer-Encoding isn't supported, returns -1 and sets error to
    MAIL_ERROR_CONVERSION. If the part refers to a multipart, all of its
--- a/src/lib-storage/mail.c	Tue Aug 02 21:16:15 2016 +0300
+++ b/src/lib-storage/mail.c	Mon Jul 25 14:16:39 2016 -0400
@@ -247,21 +247,13 @@
 int mail_get_stream(struct mail *mail, struct message_size *hdr_size,
 		    struct message_size *body_size, struct istream **stream_r)
 {
-	struct mail_private *p = (struct mail_private *)mail;
-	int ret;
-
-	if (mail->lookup_abort != MAIL_LOOKUP_ABORT_NEVER) {
-		mail_set_aborted(mail);
-		return -1;
-	}
-	T_BEGIN {
-		ret = p->v.get_stream(mail, TRUE, hdr_size, body_size, stream_r);
-	} T_END;
-	return ret;
+	return mail_get_stream_because(mail, hdr_size, body_size,
+				       "mail stream", stream_r);
 }
 
-int mail_get_hdr_stream(struct mail *mail, struct message_size *hdr_size,
-			struct istream **stream_r)
+int mail_get_stream_because(struct mail *mail, struct message_size *hdr_size,
+			    struct message_size *body_size,
+			    const char *reason, struct istream **stream_r)
 {
 	struct mail_private *p = (struct mail_private *)mail;
 	int ret;
@@ -271,7 +263,34 @@
 		return -1;
 	}
 	T_BEGIN {
+		p->get_stream_reason = reason;
+		ret = p->v.get_stream(mail, TRUE, hdr_size, body_size, stream_r);
+		p->get_stream_reason = "";
+	} T_END;
+	return ret;
+}
+
+int mail_get_hdr_stream(struct mail *mail, struct message_size *hdr_size,
+			struct istream **stream_r)
+{
+	return mail_get_hdr_stream_because(mail, hdr_size, "header stream", stream_r);
+}
+
+int mail_get_hdr_stream_because(struct mail *mail,
+				struct message_size *hdr_size,
+				const char *reason, struct istream **stream_r)
+{
+	struct mail_private *p = (struct mail_private *)mail;
+	int ret;
+
+	if (mail->lookup_abort != MAIL_LOOKUP_ABORT_NEVER) {
+		mail_set_aborted(mail);
+		return -1;
+	}
+	T_BEGIN {
+		p->get_stream_reason = reason;
 		ret = p->v.get_stream(mail, FALSE, hdr_size, NULL, stream_r);
+		p->get_stream_reason = "";
 	} T_END;
 	return ret;
 }