changeset 11612:8beef17e8c9d

6920272 libdevinfo is too connected, libbsm must not depend upon it
author Jan Parcel <Jan.Parcel@Sun.COM>
date Mon, 01 Feb 2010 14:20:32 -0800
parents 8bcfad2f0829
children 4e70c20fe777
files usr/src/lib/Makefile usr/src/lib/libbsm/Makefile.com usr/src/lib/libbsm/common/getdment.c
diffstat 3 files changed, 117 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/lib/Makefile	Mon Feb 01 16:36:14 2010 -0500
+++ b/usr/src/lib/Makefile	Mon Feb 01 14:20:32 2010 -0800
@@ -568,7 +568,7 @@
 libast: 	libsocket
 libadutils: 	libldap5 libresolv libsocket libnsl
 nsswitch:	libadutils libidmap
-libbsm:		libtsol	libdevinfo
+libbsm:		libtsol
 libcmd: 	libsum libast libsocket libnsl
 libcmdutils:	libavl
 libcontract:	libnvpair
--- a/usr/src/lib/libbsm/Makefile.com	Mon Feb 01 16:36:14 2010 -0500
+++ b/usr/src/lib/libbsm/Makefile.com	Mon Feb 01 14:20:32 2010 -0800
@@ -86,7 +86,7 @@
 CLEANFILES +=	$(LINTOUT) $(LINTLIB)
 
 CFLAGS	+=	$(CCVERBOSE)
-LDLIBS +=	-lsocket -lnsl -lmd -lc -ldevinfo -lsecdb -ltsol -linetutil
+LDLIBS +=	-lsocket -lnsl -lmd -lc -lsecdb -ltsol -linetutil
 
 COMDIR=		../common
 
--- a/usr/src/lib/libbsm/common/getdment.c	Mon Feb 01 16:36:14 2010 -0500
+++ b/usr/src/lib/libbsm/common/getdment.c	Mon Feb 01 14:20:32 2010 -0800
@@ -28,7 +28,6 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <limits.h>
-#include <device_info.h>
 #include <bsm/devices.h>
 #include <bsm/devalloc.h>
 
@@ -376,6 +375,120 @@
 }
 
 /*
+ * Temporarily duplicated directly from libdevinfo's is_minor_node(),
+ * and renamed, because we cannot link this from libdevinfo.
+ *
+ * To be resolved in a couple of builds.
+ *
+ * The real fix is to move device allocation out of libbsm.
+ *
+ * returns 1 if contents is a minor node in /devices.
+ * If mn_root is not NULL, mn_root is set to:
+ *	if contents is a /dev node, mn_root = contents
+ *			OR
+ *	if contents is a /devices node, mn_root set to the '/'
+ *	following /devices.
+ */
+static int
+dmap_minor_root(const char *contents, const char **mn_root)
+{
+	char *ptr, *prefix;
+
+	prefix = "../devices/";
+
+	if ((ptr = strstr(contents, prefix)) != NULL) {
+
+		/* mn_root should point to the / following /devices */
+		if (mn_root != NULL) {
+			*mn_root = ptr += strlen(prefix) - 1;
+		}
+		return (1);
+	}
+
+	prefix = "/devices/";
+
+	if (strncmp(contents, prefix, strlen(prefix)) == 0) {
+
+		/* mn_root should point to the / following /devices/ */
+		if (mn_root != NULL) {
+			*mn_root = contents + strlen(prefix) - 1;
+		}
+		return (1);
+	}
+
+	if (mn_root != NULL) {
+		*mn_root = contents;
+	}
+	return (0);
+}
+
+/*
+ * Temporarily duplicated directly from libdevinfo's devfs_resolve_link(),
+ * and renamed, because we cannot link this from libdevinfo now, and will
+ * create a sensible solution in the near future.
+ *
+ * returns 0 if resolved, -1 otherwise.
+ * devpath: Absolute path to /dev link
+ * devfs_path: Returns malloced string: /devices path w/out "/devices"
+ */
+static int
+dmap_resolve_link(char *devpath, char **devfs_path)
+{
+	char contents[PATH_MAX + 1];
+	char stage_link[PATH_MAX + 1];
+	char *ptr;
+	int linksize;
+	char *slashdev = "/dev/";
+
+	if (devfs_path) {
+		*devfs_path = NULL;
+	}
+
+	linksize = readlink(devpath, contents, PATH_MAX);
+
+	if (linksize <= 0) {
+		return (-1);
+	} else {
+		contents[linksize] = '\0';
+	}
+
+	/*
+	 * if the link contents is not a minor node assume
+	 * that link contents is really a pointer to another
+	 * link, and if so recurse and read its link contents.
+	 */
+	if (dmap_minor_root((const char *)contents, (const char **)&ptr) !=
+	    1) {
+		if (strncmp(contents, slashdev, strlen(slashdev)) == 0)  {
+			/* absolute path, starting with /dev */
+			(void) strcpy(stage_link, contents);
+		} else {
+			/* relative path, prefix devpath */
+			if ((ptr = strrchr(devpath, '/')) == NULL) {
+				/* invalid link */
+				return (-1);
+			}
+			*ptr = '\0';
+			(void) strcpy(stage_link, devpath);
+			*ptr = '/';
+			(void) strcat(stage_link, "/");
+			(void) strcat(stage_link, contents);
+
+		}
+		return (dmap_resolve_link(stage_link, devfs_path));
+	}
+
+	if (devfs_path) {
+		*devfs_path = strdup(ptr);
+		if (*devfs_path == NULL) {
+			return (-1);
+		}
+	}
+
+	return (0);
+}
+
+/*
  * dmap_physname: path to /devices device
  * Returns:
  *	strdup'd (i.e. malloc'd) real device file if successful
@@ -393,7 +506,7 @@
 
 	(void) strncpy(stage_link, dmap->dmap_devarray[0], sizeof (stage_link));
 
-	if (devfs_resolve_link(stage_link, &oldlink) == 0)
+	if (dmap_resolve_link(stage_link, &oldlink) == 0)
 		return (oldlink);
 	return (NULL);
 }