changeset 4083:08c82bb85ef2

6539019 /usr/lib/fm/fmd/schemes/mem.so depends on non-existent library on sun4u
author rb144127
date Mon, 23 Apr 2007 09:19:26 -0700
parents 2e3825fd8bb5
children 1838f1bb1fda
files usr/src/lib/fm/libldom/Makefile.com usr/src/lib/fm/libldom/sparc/ldom.c
diffstat 2 files changed, 61 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/lib/fm/libldom/Makefile.com	Fri Apr 20 17:46:13 2007 -0700
+++ b/usr/src/lib/fm/libldom/Makefile.com	Mon Apr 23 09:19:26 2007 -0700
@@ -44,7 +44,7 @@
 CFLAGS64 += $(CCVERBOSE) $(C_BIGPICFLAGS)
 
 LDLIBS += $(MACH_LDLIBS)
-LDLIBS += -lnvpair -lmdesc -lpri -lc
+LDLIBS += -lnvpair -lmdesc -lc
 
 LINTFLAGS = -msux
 LINTFLAGS64 = -msux -Xarch=$(MACH64:sparcv9=v9)
--- a/usr/src/lib/fm/libldom/sparc/ldom.c	Fri Apr 20 17:46:13 2007 -0700
+++ b/usr/src/lib/fm/libldom/sparc/ldom.c	Mon Apr 23 09:19:26 2007 -0700
@@ -33,6 +33,8 @@
 #include <pthread.h>
 #include <errno.h>
 #include <libnvpair.h>
+#include <dlfcn.h>
+#include <link.h>
 
 #include <sys/processor.h>
 #include <sys/stat.h>
@@ -51,6 +53,51 @@
 #define	MD_STR_PLATFORM		"platform"
 #define	MD_STR_DOM_ENABLE	"domaining-enabled"
 
+static void *ldom_dl_hp = (void *)NULL;
+static const char *ldom_dl_path = "libpri.so.1";
+static int ldom_dl_mode = (RTLD_NOW | RTLD_LOCAL);
+
+static int (*ldom_pri_init)(void) = (int (*)(void))NULL;
+static void (*ldom_pri_fini)(void) = (void (*)(void))NULL;
+static ssize_t (*ldom_pri_get)(uint8_t wait, uint64_t *token, uint64_t **buf,
+	void *(*allocp)(size_t), void (*freep)(void *, size_t)) =
+	(ssize_t (*)(uint8_t wait, uint64_t *token, uint64_t **buf,
+	void *(*allocp)(size_t), void (*freep)(void *, size_t)))NULL;
+
+static void
+ldom_pri_config(void)
+{
+	char isa[MAXNAMELEN];	/* used to see if machine is sun4v */
+
+	if (sysinfo(SI_MACHINE, isa, MAXNAMELEN) < 0)
+		return;
+	if (strcmp(isa, "sun4v") != 0)
+		return;
+	if ((ldom_dl_hp = dlopen(ldom_dl_path, ldom_dl_mode)) == NULL)
+		return;
+
+	ldom_pri_init = (int (*)(void))dlsym(ldom_dl_hp, "pri_init");
+	ldom_pri_fini = (void (*)(void))dlsym(ldom_dl_hp, "pri_fini");
+	ldom_pri_get = (ssize_t (*)(uint8_t wait, uint64_t *token,
+	    uint64_t **buf, void *(*allocp)(size_t),
+	    void (*freep)(void *, size_t)))dlsym(ldom_dl_hp, "pri_get");
+}
+
+static void
+ldom_pri_unconfig(void)
+{
+	if (ldom_dl_hp == NULL)
+		return;
+
+	ldom_pri_init = (int (*)(void))NULL;
+	ldom_pri_fini = (void (*)(void))NULL;
+	ldom_pri_get = (ssize_t (*)(uint8_t wait, uint64_t *token,
+	    uint64_t **buf, void *(*allocp)(size_t),
+	    void (*freep)(void *, size_t)))NULL;
+	(void) dlclose(ldom_dl_hp);
+	ldom_dl_hp = (void *)NULL;
+}
+
 static ssize_t
 get_local_core_md(ldom_hdl_t *lhp, uint64_t **buf)
 {
@@ -60,8 +107,10 @@
 	uint64_t tok;
 	uint64_t *bufp;
 
-	if ((ssize = pri_get(PRI_GET, &tok, buf, lhp->allocp, lhp->freep)) >= 0)
-		return (ssize);
+	if (ldom_pri_get != NULL)
+		if ((ssize = (*ldom_pri_get)(PRI_GET, &tok, buf,
+		    lhp->allocp, lhp->freep)) >= 0)
+			return (ssize);
 
 	if ((fh = open("/devices/pseudo/mdesc@0:mdesc", O_RDONLY, 0)) < 0)
 		return (-1);
@@ -557,11 +606,14 @@
 {
 	struct ldom_hdl *lhp;
 
-	if (pri_init() < 0)
-		return (NULL);
+	ldom_pri_config();
+	if (ldom_pri_init != NULL)
+		if ((*ldom_pri_init)() < 0)
+			return (NULL);
 
 	if ((lhp = allocp(sizeof (struct ldom_hdl))) == NULL) {
-		pri_fini();
+		if (ldom_pri_fini != NULL)
+			(*ldom_pri_fini)();
 		return (NULL);
 	}
 
@@ -584,7 +636,9 @@
 	ldmsvcs_fini(lhp);
 	lhp->freep(lhp, sizeof (struct ldom_hdl));
 
-	pri_fini();
+	if (ldom_pri_fini != NULL)
+		(*ldom_pri_fini)();
+	ldom_pri_unconfig();
 }
 
 /* end file */