dovecot-2.2: lib-fs: Automatically try to load missing driver as...
dovecot at dovecot.org
dovecot at dovecot.org
Tue Nov 27 00:44:46 EET 2012
details: http://hg.dovecot.org/dovecot-2.2/rev/47c0a5a19211
changeset: 15417:47c0a5a19211
user: Timo Sirainen <tss at iki.fi>
date: Tue Nov 27 00:43:53 2012 +0200
description:
lib-fs: Automatically try to load missing driver as plugin.
diffstat:
src/lib-fs/Makefile.am | 3 +-
src/lib-fs/fs-api-private.h | 6 +-
src/lib-fs/fs-api.c | 85 ++++++++++++++++++++++++++++++++++++++------
src/lib-fs/fs-posix.c | 2 +-
src/lib-fs/fs-sis-queue.c | 2 +-
src/lib-fs/fs-sis.c | 2 +-
6 files changed, 80 insertions(+), 20 deletions(-)
diffs (176 lines):
diff -r 2aef2557bdf1 -r 47c0a5a19211 src/lib-fs/Makefile.am
--- a/src/lib-fs/Makefile.am Tue Nov 27 00:43:23 2012 +0200
+++ b/src/lib-fs/Makefile.am Tue Nov 27 00:43:53 2012 +0200
@@ -1,7 +1,8 @@
noinst_LTLIBRARIES = libfs.la
AM_CPPFLAGS = \
- -I$(top_srcdir)/src/lib
+ -I$(top_srcdir)/src/lib \
+ -DMODULE_DIR=\""$(moduledir)"\"
libfs_la_SOURCES = \
fs-api.c \
diff -r 2aef2557bdf1 -r 47c0a5a19211 src/lib-fs/fs-api-private.h
--- a/src/lib-fs/fs-api-private.h Tue Nov 27 00:43:23 2012 +0200
+++ b/src/lib-fs/fs-api-private.h Tue Nov 27 00:43:53 2012 +0200
@@ -74,9 +74,9 @@
struct fs *fs;
};
-extern struct fs fs_class_posix;
-extern struct fs fs_class_sis;
-extern struct fs fs_class_sis_queue;
+extern const struct fs fs_class_posix;
+extern const struct fs fs_class_sis;
+extern const struct fs fs_class_sis_queue;
void fs_set_error(struct fs *fs, const char *fmt, ...) ATTR_FORMAT(2, 3);
void fs_set_critical(struct fs *fs, const char *fmt, ...) ATTR_FORMAT(2, 3);
diff -r 2aef2557bdf1 -r 47c0a5a19211 src/lib-fs/fs-api.c
--- a/src/lib-fs/fs-api.c Tue Nov 27 00:43:23 2012 +0200
+++ b/src/lib-fs/fs-api.c Tue Nov 27 00:43:53 2012 +0200
@@ -1,14 +1,13 @@
/* Copyright (c) 2010-2012 Dovecot authors, see the included COPYING file */
#include "lib.h"
+#include "array.h"
+#include "module-dir.h"
#include "str.h"
#include "fs-api-private.h"
-static struct fs *fs_classes[] = {
- &fs_class_posix,
- &fs_class_sis,
- &fs_class_sis_queue
-};
+static struct module *fs_modules = NULL;
+static ARRAY(const struct fs *) fs_classes;
static int
fs_alloc(const struct fs *fs_class, const char *args,
@@ -36,20 +35,80 @@
return 0;
}
+static void fs_class_register(const struct fs *fs_class)
+{
+ array_append(&fs_classes, &fs_class, 1);
+}
+
+static void fs_classes_init(void)
+{
+ i_array_init(&fs_classes, 8);
+ fs_class_register(&fs_class_posix);
+ fs_class_register(&fs_class_sis);
+ fs_class_register(&fs_class_sis_queue);
+}
+
+static const struct fs *fs_class_find(const char *driver)
+{
+ const struct fs *const *classp;
+
+ if (!array_is_created(&fs_classes))
+ fs_classes_init();
+
+ array_foreach(&fs_classes, classp) {
+ if (strcmp((*classp)->name, driver) == 0)
+ return *classp;
+ }
+ return NULL;
+}
+
+static void fs_class_deinit_modules(void)
+{
+ module_dir_unload(&fs_modules);
+}
+
+static void fs_class_try_load_plugin(const char *driver)
+{
+ const char *module_name = t_strdup_printf("fs_%s", driver);
+ struct module *module;
+ struct module_dir_load_settings mod_set;
+ const struct fs *fs_class;
+
+ memset(&mod_set, 0, sizeof(mod_set));
+ mod_set.abi_version = DOVECOT_ABI_VERSION;
+ mod_set.ignore_missing = TRUE;
+
+ fs_modules = module_dir_load_missing(fs_modules, MODULE_DIR,
+ module_name, &mod_set);
+ module_dir_init(fs_modules);
+
+ module = module_dir_find(fs_modules, module_name);
+ fs_class = module_get_symbol(module,
+ t_strdup_printf("fs_class_%s", driver));
+ if (fs_class != NULL)
+ fs_class_register(fs_class);
+
+ lib_atexit(fs_class_deinit_modules);
+}
+
int fs_init(const char *driver, const char *args,
const struct fs_settings *set,
struct fs **fs_r, const char **error_r)
{
- unsigned int i;
+ const struct fs *fs_class;
- for (i = 0; i < N_ELEMENTS(fs_classes); i++) {
- if (strcmp(fs_classes[i]->name, driver) == 0) {
- return fs_alloc(fs_classes[i], args,
- set, fs_r, error_r);
- }
+ fs_class = fs_class_find(driver);
+ if (fs_class == NULL) {
+ T_BEGIN {
+ fs_class_try_load_plugin(driver);
+ } T_END;
+ fs_class = fs_class_find(driver);
}
- *error_r = t_strdup_printf("Unknown fs driver: %s", driver);
- return -1;
+ if (fs_class == NULL) {
+ *error_r = t_strdup_printf("Unknown fs driver: %s", driver);
+ return -1;
+ }
+ return fs_alloc(fs_class, args, set, fs_r, error_r);
}
void fs_deinit(struct fs **_fs)
diff -r 2aef2557bdf1 -r 47c0a5a19211 src/lib-fs/fs-posix.c
--- a/src/lib-fs/fs-posix.c Tue Nov 27 00:43:23 2012 +0200
+++ b/src/lib-fs/fs-posix.c Tue Nov 27 00:43:53 2012 +0200
@@ -724,7 +724,7 @@
return ret;
}
-struct fs fs_class_posix = {
+const struct fs fs_class_posix = {
.name = "posix",
.v = {
fs_posix_alloc,
diff -r 2aef2557bdf1 -r 47c0a5a19211 src/lib-fs/fs-sis-queue.c
--- a/src/lib-fs/fs-sis-queue.c Tue Nov 27 00:43:23 2012 +0200
+++ b/src/lib-fs/fs-sis-queue.c Tue Nov 27 00:43:53 2012 +0200
@@ -335,7 +335,7 @@
return fs_iter_init(fs->super, path);
}
-struct fs fs_class_sis_queue = {
+const struct fs fs_class_sis_queue = {
.name = "sis-queue",
.v = {
fs_sis_queue_alloc,
diff -r 2aef2557bdf1 -r 47c0a5a19211 src/lib-fs/fs-sis.c
--- a/src/lib-fs/fs-sis.c Tue Nov 27 00:43:23 2012 +0200
+++ b/src/lib-fs/fs-sis.c Tue Nov 27 00:43:53 2012 +0200
@@ -470,7 +470,7 @@
return fs_iter_init(fs->super, path);
}
-struct fs fs_class_sis = {
+const struct fs fs_class_sis = {
.name = "sis",
.v = {
fs_sis_alloc,
More information about the dovecot-cvs
mailing list