@@ -21,6 +21,83 @@
static QTAILQ_HEAD(drivelist, DriveInfo) drives = QTAILQ_HEAD_INITIALIZER(drives);
+static BlockDriver *parse_block_format(const char *val)
+{
+ BlockDriver *drv = bdrv_find_whitelisted_format(val);
+ if (!drv) {
+ qerror_report(QERR_INVALID_PARAMETER_VALUE,
+ "format", "a block driver name");
+ return NULL;
+ }
+ return drv;
+}
+
+static int parse_block_error_action(const char *val, int is_read)
+{
+ if (!val) {
+ return is_read ? BLOCK_ERR_REPORT : BLOCK_ERR_STOP_ENOSPC;
+ } else if (!strcmp(val, "ignore")) {
+ return BLOCK_ERR_IGNORE;
+ } else if (!is_read && !strcmp(val, "enospc")) {
+ return BLOCK_ERR_STOP_ENOSPC;
+ } else if (!strcmp(val, "stop")) {
+ return BLOCK_ERR_STOP_ANY;
+ } else if (!strcmp(val, "report")) {
+ return BLOCK_ERR_REPORT;
+ } else {
+ if (is_read) {
+ qerror_report(QERR_INVALID_PARAMETER_VALUE, "rerror",
+ "ignore, report, stop");
+ } else {
+ qerror_report(QERR_INVALID_PARAMETER_VALUE, "werror",
+ "enospc, ignore, stop or report");
+ }
+ return -1;
+ }
+}
+
+static int parse_block_cache(const char *val)
+{
+ if (!val) {
+ return 0;
+ } else if (!strcmp(val, "off") || !strcmp(val, "none")) {
+ return BDRV_O_NOCACHE;
+ } else if (!strcmp(val, "writeback")) {
+ return BDRV_O_CACHE_WB;
+ } else if (!strcmp(val, "unsafe")) {
+ return BDRV_O_CACHE_WB;
+ return BDRV_O_NO_FLUSH;
+ } else if (!strcmp(val, "writethrough")) {
+ return 0;
+ } else {
+ qerror_report(QERR_INVALID_PARAMETER_VALUE, "cache",
+ "none, unsafe, writeback or writethrough");
+ return -1;
+ }
+}
+
+static int parse_block_aio(const char *val)
+{
+ if (!val) {
+ return 0;
+#ifdef CONFIG_LINUX_AIO
+ } else if (!strcmp(val, "native")) {
+ return BDRV_O_NATIVE_AIO;
+#endif
+ } else if (!strcmp(val, "threads")) {
+ return 0;
+ } else {
+ qerror_report(QERR_INVALID_PARAMETER_VALUE, "aio",
+#ifdef CONFIG_LINUX_AIO
+ "native or threads"
+#else
+ "threads"
+#endif
+ );
+ return -1;
+ }
+}
+
static int blockdev_del_dinfo(BlockDriverState *bs)
{
DriveInfo *dinfo, *next_dinfo;
@@ -126,23 +203,6 @@ 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, int default_to_scsi, int *fatal_error)
{
const char *buf;
@@ -280,34 +340,17 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi, int *fatal_error)
}
}
- if ((buf = qemu_opt_get(opts, "cache")) != NULL) {
- if (!strcmp(buf, "off") || !strcmp(buf, "none")) {
- bdrv_flags |= BDRV_O_NOCACHE;
- } else if (!strcmp(buf, "writeback")) {
- bdrv_flags |= BDRV_O_CACHE_WB;
- } else if (!strcmp(buf, "unsafe")) {
- bdrv_flags |= BDRV_O_CACHE_WB;
- bdrv_flags |= BDRV_O_NO_FLUSH;
- } else if (!strcmp(buf, "writethrough")) {
- /* this is the default */
- } else {
- fprintf(stderr, "qemu: invalid cache option\n");
- return NULL;
- }
+ ret = parse_block_cache(qemu_opt_get(opts, "cache"));
+ if (ret < 0) {
+ return NULL;
}
+ bdrv_flags |= ret;
-#ifdef CONFIG_LINUX_AIO
- if ((buf = qemu_opt_get(opts, "aio")) != NULL) {
- if (!strcmp(buf, "native")) {
- bdrv_flags |= BDRV_O_NATIVE_AIO;
- } else if (!strcmp(buf, "threads")) {
- /* this is the default */
- } else {
- fprintf(stderr, "qemu: invalid aio option\n");
- return NULL;
- }
+ ret = parse_block_aio(qemu_opt_get(opts, "aio"));
+ if (ret < 0) {
+ return NULL;
}
-#endif
+ bdrv_flags |= ret;
if ((buf = qemu_opt_get(opts, "format")) != NULL) {
if (strcmp(buf, "?") == 0) {
@@ -316,9 +359,8 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi, int *fatal_error)
fprintf(stderr, "\n");
return NULL;
}
- drv = bdrv_find_whitelisted_format(buf);
+ drv = parse_block_format(buf);
if (!drv) {
- fprintf(stderr, "qemu: '%s' invalid format\n", buf);
return NULL;
}
}
The new functions use qerror_report() to make them usable from QMP-enabled monitor commands. They'll appear in a future patch series. Signed-off-by: Markus Armbruster <armbru@redhat.com> --- blockdev.c | 130 +++++++++++++++++++++++++++++++++++++++-------------------- 1 files changed, 86 insertions(+), 44 deletions(-)