From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1LQ5dv-0005Qa-V8 for qemu-devel@nongnu.org; Thu, 22 Jan 2009 14:55:12 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1LQ5dq-0005I8-Ve for qemu-devel@nongnu.org; Thu, 22 Jan 2009 14:55:10 -0500 Received: from [199.232.76.173] (port=59622 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1LQ5dp-0005Ha-BM for qemu-devel@nongnu.org; Thu, 22 Jan 2009 14:55:05 -0500 Received: from e6.ny.us.ibm.com ([32.97.182.146]:36341) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1LQ5do-0000HN-SL for qemu-devel@nongnu.org; Thu, 22 Jan 2009 14:55:05 -0500 Received: from d01relay02.pok.ibm.com (d01relay02.pok.ibm.com [9.56.227.234]) by e6.ny.us.ibm.com (8.13.1/8.13.1) with ESMTP id n0MJtHLL007667 for ; Thu, 22 Jan 2009 14:55:17 -0500 Received: from d01av01.pok.ibm.com (d01av01.pok.ibm.com [9.56.224.215]) by d01relay02.pok.ibm.com (8.13.8/8.13.8/NCO v9.1) with ESMTP id n0MJsvPT195644 for ; Thu, 22 Jan 2009 14:54:57 -0500 Received: from d01av01.pok.ibm.com (loopback [127.0.0.1]) by d01av01.pok.ibm.com (8.12.11.20060308/8.13.3) with ESMTP id n0MJsvkF025908 for ; Thu, 22 Jan 2009 14:54:57 -0500 Received: from squirrel.codemonkey.ws (sig-9-65-90-232.mts.ibm.com [9.65.90.232]) by d01av01.pok.ibm.com (8.12.11.20060308/8.12.11) with ESMTP id n0MJsuS0025861 for ; Thu, 22 Jan 2009 14:54:57 -0500 Message-ID: <4978CF05.5010701@us.ibm.com> Date: Thu, 22 Jan 2009 13:54:45 -0600 From: Anthony Liguori MIME-Version: 1.0 Subject: Re: [Qemu-devel] [PATCH 1/2] Stop VM on error in scsi-disk References: <20090122133142.16090.9308.stgit@dhcp-1-237.tlv.redhat.com> In-Reply-To: <20090122133142.16090.9308.stgit@dhcp-1-237.tlv.redhat.com> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Gleb Natapov wrote: > Signed-off-by: Gleb Natapov > Applied both. Thanks. Regards, Anthony Liguori > --- > > hw/scsi-disk.c | 86 +++++++++++++++++++++++++++++++++++++++++++++----------- > vl.c | 4 +-- > 2 files changed, 71 insertions(+), 19 deletions(-) > > diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c > index 744573e..9eda2f6 100644 > --- a/hw/scsi-disk.c > +++ b/hw/scsi-disk.c > @@ -42,6 +42,8 @@ do { fprintf(stderr, "scsi-disk: " fmt , ##args); } while (0) > #define SCSI_DMA_BUF_SIZE 131072 > #define SCSI_MAX_INQUIRY_LEN 256 > > +#define SCSI_REQ_STATUS_RETRY 0x01 > + > typedef struct SCSIRequest { > SCSIDeviceState *dev; > uint32_t tag; > @@ -55,6 +57,7 @@ typedef struct SCSIRequest { > uint8_t *dma_buf; > BlockDriverAIOCB *aiocb; > struct SCSIRequest *next; > + uint32_t status; > } SCSIRequest; > > struct SCSIDeviceState > @@ -92,6 +95,7 @@ static SCSIRequest *scsi_new_request(SCSIDeviceState *s, uint32_t tag) > r->sector_count = 0; > r->buf_len = 0; > r->aiocb = NULL; > + r->status = 0; > > r->next = s->requests; > s->requests = r; > @@ -212,18 +216,42 @@ static void scsi_read_data(SCSIDevice *d, uint32_t tag) > r->sector_count -= n; > } > > +static int scsi_handle_write_error(SCSIRequest *r, int error) > +{ > + BlockInterfaceErrorAction action = drive_get_onerror(r->dev->bdrv); > + > + if (action == BLOCK_ERR_IGNORE) > + return 0; > + > + if ((error == ENOSPC && action == BLOCK_ERR_STOP_ENOSPC) > + || action == BLOCK_ERR_STOP_ANY) { > + r->status |= SCSI_REQ_STATUS_RETRY; > + vm_stop(0); > + } else { > + scsi_command_complete(r, STATUS_CHECK_CONDITION, > + SENSE_HARDWARE_ERROR); > + } > + > + return 1; > +} > + > static void scsi_write_complete(void * opaque, int ret) > { > SCSIRequest *r = (SCSIRequest *)opaque; > SCSIDeviceState *s = r->dev; > uint32_t len; > + uint32_t n; > + > + r->aiocb = NULL; > > if (ret) { > - fprintf(stderr, "scsi-disc: IO write error\n"); > - exit(1); > + if (scsi_handle_write_error(r, -ret)) > + return; > } > > - r->aiocb = NULL; > + n = r->buf_len / 512; > + r->sector += n; > + r->sector_count -= n; > if (r->sector_count == 0) { > scsi_command_complete(r, STATUS_GOOD, SENSE_NO_SENSE); > } else { > @@ -237,13 +265,30 @@ static void scsi_write_complete(void * opaque, int ret) > } > } > > +static void scsi_write_request(SCSIRequest *r) > +{ > + SCSIDeviceState *s = r->dev; > + uint32_t n; > + > + n = r->buf_len / 512; > + if (n) { > + r->aiocb = bdrv_aio_write(s->bdrv, r->sector, r->dma_buf, n, > + scsi_write_complete, r); > + if (r->aiocb == NULL) > + scsi_command_complete(r, STATUS_CHECK_CONDITION, > + SENSE_HARDWARE_ERROR); > + } else { > + /* Invoke completion routine to fetch data from host. */ > + scsi_write_complete(r, 0); > + } > +} > + > /* Write data to a scsi device. Returns nonzero on failure. > The transfer may complete asynchronously. */ > static int scsi_write_data(SCSIDevice *d, uint32_t tag) > { > SCSIDeviceState *s = d->state; > SCSIRequest *r; > - uint32_t n; > > DPRINTF("Write data tag=0x%x\n", tag); > r = scsi_find_request(s, tag); > @@ -252,25 +297,31 @@ static int scsi_write_data(SCSIDevice *d, uint32_t tag) > scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_HARDWARE_ERROR); > return 1; > } > + > if (r->aiocb) > BADF("Data transfer already in progress\n"); > - n = r->buf_len / 512; > - if (n) { > - r->aiocb = bdrv_aio_write(s->bdrv, r->sector, r->dma_buf, n, > - scsi_write_complete, r); > - if (r->aiocb == NULL) > - scsi_command_complete(r, STATUS_CHECK_CONDITION, > - SENSE_HARDWARE_ERROR); > - r->sector += n; > - r->sector_count -= n; > - } else { > - /* Invoke completion routine to fetch data from host. */ > - scsi_write_complete(r, 0); > - } > + > + scsi_write_request(r); > > return 0; > } > > +static void scsi_dma_restart_cb(void *opaque, int running) > +{ > + SCSIDeviceState *s = opaque; > + SCSIRequest *r = s->requests; > + if (!running) > + return; > + > + while (r) { > + if (r->status & SCSI_REQ_STATUS_RETRY) { > + r->status &= ~SCSI_REQ_STATUS_RETRY; > + scsi_write_request(r); > + } > + r = r->next; > + } > +} > + > /* Return a pointer to the data buffer. */ > static uint8_t *scsi_get_buf(SCSIDevice *d, uint32_t tag) > { > @@ -822,6 +873,7 @@ SCSIDevice *scsi_disk_init(BlockDriverState *bdrv, int tcq, > sizeof(s->drive_serial_str)); > if (strlen(s->drive_serial_str) == 0) > pstrcpy(s->drive_serial_str, sizeof(s->drive_serial_str), "0"); > + qemu_add_vm_change_state_handler(scsi_dma_restart_cb, s); > d = (SCSIDevice *)qemu_mallocz(sizeof(SCSIDevice)); > d->state = s; > d->destroy = scsi_destroy; > diff --git a/vl.c b/vl.c > index 045b09f..a325c81 100644 > --- a/vl.c > +++ b/vl.c > @@ -2432,8 +2432,8 @@ static int drive_init(struct drive_opt *arg, int snapshot, > > onerror = BLOCK_ERR_REPORT; > if (get_param_value(buf, sizeof(serial), "werror", str)) { > - if (type != IF_IDE) { > - fprintf(stderr, "werror is supported only by IDE\n"); > + if (type != IF_IDE && type != IF_SCSI) { > + fprintf(stderr, "werror is no supported by this format\n"); > return -1; > } > if (!strcmp(buf, "ignore")) > > > > >