From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from [140.186.70.92] (port=43461 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PLAte-0000QK-Vw for qemu-devel@nongnu.org; Wed, 24 Nov 2010 03:40:12 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PLAtd-0007Aw-CR for qemu-devel@nongnu.org; Wed, 24 Nov 2010 03:40:10 -0500 Received: from nm19-vm0.bullet.mail.sp2.yahoo.com ([98.139.91.216]:35295) by eggs.gnu.org with smtp (Exim 4.71) (envelope-from ) id 1PLAtc-0007Af-TV for qemu-devel@nongnu.org; Wed, 24 Nov 2010 03:40:09 -0500 From: "Nicholas A. Bellinger" Date: Wed, 24 Nov 2010 00:40:04 -0800 Message-Id: <1290588004-8872-1-git-send-email-nab@linux-iscsi.org> Subject: [Qemu-devel] [PATCH 1/5] block: Add top level BSG support List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Hannes Reinecke , Kevin Wolf Cc: qemu-devel , Stefan Hajnoczi , Gerd Hoffmann , Nicholas Bellinger , Paolo Bonzini From: Nicholas Bellinger This patch adds top level BSG support to QEMU-KVM block and adds the BDS_* prefixed defines for SG_IO and BSG. It adds the BDS_SCSI_GENERIC and BDS_BSG assignments in block/raw-posix.c:hdev_open() using S_ISCHR() and major(st.st_rdev) in order to determine when we are dealing with scsi-generic or scsi-bsg backstores. Signed-off-by: Nicholas A. Bellinger --- block.c | 7 +++++- block.h | 1 + block/raw-posix.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++--- block_int.h | 6 +++++ 4 files changed, 74 insertions(+), 5 deletions(-) diff --git a/block.c b/block.c index 6b505fb..8faf25d 100644 --- a/block.c +++ b/block.c @@ -1340,7 +1340,12 @@ int bdrv_is_read_only(BlockDriverState *bs) int bdrv_is_sg(BlockDriverState *bs) { - return bs->sg; + return bs->sg == BDS_SCSI_GENERIC; +} + +int bdrv_is_bsg(BlockDriverState *bs) +{ + return bs->sg == BDS_BSG; } int bdrv_enable_write_cache(BlockDriverState *bs) diff --git a/block.h b/block.h index 78ecfac..5869c8c 100644 --- a/block.h +++ b/block.h @@ -174,6 +174,7 @@ void bdrv_set_removable(BlockDriverState *bs, int removable); int bdrv_is_removable(BlockDriverState *bs); int bdrv_is_read_only(BlockDriverState *bs); int bdrv_is_sg(BlockDriverState *bs); +int bdrv_is_bsg(BlockDriverState *bs); int bdrv_enable_write_cache(BlockDriverState *bs); int bdrv_is_inserted(BlockDriverState *bs); int bdrv_media_changed(BlockDriverState *bs); diff --git a/block/raw-posix.c b/block/raw-posix.c index bf89717..2802c97 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -53,6 +53,7 @@ #include #include #include +#include #endif #if defined (__FreeBSD__) || defined(__FreeBSD_kernel__) #include @@ -885,13 +886,69 @@ static int hdev_open(BlockDriverState *bs, const char *filename, int flags) s->type = FTYPE_FILE; #if defined(__linux__) { - char resolved_path[ MAXPATHLEN ], *temp; + struct stat st, st2; + FILE *file; + char major[8], dev[64], path[128], *p, *buf; + int ch, i; - temp = realpath(filename, resolved_path); - if (temp && strstart(temp, "/dev/sg", NULL)) { - bs->sg = 1; + if (stat(filename, &st) < 0) { + printf("stat() failed errno: %d\n", errno); + return -1; + } + + if (major(st.st_rdev) == SCSI_GENERIC_MAJOR) { + bs->sg = BDS_SCSI_GENERIC; + goto out; + } + + memset(major, 0, 8); + memset(dev, 0, 64); + memset(path, 0, 128); + + buf = strdup(filename); + if (!buf) + goto out; + /* + * Locate the device name from the path, we are interested + * in the last strsep() token.. + */ + while ((p = strsep(&buf, "/"))) + snprintf(dev, 64, "%s", p); + /* + * Check to sure the sysfs entry exists before calling open + */ + snprintf(path, 128, "/sys/class/bsg/%s/dev", dev); + if (stat(path, &st2) < 0) { + free(buf); + goto out; + } + + file = fopen(path, "r"); + if (!file) { + printf("fopen() failed for BSG sysfs path: %s\n", path); + free(buf); + goto out; + } + ch = fgetc(file); + for (i = 0; i < 7; i++) { + if (ch == ':') { + major[i] = '\0'; + break; + } + major[i] = ch; + ch = fgetc(file); } + fclose(file); + /* + * If the major returned by /sys/class/bsg/$H:C:T:L/dev matches + * stat(), then we signal BDS_BSG usage. + */ + if (major(st.st_rdev) == atoi(major)) + bs->sg = BDS_BSG; + + free(buf); } +out: #endif return raw_open_common(bs, filename, flags, 0); diff --git a/block_int.h b/block_int.h index 3c3adb5..8fdc816 100644 --- a/block_int.h +++ b/block_int.h @@ -40,6 +40,11 @@ #define BLOCK_OPT_CLUSTER_SIZE "cluster_size" #define BLOCK_OPT_PREALLOC "preallocation" +/* Used for BlockDriverState->sg */ +#define BDS_NONE 0 +#define BDS_SCSI_GENERIC 1 +#define BDS_BSG 2 + typedef struct AIOPool { void (*cancel)(BlockDriverAIOCB *acb); int aiocb_size; @@ -150,6 +155,7 @@ struct BlockDriverState { int encrypted; /* if true, the media is encrypted */ int valid_key; /* if true, a valid encryption key has been set */ int sg; /* if true, the device is a /dev/sg* */ + int fd; /* Used for BSG file descriptor */ /* event callback when inserting/removing */ void (*change_cb)(void *opaque); void *change_opaque; -- 1.5.6.5