dovecot-2.0: lib-master: Added support for caching config lookups.

dovecot at dovecot.org dovecot at dovecot.org
Sat Feb 20 17:17:29 EET 2010


details:   http://hg.dovecot.org/dovecot-2.0/rev/bf4822f0846b
changeset: 10793:bf4822f0846b
user:      Timo Sirainen <tss at iki.fi>
date:      Sat Feb 20 17:16:41 2010 +0200
description:
lib-master: Added support for caching config lookups.
Currently caching won't work if config has any remote {} blocks.

diffstat:

 src/config/config-connection.c                 |   23 ++-
 src/config/config-filter.c                     |   44 +++-
 src/config/config-filter.h                     |    3 +
 src/config/config-parser.c                     |    5 +-
 src/config/config-request.c                    |  107 +++++++---
 src/config/config-request.h                    |   13 +-
 src/config/doveconf.c                          |   23 +-
 src/lib-master/Makefile.am                     |    1 +
 src/lib-master/master-service-settings-cache.c |  286 ++++++++++++++++++++++++++++
 src/lib-master/master-service-settings-cache.h |   15 +
 src/lib-master/master-service-settings.c       |   52 ++++-
 src/lib-master/master-service-settings.h       |   13 +
 src/lib-storage/mail-storage-service.c         |  116 +++++++---
 src/lib-storage/mail-storage-service.h         |    2 +
 src/lib-storage/mail-storage-settings.c        |    5 +-
 src/lib-storage/mail-storage-settings.h        |    3 +-
 src/lmtp/client.c                              |    6 +-
 src/lmtp/lmtp-settings.c                       |    5 +-
 src/lmtp/lmtp-settings.h                       |    3 +-
 src/login-common/login-settings.c              |   37 ++-
 src/login-common/login-settings.h              |    5 +-
 src/login-common/main.c                        |    5 +-
 src/login-common/ssl-proxy-openssl.c           |    3 +-
 src/master/main.c                              |    4 +-
 24 files changed, 655 insertions(+), 124 deletions(-)

diffs (truncated from 1475 to 300 lines):

diff -r 19a5f933849c -r bf4822f0846b src/config/config-connection.c
--- a/src/config/config-connection.c	Sat Feb 20 17:16:31 2010 +0200
+++ b/src/config/config-connection.c	Sat Feb 20 17:16:41 2010 +0200
@@ -6,6 +6,7 @@
 #include "ostream.h"
 #include "settings-parser.h"
 #include "master-service.h"
+#include "master-service-settings.h"
 #include "config-request.h"
 #include "config-parser.h"
 #include "config-connection.h"
@@ -15,7 +16,7 @@
 
 #define MAX_INBUF_SIZE 1024
 
-#define CONFIG_CLIENT_PROTOCOL_MAJOR_VERSION 1
+#define CONFIG_CLIENT_PROTOCOL_MAJOR_VERSION 2
 #define CONFIG_CLIENT_PROTOCOL_MINOR_VERSION 0
 
 struct config_connection {
@@ -65,6 +66,8 @@
 static int config_connection_request(struct config_connection *conn,
 				     const char *const *args)
 {
+	struct config_export_context *ctx;
+	struct master_service_settings_output output;
 	struct config_filter filter;
 	const char *path, *error, *module = "";
 
@@ -106,8 +109,22 @@
 	}
 
 	o_stream_cork(conn->output);
-	if (config_request_handle(&filter, module, CONFIG_DUMP_SCOPE_SET, 0,
-				  config_request_output, conn->output) < 0) {
+
+	ctx = config_export_init(&filter, module, CONFIG_DUMP_SCOPE_SET, 0,
+				 config_request_output, conn->output);
+	config_export_get_output(ctx, &output);
+
+	if (output.service_uses_local)
+		o_stream_send_str(conn->output, "service-uses-local\t");
+	if (output.service_uses_remote)
+		o_stream_send_str(conn->output, "service-uses-remote\t");
+	if (output.used_local)
+		o_stream_send_str(conn->output, "used-local\t");
+	if (output.used_remote)
+		o_stream_send_str(conn->output, "used-remote\t");
+	o_stream_send_str(conn->output, "\n");
+
+	if (config_export_finish(&ctx) < 0) {
 		config_connection_destroy(conn);
 		return -1;
 	}
diff -r 19a5f933849c -r bf4822f0846b src/config/config-filter.c
--- a/src/config/config-filter.c	Sat Feb 20 17:16:31 2010 +0200
+++ b/src/config/config-filter.c	Sat Feb 20 17:16:41 2010 +0200
@@ -3,6 +3,7 @@
 #include "lib.h"
 #include "array.h"
 #include "settings-parser.h"
+#include "master-service-settings.h"
 #include "config-parser.h"
 #include "config-filter.h"
 
@@ -11,8 +12,8 @@
 	struct config_filter_parser *const *parsers;
 };
 
-bool config_filter_match(const struct config_filter *mask,
-			 const struct config_filter *filter)
+static bool config_filter_match_service(const struct config_filter *mask,
+					const struct config_filter *filter)
 {
 	if (mask->service != NULL) {
 		if (filter->service == NULL)
@@ -26,6 +27,12 @@
 				return FALSE;
 		}
 	}
+	return TRUE;
+}
+
+static bool config_filter_match_rest(const struct config_filter *mask,
+				     const struct config_filter *filter)
+{
 	if (mask->local_host != NULL) {
 		if (filter->local_host == NULL)
 			return FALSE;
@@ -56,6 +63,15 @@
 	return TRUE;
 }
 
+bool config_filter_match(const struct config_filter *mask,
+			 const struct config_filter *filter)
+{
+	if (!config_filter_match_service(mask, filter))
+		return FALSE;
+
+	return config_filter_match_rest(mask, filter);
+}
+
 bool config_filters_equal(const struct config_filter *f1,
 			  const struct config_filter *f2)
 {
@@ -134,15 +150,32 @@
 
 static struct config_filter_parser *const *
 config_filter_find_all(struct config_filter_context *ctx,
-		       const struct config_filter *filter)
+		       const struct config_filter *filter,
+		       struct master_service_settings_output *output_r)
 {
 	ARRAY_TYPE(config_filter_parsers) matches;
 	unsigned int i;
 
+	memset(output_r, 0, sizeof(*output_r));
+
 	t_array_init(&matches, 8);
 	for (i = 0; ctx->parsers[i] != NULL; i++) {
-		if (config_filter_match(&ctx->parsers[i]->filter, filter))
+		const struct config_filter *mask = &ctx->parsers[i]->filter;
+
+		if (!config_filter_match_service(mask, filter))
+			continue;
+
+		if (mask->local_bits > 0)
+			output_r->service_uses_local = TRUE;
+		if (mask->remote_bits > 0)
+			output_r->service_uses_remote = TRUE;
+		if (config_filter_match_rest(mask, filter)) {
+			if (mask->local_bits > 0)
+				output_r->used_local = TRUE;
+			if (mask->remote_bits > 0)
+				output_r->used_remote = TRUE;
 			array_append(&matches, &ctx->parsers[i], 1);
+		}
 	}
 	array_sort(&matches, config_filter_parser_cmp);
 	(void)array_append_space(&matches);
@@ -187,6 +220,7 @@
 int config_filter_parsers_get(struct config_filter_context *ctx, pool_t pool,
 			      const struct config_filter *filter,
 			      struct config_module_parser **parsers_r,
+			      struct master_service_settings_output *output_r,
 			      const char **error_r)
 {
 	struct config_filter_parser *const *src;
@@ -194,7 +228,7 @@
 	const char *error, **error_p;
 	unsigned int i, count;
 
-	src = config_filter_find_all(ctx, filter);
+	src = config_filter_find_all(ctx, filter, output_r);
 
 	/* all of them should have the same number of parsers.
 	   duplicate our initial parsers from the first match */
diff -r 19a5f933849c -r bf4822f0846b src/config/config-filter.h
--- a/src/config/config-filter.h	Sat Feb 20 17:16:31 2010 +0200
+++ b/src/config/config-filter.h	Sat Feb 20 17:16:41 2010 +0200
@@ -3,6 +3,8 @@
 
 #include "network.h"
 
+struct master_service_settings_output;
+
 struct config_filter {
 	const char *service;
 	const char *local_host, *remote_host;
@@ -29,6 +31,7 @@
 int config_filter_parsers_get(struct config_filter_context *ctx, pool_t pool,
 			      const struct config_filter *filter,
 			      struct config_module_parser **parsers_r,
+			      struct master_service_settings_output *output_r,
 			      const char **error_r);
 void config_filter_parsers_free(struct config_module_parser *parsers);
 
diff -r 19a5f933849c -r bf4822f0846b src/config/config-parser.c
--- a/src/config/config-parser.c	Sat Feb 20 17:16:31 2010 +0200
+++ b/src/config/config-parser.c	Sat Feb 20 17:16:41 2010 +0200
@@ -9,6 +9,7 @@
 #include "module-dir.h"
 #include "settings-parser.h"
 #include "service-settings.h"
+#include "master-service-settings.h"
 #include "all-settings.h"
 #include "config-filter.h"
 #include "config-request.h"
@@ -321,6 +322,7 @@
 {
 	struct config_filter_parser *const *parsers;
 	struct config_module_parser *tmp_parsers;
+	struct master_service_settings_output output;
 	unsigned int i, count;
 	pool_t tmp_pool;
 	int ret = 0;
@@ -332,7 +334,8 @@
 	for (i = 0; i < count && ret == 0; i++) {
 		if (config_filter_parsers_get(new_filter, tmp_pool,
 					      &parsers[i]->filter,
-					      &tmp_parsers, error_r) < 0) {
+					      &tmp_parsers, &output,
+					      error_r) < 0) {
 			ret = -1;
 			break;
 		}
diff -r 19a5f933849c -r bf4822f0846b src/config/config-request.c
--- a/src/config/config-request.c	Sat Feb 20 17:16:31 2010 +0200
+++ b/src/config/config-request.c	Sat Feb 20 17:16:41 2010 +0200
@@ -11,7 +11,7 @@
 #include "config-parser.h"
 #include "config-request.h"
 
-struct settings_export_context {
+struct config_export_context {
 	pool_t pool;
 	string_t *value;
 	string_t *prefix;
@@ -21,7 +21,12 @@
 	config_request_callback_t *callback;
 	void *context;
 
+	const char *module;
 	enum config_dump_flags flags;
+	struct config_module_parser *parsers;
+	struct master_service_settings_output output;
+
+	bool failed;
 };
 
 static bool parsers_are_connected(const struct setting_parser_info *root,
@@ -157,7 +162,7 @@
 }
 
 static void
-settings_export(struct settings_export_context *ctx,
+settings_export(struct config_export_context *ctx,
 		const struct setting_parser_info *info,
 		bool parent_unique_deflist,
 		const void *set, const void *change_set)
@@ -305,53 +310,85 @@
 	}
 }
 
-int config_request_handle(const struct config_filter *filter,
-			  const char *module, enum config_dump_scope scope,
-			  enum config_dump_flags flags,
-			  config_request_callback_t *callback, void *context)
+struct config_export_context *
+config_export_init(const struct config_filter *filter,
+		   const char *module, enum config_dump_scope scope,
+		   enum config_dump_flags flags,
+		   config_request_callback_t *callback, void *context)
 {
-	struct config_module_parser *parsers, *parser;
-	struct settings_export_context ctx;
+	struct config_export_context *ctx;
+	const char *error;
+	pool_t pool;
+
+	pool = pool_alloconly_create("config export", 1024*64);
+	ctx = p_new(pool, struct config_export_context, 1);
+	ctx->pool = pool;
+
+	ctx->module = p_strdup(pool, module);
+	ctx->flags = flags;
+	ctx->callback = callback;
+	ctx->context = context;
+	ctx->scope = scope;
+	ctx->value = t_str_new(256);
+	ctx->prefix = t_str_new(64);
+	ctx->keys = hash_table_create(default_pool, ctx->pool, 0,
+				      str_hash, (hash_cmp_callback_t *)strcmp);
+
+	if (config_filter_parsers_get(config_filter, ctx->pool, filter,
+				      &ctx->parsers, &ctx->output,
+				      &error) < 0) {
+		i_error("%s", error);
+		ctx->failed = TRUE;
+	}
+	return ctx;
+}
+
+void config_export_get_output(struct config_export_context *ctx,
+			      struct master_service_settings_output *output_r)
+{
+	*output_r = ctx->output;
+}
+
+static void config_export_free(struct config_export_context *ctx)
+{
+	if (ctx->parsers != NULL)
+		config_filter_parsers_free(ctx->parsers);
+	hash_table_destroy(&ctx->keys);
+	pool_unref(&ctx->pool);
+}
+
+int config_export_finish(struct config_export_context **_ctx)
+{
+	struct config_export_context *ctx = *_ctx;


More information about the dovecot-cvs mailing list