* [Qemu-devel] [PATCH 1/2] Stop VM on error in scsi-disk
@ 2009-01-22 13:31 Gleb Natapov
2009-01-22 13:31 ` [Qemu-devel] [PATCH 2/2] Stop VM on error in virtio-blk Gleb Natapov
2009-01-22 19:54 ` [Qemu-devel] [PATCH 1/2] Stop VM on error in scsi-disk Anthony Liguori
0 siblings, 2 replies; 3+ messages in thread
From: Gleb Natapov @ 2009-01-22 13:31 UTC (permalink / raw)
To: qemu-devel
Signed-off-by: Gleb Natapov <gleb@redhat.com>
---
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"))
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [Qemu-devel] [PATCH 2/2] Stop VM on error in virtio-blk.
2009-01-22 13:31 [Qemu-devel] [PATCH 1/2] Stop VM on error in scsi-disk Gleb Natapov
@ 2009-01-22 13:31 ` Gleb Natapov
2009-01-22 19:54 ` [Qemu-devel] [PATCH 1/2] Stop VM on error in scsi-disk Anthony Liguori
1 sibling, 0 replies; 3+ messages in thread
From: Gleb Natapov @ 2009-01-22 13:31 UTC (permalink / raw)
To: qemu-devel
Signed-off-by: Gleb Natapov <gleb@redhat.com>
---
hw/virtio-blk.c | 170 ++++++++++++++++++++++++++++++++++++++++---------------
vl.c | 2 -
2 files changed, 125 insertions(+), 47 deletions(-)
diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index e654cc5..b5ac467 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -11,6 +11,8 @@
*
*/
+#include <qemu-common.h>
+#include <sysemu.h>
#include "virtio-blk.h"
#include "block_int.h"
@@ -19,6 +21,7 @@ typedef struct VirtIOBlock
VirtIODevice vdev;
BlockDriverState *bs;
VirtQueue *vq;
+ void *rq;
} VirtIOBlock;
static VirtIOBlock *to_virtio_blk(VirtIODevice *vdev)
@@ -34,12 +37,44 @@ typedef struct VirtIOBlockReq
struct virtio_blk_outhdr *out;
size_t size;
uint8_t *buffer;
+ struct VirtIOBlockReq *next;
} VirtIOBlockReq;
+static void virtio_blk_req_complete(VirtIOBlockReq *req, int status)
+{
+ VirtIOBlock *s = req->dev;
+
+ req->in->status = status;
+ virtqueue_push(s->vq, &req->elem, req->size + sizeof(*req->in));
+ virtio_notify(&s->vdev, s->vq);
+
+ qemu_free(req->buffer);
+ qemu_free(req);
+}
+
+static int virtio_blk_handle_write_error(VirtIOBlockReq *req, int error)
+{
+ BlockInterfaceErrorAction action = drive_get_onerror(req->dev->bs);
+ VirtIOBlock *s = req->dev;
+
+ if (action == BLOCK_ERR_IGNORE)
+ return 0;
+
+ if ((error == ENOSPC && action == BLOCK_ERR_STOP_ENOSPC)
+ || action == BLOCK_ERR_STOP_ANY) {
+ req->next = s->rq;
+ s->rq = req;
+ vm_stop(0);
+ } else {
+ virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR);
+ }
+
+ return 1;
+}
+
static void virtio_blk_rw_complete(void *opaque, int ret)
{
VirtIOBlockReq *req = opaque;
- VirtIOBlock *s = req->dev;
/* Copy read data to the guest */
if (!ret && !(req->out->type & VIRTIO_BLK_T_OUT)) {
@@ -58,33 +93,71 @@ static void virtio_blk_rw_complete(void *opaque, int ret)
len);
offset += len;
}
+ } else if (ret && (req->out->type & VIRTIO_BLK_T_OUT)) {
+ if (virtio_blk_handle_write_error(req, -ret))
+ return;
}
- req->in->status = ret ? VIRTIO_BLK_S_IOERR : VIRTIO_BLK_S_OK;
- virtqueue_push(s->vq, &req->elem, req->size + sizeof(*req->in));
- virtio_notify(&s->vdev, s->vq);
+ virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);
+}
- qemu_free(req->buffer);
- qemu_free(req);
+static VirtIOBlockReq *virtio_blk_alloc_request(VirtIOBlock *s)
+{
+ VirtIOBlockReq *req = qemu_mallocz(sizeof(*req));
+ if (req != NULL)
+ req->dev = s;
+ return req;
}
static VirtIOBlockReq *virtio_blk_get_request(VirtIOBlock *s)
{
- VirtIOBlockReq *req;
+ VirtIOBlockReq *req = virtio_blk_alloc_request(s);
- req = qemu_mallocz(sizeof(*req));
- if (req == NULL)
- return NULL;
-
- req->dev = s;
- if (!virtqueue_pop(s->vq, &req->elem)) {
- qemu_free(req);
- return NULL;
+ if (req != NULL) {
+ if (!virtqueue_pop(s->vq, &req->elem)) {
+ qemu_free(req);
+ return NULL;
+ }
}
return req;
}
+static int virtio_blk_handle_write(VirtIOBlockReq *req)
+{
+ if (!req->buffer) {
+ size_t offset = 0;
+ int i;
+
+ for (i = 1; i < req->elem.out_num; i++)
+ req->size += req->elem.out_sg[i].iov_len;
+
+ req->buffer = qemu_memalign(512, req->size);
+ if (req->buffer == NULL) {
+ qemu_free(req);
+ return -1;
+ }
+
+ /* We copy the data from the SG list to avoid splitting up the request.
+ This helps performance a lot until we can pass full sg lists as AIO
+ operations */
+ for (i = 1; i < req->elem.out_num; i++) {
+ size_t len;
+
+ len = MIN(req->elem.out_sg[i].iov_len,
+ req->size - offset);
+ memcpy(req->buffer + offset,
+ req->elem.out_sg[i].iov_base,
+ len);
+ offset += len;
+ }
+ }
+
+ bdrv_aio_write(req->dev->bs, req->out->sector, req->buffer, req->size / 512,
+ virtio_blk_rw_complete, req);
+ return 0;
+}
+
static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq)
{
VirtIOBlock *s = to_virtio_blk(vdev);
@@ -115,36 +188,8 @@ static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq)
virtio_notify(vdev, vq);
qemu_free(req);
} else if (req->out->type & VIRTIO_BLK_T_OUT) {
- size_t offset;
-
- for (i = 1; i < req->elem.out_num; i++)
- req->size += req->elem.out_sg[i].iov_len;
-
- req->buffer = qemu_memalign(512, req->size);
- if (req->buffer == NULL) {
- qemu_free(req);
+ if (virtio_blk_handle_write(req) < 0)
break;
- }
-
- /* We copy the data from the SG list to avoid splitting up the request. This helps
- performance a lot until we can pass full sg lists as AIO operations */
- offset = 0;
- for (i = 1; i < req->elem.out_num; i++) {
- size_t len;
-
- len = MIN(req->elem.out_sg[i].iov_len,
- req->size - offset);
- memcpy(req->buffer + offset,
- req->elem.out_sg[i].iov_base,
- len);
- offset += len;
- }
-
- bdrv_aio_write(s->bs, req->out->sector,
- req->buffer,
- req->size / 512,
- virtio_blk_rw_complete,
- req);
} else {
for (i = 0; i < req->elem.in_num - 1; i++)
req->size += req->elem.in_sg[i].iov_len;
@@ -169,6 +214,22 @@ static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq)
*/
}
+static void virtio_blk_dma_restart_cb(void *opaque, int running)
+{
+ VirtIOBlock *s = opaque;
+ VirtIOBlockReq *req = s->rq;
+
+ if (!running)
+ return;
+
+ s->rq = NULL;
+
+ while (req) {
+ virtio_blk_handle_write(req);
+ req = req->next;
+ }
+}
+
static void virtio_blk_reset(VirtIODevice *vdev)
{
/*
@@ -203,17 +264,32 @@ static uint32_t virtio_blk_get_features(VirtIODevice *vdev)
static void virtio_blk_save(QEMUFile *f, void *opaque)
{
VirtIOBlock *s = opaque;
+ VirtIOBlockReq *req = s->rq;
+
virtio_save(&s->vdev, f);
+
+ while (req) {
+ qemu_put_sbyte(f, 1);
+ qemu_put_buffer(f, (unsigned char*)&req->elem, sizeof(req->elem));
+ req = req->next;
+ }
+ qemu_put_sbyte(f, 0);
}
static int virtio_blk_load(QEMUFile *f, void *opaque, int version_id)
{
VirtIOBlock *s = opaque;
- if (version_id != 1)
+ if (version_id != 2)
return -EINVAL;
virtio_load(&s->vdev, f);
+ while (qemu_get_sbyte(f)) {
+ VirtIOBlockReq *req = virtio_blk_alloc_request(s);
+ qemu_get_buffer(f, (unsigned char*)&req->elem, sizeof(req->elem));
+ req->next = s->rq;
+ s->rq = req->next;
+ }
return 0;
}
@@ -237,12 +313,14 @@ void *virtio_blk_init(PCIBus *bus, BlockDriverState *bs)
s->vdev.get_features = virtio_blk_get_features;
s->vdev.reset = virtio_blk_reset;
s->bs = bs;
+ s->rq = NULL;
bdrv_guess_geometry(s->bs, &cylinders, &heads, &secs);
bdrv_set_geometry_hint(s->bs, cylinders, heads, secs);
s->vq = virtio_add_queue(&s->vdev, 128, virtio_blk_handle_output);
- register_savevm("virtio-blk", virtio_blk_id++, 1,
+ qemu_add_vm_change_state_handler(virtio_blk_dma_restart_cb, s);
+ register_savevm("virtio-blk", virtio_blk_id++, 2,
virtio_blk_save, virtio_blk_load, s);
return s;
diff --git a/vl.c b/vl.c
index a325c81..32f3cfb 100644
--- a/vl.c
+++ b/vl.c
@@ -2432,7 +2432,7 @@ 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 && type != IF_SCSI) {
+ if (type != IF_IDE && type != IF_SCSI && type != IF_VIRTIO) {
fprintf(stderr, "werror is no supported by this format\n");
return -1;
}
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [Qemu-devel] [PATCH 1/2] Stop VM on error in scsi-disk
2009-01-22 13:31 [Qemu-devel] [PATCH 1/2] Stop VM on error in scsi-disk Gleb Natapov
2009-01-22 13:31 ` [Qemu-devel] [PATCH 2/2] Stop VM on error in virtio-blk Gleb Natapov
@ 2009-01-22 19:54 ` Anthony Liguori
1 sibling, 0 replies; 3+ messages in thread
From: Anthony Liguori @ 2009-01-22 19:54 UTC (permalink / raw)
To: qemu-devel
Gleb Natapov wrote:
> Signed-off-by: Gleb Natapov <gleb@redhat.com>
>
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"))
>
>
>
>
>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2009-01-22 19:55 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-01-22 13:31 [Qemu-devel] [PATCH 1/2] Stop VM on error in scsi-disk Gleb Natapov
2009-01-22 13:31 ` [Qemu-devel] [PATCH 2/2] Stop VM on error in virtio-blk Gleb Natapov
2009-01-22 19:54 ` [Qemu-devel] [PATCH 1/2] Stop VM on error in scsi-disk Anthony Liguori
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).