File eject-scsi-check-host_status-and-driver_status.patch of Package util-linux.openSUSE_13.1_Update

From 90a0e97c7be9da39fd54600228e006b98667ad56 Mon Sep 17 00:00:00 2001
From: Karel Zak <kzak@redhat.com>
Date: Tue, 18 Jun 2013 12:24:28 +0200
Subject: [PATCH 1/2] 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>
---
 sys-utils/eject.c | 24 +++++++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/sys-utils/eject.c b/sys-utils/eject.c
index 4ec69e7..f98f227 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 */
-- 
1.8.1.4

openSUSE Build Service is sponsored by