From a66c9dc734fb30de1e18e9dc217f2d37e16c492a Mon Sep 17 00:00:00 2001 From: John Snow Date: Wed, 1 Oct 2014 14:19:24 -0400 Subject: blockdev: Orphaned drive search When users use command line options like -hda, -cdrom, or even -drive if=ide, it is up to the board initialization routines to pick up these drives and create backing devices for them. Some boards, like Q35, have not been doing this. However, there is no warning explaining why certain drive specifications are just silently ignored, so this function adds a check to print some warnings to assist users in debugging these sorts of issues in the future. This patch will not warn about drives added with if_none, for which it is not possible to tell in advance if the omission of a backing device is an issue. A warning in these cases is considered appropriate. Signed-off-by: John Snow Reviewed-by: Markus Armbruster Message-id: 1412187569-23452-2-git-send-email-jsnow@redhat.com Signed-off-by: Stefan Hajnoczi --- include/sysemu/blockdev.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h index abec381049..30402867b9 100644 --- a/include/sysemu/blockdev.h +++ b/include/sysemu/blockdev.h @@ -38,6 +38,7 @@ struct DriveInfo { int unit; int auto_del; /* see blockdev_mark_auto_del() */ bool enable_auto_del; /* Only for legacy drive_new() */ + bool is_default; /* Added by default_drive() ? */ int media_cd; int cyls, heads, secs, trans; QemuOpts *opts; @@ -46,6 +47,7 @@ struct DriveInfo { }; DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit); +bool drive_check_orphaned(void); DriveInfo *drive_get_by_index(BlockInterfaceType type, int index); int drive_get_max_bus(BlockInterfaceType type); DriveInfo *drive_get_next(BlockInterfaceType type); -- cgit 1.4.1 From 21dff8cf38d311a917ab33f19d5cea7696f0c354 Mon Sep 17 00:00:00 2001 From: John Snow Date: Wed, 1 Oct 2014 14:19:25 -0400 Subject: blockdev: Allow overriding if_max_dev property The if_max_devs table as in the past been an immutable default that controls the mapping of index => (bus,unit) for all boards and all HBAs for each interface type. Since adding this mapping information to the HBA device itself is currently unwieldly from the perspective of retrieving this information at option parsing time (e.g, within drive_new), we consider the alternative of marking the if_max_devs table mutable so that later configuration and initialization can adjust the mapping at will, but only up until a drive is added, at which point the mapping is finalized. Signed-off-by: John Snow Reviewed-by: Markus Armbruster Message-id: 1412187569-23452-3-git-send-email-jsnow@redhat.com Signed-off-by: Stefan Hajnoczi --- blockdev.c | 26 +++++++++++++++++++++++++- include/sysemu/blockdev.h | 2 ++ 2 files changed, 27 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/blockdev.c b/blockdev.c index 48da1a7e0f..1780d7723a 100644 --- a/blockdev.c +++ b/blockdev.c @@ -60,7 +60,7 @@ static const char *const if_name[IF_COUNT] = { [IF_XEN] = "xen", }; -static const int if_max_devs[IF_COUNT] = { +static int if_max_devs[IF_COUNT] = { /* * Do not change these numbers! They govern how drive option * index maps to unit and bus. That mapping is ABI. @@ -79,6 +79,30 @@ static const int if_max_devs[IF_COUNT] = { [IF_SCSI] = 7, }; +/** + * Boards may call this to offer board-by-board overrides + * of the default, global values. + */ +void override_max_devs(BlockInterfaceType type, int max_devs) +{ + DriveInfo *dinfo; + + if (max_devs <= 0) { + return; + } + + QTAILQ_FOREACH(dinfo, &drives, next) { + if (dinfo->type == type) { + fprintf(stderr, "Cannot override units-per-bus property of" + " the %s interface, because a drive of that type has" + " already been added.\n", if_name[type]); + g_assert_not_reached(); + } + } + + if_max_devs[type] = max_devs; +} + /* * We automatically delete the drive when a device using it gets * unplugged. Questionable feature, but we can't just drop it. diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h index 30402867b9..a4033d4c29 100644 --- a/include/sysemu/blockdev.h +++ b/include/sysemu/blockdev.h @@ -46,6 +46,8 @@ struct DriveInfo { QTAILQ_ENTRY(DriveInfo) next; }; +void override_max_devs(BlockInterfaceType type, int max_devs); + DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit); bool drive_check_orphaned(void); DriveInfo *drive_get_by_index(BlockInterfaceType type, int index); -- cgit 1.4.1 From 1602651833c081e32366c9e534ad72e4287840c5 Mon Sep 17 00:00:00 2001 From: John Snow Date: Wed, 1 Oct 2014 14:19:26 -0400 Subject: pc/vl: Add units-per-default-bus property This patch adds the 'units_per_default_bus' property which allows individual boards to declare their desired index => (bus,unit) mapping for their default HBA, so that boards such as Q35 can specify that its default if_ide HBA, AHCI, only accepts one unit per bus. This property only overrides the mapping for drives matching the block_default_type interface. This patch also adds this property to *all* past and present Q35 machine types. This retroactive addition is justified because the previous erroneous index=>(bus,unit) mappings caused by lack of such a property were not utilized due to lack of initialization code in the Q35 init routine. Further, semantically, the Q35 board type has always had the property that its default HBA, AHCI, only accepts one unit per bus. The new code added to add devices to drives relies upon the accuracy of this mapping. Thus, the property is applied retroactively to reduce complexity of allowing IDE HBAs with different units per bus. Examples: Prior to this patch, all IDE HBAs were assumed to use 2 units per bus (Master, Slave). When using Q35 and AHCI, however, we only allow one unit per bus. -hdb foo.qcow2 would become index=1, or bus=0,unit=1. -hdd foo.qcow2 would become index=3, or bus=1,unit=1. -drive file=foo.qcow2,index=5 becomes bus=2,unit=1. These are invalid for AHCI. They now become, under Q35 only: -hdb foo.qcow2 --> index=1, bus=1, unit=0. -hdd foo.qcow2 --> index=3, bus=3, unit=0. -drive file=foo.qcow2,index=5 --> bus=5,unit=0. The mapping is adjusted based on the fact that the default IF for the Q35 machine type is IF_IDE, and units-per-default-bus overrides the IDE mapping from its default of 2 units per bus to just 1 unit per bus. Signed-off-by: John Snow Reviewed-by: Markus Armbruster Reviewed-by: Michael S. Tsirkin Message-id: 1412187569-23452-4-git-send-email-jsnow@redhat.com Signed-off-by: Stefan Hajnoczi --- hw/i386/pc.c | 1 + hw/i386/pc_q35.c | 3 ++- include/hw/boards.h | 2 ++ vl.c | 8 ++++++++ 4 files changed, 13 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 82a7daa188..d045e8b454 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1524,6 +1524,7 @@ static void pc_generic_machine_class_init(ObjectClass *oc, void *data) mc->hot_add_cpu = qm->hot_add_cpu; mc->kvm_type = qm->kvm_type; mc->block_default_type = qm->block_default_type; + mc->units_per_default_bus = qm->units_per_default_bus; mc->max_cpus = qm->max_cpus; mc->no_serial = qm->no_serial; mc->no_parallel = qm->no_parallel; diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index d4a907c71b..b28ddbb742 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -344,7 +344,8 @@ static void pc_q35_init_1_4(MachineState *machine) #define PC_Q35_MACHINE_OPTIONS \ PC_DEFAULT_MACHINE_OPTIONS, \ .desc = "Standard PC (Q35 + ICH9, 2009)", \ - .hot_add_cpu = pc_hot_add_cpu + .hot_add_cpu = pc_hot_add_cpu, \ + .units_per_default_bus = 1 #define PC_Q35_2_2_MACHINE_OPTIONS \ PC_Q35_MACHINE_OPTIONS, \ diff --git a/include/hw/boards.h b/include/hw/boards.h index dfb6718dc1..663f16acdd 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -28,6 +28,7 @@ struct QEMUMachine { QEMUMachineHotAddCPUFunc *hot_add_cpu; QEMUMachineGetKvmtypeFunc *kvm_type; BlockInterfaceType block_default_type; + int units_per_default_bus; int max_cpus; unsigned int no_serial:1, no_parallel:1, @@ -86,6 +87,7 @@ struct MachineClass { int (*kvm_type)(const char *arg); BlockInterfaceType block_default_type; + int units_per_default_bus; int max_cpus; unsigned int no_serial:1, no_parallel:1, diff --git a/vl.c b/vl.c index 4bc8f97c25..debcbcceea 100644 --- a/vl.c +++ b/vl.c @@ -1585,6 +1585,7 @@ static void machine_class_init(ObjectClass *oc, void *data) mc->hot_add_cpu = qm->hot_add_cpu; mc->kvm_type = qm->kvm_type; mc->block_default_type = qm->block_default_type; + mc->units_per_default_bus = qm->units_per_default_bus; mc->max_cpus = qm->max_cpus; mc->no_serial = qm->no_serial; mc->no_parallel = qm->no_parallel; @@ -4375,6 +4376,13 @@ int main(int argc, char **argv, char **envp) blk_mig_init(); ram_mig_init(); + /* If the currently selected machine wishes to override the units-per-bus + * property of its default HBA interface type, do so now. */ + if (machine_class->units_per_default_bus) { + override_max_devs(machine_class->block_default_type, + machine_class->units_per_default_bus); + } + /* open the virtual block devices */ if (snapshot) qemu_opts_foreach(qemu_find_opts("drive"), drive_enable_snapshot, NULL, 0); -- cgit 1.4.1 From d8f94e1bb275ab6a14a15220fd6afd0d04324aeb Mon Sep 17 00:00:00 2001 From: John Snow Date: Wed, 1 Oct 2014 14:19:27 -0400 Subject: ide: Update ide_drive_get to be HBA agnostic Instead of duplicating the logic for the if_ide (bus,unit) mappings, rely on the blockdev layer for managing those mappings for us, and use the drive_get_by_index call instead. This allows ide_drive_get to work for AHCI HBAs as well, and can be used in the Q35 initialization. Lastly, change the nature of the argument to ide_drive_get so that represents the number of total drives we can support, and not the total number of buses. This will prevent array overflows if the units-per-default-bus property ever needs to be adjusted for compatibility reasons. Signed-off-by: John Snow Reviewed-by: Markus Armbruster Reviewed-by: Michael S. Tsirkin Message-id: 1412187569-23452-5-git-send-email-jsnow@redhat.com Signed-off-by: Stefan Hajnoczi --- blockdev.c | 17 +++++++++++++++++ hw/alpha/dp264.c | 2 +- hw/i386/pc_piix.c | 2 +- hw/ide/core.c | 22 +++++++++++++++++----- hw/mips/mips_fulong2e.c | 2 +- hw/mips/mips_malta.c | 2 +- hw/mips/mips_r4k.c | 2 +- hw/ppc/mac_newworld.c | 2 +- hw/ppc/mac_oldworld.c | 2 +- hw/ppc/prep.c | 2 +- hw/sparc64/sun4u.c | 2 +- include/sysemu/blockdev.h | 1 + 12 files changed, 44 insertions(+), 14 deletions(-) (limited to 'include') diff --git a/blockdev.c b/blockdev.c index 1780d7723a..e595910476 100644 --- a/blockdev.c +++ b/blockdev.c @@ -135,6 +135,23 @@ void blockdev_auto_del(BlockDriverState *bs) } } +/** + * Returns the current mapping of how many units per bus + * a particular interface can support. + * + * A positive integer indicates n units per bus. + * 0 implies the mapping has not been established. + * -1 indicates an invalid BlockInterfaceType was given. + */ +int drive_get_max_devs(BlockInterfaceType type) +{ + if (type >= IF_IDE && type < IF_COUNT) { + return if_max_devs[type]; + } + + return -1; +} + static int drive_index_to_bus_id(BlockInterfaceType type, int index) { int max_devs = if_max_devs[type]; diff --git a/hw/alpha/dp264.c b/hw/alpha/dp264.c index b178a03604..84a55e41a2 100644 --- a/hw/alpha/dp264.c +++ b/hw/alpha/dp264.c @@ -97,7 +97,7 @@ static void clipper_init(MachineState *machine) /* IDE disk setup. */ { DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; - ide_drive_get(hd, MAX_IDE_BUS); + ide_drive_get(hd, ARRAY_SIZE(hd)); pci_cmd646_ide_init(pci_bus, hd, 0); } diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 103d756a72..43846339bc 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -239,7 +239,7 @@ static void pc_init1(MachineState *machine, pc_nic_init(isa_bus, pci_bus); - ide_drive_get(hd, MAX_IDE_BUS); + ide_drive_get(hd, ARRAY_SIZE(hd)); if (pci_enabled) { PCIDevice *dev; if (xen_enabled()) { diff --git a/hw/ide/core.c b/hw/ide/core.c index 190700ac74..ae85428864 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -2558,16 +2558,28 @@ const VMStateDescription vmstate_ide_bus = { } }; -void ide_drive_get(DriveInfo **hd, int max_bus) +void ide_drive_get(DriveInfo **hd, int n) { int i; + int highest_bus = drive_get_max_bus(IF_IDE) + 1; + int max_devs = drive_get_max_devs(IF_IDE); + int n_buses = max_devs ? (n / max_devs) : n; - if (drive_get_max_bus(IF_IDE) >= max_bus) { - fprintf(stderr, "qemu: too many IDE bus: %d\n", max_bus); + /* + * Note: The number of actual buses available is not known. + * We compute this based on the size of the DriveInfo* array, n. + * If it is less than max_devs * , + * We will stop looking for drives prematurely instead of overfilling + * the array. + */ + + if (highest_bus > n_buses) { + error_report("Too many IDE buses defined (%d > %d)", + highest_bus, n_buses); exit(1); } - for(i = 0; i < max_bus * MAX_IDE_DEVS; i++) { - hd[i] = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS); + for (i = 0; i < n; i++) { + hd[i] = drive_get_by_index(IF_IDE, i); } } diff --git a/hw/mips/mips_fulong2e.c b/hw/mips/mips_fulong2e.c index be286da18b..29cd708e07 100644 --- a/hw/mips/mips_fulong2e.c +++ b/hw/mips/mips_fulong2e.c @@ -350,7 +350,7 @@ static void mips_fulong2e_init(MachineState *machine) pci_bus = bonito_init((qemu_irq *)&(env->irq[2])); /* South bridge */ - ide_drive_get(hd, MAX_IDE_BUS); + ide_drive_get(hd, ARRAY_SIZE(hd)); isa_bus = vt82c686b_init(pci_bus, PCI_DEVFN(FULONG2E_VIA_SLOT, 0)); if (!isa_bus) { diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c index 2d87de9ea5..b20807c4e4 100644 --- a/hw/mips/mips_malta.c +++ b/hw/mips/mips_malta.c @@ -1147,7 +1147,7 @@ void mips_malta_init(MachineState *machine) pci_bus = gt64120_register(isa_irq); /* Southbridge */ - ide_drive_get(hd, MAX_IDE_BUS); + ide_drive_get(hd, ARRAY_SIZE(hd)); piix4_devfn = piix4_init(pci_bus, &isa_bus, 80); diff --git a/hw/mips/mips_r4k.c b/hw/mips/mips_r4k.c index e219766f3e..93606a490c 100644 --- a/hw/mips/mips_r4k.c +++ b/hw/mips/mips_r4k.c @@ -294,7 +294,7 @@ void mips_r4k_init(MachineState *machine) if (nd_table[0].used) isa_ne2000_init(isa_bus, 0x300, 9, &nd_table[0]); - ide_drive_get(hd, MAX_IDE_BUS); + ide_drive_get(hd, ARRAY_SIZE(hd)); for(i = 0; i < MAX_IDE_BUS; i++) isa_ide_init(isa_bus, ide_iobase[i], ide_iobase2[i], ide_irq[i], hd[MAX_IDE_DEVS * i], diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c index 1626db44ef..4094beb0ed 100644 --- a/hw/ppc/mac_newworld.c +++ b/hw/ppc/mac_newworld.c @@ -400,7 +400,7 @@ static void ppc_core99_init(MachineState *machine) macio_init(macio, pic_mem, escc_bar); /* We only emulate 2 out of 3 IDE controllers for now */ - ide_drive_get(hd, MAX_IDE_BUS); + ide_drive_get(hd, ARRAY_SIZE(hd)); macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio), "ide[0]")); diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c index be9a194038..ebd87fb8f5 100644 --- a/hw/ppc/mac_oldworld.c +++ b/hw/ppc/mac_oldworld.c @@ -278,7 +278,7 @@ static void ppc_heathrow_init(MachineState *machine) pci_nic_init_nofail(&nd_table[i], pci_bus, "ne2k_pci", NULL); - ide_drive_get(hd, MAX_IDE_BUS); + ide_drive_get(hd, ARRAY_SIZE(hd)); macio = pci_create(pci_bus, -1, TYPE_OLDWORLD_MACIO); dev = DEVICE(macio); diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c index f0ef1af118..9f484cdcb8 100644 --- a/hw/ppc/prep.c +++ b/hw/ppc/prep.c @@ -519,7 +519,7 @@ static void ppc_prep_init(MachineState *machine) } } - ide_drive_get(hd, MAX_IDE_BUS); + ide_drive_get(hd, ARRAY_SIZE(hd)); for(i = 0; i < MAX_IDE_BUS; i++) { isa_ide_init(isa_bus, ide_iobase[i], ide_iobase2[i], ide_irq[i], hd[2 * i], diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c index 9c77e18244..871a0ea246 100644 --- a/hw/sparc64/sun4u.c +++ b/hw/sparc64/sun4u.c @@ -864,7 +864,7 @@ static void sun4uv_init(MemoryRegion *address_space_mem, for(i = 0; i < nb_nics; i++) pci_nic_init_nofail(&nd_table[i], pci_bus, "ne2k_pci", NULL); - ide_drive_get(hd, MAX_IDE_BUS); + ide_drive_get(hd, ARRAY_SIZE(hd)); pci_cmd646_ide_init(pci_bus, hd, 1); diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h index a4033d4c29..09716de809 100644 --- a/include/sysemu/blockdev.h +++ b/include/sysemu/blockdev.h @@ -52,6 +52,7 @@ DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit); bool drive_check_orphaned(void); DriveInfo *drive_get_by_index(BlockInterfaceType type, int index); int drive_get_max_bus(BlockInterfaceType type); +int drive_get_max_devs(BlockInterfaceType type); DriveInfo *drive_get_next(BlockInterfaceType type); DriveInfo *drive_get_by_blockdev(BlockDriverState *bs); -- cgit 1.4.1 From f5bebbbb28dc7a149a891f0f1e112fb50bb72664 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Tue, 30 Sep 2014 13:59:30 +0200 Subject: util: Emancipate id_wellformed() from QemuOpts IDs have long spread beyond QemuOpts: not everything with an ID necessarily goes through QemuOpts. Commit 9aebf3b is about such a case: block layer names are meant to be well-formed IDs, but some of them don't go through QemuOpts, and thus weren't checked. The commit fixed that the straightforward way: rename the internal QemuOpts helper id_wellformed() to qemu_opts_id_wellformed() and give it external linkage. Instead of using it directly in block.c, the commit adds wrapper bdrv_is_valid_name(), probably to hide the connection to QemuOpts. Go one logical step further: emancipate IDs from QemuOpts. Rename the function back to id_wellformed(), and put it in another file. While there, clean up its value to bool. Peel off the bdrv_is_valid_name() wrapper. [Replaced stray return 0 with return false to match bool returns used elsewhere in id_wellformed(). --Stefan] Signed-off-by: Markus Armbruster Signed-off-by: Stefan Hajnoczi --- block.c | 9 ++------- include/qemu-common.h | 3 +++ include/qemu/option.h | 1 - util/Makefile.objs | 1 + util/id.c | 28 ++++++++++++++++++++++++++++ util/qemu-option.c | 17 +---------------- 6 files changed, 35 insertions(+), 24 deletions(-) create mode 100644 util/id.c (limited to 'include') diff --git a/block.c b/block.c index c5a251c57e..d3aebeb050 100644 --- a/block.c +++ b/block.c @@ -335,18 +335,13 @@ void bdrv_register(BlockDriver *bdrv) QLIST_INSERT_HEAD(&bdrv_drivers, bdrv, list); } -static bool bdrv_is_valid_name(const char *name) -{ - return qemu_opts_id_wellformed(name); -} - /* create a new block device (by default it is empty) */ BlockDriverState *bdrv_new(const char *device_name, Error **errp) { BlockDriverState *bs; int i; - if (*device_name && !bdrv_is_valid_name(device_name)) { + if (*device_name && !id_wellformed(device_name)) { error_setg(errp, "Invalid device name"); return NULL; } @@ -874,7 +869,7 @@ static void bdrv_assign_node_name(BlockDriverState *bs, } /* Check for empty string or invalid characters */ - if (!bdrv_is_valid_name(node_name)) { + if (!id_wellformed(node_name)) { error_setg(errp, "Invalid node name"); return; } diff --git a/include/qemu-common.h b/include/qemu-common.h index dcb57ab4b9..b87e9c2d8b 100644 --- a/include/qemu-common.h +++ b/include/qemu-common.h @@ -190,6 +190,9 @@ int64_t strtosz_suffix_unit(const char *nptr, char **end, /* used to print char* safely */ #define STR_OR_NULL(str) ((str) ? (str) : "null") +/* id.c */ +bool id_wellformed(const char *id); + /* path.c */ void init_paths(const char *prefix); const char *path(const char *pathname); diff --git a/include/qemu/option.h b/include/qemu/option.h index 945347cc8f..59bea759a2 100644 --- a/include/qemu/option.h +++ b/include/qemu/option.h @@ -103,7 +103,6 @@ typedef int (*qemu_opt_loopfunc)(const char *name, const char *value, void *opaq int qemu_opt_foreach(QemuOpts *opts, qemu_opt_loopfunc func, void *opaque, int abort_on_failure); -int qemu_opts_id_wellformed(const char *id); QemuOpts *qemu_opts_find(QemuOptsList *list, const char *id); QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id, int fail_if_exists, Error **errp); diff --git a/util/Makefile.objs b/util/Makefile.objs index cb8862ba92..93007e2f56 100644 --- a/util/Makefile.objs +++ b/util/Makefile.objs @@ -8,6 +8,7 @@ util-obj-y += fifo8.o util-obj-y += acl.o util-obj-y += error.o qemu-error.o util-obj-$(CONFIG_POSIX) += compatfd.o +util-obj-y += id.o util-obj-y += iov.o aes.o qemu-config.o qemu-sockets.o uri.o notify.o util-obj-y += qemu-option.o qemu-progress.o util-obj-y += hexdump.o diff --git a/util/id.c b/util/id.c new file mode 100644 index 0000000000..09b22fb8fa --- /dev/null +++ b/util/id.c @@ -0,0 +1,28 @@ +/* + * Dealing with identifiers + * + * Copyright (C) 2014 Red Hat, Inc. + * + * Authors: + * Markus Armbruster , + * + * This work is licensed under the terms of the GNU LGPL, version 2.1 + * or later. See the COPYING.LIB file in the top-level directory. + */ + +#include "qemu-common.h" + +bool id_wellformed(const char *id) +{ + int i; + + if (!qemu_isalpha(id[0])) { + return false; + } + for (i = 1; id[i]; i++) { + if (!qemu_isalnum(id[i]) && !strchr("-._", id[i])) { + return false; + } + } + return true; +} diff --git a/util/qemu-option.c b/util/qemu-option.c index 0cf9960fc5..5d106959ca 100644 --- a/util/qemu-option.c +++ b/util/qemu-option.c @@ -641,28 +641,13 @@ QemuOpts *qemu_opts_find(QemuOptsList *list, const char *id) return NULL; } -int qemu_opts_id_wellformed(const char *id) -{ - int i; - - if (!qemu_isalpha(id[0])) { - return 0; - } - for (i = 1; id[i]; i++) { - if (!qemu_isalnum(id[i]) && !strchr("-._", id[i])) { - return 0; - } - } - return 1; -} - QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id, int fail_if_exists, Error **errp) { QemuOpts *opts = NULL; if (id) { - if (!qemu_opts_id_wellformed(id)) { + if (!id_wellformed(id)) { error_set(errp,QERR_INVALID_PARAMETER_VALUE, "id", "an identifier"); #if 0 /* conversion from qerror_report() to error_set() broke this: */ error_printf_unless_qmp("Identifiers consist of letters, digits, '-', '.', '_', starting with a letter.\n"); -- cgit 1.4.1