[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