diff --git a/lib/Makefile.in b/lib/Makefile.in index 7af0d978a..d791f0057 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -39,6 +39,7 @@ SOURCES=\ label/label.c \ label/uuid-map.c \ locking/file_locking.c \ + locking/external_locking.c \ locking/locking.c \ log/log.c \ metadata/lv_manip.c \ diff --git a/lib/locking/external_locking.c b/lib/locking/external_locking.c new file mode 100644 index 000000000..500d90e69 --- /dev/null +++ b/lib/locking/external_locking.c @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2002 Sistina Software (UK) Limited. + * + * This file is released under the LGPL. + * + */ + +#include "log.h" +#include "locking.h" +#include "locking_types.h" +#include "activate.h" +#include "config.h" +#include "defaults.h" +#include "lvm-file.h" +#include "lvm-string.h" +#include "dbg_malloc.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +static void *locking_module = NULL; +static void (*end_fn)(void) = NULL; +static int (*lock_fn)(struct cmd_context *cmd, const char *resource, int flags) = NULL; +static int (*init_fn)(int type, struct config_file *cf) = NULL; + +static int lock_resource(struct cmd_context *cmd, const char *resource, int flags) +{ + if (lock_fn) + return lock_fn(cmd, resource, flags); + else + return 0; +} + + +static void fin_external_locking(void) +{ + if (end_fn) + end_fn(); + + dlclose(locking_module); + + locking_module = NULL; + end_fn = NULL; + lock_fn = NULL; +} + +int init_external_locking(struct locking_type *locking, struct config_file *cf) +{ + char _lock_lib[PATH_MAX]; + + if (locking_module) + { + log_error("External locking already initialised\n"); + return 1; + } + locking->lock_resource = lock_resource; + locking->fin_locking = fin_external_locking; + + /* Get locking module name from config file */ + strncpy(_lock_lib, find_config_str(cf->root, "global/locking_library", + '/', "lvm2_locking.so"), + sizeof(_lock_lib)); + + + /* If there is a module_dir in the config file then + look for the locking module in there first and then + using the normal dlopen(3) mechanism of looking + down LD_LIBRARY_PATH and /lib, /usr/lib. + If course, if the library name starts with a slash then + just use the name... */ + if (_lock_lib[0] != '/') + { + struct stat st; + char _lock_lib1[PATH_MAX]; + + lvm_snprintf(_lock_lib1, sizeof(_lock_lib1), + "%s/%s", + find_config_str(cf->root, "global/module_dir", + '/', "RUBBISH"), + _lock_lib); + + /* Does it exist ? */ + if (stat(_lock_lib1, &st) == 0) + { + strcpy(_lock_lib, _lock_lib1); + } + } + + log_very_verbose("Opening locking library %s\n", _lock_lib); + + locking_module = dlopen(_lock_lib, RTLD_LAZY); + if (!locking_module) + { + log_error("Unable to open external locking module %s\n", _lock_lib); + return 0; + } + + /* Get the functions we need */ + init_fn = dlsym(locking_module, "init_locking"); + lock_fn = dlsym(locking_module, "lock_resource"); + end_fn = dlsym(locking_module, "end_locking"); + + /* Are they all there ? */ + if (!end_fn || !init_fn || !lock_fn) + { + log_error("shared library %s does not contain locking functions\n", _lock_lib); + dlclose(locking_module); + return 0; + } + + log_verbose("Opened external locking module %s\n", _lock_lib); + return init_fn(2, cf); +} diff --git a/lib/locking/locking.c b/lib/locking/locking.c index 61cd868b6..b75a6a472 100644 --- a/lib/locking/locking.c +++ b/lib/locking/locking.c @@ -101,13 +101,13 @@ int init_locking(int type, struct config_file *cf) return 0; log_very_verbose("File-based locking enabled."); break; -/****** + case 2: - if (!init_other_locking(&_locking, cf)) + if (!init_external_locking(&_locking, cf)) return 0; - log_very_verbose("Other locking enabled."); + log_very_verbose("External locking enabled."); break; -******/ + default: log_error("Unknown locking type requested."); return 0; diff --git a/tools/Makefile.in b/tools/Makefile.in index bff661830..f337684a4 100644 --- a/tools/Makefile.in +++ b/tools/Makefile.in @@ -62,7 +62,7 @@ include ../make.tmpl lvm: $(OBJECTS) $(top_srcdir)/lib/liblvm.a $(CC) -o lvm $(OBJECTS) $(LD_FLAGS) -L$(top_srcdir)/lib \ - -L$(DESTDIR)/lib -llvm -ldevmapper $(LIBS) + -L$(DESTDIR)/lib -llvm -ldevmapper $(LIBS) -ldl -rdynamic .commands: commands.h cmdnames.h $(CC) -E -P cmdnames.h | grep -v help > .commands