changeset 12923:3c964548d01f

6968425 Seeing build_devlink_list: readlink failed messages in console with Osolb143
author John Levon <john.levon@sun.com>
date Mon, 26 Jul 2010 11:11:38 -0700
parents ecb14ee9a829
children c9b2c6a6a9c0
files usr/src/cmd/devfsadm/devfsadm.c usr/src/uts/common/fs/dev/sdev_subr.c usr/src/uts/common/io/lofi.c
diffstat 3 files changed, 37 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/devfsadm/devfsadm.c	Mon Jul 26 11:09:11 2010 -0700
+++ b/usr/src/cmd/devfsadm/devfsadm.c	Mon Jul 26 11:11:38 2010 -0700
@@ -226,12 +226,12 @@
 static mutex_t  nfp_mutex = DEFAULTMUTEX;
 
 /*
- * Packaged directories - not removed even when empty.
- * The dirs must be listed in canonical form
- * i.e. without leading "/dev/"
+ * Directories not removed even when empty.  They are packaged, or may
+ * be referred to from a non-global zone.  The dirs must be listed in
+ * canonical form i.e. without leading "/dev/"
  */
-static char *packaged_dirs[] =
-	{"dsk", "rdsk", "term", NULL};
+static char *sticky_dirs[] =
+	{"dsk", "rdsk", "term", "lofi", "rlofi", NULL};
 
 /* Devname globals */
 static int lookup_door_fd = -1;
@@ -3195,17 +3195,17 @@
 
 	/*
 	 * Certain directories are created at install time by packages.
-	 * Some of them (listed in packaged_dirs[]) are required by apps
+	 * Some of them (listed in sticky_dirs[]) are required by apps
 	 * and need to be present even when empty.
 	 */
-	vprint(REMOVE_MID, "%s: checking if %s is packaged\n", fcn, path);
+	vprint(REMOVE_MID, "%s: checking if %s is sticky\n", fcn, path);
 
 	rpath = path + strlen(dev_dir) + 1;
 
-	for (i = 0; (dir = packaged_dirs[i]) != NULL; i++) {
+	for (i = 0; (dir = sticky_dirs[i]) != NULL; i++) {
 		if (*rpath == *dir) {
 			if (strcmp(rpath, dir) == 0) {
-				vprint(REMOVE_MID, "%s: skipping packaged dir: "
+				vprint(REMOVE_MID, "%s: skipping sticky dir: "
 				    "%s\n", fcn, path);
 				errno = EEXIST;
 				return (-1);
--- a/usr/src/uts/common/fs/dev/sdev_subr.c	Mon Jul 26 11:09:11 2010 -0700
+++ b/usr/src/uts/common/fs/dev/sdev_subr.c	Mon Jul 26 11:11:38 2010 -0700
@@ -547,8 +547,22 @@
 	{ "ipnet", devipnet_vnodeops_tbl, NULL, &devipnet_vnodeops,
 	devipnet_validate, SDEV_DYNAMIC | SDEV_VTOR | SDEV_NO_NCACHE },
 
-	{ "lofi", NULL, NULL, NULL, NULL, SDEV_ZONED },
-	{ "rlofi", NULL, NULL, NULL, NULL, SDEV_ZONED },
+	/*
+	 * SDEV_DYNAMIC: prevent calling out to devfsadm, since only the
+	 * lofi driver controls child nodes.
+	 *
+	 * SDEV_PERSIST: ensure devfsadm knows to clean up any persisted
+	 * stale nodes (e.g. from devfsadm -R).
+	 *
+	 * In addition, devfsadm knows not to attempt a rmdir: a zone
+	 * may hold a reference, which would zombify the node,
+	 * preventing a mkdir.
+	 */
+
+	{ "lofi", NULL, NULL, NULL, NULL,
+	    SDEV_ZONED | SDEV_DYNAMIC | SDEV_PERSIST },
+	{ "rlofi", NULL, NULL, NULL, NULL,
+	    SDEV_ZONED | SDEV_DYNAMIC | SDEV_PERSIST },
 
 	{ NULL, NULL, NULL, NULL, NULL, 0}
 };
@@ -1531,6 +1545,13 @@
 	vap->va_mtime = vap->va_atime;
 	vap->va_ctime = vap->va_atime;
 	for (i = 0; vtab[i].vt_name != NULL; i++) {
+		/*
+		 * This early, we may be in a read-only /dev
+		 * environment: leave the creation of any nodes we'd
+		 * attempt to persist to devfsadm.
+		 */
+		if (vtab[i].vt_flags & SDEV_PERSIST)
+			continue;
 		nm = vtab[i].vt_name;
 		ASSERT(RW_WRITE_HELD(&ddv->sdev_contents));
 		dv = NULL;
--- a/usr/src/uts/common/io/lofi.c	Mon Jul 26 11:09:11 2010 -0700
+++ b/usr/src/uts/common/io/lofi.c	Mon Jul 26 11:11:38 2010 -0700
@@ -510,7 +510,7 @@
 	 * out of the door.
 	 */
 	if (!is_opened(lsp) && (lsp->ls_cleanup || lsp->ls_vp == NULL)) {
-		lofi_free_dev(dev);
+		lofi_free_dev(lsp->ls_dev);
 		lofi_destroy(lsp, credp);
 	}
 
@@ -2330,7 +2330,7 @@
  * unmap a file.
  */
 static int
-lofi_unmap_file(dev_t dev, struct lofi_ioctl *ulip, int byfilename,
+lofi_unmap_file(struct lofi_ioctl *ulip, int byfilename,
     struct cred *credp, int ioctl_flag)
 {
 	struct lofi_state *lsp;
@@ -2409,7 +2409,7 @@
 	}
 
 out:
-	lofi_free_dev(dev);
+	lofi_free_dev(lsp->ls_dev);
 	lofi_destroy(lsp, credp);
 
 	mutex_exit(&lofi_lock);
@@ -2533,11 +2533,11 @@
 		case LOFI_UNMAP_FILE:
 			if ((flag & FWRITE) == 0)
 				return (EPERM);
-			return (lofi_unmap_file(dev, lip, 1, credp, flag));
+			return (lofi_unmap_file(lip, 1, credp, flag));
 		case LOFI_UNMAP_FILE_MINOR:
 			if ((flag & FWRITE) == 0)
 				return (EPERM);
-			return (lofi_unmap_file(dev, lip, 0, credp, flag));
+			return (lofi_unmap_file(lip, 0, credp, flag));
 		case LOFI_GET_FILENAME:
 			return (lofi_get_info(dev, lip, LOFI_GET_FILENAME,
 			    credp, flag));