From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MTGji-0001Vy-H0 for qemu-devel@nongnu.org; Tue, 21 Jul 2009 10:54:34 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MTGjc-0001N5-KY for qemu-devel@nongnu.org; Tue, 21 Jul 2009 10:54:32 -0400 Received: from [199.232.76.173] (port=38355 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MTGjc-0001Mk-Dq for qemu-devel@nongnu.org; Tue, 21 Jul 2009 10:54:28 -0400 Received: from mx2.redhat.com ([66.187.237.31]:41720) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1MTGjb-0006mX-Cd for qemu-devel@nongnu.org; Tue, 21 Jul 2009 10:54:27 -0400 Received: from int-mx2.corp.redhat.com (int-mx2.corp.redhat.com [172.16.27.26]) by mx2.redhat.com (8.13.8/8.13.8) with ESMTP id n6LEsQGS004438 for ; Tue, 21 Jul 2009 10:54:26 -0400 From: Gerd Hoffmann Date: Tue, 21 Jul 2009 16:54:09 +0200 Message-Id: <1248188049-16871-6-git-send-email-kraxel@redhat.com> In-Reply-To: <1248188049-16871-1-git-send-email-kraxel@redhat.com> References: <1248188049-16871-1-git-send-email-kraxel@redhat.com> Subject: [Qemu-devel] [PATCH 5/5] switch -drive to QemuOpts. List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Gerd Hoffmann Demo QemuOpts in action ;) Implementing a alternative way to specify the filename should be just a few lines of code now once we decided how the cmd line syntax should look like. Signed-off-by: Gerd Hoffmann --- hw/device-hotplug.c | 12 ++-- sysemu.h | 15 +--- vl.c | 214 +++++++++++++++++++++++++++------------------------ 3 files changed, 124 insertions(+), 117 deletions(-) diff --git a/hw/device-hotplug.c b/hw/device-hotplug.c index 8f0dec8..fd4cc3f 100644 --- a/hw/device-hotplug.c +++ b/hw/device-hotplug.c @@ -28,19 +28,19 @@ #include "block_int.h" #include "sysemu.h" -DriveInfo *add_init_drive(const char *opts) +DriveInfo *add_init_drive(const char *optstr) { int fatal_error; DriveInfo *dinfo; - DriveOpt *dopt; + QemuOpts *opts; - dopt = drive_add(NULL, "%s", opts); - if (!dopt) + opts = drive_add(NULL, "%s", optstr); + if (!opts) return NULL; - dinfo = drive_init(dopt, 0, current_machine, &fatal_error); + dinfo = drive_init(opts, current_machine, &fatal_error); if (!dinfo) { - drive_remove(dopt); + qemu_opts_del(opts); return NULL; } diff --git a/sysemu.h b/sysemu.h index ec55877..c944b28 100644 --- a/sysemu.h +++ b/sysemu.h @@ -3,6 +3,7 @@ /* Misc. things related to the system emulator. */ #include "qemu-common.h" +#include "qemu-opts.h" #include "sys-queue.h" #ifdef _WIN32 @@ -159,12 +160,6 @@ typedef enum { #define BLOCK_SERIAL_STRLEN 20 -typedef struct DriveOpt { - const char *file; - char opt[1024]; - TAILQ_ENTRY(DriveOpt) next; -} DriveOpt; - typedef struct DriveInfo { BlockDriverState *bdrv; char *id; @@ -172,7 +167,7 @@ typedef struct DriveInfo { BlockInterfaceType type; int bus; int unit; - DriveOpt *opt; + QemuOpts *opts; BlockInterfaceErrorAction onerror; char serial[BLOCK_SERIAL_STRLEN + 1]; TAILQ_ENTRY(DriveInfo) next; @@ -189,15 +184,13 @@ extern DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit); extern DriveInfo *drive_get_by_id(char *id); extern int drive_get_max_bus(BlockInterfaceType type); extern void drive_uninit(BlockDriverState *bdrv); -extern void drive_remove(DriveOpt *opt); extern const char *drive_get_serial(BlockDriverState *bdrv); extern BlockInterfaceErrorAction drive_get_onerror(BlockDriverState *bdrv); BlockDriverState *qdev_init_bdrv(DeviceState *dev, BlockInterfaceType type); -extern DriveOpt *drive_add(const char *file, const char *fmt, ...); -extern DriveInfo *drive_init(DriveOpt *arg, int snapshot, void *machine, - int *fatal_error); +extern QemuOpts *drive_add(const char *file, const char *fmt, ...); +extern DriveInfo *drive_init(QemuOpts *arg, void *machine, int *fatal_error); /* acpi */ typedef void (*qemu_system_device_hot_add_t)(int pcibus, int slot, int state); diff --git a/vl.c b/vl.c index ae91999..0337475 100644 --- a/vl.c +++ b/vl.c @@ -1869,27 +1869,36 @@ static int bt_parse(const char *opt) #define MTD_ALIAS "if=mtd" #define SD_ALIAS "index=0,if=sd" -DriveOpt *drive_add(const char *file, const char *fmt, ...) +static QemuOptsList drive_opt_list = { + .name = "drive", + .head = TAILQ_HEAD_INITIALIZER(drive_opt_list.head), + .valid = { "bus", "unit", "if", "index", + "cyls", "heads", "secs", "trans", + "media", "snapshot", "file", + "cache", "format", "serial", + "werror", "addr", + NULL }, +}; + +QemuOpts *drive_add(const char *file, const char *fmt, ...) { va_list ap; - DriveOpt *dopt; - - dopt = qemu_mallocz(sizeof(*dopt)); + char optstr[1024]; + QemuOpts *opts; - dopt->file = file; va_start(ap, fmt); - vsnprintf(dopt->opt, - sizeof(dopt->opt), fmt, ap); + vsnprintf(optstr, sizeof(optstr), fmt, ap); va_end(ap); - TAILQ_INSERT_TAIL(&driveopts, dopt, next); - return dopt; -} - -void drive_remove(DriveOpt *dopt) -{ - TAILQ_REMOVE(&driveopts, dopt, next); - qemu_free(dopt); + opts = qemu_opts_parse(&drive_opt_list, optstr); + if (!opts) { + fprintf(stderr, "%s: huh? duplicate? (%s)\n", + __FUNCTION__, optstr); + return NULL; + } + if (file) + qemu_opt_set(opts, "file", file); + return opts; } DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit) @@ -1970,20 +1979,20 @@ void drive_uninit(BlockDriverState *bdrv) TAILQ_FOREACH(dinfo, &drives, next) { if (dinfo->bdrv != bdrv) continue; - drive_remove(dinfo->opt); + qemu_opts_del(dinfo->opts); TAILQ_REMOVE(&drives, dinfo, next); qemu_free(dinfo); break; } } -DriveInfo *drive_init(DriveOpt *arg, int snapshot, void *opaque, +DriveInfo *drive_init(QemuOpts *opts, void *opaque, int *fatal_error) { - char buf[128]; - char file[1024]; + const char *buf; + const char *file = NULL; char devname[128]; - char serial[21]; + const char *serial; const char *mediastr = ""; BlockInterfaceType type; enum { MEDIA_DISK, MEDIA_CDROM } media; @@ -1997,22 +2006,10 @@ DriveInfo *drive_init(DriveOpt *arg, int snapshot, void *opaque, int bdrv_flags, onerror; const char *devaddr; DriveInfo *dinfo; - char *str = arg->opt; - static const char * const params[] = { "bus", "unit", "if", "index", - "cyls", "heads", "secs", "trans", - "media", "snapshot", "file", - "cache", "format", "serial", - "werror", "addr", "id", - NULL }; - *fatal_error = 1; + int snapshot = 0; - if (check_params(buf, sizeof(buf), params, str) < 0) { - fprintf(stderr, "qemu: unknown parameter '%s' in '%s'\n", - buf, str); - return NULL; - } + *fatal_error = 1; - file[0] = 0; cyls = heads = secs = 0; bus_id = 0; unit_id = -1; @@ -2033,23 +2030,23 @@ DriveInfo *drive_init(DriveOpt *arg, int snapshot, void *opaque, /* extract parameters */ - if (get_param_value(buf, sizeof(buf), "bus", str)) { + if ((buf = qemu_opt_get(opts, "bus")) != NULL) { bus_id = strtol(buf, NULL, 0); if (bus_id < 0) { - fprintf(stderr, "qemu: '%s' invalid bus id\n", str); + fprintf(stderr, "qemu: '%s' invalid bus id\n", buf); return NULL; } } - if (get_param_value(buf, sizeof(buf), "unit", str)) { + if ((buf = qemu_opt_get(opts, "unit")) != NULL) { unit_id = strtol(buf, NULL, 0); if (unit_id < 0) { - fprintf(stderr, "qemu: '%s' invalid unit id\n", str); + fprintf(stderr, "qemu: '%s' invalid unit id\n", buf); return NULL; } } - if (get_param_value(buf, sizeof(buf), "if", str)) { + if ((buf = qemu_opt_get(opts, "if")) != NULL) { pstrcpy(devname, sizeof(devname), buf); if (!strcmp(buf, "ide")) { type = IF_IDE; @@ -2076,51 +2073,51 @@ DriveInfo *drive_init(DriveOpt *arg, int snapshot, void *opaque, type = IF_XEN; max_devs = 0; } else { - fprintf(stderr, "qemu: '%s' unsupported bus type '%s'\n", str, buf); + fprintf(stderr, "qemu: unsupported bus type '%s'\n", buf); return NULL; } } - if (get_param_value(buf, sizeof(buf), "index", str)) { + if ((buf = qemu_opt_get(opts, "index")) != NULL) { index = strtol(buf, NULL, 0); if (index < 0) { - fprintf(stderr, "qemu: '%s' invalid index\n", str); + fprintf(stderr, "qemu: '%s' invalid index\n", buf); return NULL; } } - if (get_param_value(buf, sizeof(buf), "cyls", str)) { + if ((buf = qemu_opt_get(opts, "cyls")) != NULL) { cyls = strtol(buf, NULL, 0); } - if (get_param_value(buf, sizeof(buf), "heads", str)) { + if ((buf = qemu_opt_get(opts, "heads")) != NULL) { heads = strtol(buf, NULL, 0); } - if (get_param_value(buf, sizeof(buf), "secs", str)) { + if ((buf = qemu_opt_get(opts, "secs")) != NULL) { secs = strtol(buf, NULL, 0); } if (cyls || heads || secs) { if (cyls < 1 || cyls > 16383) { - fprintf(stderr, "qemu: '%s' invalid physical cyls number\n", str); + fprintf(stderr, "qemu: '%s' invalid physical cyls number\n", buf); return NULL; } if (heads < 1 || heads > 16) { - fprintf(stderr, "qemu: '%s' invalid physical heads number\n", str); + fprintf(stderr, "qemu: '%s' invalid physical heads number\n", buf); return NULL; } if (secs < 1 || secs > 63) { - fprintf(stderr, "qemu: '%s' invalid physical secs number\n", str); + fprintf(stderr, "qemu: '%s' invalid physical secs number\n", buf); return NULL; } } - if (get_param_value(buf, sizeof(buf), "trans", str)) { + if ((buf = qemu_opt_get(opts, "trans")) != NULL) { if (!cyls) { fprintf(stderr, "qemu: '%s' trans must be used with cyls,heads and secs\n", - str); + buf); return NULL; } if (!strcmp(buf, "none")) @@ -2130,39 +2127,39 @@ DriveInfo *drive_init(DriveOpt *arg, int snapshot, void *opaque, else if (!strcmp(buf, "auto")) translation = BIOS_ATA_TRANSLATION_AUTO; else { - fprintf(stderr, "qemu: '%s' invalid translation type\n", str); + fprintf(stderr, "qemu: '%s' invalid translation type\n", buf); return NULL; } } - if (get_param_value(buf, sizeof(buf), "media", str)) { + if ((buf = qemu_opt_get(opts, "media")) != NULL) { if (!strcmp(buf, "disk")) { media = MEDIA_DISK; } else if (!strcmp(buf, "cdrom")) { if (cyls || secs || heads) { fprintf(stderr, - "qemu: '%s' invalid physical CHS format\n", str); + "qemu: '%s' invalid physical CHS format\n", buf); return NULL; } media = MEDIA_CDROM; } else { - fprintf(stderr, "qemu: '%s' invalid media\n", str); + fprintf(stderr, "qemu: '%s' invalid media\n", buf); return NULL; } } - if (get_param_value(buf, sizeof(buf), "snapshot", str)) { + if ((buf = qemu_opt_get(opts, "snapshot")) != NULL) { if (!strcmp(buf, "on")) snapshot = 1; else if (!strcmp(buf, "off")) snapshot = 0; else { - fprintf(stderr, "qemu: '%s' invalid snapshot option\n", str); + fprintf(stderr, "qemu: '%s' invalid snapshot option\n", buf); return NULL; } } - if (get_param_value(buf, sizeof(buf), "cache", str)) { + if ((buf = qemu_opt_get(opts, "cache")) != NULL) { if (!strcmp(buf, "off") || !strcmp(buf, "none")) cache = 0; else if (!strcmp(buf, "writethrough")) @@ -2175,7 +2172,7 @@ DriveInfo *drive_init(DriveOpt *arg, int snapshot, void *opaque, } } - if (get_param_value(buf, sizeof(buf), "format", str)) { + if ((buf = qemu_opt_get(opts, "format")) != NULL) { if (strcmp(buf, "?") == 0) { fprintf(stderr, "qemu: Supported formats:"); bdrv_iterate_format(bdrv_format_print, NULL); @@ -2189,16 +2186,11 @@ DriveInfo *drive_init(DriveOpt *arg, int snapshot, void *opaque, } } - if (arg->file == NULL) - get_param_value(file, sizeof(file), "file", str); - else - pstrcpy(file, sizeof(file), arg->file); - - if (!get_param_value(serial, sizeof(serial), "serial", str)) - memset(serial, 0, sizeof(serial)); + file = qemu_opt_get(opts, "file"); + serial = qemu_opt_get(opts, "serial"); onerror = BLOCK_ERR_STOP_ENOSPC; - if (get_param_value(buf, sizeof(serial), "werror", str)) { + 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; @@ -2217,13 +2209,11 @@ DriveInfo *drive_init(DriveOpt *arg, int snapshot, void *opaque, } } - devaddr = NULL; - if (get_param_value(buf, sizeof(buf), "addr", str)) { + if ((devaddr = qemu_opt_get(opts, "addr")) != NULL) { if (type != IF_VIRTIO) { - fprintf(stderr, "addr is not supported by in '%s'\n", str); + fprintf(stderr, "addr is not supported\n"); return NULL; } - devaddr = strdup(buf); } /* compute bus and unit according index */ @@ -2231,7 +2221,7 @@ DriveInfo *drive_init(DriveOpt *arg, int snapshot, void *opaque, if (index != -1) { if (bus_id != 0 || unit_id != -1) { fprintf(stderr, - "qemu: '%s' index cannot be used with bus and unit\n", str); + "qemu: index cannot be used with bus and unit\n"); return NULL; } if (max_devs == 0) @@ -2262,8 +2252,8 @@ DriveInfo *drive_init(DriveOpt *arg, int snapshot, void *opaque, /* check unit id */ if (max_devs && unit_id >= max_devs) { - fprintf(stderr, "qemu: '%s' unit %d too big (max is %d)\n", - str, unit_id, max_devs - 1); + fprintf(stderr, "qemu: unit %d too big (max is %d)\n", + unit_id, max_devs - 1); return NULL; } @@ -2279,26 +2269,29 @@ DriveInfo *drive_init(DriveOpt *arg, int snapshot, void *opaque, /* init */ dinfo = qemu_mallocz(sizeof(*dinfo)); - if (!get_param_value(buf, sizeof(buf), "id", str)) { + if ((buf = qemu_opt_get(opts, "id")) != NULL) { + dinfo->id = qemu_strdup(buf); + } else { /* no id supplied -> create one */ + dinfo->id = qemu_mallocz(32); if (type == IF_IDE || type == IF_SCSI) mediastr = (media == MEDIA_CDROM) ? "-cd" : "-hd"; if (max_devs) - snprintf(buf, sizeof(buf), "%s%i%s%i", + snprintf(dinfo->id, 32, "%s%i%s%i", devname, bus_id, mediastr, unit_id); else - snprintf(buf, sizeof(buf), "%s%s%i", + snprintf(dinfo->id, 32, "%s%s%i", devname, mediastr, unit_id); } - dinfo->id = qemu_strdup(buf); dinfo->bdrv = bdrv_new(dinfo->id); dinfo->devaddr = devaddr; dinfo->type = type; dinfo->bus = bus_id; dinfo->unit = unit_id; dinfo->onerror = onerror; - dinfo->opt = arg; - strncpy(dinfo->serial, serial, sizeof(serial)); + dinfo->opts = opts; + if (serial) + strncpy(dinfo->serial, serial, sizeof(serial)); TAILQ_INSERT_TAIL(&drives, dinfo, next); switch(type) { @@ -2330,7 +2323,7 @@ DriveInfo *drive_init(DriveOpt *arg, int snapshot, void *opaque, case IF_COUNT: abort(); } - if (!file[0]) { + if (!file) { *fatal_error = 0; return NULL; } @@ -2354,6 +2347,26 @@ DriveInfo *drive_init(DriveOpt *arg, int snapshot, void *opaque, return dinfo; } +static int drive_init_func(QemuOpts *opts, void *opaque) +{ + QEMUMachine *machine = opaque; + int fatal_error = 0; + + if (drive_init(opts, machine, &fatal_error) == NULL) { + if (fatal_error) + return 1; + } + return 0; +} + +static int drive_enable_snapshot(QemuOpts *opts, void *opaque) +{ + if (NULL == qemu_opt_get(opts, "snapshot")) { + qemu_opt_set(opts, "snapshot", "on"); + } + return 0; +} + void qemu_register_boot_set(QEMUBootSetHandler *func, void *opaque) { boot_set_handler = func; @@ -4833,7 +4846,7 @@ int main(int argc, char **argv, char **envp) int nb_net_clients; const char *bt_opts[MAX_BT_CMDLINE]; int nb_bt_opts; - DriveOpt *dopt, *hda_opt = NULL; + QemuOpts *hda_opts = NULL; int optind; const char *r, *optarg; CharDriverState *monitor_hd = NULL; @@ -4947,7 +4960,7 @@ int main(int argc, char **argv, char **envp) break; r = argv[optind]; if (r[0] != '-') { - hda_opt = drive_add(argv[optind++], HD_ALIAS, 0); + hda_opts = drive_add(argv[optind++], HD_ALIAS, 0); } else { const QEMUOption *popt; @@ -5008,9 +5021,9 @@ int main(int argc, char **argv, char **envp) break; case QEMU_OPTION_hda: if (cyls == 0) - hda_opt = drive_add(optarg, HD_ALIAS, 0); + hda_opts = drive_add(optarg, HD_ALIAS, 0); else - hda_opt = drive_add(optarg, HD_ALIAS + hda_opts = drive_add(optarg, HD_ALIAS ",cyls=%d,heads=%d,secs=%d%s", 0, cyls, heads, secs, translation == BIOS_ATA_TRANSLATION_LBA ? @@ -5072,15 +5085,19 @@ int main(int argc, char **argv, char **envp) fprintf(stderr, "qemu: invalid physical CHS format\n"); exit(1); } - if (hda_opt != NULL) - snprintf(hda_opt->opt, - sizeof(hda_opt->opt), - HD_ALIAS ",cyls=%d,heads=%d,secs=%d%s", - 0, cyls, heads, secs, - translation == BIOS_ATA_TRANSLATION_LBA ? - ",trans=lba" : - translation == BIOS_ATA_TRANSLATION_NONE ? - ",trans=none" : ""); + if (hda_opts != NULL) { + char num[16]; + snprintf(num, sizeof(num), "%d", cyls); + qemu_opt_set(hda_opts, "cyls", num); + snprintf(num, sizeof(num), "%d", heads); + qemu_opt_set(hda_opts, "heads", num); + snprintf(num, sizeof(num), "%d", secs); + qemu_opt_set(hda_opts, "secs", num); + if (translation == BIOS_ATA_TRANSLATION_LBA) + qemu_opt_set(hda_opts, "trans", "lba"); + if (translation == BIOS_ATA_TRANSLATION_NONE) + qemu_opt_set(hda_opts, "trans", "none"); + } } break; case QEMU_OPTION_numa: @@ -5799,13 +5816,10 @@ int main(int argc, char **argv, char **envp) drive_add(NULL, SD_ALIAS); /* open the virtual block devices */ - - TAILQ_FOREACH(dopt, &driveopts, next) { - int fatal_error; - if (drive_init(dopt, snapshot, machine, &fatal_error) == NULL) - if (fatal_error) - exit(1); - } + if (snapshot) + qemu_opts_foreach(&drive_opt_list, drive_enable_snapshot, NULL, 0); + if (qemu_opts_foreach(&drive_opt_list, drive_init_func, machine, 1) != 0) + exit(1); register_savevm("timer", 0, 2, timer_save, timer_load, NULL); register_savevm_live("ram", 0, 3, ram_save_live, NULL, ram_load, NULL); -- 1.6.2.5