[Ocfs2-tools-devel] [PATCH 07/11] libo2dlm: Dynamically load libdlm.
Joel Becker
joel.becker at oracle.com
Tue May 27 18:44:27 PDT 2008
We want ocfs2-tools to be runnable without cman/libdlm installed. Users
running o2cb should not require the extra packages. Thus, libo2dlm should
dynamically load libdlm when needed.
Signed-off-by: Joel Becker <joel.becker at oracle.com>
---
fsck.ocfs2/Makefile | 2 +-
fswreck/Makefile | 2 +-
libo2dlm/o2dlm.c | 97 ++++++++++++++++++++++++++++++----
libocfs2/Makefile | 2 +-
listuuid/Makefile | 2 +-
mkfs.ocfs2/Makefile | 2 +-
mount.ocfs2/Makefile | 2 +-
mounted.ocfs2/Makefile | 2 +-
o2dlm.pc.in | 2 +-
ocfs2_hb_ctl/Makefile | 2 +-
ocfs2cdsl/Makefile | 2 +-
ocfs2console/ocfs2interface/Makefile | 2 +-
tunefs.ocfs2/Makefile | 2 +-
13 files changed, 99 insertions(+), 22 deletions(-)
diff --git a/fsck.ocfs2/Makefile b/fsck.ocfs2/Makefile
index 3b6fc82..260c2ed 100644
--- a/fsck.ocfs2/Makefile
+++ b/fsck.ocfs2/Makefile
@@ -8,7 +8,7 @@ SBIN_PROGRAMS = fsck.ocfs2
INCLUDES = -I$(TOPDIR)/include -Iinclude
LIBOCFS2_LIBS = -L$(TOPDIR)/libocfs2 -locfs2
LIBOCFS2_DEPS = $(TOPDIR)/libocfs2/libocfs2.a
-LIBO2DLM_LIBS = -L$(TOPDIR)/libo2dlm -lo2dlm
+LIBO2DLM_LIBS = -L$(TOPDIR)/libo2dlm -lo2dlm -ldl
LIBO2DLM_DEPS = $(TOPDIR)/libo2dlm/libo2dlm.a
LIBO2CB_LIBS = -L$(TOPDIR)/libo2cb -lo2cb
LIBO2CB_DEPS = $(TOPDIR)/libo2cb/libo2cb.a
diff --git a/fswreck/Makefile b/fswreck/Makefile
index e6f3e06..472fec1 100644
--- a/fswreck/Makefile
+++ b/fswreck/Makefile
@@ -24,7 +24,7 @@ OBJS = $(subst .c,.o,$(CFILES))
LIBOCFS2_LIBS = -L$(TOPDIR)/libocfs2 -locfs2
LIBOCFS2_DEPS = $(TOPDIR)/libocfs2/libocfs2.a
-LIBO2DLM_LIBS = -L$(TOPDIR)/libo2dlm -lo2dlm
+LIBO2DLM_LIBS = -L$(TOPDIR)/libo2dlm -lo2dlm -ldl
LIBO2DLM_DEPS = $(TOPDIR)/libo2dlm/libo2dlm.a
LIBO2CB_LIBS = -L$(TOPDIR)/libo2cb -lo2cb
diff --git a/libo2dlm/o2dlm.c b/libo2dlm/o2dlm.c
index bdf9a68..7f2274f 100644
--- a/libo2dlm/o2dlm.c
+++ b/libo2dlm/o2dlm.c
@@ -36,6 +36,7 @@
#include <inttypes.h>
#include <sys/statfs.h>
#include <string.h>
+#include <dlfcn.h>
#include <errno.h>
#include <libdlm.h>
@@ -68,6 +69,7 @@ struct o2dlm_ctxt
char ct_domain_path[O2DLM_MAX_FULL_DOMAIN_PATH]; /* domain
* dir */
char ct_ctxt_lock_name[O2DLM_LOCK_ID_MAX_LEN];
+ void *ct_lib_handle;
dlm_lshandle_t ct_handle;
};
@@ -673,6 +675,64 @@ static errcode_t o2dlm_initialize_classic(const char *dlmfs_path,
* fsdlm operations
*/
+/* Dynamic symbols */
+static dlm_lshandle_t (*fsdlm_create_lockspace)(const char *name,
+ mode_t mode);
+static dlm_lshandle_t (*fsdlm_open_lockspace)(const char *name);
+static int (*fsdlm_release_lockspace)(const char *name,
+ dlm_lshandle_t ls,
+ int force);
+static int (*fsdlm_ls_lock_wait)(dlm_lshandle_t ls,
+ uint32_t mode,
+ struct dlm_lksb *lksb,
+ uint32_t flags,
+ const void *name,
+ unsigned int namelen,
+ uint32_t parent,
+ void *bastarg,
+ void (*bastaddr)(void *bastarg),
+ void *range);
+static int (*fsdlm_ls_unlock_wait)(dlm_lshandle_t ls,
+ uint32_t lkid,
+ uint32_t flags,
+ struct dlm_lksb *lksb);
+
+static errcode_t load_fsdlm(struct o2dlm_ctxt *ctxt)
+{
+ errcode_t ret = O2DLM_ET_SERVICE_UNAVAILABLE;
+
+ if (ctxt->ct_lib_handle) {
+ ret = 0;
+ goto out;
+ }
+
+ ctxt->ct_lib_handle = dlopen("libdlm_lt.so",
+ RTLD_NOW | RTLD_LOCAL);
+ if (!ctxt->ct_lib_handle)
+ goto out;
+
+#define load_sym(_sym) do { \
+ fs ## _sym = dlsym(ctxt->ct_lib_handle, #_sym); \
+ if (! fs ## _sym) \
+ goto out; \
+} while (0)
+
+ load_sym(dlm_create_lockspace);
+ load_sym(dlm_open_lockspace);
+ load_sym(dlm_release_lockspace);
+ load_sym(dlm_ls_lock_wait);
+ load_sym(dlm_ls_unlock_wait);
+
+ ret = 0;
+
+out:
+ if (ret && ctxt->ct_lib_handle) {
+ dlclose(ctxt->ct_lib_handle);
+ ctxt->ct_lib_handle = NULL;
+ }
+ return ret;
+}
+
static void to_fsdlm_lock(enum o2dlm_lock_level level, int lockflags,
uint32_t *fsdlm_mode, uint32_t *fsdlm_flags)
{
@@ -703,6 +763,9 @@ static errcode_t o2dlm_lock_fsdlm(struct o2dlm_ctxt *ctxt,
struct o2dlm_lock_res *lockres;
uint32_t mode, flags;
+ if (!fsdlm_ls_lock_wait)
+ return O2DLM_ET_SERVICE_UNAVAILABLE;
+
lockres = o2dlm_find_lock_res(ctxt, lockid);
if (lockres)
return O2DLM_ET_RECURSIVE_LOCK;
@@ -714,9 +777,9 @@ static errcode_t o2dlm_lock_fsdlm(struct o2dlm_ctxt *ctxt,
to_fsdlm_lock(level, lockflags, &mode, &flags);
flags |= LKF_VALBLK; /* Always use LVBs */
- rc = dlm_ls_lock_wait(ctxt->ct_handle, mode, &lockres->l_lksb,
- flags, lockid, strlen(lockid),
- 0, NULL, NULL, NULL);
+ rc = fsdlm_ls_lock_wait(ctxt->ct_handle, mode, &lockres->l_lksb,
+ flags, lockid, strlen(lockid),
+ 0, NULL, NULL, NULL);
if (rc)
rc = errno;
else
@@ -759,8 +822,11 @@ static errcode_t o2dlm_unlock_lock_res_fsdlm(struct o2dlm_ctxt *ctxt,
int rc;
errcode_t ret = 0;
- rc = dlm_ls_unlock_wait(ctxt->ct_handle, lockres->l_lksb.sb_lkid,
- LKF_VALBLK, &lockres->l_lksb);
+ if (!fsdlm_ls_unlock_wait)
+ return O2DLM_ET_SERVICE_UNAVAILABLE;
+
+ rc = fsdlm_ls_unlock_wait(ctxt->ct_handle, lockres->l_lksb.sb_lkid,
+ LKF_VALBLK, &lockres->l_lksb);
if (rc)
rc = errno;
else
@@ -848,9 +914,15 @@ static errcode_t o2dlm_initialize_fsdlm(const char *domain_name,
if (ret)
return ret;
- ctxt->ct_handle = dlm_create_lockspace(ctxt->ct_domain_path, 0600);
+ ret = load_fsdlm(ctxt);
+ if (ret) {
+ o2dlm_free_ctxt(ctxt);
+ return ret;
+ }
+
+ ctxt->ct_handle = fsdlm_create_lockspace(ctxt->ct_domain_path, 0600);
if (!ctxt->ct_handle && (errno == EEXIST))
- ctxt->ct_handle = dlm_open_lockspace(ctxt->ct_domain_path);
+ ctxt->ct_handle = fsdlm_open_lockspace(ctxt->ct_domain_path);
if (!ctxt->ct_handle) {
switch (errno) {
@@ -868,6 +940,7 @@ static errcode_t o2dlm_initialize_fsdlm(const char *domain_name,
ret = O2DLM_ET_INTERNAL_FAILURE;
break;
}
+ o2dlm_free_ctxt(ctxt);
return ret;
}
@@ -879,8 +952,8 @@ static errcode_t o2dlm_initialize_fsdlm(const char *domain_name,
O2DLM_LEVEL_PRMODE);
if (ret) {
/* Ignore the error, we want ret to be propagated */
- dlm_release_lockspace(ctxt->ct_domain_path,
- ctxt->ct_handle, 0);
+ fsdlm_release_lockspace(ctxt->ct_domain_path,
+ ctxt->ct_handle, 0);
o2dlm_free_ctxt(ctxt);
return ret;
}
@@ -896,6 +969,9 @@ static errcode_t o2dlm_destroy_fsdlm(struct o2dlm_ctxt *ctxt)
struct o2dlm_lock_res *lockres;
struct list_head *p, *n, *bucket;
+ if (!fsdlm_release_lockspace)
+ return O2DLM_ET_SERVICE_UNAVAILABLE;
+
for(i = 0; i < ctxt->ct_hash_size; i++) {
bucket = &ctxt->ct_hash[i];
@@ -914,7 +990,8 @@ static errcode_t o2dlm_destroy_fsdlm(struct o2dlm_ctxt *ctxt)
if (error)
goto free_and_exit;
- rc = dlm_release_lockspace(ctxt->ct_domain_path, ctxt->ct_handle, 0);
+ rc = fsdlm_release_lockspace(ctxt->ct_domain_path, ctxt->ct_handle,
+ 0);
if (!rc)
goto free_and_exit;
diff --git a/libocfs2/Makefile b/libocfs2/Makefile
index 7fd0042..6e998bb 100644
--- a/libocfs2/Makefile
+++ b/libocfs2/Makefile
@@ -6,7 +6,7 @@ INCLUDES = -I$(TOPDIR)/include
LIBRARIES = libocfs2.a
-LIBO2DLM_LIBS = -L$(TOPDIR)/libo2dlm -lo2dlm
+LIBO2DLM_LIBS = -L$(TOPDIR)/libo2dlm -lo2dlm -ldl
LIBO2DLM_DEPS = $(TOPDIR)/libo2dlm/libo2dlm.a
LIBO2CB_LIBS = -L$(TOPDIR)/libo2cb -lo2cb
diff --git a/listuuid/Makefile b/listuuid/Makefile
index 46e8dd9..268f0b3 100644
--- a/listuuid/Makefile
+++ b/listuuid/Makefile
@@ -7,7 +7,7 @@ INCLUDES = -I$(TOPDIR)/include
LIBOCFS2_LIBS = -L$(TOPDIR)/libocfs2 -locfs2
LIBOCFS2_DEPS = $(TOPDIR)/libocfs2/libocfs2.a
-LIBO2DLM_LIBS = -L$(TOPDIR)/libo2dlm -lo2dlm
+LIBO2DLM_LIBS = -L$(TOPDIR)/libo2dlm -lo2dlm -ldl
LIBO2DLM_DEPS = $(TOPDIR)/libo2dlm/libo2dlm.a
LIBO2CB_LIBS = -L$(TOPDIR)/libo2cb -lo2cb
diff --git a/mkfs.ocfs2/Makefile b/mkfs.ocfs2/Makefile
index 074c7d6..1498ad6 100644
--- a/mkfs.ocfs2/Makefile
+++ b/mkfs.ocfs2/Makefile
@@ -11,7 +11,7 @@ LIBOCFS2_DEPS = $(TOPDIR)/libocfs2/libocfs2.a
LIBO2CB_LIBS = -L$(TOPDIR)/libo2cb -lo2cb
LIBO2CB_DEPS = $(TOPDIR)/libo2cb/libo2cb.a
-LIBO2DLM_LIBS = -L$(TOPDIR)/libo2dlm -lo2dlm
+LIBO2DLM_LIBS = -L$(TOPDIR)/libo2dlm -lo2dlm -ldl
LIBO2DLM_DEPS = $(TOPDIR)/libo2dlm/libo2dlm.a
INCLUDES = -I$(TOPDIR)/include -I.
diff --git a/mount.ocfs2/Makefile b/mount.ocfs2/Makefile
index cb1dc4b..ac9e162 100644
--- a/mount.ocfs2/Makefile
+++ b/mount.ocfs2/Makefile
@@ -8,7 +8,7 @@ SBIN_PROGRAMS = mount.ocfs2 umount.ocfs2
INCLUDES = -I$(TOPDIR)/include
LIBOCFS2_LIBS = -L$(TOPDIR)/libocfs2 -locfs2
LIBOCFS2_DEPS = $(TOPDIR)/libocfs2/libocfs2.a
-LIBO2DLM_LIBS = -L$(TOPDIR)/libo2dlm -lo2dlm
+LIBO2DLM_LIBS = -L$(TOPDIR)/libo2dlm -lo2dlm -ldl
LIBO2DLM_DEPS = $(TOPDIR)/libo2dlm/libo2dlm.a
LIBO2CB_LIBS = -L$(TOPDIR)/libo2cb -lo2cb
LIBO2CB_DEPS = $(TOPDIR)/libo2cb/libo2cb.a
diff --git a/mounted.ocfs2/Makefile b/mounted.ocfs2/Makefile
index 21f7b88..967d519 100644
--- a/mounted.ocfs2/Makefile
+++ b/mounted.ocfs2/Makefile
@@ -5,7 +5,7 @@ include $(TOPDIR)/Preamble.make
LIBOCFS2_LIBS = -L$(TOPDIR)/libocfs2 -locfs2
LIBOCFS2_DEPS = $(TOPDIR)/libocfs2/libocfs2.a
-LIBO2DLM_LIBS = -L$(TOPDIR)/libo2dlm -lo2dlm
+LIBO2DLM_LIBS = -L$(TOPDIR)/libo2dlm -lo2dlm -ldl
LIBO2DLM_DEPS = $(TOPDIR)/libo2dlm/libo2dlm.a
LIBO2CB_LIBS = -L$(TOPDIR)/libo2cb -lo2cb
diff --git a/o2dlm.pc.in b/o2dlm.pc.in
index 6058b20..a50f70b 100644
--- a/o2dlm.pc.in
+++ b/o2dlm.pc.in
@@ -7,5 +7,5 @@ Name: o2dlm
Description: Library for accessing the ocfs2 DLM
Version: @VERSION@
Requires: com_err
-Libs: -L${libdir} -lo2dlm
+Libs: -L${libdir} -lo2dlm -ldl
Cflags: -I${includedir}
diff --git a/ocfs2_hb_ctl/Makefile b/ocfs2_hb_ctl/Makefile
index fc426d3..804caf6 100644
--- a/ocfs2_hb_ctl/Makefile
+++ b/ocfs2_hb_ctl/Makefile
@@ -8,7 +8,7 @@ SBIN_PROGRAMS = ocfs2_hb_ctl
INCLUDES = -I$(TOPDIR)/include
LIBOCFS2_LIBS = -L$(TOPDIR)/libocfs2 -locfs2
LIBOCFS2_DEPS = $(TOPDIR)/libocfs2/libocfs2.a
-LIBO2DLM_LIBS = -L$(TOPDIR)/libo2dlm -lo2dlm
+LIBO2DLM_LIBS = -L$(TOPDIR)/libo2dlm -lo2dlm -ldl
LIBO2DLM_DEPS = $(TOPDIR)/libo2dlm/libo2dlm.a
LIBO2CB_LIBS = -L$(TOPDIR)/libo2cb -lo2cb
LIBO2CB_DEPS = $(TOPDIR)/libo2cb/libo2cb.a
diff --git a/ocfs2cdsl/Makefile b/ocfs2cdsl/Makefile
index 0e21975..55fc72b 100644
--- a/ocfs2cdsl/Makefile
+++ b/ocfs2cdsl/Makefile
@@ -5,7 +5,7 @@ include $(TOPDIR)/Preamble.make
LIBOCFS2_LIBS = -L$(TOPDIR)/libocfs2 -locfs2
LIBOCFS2_DEPS = $(TOPDIR)/libocfs2/libocfs2.a
-LIBO2DLM_LIBS = -L$(TOPDIR)/libo2dlm -lo2dlm
+LIBO2DLM_LIBS = -L$(TOPDIR)/libo2dlm -lo2dlm -ldl
LIBO2DLM_DEPS = $(TOPDIR)/libo2dlm/libo2dlm.a
LIBO2CB_LIBS = -L$(TOPDIR)/libo2cb -lo2cb
diff --git a/ocfs2console/ocfs2interface/Makefile b/ocfs2console/ocfs2interface/Makefile
index 643d02d..cb95154 100644
--- a/ocfs2console/ocfs2interface/Makefile
+++ b/ocfs2console/ocfs2interface/Makefile
@@ -11,7 +11,7 @@ PYMOD_CFLAGS = -fno-strict-aliasing $(PYTHON_INCLUDES)
LIBOCFS2_LIBS = -L$(TOPDIR)/libocfs2 -locfs2
LIBOCFS2_DEPS = $(TOPDIR)/libocfs2/libocfs2.a
-LIBO2DLM_LIBS = -L$(TOPDIR)/libo2dlm -lo2dlm
+LIBO2DLM_LIBS = -L$(TOPDIR)/libo2dlm -lo2dlm -ldl
LIBO2DLM_DEPS = $(TOPDIR)/libo2dlm/libo2dlm.a
LIBO2CB_LIBS = -L$(TOPDIR)/libo2cb -lo2cb
diff --git a/tunefs.ocfs2/Makefile b/tunefs.ocfs2/Makefile
index f13383e..ef1c9fc 100644
--- a/tunefs.ocfs2/Makefile
+++ b/tunefs.ocfs2/Makefile
@@ -5,7 +5,7 @@ include $(TOPDIR)/Preamble.make
LIBOCFS2_LIBS = -L$(TOPDIR)/libocfs2 -locfs2
LIBOCFS2_DEPS = $(TOPDIR)/libocfs2/libocfs2.a
-LIBO2DLM_LIBS = -L$(TOPDIR)/libo2dlm -lo2dlm
+LIBO2DLM_LIBS = -L$(TOPDIR)/libo2dlm -lo2dlm -ldl
LIBO2DLM_DEPS = $(TOPDIR)/libo2dlm/libo2dlm.a
LIBO2CB_LIBS = -L$(TOPDIR)/libo2cb -lo2cb
--
1.5.4.5
More information about the Ocfs2-tools-devel
mailing list