dovecot-2.2: virtual plugin: Auto-close mailboxes by hooking int...

dovecot at dovecot.org dovecot at dovecot.org
Thu Sep 24 16:28:32 UTC 2015


details:   http://hg.dovecot.org/dovecot-2.2/rev/055d1e2d894c
changeset: 19215:055d1e2d894c
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Sep 24 19:27:10 2015 +0300
description:
virtual plugin: Auto-close mailboxes by hooking into backend's mailbox_open()
This is a more reliable way of doing it. The earlier version had problems
that all the backend mailboxes could be opened when doing a search on the
virtual mailbox (for getting the GUID of the mailboxes).

diffstat:

 src/plugins/virtual/virtual-config.c  |   1 +
 src/plugins/virtual/virtual-plugin.c  |   6 +++++
 src/plugins/virtual/virtual-storage.c |  38 ++++++++++++++++------------------
 src/plugins/virtual/virtual-storage.h |   7 ++++-
 src/plugins/virtual/virtual-sync.c    |   9 ++-----
 5 files changed, 33 insertions(+), 28 deletions(-)

diffs (159 lines):

diff -r 4b5b8e6a4a32 -r 055d1e2d894c src/plugins/virtual/virtual-config.c
--- a/src/plugins/virtual/virtual-config.c	Thu Sep 24 19:07:12 2015 +0300
+++ b/src/plugins/virtual/virtual-config.c	Thu Sep 24 19:27:10 2015 +0300
@@ -138,6 +138,7 @@
 
 	/* new mailbox. the search args are added to it later. */
 	bbox = p_new(ctx->pool, struct virtual_backend_box, 1);
+	bbox->virtual_mbox = ctx->mbox;
 	if (strcasecmp(line, "INBOX") == 0)
 		line = "INBOX";
 	bbox->name = p_strdup(ctx->pool, line);
diff -r 4b5b8e6a4a32 -r 055d1e2d894c src/plugins/virtual/virtual-plugin.c
--- a/src/plugins/virtual/virtual-plugin.c	Thu Sep 24 19:07:12 2015 +0300
+++ b/src/plugins/virtual/virtual-plugin.c	Thu Sep 24 19:27:10 2015 +0300
@@ -7,12 +7,18 @@
 
 const char *virtual_plugin_version = DOVECOT_ABI_VERSION;
 
+static struct mail_storage_hooks acl_mail_storage_hooks = {
+	.mailbox_opened = virtual_mailbox_opened_hook
+};
+
 void virtual_plugin_init(struct module *module ATTR_UNUSED)
 {
 	mail_storage_class_register(&virtual_storage);
+	mail_storage_hooks_add(module, &acl_mail_storage_hooks);
 }
 
 void virtual_plugin_deinit(void)
 {
 	mail_storage_class_unregister(&virtual_storage);
+	mail_storage_hooks_remove(&acl_mail_storage_hooks);
 }
diff -r 4b5b8e6a4a32 -r 055d1e2d894c src/plugins/virtual/virtual-storage.c
--- a/src/plugins/virtual/virtual-storage.c	Thu Sep 24 19:07:12 2015 +0300
+++ b/src/plugins/virtual/virtual-storage.c	Thu Sep 24 19:27:10 2015 +0300
@@ -182,6 +182,7 @@
 	mailbox = bbox->name;
 	ns = mail_namespace_find(user->namespaces, mailbox);
 	bbox->box = mailbox_alloc(ns->list, mailbox, flags);
+	MODULE_CONTEXT_SET(bbox->box, virtual_storage_module, bbox);
 
 	if (mailbox_exists(bbox->box, TRUE, &existence) < 0)
 		return virtual_backend_box_open_failed(mbox, bbox);
@@ -322,10 +323,17 @@
 	return FALSE;
 }
 
-void virtual_backend_box_opened(struct virtual_mailbox *mbox,
-				struct virtual_backend_box *bbox)
+void virtual_mailbox_opened_hook(struct mailbox *box)
 {
+	struct virtual_backend_box *bbox = VIRTUAL_CONTEXT(box);
+	struct virtual_mailbox *mbox;
+
+	if (bbox == NULL) {
+		/* not a backend for a virtual mailbox */
+		return;
+	}
 	i_assert(!bbox->open_tracked);
+	mbox = bbox->virtual_mbox;
 
 	/* the backend mailbox was already opened. if we didn't get here
 	   from virtual_backend_box_open() we may need to close a mailbox */
@@ -351,16 +359,14 @@
 	       virtual_backend_box_close_any_except(mbox, bbox))
 		;
 
-	if (mailbox_open(bbox->box) < 0)
-		return -1;
-	virtual_backend_box_opened(mbox, bbox);
-	return 0;
+	return mailbox_open(bbox->box);
 }
 
 void virtual_backend_box_close(struct virtual_mailbox *mbox,
 			       struct virtual_backend_box *bbox)
 {
 	i_assert(bbox->box->opened);
+	i_assert(bbox->open_tracked);
 
 	if (bbox->search_result != NULL)
 		mailbox_search_result_free(&bbox->search_result);
@@ -370,21 +376,13 @@
 		mail_search_args_deinit(bbox->search_args);
 		bbox->search_args_initialized = FALSE;
 	}
-	if (bbox->open_tracked) {
-		i_assert(mbox->backends_open_count > 0);
-		mbox->backends_open_count--;
-		bbox->open_tracked = FALSE;
+	i_assert(mbox->backends_open_count > 0);
+	mbox->backends_open_count--;
+	bbox->open_tracked = FALSE;
 
-		DLLIST2_REMOVE_FULL(&mbox->open_backend_boxes_head,
-				    &mbox->open_backend_boxes_tail, bbox,
-				    prev_open, next_open);
-	} else {
-		/* mailbox can be leaked outside our code via
-		   virtual_get_virtual_backend_boxes() and it could have
-		   been opened there. FIXME: maybe we could hook into the
-		   backend open/close functions to do the tracking and
-		   auto-closing. */
-	}
+	DLLIST2_REMOVE_FULL(&mbox->open_backend_boxes_head,
+			    &mbox->open_backend_boxes_tail, bbox,
+			    prev_open, next_open);
 	mailbox_close(bbox->box);
 }
 
diff -r 4b5b8e6a4a32 -r 055d1e2d894c src/plugins/virtual/virtual-storage.h
--- a/src/plugins/virtual/virtual-storage.h	Thu Sep 24 19:07:12 2015 +0300
+++ b/src/plugins/virtual/virtual-storage.h	Thu Sep 24 19:27:10 2015 +0300
@@ -62,6 +62,9 @@
 };
 
 struct virtual_backend_box {
+	union mailbox_module_context module_ctx;
+	struct virtual_mailbox *virtual_mbox;
+
 	/* linked list for virtual_mailbox->open_backend_boxes_{head,tail} */
 	struct virtual_backend_box *prev_open, *next_open;
 
@@ -188,8 +191,6 @@
 			       struct virtual_backend_box *bbox);
 void virtual_backend_box_accessed(struct virtual_mailbox *mbox,
 				  struct virtual_backend_box *bbox);
-void virtual_backend_box_opened(struct virtual_mailbox *mbox,
-				struct virtual_backend_box *bbox);
 void virtual_backend_box_sync_mail_unset(struct virtual_backend_box *bbox);
 
 struct mail_search_context *
@@ -224,4 +225,6 @@
 
 void virtual_box_copy_error(struct mailbox *dest, struct mailbox *src);
 
+void virtual_mailbox_opened_hook(struct mailbox *box);
+
 #endif
diff -r 4b5b8e6a4a32 -r 055d1e2d894c src/plugins/virtual/virtual-sync.c
--- a/src/plugins/virtual/virtual-sync.c	Thu Sep 24 19:07:12 2015 +0300
+++ b/src/plugins/virtual/virtual-sync.c	Thu Sep 24 19:27:10 2015 +0300
@@ -1131,12 +1131,9 @@
 			bbox->open_failed = FALSE;
 		}
 
-		ret = mailbox_get_status(bbox->box, STATUS_UIDVALIDITY |
-					 STATUS_UIDNEXT | STATUS_HIGHESTMODSEQ,
-					 &status);
-		if (!bbox_index_opened && bbox->box->opened)
-			virtual_backend_box_opened(ctx->mbox, bbox);
-		if (ret < 0) {
+		if (mailbox_get_status(bbox->box, STATUS_UIDVALIDITY |
+				       STATUS_UIDNEXT | STATUS_HIGHESTMODSEQ,
+				       &status) < 0) {
 			if (mailbox_get_last_mail_error(bbox->box) != MAIL_ERROR_NOTFOUND)
 				return -1;
 			/* mailbox was deleted */


More information about the dovecot-cvs mailing list