summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorJohn Levon <john.levon@sun.com>2010-07-26 11:11:38 -0700
committerJohn Levon <john.levon@sun.com>2010-07-26 11:11:38 -0700
commit67323fc4f7476c5e8b55a5fe505c6f2dbf00e89a (patch)
treeaf030066a90e98c42fe98cadbdc5f8a5b9b81aff /usr/src
parentda060432c3093844dd0ff46d9651bdf06c12dd66 (diff)
downloadillumos-joyent-67323fc4f7476c5e8b55a5fe505c6f2dbf00e89a.tar.gz
6968425 Seeing build_devlink_list: readlink failed messages in console with Osolb143
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/devfsadm/devfsadm.c18
-rw-r--r--usr/src/uts/common/fs/dev/sdev_subr.c25
-rw-r--r--usr/src/uts/common/io/lofi.c10
3 files changed, 37 insertions, 16 deletions
diff --git a/usr/src/cmd/devfsadm/devfsadm.c b/usr/src/cmd/devfsadm/devfsadm.c
index d37bc70835..2289db2a88 100644
--- a/usr/src/cmd/devfsadm/devfsadm.c
+++ b/usr/src/cmd/devfsadm/devfsadm.c
@@ -226,12 +226,12 @@ static item_t **nfp_hash;
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 @@ s_rmdir(char *path)
/*
* 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);
diff --git a/usr/src/uts/common/fs/dev/sdev_subr.c b/usr/src/uts/common/fs/dev/sdev_subr.c
index a47493ab55..b814175e8a 100644
--- a/usr/src/uts/common/fs/dev/sdev_subr.c
+++ b/usr/src/uts/common/fs/dev/sdev_subr.c
@@ -547,8 +547,22 @@ static struct sdev_vop_table vtab[] =
{ "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 @@ sdev_filldir_dynamic(struct sdev_node *ddv)
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;
diff --git a/usr/src/uts/common/io/lofi.c b/usr/src/uts/common/io/lofi.c
index abafd483aa..2bc7cf3620 100644
--- a/usr/src/uts/common/io/lofi.c
+++ b/usr/src/uts/common/io/lofi.c
@@ -510,7 +510,7 @@ lofi_close(dev_t dev, int flag, int otyp, struct cred *credp)
* 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 @@ err:
* 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 @@ lofi_unmap_file(dev_t dev, struct lofi_ioctl *ulip, int byfilename,
}
out:
- lofi_free_dev(dev);
+ lofi_free_dev(lsp->ls_dev);
lofi_destroy(lsp, credp);
mutex_exit(&lofi_lock);
@@ -2533,11 +2533,11 @@ lofi_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *credp,
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));