From patchwork Wed Nov 24 08:40:04 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Nicholas A. Bellinger" X-Patchwork-Id: 72814 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 5EA5DB7080 for ; Wed, 24 Nov 2010 19:41:14 +1100 (EST) Received: from localhost ([127.0.0.1]:60201 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PLAud-0000QP-7S for incoming@patchwork.ozlabs.org; Wed, 24 Nov 2010 03:41:11 -0500 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 Received: from [98.139.91.66] by nm19.bullet.mail.sp2.yahoo.com with NNFMP; 24 Nov 2010 08:40:07 -0000 Received: from [98.139.91.33] by tm6.bullet.mail.sp2.yahoo.com with NNFMP; 24 Nov 2010 08:40:07 -0000 Received: from [127.0.0.1] by omp1033.mail.sp2.yahoo.com with NNFMP; 24 Nov 2010 08:40:07 -0000 X-Yahoo-Newman-Id: 819539.81247.bm@omp1033.mail.sp2.yahoo.com Received: (qmail 35123 invoked from network); 24 Nov 2010 08:40:07 -0000 Received: from localhost.localdomain (nab@70.231.233.146 with login) by smtp107.sbc.mail.mud.yahoo.com with SMTP; 24 Nov 2010 00:40:06 -0800 PST X-Yahoo-SMTP: fzDSGlOswBCWnIOrNw7KwwK1j9PqyNbe5PtLKiS4dDU.UNl_t6bdEZu9tTLW X-YMail-OSG: lVbnj5kVM1nMn0Y.fMxHfpPnIYDydUkBC7Bn9LLm.6t6X24 Id8TMCprfDdpJ.ZVugJVgc.XiVQYuh4HPdzxXnSg44_fhUwJOSh8lH0OTnUZ qBNOgXhsuq3RKLPzlngMtl3JIz32ExBMrRdW88mgoWPNrtM7AWiANNDH.Kn. 5Znezj9rMn1DlujDxtMFbY2ok5Nhqw1IjYcZuzveK9oKddaYhRG5et5x7RMA aca.TxwDzIoBhWY7rGi8HXVXWZO0CkfWj6OGqxAz5xNTveq5R02q5pOl8ERw V5Z0mWDpkKkPoG8IJwH0lJ5asjM2A627corBCw7zoAVeY9Eh1NSuWCIVBKQx ArI4px5bXQfG3 X-Yahoo-Newman-Property: ymail-3 From: "Nicholas A. Bellinger" To: Hannes Reinecke , Kevin Wolf Date: Wed, 24 Nov 2010 00:40:04 -0800 Message-Id: <1290588004-8872-1-git-send-email-nab@linux-iscsi.org> X-Mailer: git-send-email 1.5.6.5 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. Cc: qemu-devel , Stefan Hajnoczi , Gerd Hoffmann , Nicholas Bellinger , Paolo Bonzini Subject: [Qemu-devel] [PATCH 1/5] block: Add top level BSG support X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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;