summaryrefslogtreecommitdiffstats
path: root/sys-utils/eject.c
diff options
context:
space:
mode:
authorKarel Zak2013-06-18 12:24:28 +0200
committerKarel Zak2013-06-18 12:24:28 +0200
commit90a0e97c7be9da39fd54600228e006b98667ad56 (patch)
treec39f5c88f151d5f73de2168f02d3c80f99ac4a67 /sys-utils/eject.c
parentagetty: improve wording, grammar and some formatting in man page (diff)
downloadkernel-qcow2-util-linux-90a0e97c7be9da39fd54600228e006b98667ad56.tar.gz
kernel-qcow2-util-linux-90a0e97c7be9da39fd54600228e006b98667ad56.tar.xz
kernel-qcow2-util-linux-90a0e97c7be9da39fd54600228e006b98667ad56.zip
eject: Check host_status and driver_status when using SG_IO.
Based on Suse patch, originally from Anna Bernathova <anicka@suse.cz>, May 2008 SG_IO completion status is weird but still well defined. You'll need to check both host_status, driver_status and status to determine that a command actually succeeded. -- Tejun Heo, May 2008 Note that we also need to check driver_status and sense_buffer to detect situation when there is no medium. It's valid request to call eject(8) for device with no medium. References: https://bugzilla.novell.com/show_bug.cgi?id=358033 Signed-off-by: Anna Bernathova <anicka@suse.cz> Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'sys-utils/eject.c')
-rw-r--r--sys-utils/eject.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/sys-utils/eject.c b/sys-utils/eject.c
index 4ec69e729..f98f22775 100644
--- a/sys-utils/eject.c
+++ b/sys-utils/eject.c
@@ -53,6 +53,14 @@
#include "pathnames.h"
#include "sysfs.h"
+/*
+ * sg_io_hdr_t driver_status -- see kernel include/scsi/scsi.h
+ */
+#ifndef DRIVER_SENSE
+# define DRIVER_SENSE 0x08
+#endif
+
+
#define EJECT_DEFAULT_DEVICE "/dev/cdrom"
@@ -604,17 +612,27 @@ static int eject_scsi(int fd)
io_hdr.cmdp = allowRmBlk;
status = ioctl(fd, SG_IO, (void *)&io_hdr);
- if (status < 0)
+ if (status < 0 || io_hdr.host_status || io_hdr.driver_status)
return 0;
io_hdr.cmdp = startStop1Blk;
status = ioctl(fd, SG_IO, (void *)&io_hdr);
- if (status < 0)
+ if (status < 0 || io_hdr.host_status)
+ return 0;
+
+ /* Ignore errors when there is not medium -- in this case driver sense
+ * buffer sets MEDIUM NOT PRESENT (3a) bit. For more details see:
+ * http://www.tldp.org/HOWTO/archived/SCSI-Programming-HOWTO/SCSI-Programming-HOWTO-22.html#sec-sensecodes
+ * -- kzak Jun 2013
+ */
+ if (io_hdr.driver_status != 0 &&
+ !(io_hdr.driver_status == DRIVER_SENSE && io_hdr.sbp &&
+ io_hdr.sbp[12] == 0x3a))
return 0;
io_hdr.cmdp = startStop2Blk;
status = ioctl(fd, SG_IO, (void *)&io_hdr);
- if (status < 0)
+ if (status < 0 || io_hdr.host_status || io_hdr.driver_status)
return 0;
/* force kernel to reread partition table when new disc inserted */