diff options
author | Dimitris Aragiorgis <dimara@arrikto.com> | 2015-06-23 13:45:00 +0300 |
---|---|---|
committer | Stefan Hajnoczi <stefanha@redhat.com> | 2015-06-23 15:08:52 +0100 |
commit | 3307ed7b3fac5ba99eb3b84904b0b7cdc3592a61 (patch) | |
tree | fb98300d62b250a8976a07a9384a6ba27402d2e0 /block | |
parent | a93a3982a6645463fa822131d38b17284edd5633 (diff) | |
download | qemu-3307ed7b3fac5ba99eb3b84904b0b7cdc3592a61.zip qemu-3307ed7b3fac5ba99eb3b84904b0b7cdc3592a61.tar.gz qemu-3307ed7b3fac5ba99eb3b84904b0b7cdc3592a61.tar.bz2 |
raw-posix: Introduce hdev_is_sg()
Until now, an SG device was identified only by checking if its path
started with "/dev/sg". Then, hdev_open() would set the bs->sg flag
accordingly. The patch relies on the actual properties of the device
instead of the specified file path.
To this end, test for an SG device (e.g. /dev/sg0) by ensuring that
all of the following holds:
- The specified file name corresponds to a character device
- The device supports the SG_GET_VERSION_NUM ioctl
- The device supports the SG_GET_SCSI_ID ioctl
Signed-off-by: Dimitris Aragiorgis <dimara@arrikto.com>
Message-id: 1435056300-14924-6-git-send-email-dimara@arrikto.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'block')
-rw-r--r-- | block/raw-posix.c | 39 |
1 files changed, 28 insertions, 11 deletions
diff --git a/block/raw-posix.c b/block/raw-posix.c index 57a243f..cbe6574 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -59,6 +59,7 @@ #include <linux/fd.h> #include <linux/fs.h> #include <linux/hdreg.h> +#include <scsi/sg.h> #ifdef __s390__ #include <asm/dasd.h> #endif @@ -2086,15 +2087,38 @@ static void hdev_parse_filename(const char *filename, QDict *options, qdict_put_obj(options, "filename", QOBJECT(qstring_from_str(filename))); } +static bool hdev_is_sg(BlockDriverState *bs) +{ + +#if defined(__linux__) + + struct stat st; + struct sg_scsi_id scsiid; + int sg_version; + + if (stat(bs->filename, &st) >= 0 && S_ISCHR(st.st_mode) && + !bdrv_ioctl(bs, SG_GET_VERSION_NUM, &sg_version) && + !bdrv_ioctl(bs, SG_GET_SCSI_ID, &scsiid)) { + DPRINTF("SG device found: type=%d, version=%d\n", + scsiid.scsi_type, sg_version); + return true; + } + +#endif + + return false; +} + static int hdev_open(BlockDriverState *bs, QDict *options, int flags, Error **errp) { BDRVRawState *s = bs->opaque; Error *local_err = NULL; int ret; - const char *filename = qdict_get_str(options, "filename"); #if defined(__APPLE__) && defined(__MACH__) + const char *filename = qdict_get_str(options, "filename"); + if (strstart(filename, "/dev/cdrom", NULL)) { kern_return_t kernResult; io_iterator_t mediaIterator; @@ -2123,16 +2147,6 @@ static int hdev_open(BlockDriverState *bs, QDict *options, int flags, #endif s->type = FTYPE_FILE; -#if defined(__linux__) - { - char resolved_path[ MAXPATHLEN ], *temp; - - temp = realpath(filename, resolved_path); - if (temp && strstart(temp, "/dev/sg", NULL)) { - bs->sg = 1; - } - } -#endif ret = raw_open_common(bs, options, flags, 0, &local_err); if (ret < 0) { @@ -2142,6 +2156,9 @@ static int hdev_open(BlockDriverState *bs, QDict *options, int flags, return ret; } + /* Since this does ioctl the device must be already opened */ + bs->sg = hdev_is_sg(bs); + if (flags & BDRV_O_RDWR) { ret = check_hdev_writable(s); if (ret < 0) { |