Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
dimara authored and Stefan Hajnoczi committed Jun 23, 2015
1 parent a93a398 commit 3307ed7
Showing 1 changed file with 28 additions and 11 deletions.
39 changes: 28 additions & 11 deletions block/raw-posix.c
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand All @@ -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) {
Expand Down

0 comments on commit 3307ed7

Please sign in to comment.