aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Wolf <kwolf@redhat.com>2009-11-27 13:25:37 +0100
committerAnthony Liguori <aliguori@us.ibm.com>2009-12-03 11:45:49 -0600
commite9b2e81889d9877415710484b876ee57a42b0bcb (patch)
tree0deec76b2a7bd0b80e96f789243684d07aa7f8e1
parentf785009961c335a4c9c735b2bf96d5a0d2e5bde1 (diff)
Introduce rerror option for drives
rerror controls the action to be taken when an error occurs while accessing the guest image file. It corresponds to werror which already controls the action take for write errors. This purely introduces parsing rerror command line option into the right structures, real support for it in the device emulation is added in the following patches. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
-rw-r--r--qemu-config.c3
-rw-r--r--sysemu.h1
-rw-r--r--vl.c59
3 files changed, 44 insertions, 19 deletions
diff --git a/qemu-config.c b/qemu-config.c
index 590fc052fc..92b5363ecf 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -65,6 +65,9 @@ QemuOptsList qemu_drive_opts = {
.name = "serial",
.type = QEMU_OPT_STRING,
},{
+ .name = "rerror",
+ .type = QEMU_OPT_STRING,
+ },{
.name = "werror",
.type = QEMU_OPT_STRING,
},{
diff --git a/sysemu.h b/sysemu.h
index c79a019e73..efed771d0f 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -180,6 +180,7 @@ typedef struct DriveInfo {
int bus;
int unit;
QemuOpts *opts;
+ BlockInterfaceErrorAction on_read_error;
BlockInterfaceErrorAction on_write_error;
char serial[BLOCK_SERIAL_STRLEN + 1];
QTAILQ_ENTRY(DriveInfo) next;
diff --git a/vl.c b/vl.c
index b0a2e883d4..3d64fc6534 100644
--- a/vl.c
+++ b/vl.c
@@ -1964,16 +1964,12 @@ BlockInterfaceErrorAction drive_get_on_error(
{
DriveInfo *dinfo;
- if (is_read) {
- return BLOCK_ERR_REPORT;
- }
-
QTAILQ_FOREACH(dinfo, &drives, next) {
if (dinfo->bdrv == bdrv)
- return dinfo->on_write_error;
+ return is_read ? dinfo->on_read_error : dinfo->on_write_error;
}
- return BLOCK_ERR_STOP_ENOSPC;
+ return is_read ? BLOCK_ERR_REPORT : BLOCK_ERR_STOP_ENOSPC;
}
static void bdrv_format_print(void *opaque, const char *name)
@@ -1989,6 +1985,23 @@ void drive_uninit(DriveInfo *dinfo)
qemu_free(dinfo);
}
+static int parse_block_error_action(const char *buf, int is_read)
+{
+ if (!strcmp(buf, "ignore")) {
+ return BLOCK_ERR_IGNORE;
+ } else if (!is_read && !strcmp(buf, "enospc")) {
+ return BLOCK_ERR_STOP_ENOSPC;
+ } else if (!strcmp(buf, "stop")) {
+ return BLOCK_ERR_STOP_ANY;
+ } else if (!strcmp(buf, "report")) {
+ return BLOCK_ERR_REPORT;
+ } else {
+ fprintf(stderr, "qemu: '%s' invalid %s error action\n",
+ buf, is_read ? "read" : "write");
+ return -1;
+ }
+}
+
DriveInfo *drive_init(QemuOpts *opts, void *opaque,
int *fatal_error)
{
@@ -2008,7 +2021,8 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque,
int cache;
int aio = 0;
int ro = 0;
- int bdrv_flags, onerror;
+ int bdrv_flags;
+ int on_read_error, on_write_error;
const char *devaddr;
DriveInfo *dinfo;
int snapshot = 0;
@@ -2169,22 +2183,28 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque,
}
}
- onerror = BLOCK_ERR_STOP_ENOSPC;
+ on_write_error = BLOCK_ERR_STOP_ENOSPC;
if ((buf = qemu_opt_get(opts, "werror")) != NULL) {
if (type != IF_IDE && type != IF_SCSI && type != IF_VIRTIO) {
fprintf(stderr, "werror is no supported by this format\n");
return NULL;
}
- if (!strcmp(buf, "ignore"))
- onerror = BLOCK_ERR_IGNORE;
- else if (!strcmp(buf, "enospc"))
- onerror = BLOCK_ERR_STOP_ENOSPC;
- else if (!strcmp(buf, "stop"))
- onerror = BLOCK_ERR_STOP_ANY;
- else if (!strcmp(buf, "report"))
- onerror = BLOCK_ERR_REPORT;
- else {
- fprintf(stderr, "qemu: '%s' invalid write error action\n", buf);
+
+ on_write_error = parse_block_error_action(buf, 0);
+ if (on_write_error < 0) {
+ return NULL;
+ }
+ }
+
+ on_read_error = BLOCK_ERR_REPORT;
+ if ((buf = qemu_opt_get(opts, "rerror")) != NULL) {
+ if (1) {
+ fprintf(stderr, "rerror is no supported by this format\n");
+ return NULL;
+ }
+
+ on_read_error = parse_block_error_action(buf, 1);
+ if (on_read_error < 0) {
return NULL;
}
}
@@ -2268,7 +2288,8 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque,
dinfo->type = type;
dinfo->bus = bus_id;
dinfo->unit = unit_id;
- dinfo->on_write_error = onerror;
+ dinfo->on_read_error = on_read_error;
+ dinfo->on_write_error = on_write_error;
dinfo->opts = opts;
if (serial)
strncpy(dinfo->serial, serial, sizeof(serial));