Date: Mon, 16 Jul 2007 19:17:37 +0200 (CEST) From: Tijl Coosemans <tijl@ulyssis.org> To: FreeBSD-gnats-submit@FreeBSD.org Subject: kern/114636: [patch] ioctl on empty scsi/atapicam cdrom drive locks up entire system Message-ID: <200707161717.l6GHHbwp001586@kalimero.kotnet.org> Resent-Message-ID: <200707161750.l6GHo2qY065242@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 114636 >Category: kern >Synopsis: [patch] ioctl on empty scsi/atapicam cdrom drive locks up entire system >Confidential: no >Severity: critical >Priority: high >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Mon Jul 16 17:50:01 GMT 2007 >Closed-Date: >Last-Modified: >Originator: Tijl Coosemans >Release: FreeBSD 7.0-CURRENT i386 >Organization: >Environment: cd0 at ata1 bus 0 target 0 lun 0 cd0: <MATSHITA UJ-831D 1.00> Removable CD-ROM SCSI-0 device cd0: 3.300MB/s transfers cd0: Attempt to query device size failed: NOT READY, Medium not present >Description: An ioctl call on an empty scsi/atapicam cdrom drive causes the system to semi-hang when the file descriptor is later closed. Semi meaning the system is responsive to mouse and keyboard, but (most) processes hang and no new processes can be started. Pressing ctrl+alt+delete responds by disabling terminals but doesn't reset the system. A hard reset is needed to recover. >How-To-Repeat: The following program opens /dev/cd0 and does CDIOCSTART to spin up the drive. When the drive is empty the close(2) call causes the entire system to (semi-)hang. BE WARNED because a hard reset is required to recover. So don't try if you don't like fsck. --- cdrom.c begins here --- #include <sys/cdio.h> #include <sys/ioctl.h> #include <errno.h> #include <stdio.h> #include <fcntl.h> #include <unistd.h> int main(void) { int fd; int ret; fd = open( "/dev/cd0", O_RDONLY ); ret = ioctl( fd, CDIOCSTART ); printf( "ret = %d, errno = %d\n", ret, errno ); close( fd ); return 0; } --- cdrom.c ends here --- >Fix: The problem is caused by a forgotten cam_periph_unhold() when there's no media in the drive. --- patch-sys-cam-scsi-scsi_cd.c begins here --- --- sys/cam/scsi/scsi_cd.c.orig 2007-07-12 15:32:30.000000000 +0200 +++ sys/cam/scsi/scsi_cd.c 2007-07-12 15:39:15.000000000 +0200 @@ -1859,16 +1859,18 @@ && ((cmd != CDIOCCLOSE) && (cmd != CDIOCEJECT)) && (IOCGROUP(cmd) == 'c')) { - error = cdcheckmedia(periph); + if ((error = cdcheckmedia(periph)) != 0) { + cam_periph_unhold(periph); + cam_periph_unlock(periph); + return (error); + } } + /* * Drop the lock here so later mallocs can use WAITOK. The periph * is essentially locked still with the cam_periph_hold call above. */ cam_periph_unlock(periph); - if (error != 0) - return (error); - nocopyout = 0; switch (cmd) { --- patch-sys-cam-scsi-scsi_cd.c ends here --- >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200707161717.l6GHHbwp001586>