kern/61677: Unable to open CDROM tray if boot_cdrom is in loader.conf

Jim Bauer jfbauer at nfr.com
Wed Jan 21 08:00:32 PST 2004


>Number:         61677
>Category:       kern
>Synopsis:       Unable to open CDROM tray if boot_cdrom is in loader.conf
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Jan 21 08:00:23 PST 2004
>Closed-Date:
>Last-Modified:
>Originator:     Jim Bauer
>Release:        4.8-RELEASE
>Organization:
NFR Security Inc
>Environment:
FreeBSD gyro.nidlab.nfr.net 4.8-RELEASE FreeBSD 4.8-RELEASE
#4: Mon Jan  5 12:47:40 EST 2004
jfbauer at gyro.nidlab.nfr.net:/home/jfbauer/freebsd_48_src/sys/compile/JFB  i386
>Description:
If loader.conf contains: boot_cdrom="YES" (the value is unimportant, just the existence seems to matter) but you don't actually boot from the CDROM drive (because it does not contain a CD) then the cdrom tray will remain locked.

As the system boots, the kernel will try to mount the CDROM trying 3 different CD devices.  All will fail as there is no CD in any cdrom drive.  The kernel will then fallback and mount the root FS from the hard disk.

Once the system is up and running you can login and see that nothing is mounted from the (empty) cdrom drive, but the eject command (CDIOCEJECT ioctl) will return EBUSY.  Also, pressing the eject button on the drive will fail to open the tray.

It looks like the mount attempt is not fully cleaning up and leaving the device in a busy state.


>How-To-Repeat:
1) Place this in your loader.conf file: boot_cdrom="YES"
2) Make sure there is no CD in the drive
3) Reboot (the kernel will attempt to mount the CD, fail and mount hard disk as usual)
4) Try to open the CD tray via either the eject command or the pressing the eject button on the cd drive.  Both will fail to open the tray.

>Fix:
This patch seem to fix the problem.

diff -u -r1.1.1.1 cd9660_vfsops.c
--- isofs/cd9660/cd9660_vfsops.c        11 Apr 2003 00:34:55 -0000      1.1.1.1
+++ isofs/cd9660/cd9660_vfsops.c        20 Jan 2004 20:46:31 -0000
@@ -163,7 +163,7 @@
        error = VOP_OPEN(rootvp, FREAD, FSCRED, p);
        VOP_UNLOCK(rootvp, 0, p);
        if (error)
-               return (error);
+               goto err;
 
        args.ssector = iso_get_ssector(rootdev, p);
 
@@ -173,10 +173,15 @@
                printf("iso_mountroot(): using session at block %d\n",
                       args.ssector);
        if ((error = iso_mountfs(rootvp, mp, p, &args)) != 0)
-               return (error);
+               goto err;
 
        (void)cd9660_statfs(mp, &mp->mnt_stat, p);
        return (0);
+
+    err:
+       /* Undo the addalias() called from bdevvp() */
+       delalias(rootvp, rootdev);
+       return error;
 }
 
 /*
Index: kern/vfs_subr.c
===================================================================
diff -u -r1.1.1.1 vfs_subr.c
--- kern/vfs_subr.c     11 Apr 2003 00:34:56 -0000      1.1.1.1
+++ kern/vfs_subr.c     20 Jan 2004 20:46:31 -0000
@@ -1481,6 +1481,22 @@
 }
 
 /*
+ * Remove an alias created by addalias()
+ */
+void
+delalias(nvp, dev)
+       struct vnode *nvp;
+        dev_t dev;
+{
+       if (nvp->v_type != VBLK && nvp->v_type != VCHR)
+               panic("delalias on non-special vnode");
+
+       simple_lock(&spechash_slock);
+       SLIST_REMOVE(&dev->si_hlist, nvp, vnode, v_specnext);
+        simple_unlock(&spechash_slock);
+}
+
+/*
  * Grab a particular vnode from the free list, increment its
  * reference count and lock it. The vnode lock bit is set if the
  * vnode is being eliminated in vgone. The process is awakened


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list