* [Qemu-devel] [PATCH v3 0/5] cleanup drive handling.
@ 2009-07-16 14:56 Gerd Hoffmann
2009-07-16 14:57 ` [Qemu-devel] [PATCH v3 1/5] kill drives_table Gerd Hoffmann
` (4 more replies)
0 siblings, 5 replies; 21+ messages in thread
From: Gerd Hoffmann @ 2009-07-16 14:56 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Hi,
This patch series cleans up the drive handling in qemu. It removes the
drives_table and the drives_opt table and replaces them with linked
lists. The silly table indexing stuff is gone.
It adds the ability to name drives using id=.
It also adds a new QemuOpts framework to store parameters from the
command line and switches -drive over to it.
Changes in v3:
* added QemuOpts.
* fix the "#if 0" 'ed drives_table conversion leftover.
* fix some s/name=/id=/ leftovers.
Future plans:
While qdev-ifying virtual disk drivers block/*.c) make them lookup the
BlockDriverState using the id.
cheers,
Gerd
^ permalink raw reply [flat|nested] 21+ messages in thread
* [Qemu-devel] [PATCH v3 1/5] kill drives_table
2009-07-16 14:56 [Qemu-devel] [PATCH v3 0/5] cleanup drive handling Gerd Hoffmann
@ 2009-07-16 14:57 ` Gerd Hoffmann
2009-07-16 14:57 ` [Qemu-devel] [PATCH v3 2/5] add support for drive ids Gerd Hoffmann
` (3 subsequent siblings)
4 siblings, 0 replies; 21+ messages in thread
From: Gerd Hoffmann @ 2009-07-16 14:57 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
First step cleaning up the drives handling. This one does nothing but
removing drives_table[], still it became seriously big.
drive_get_index() is gone and is replaced by drives_get() which hands
out DriveInfo pointers instead of a table index. This needs adaption in
*tons* of places all over.
The drives are now maintained as linked list.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/device-hotplug.c | 23 +++---
hw/etraxfs.c | 5 +-
hw/gumstix.c | 16 ++--
hw/mainstone.c | 9 +-
hw/mips_jazz.c | 7 +-
hw/mips_malta.c | 24 ++----
hw/mips_r4k.c | 13 +--
hw/musicpal.c | 10 +-
hw/nand.c | 8 +-
hw/omap1.c | 8 +-
hw/omap2.c | 8 +-
hw/omap_sx1.c | 10 +-
hw/onenand.c | 6 +-
hw/pc.c | 21 ++---
hw/pci-hotplug.c | 28 ++++---
hw/petalogix_s3adsp1800_mmu.c | 5 +-
hw/ppc405_boards.c | 34 ++++----
hw/ppc440_bamboo.c | 5 +-
hw/ppc_newworld.c | 9 +--
hw/ppc_oldworld.c | 30 ++-----
hw/ppc_prep.c | 16 +---
hw/ppce500_mpc8544ds.c | 5 +-
hw/pxa2xx.c | 16 ++--
hw/qdev.c | 17 ++---
hw/r2d.c | 5 +-
hw/spitz.c | 8 +-
hw/sun4m.c | 16 ++--
hw/sun4u.c | 18 ++---
hw/tosa.c | 8 +-
monitor.c | 12 ++-
qemu-char.c | 6 +-
savevm.c | 32 ++++---
sysemu.h | 13 ++--
vl.c | 177 ++++++++++++++++++++---------------------
34 files changed, 296 insertions(+), 332 deletions(-)
diff --git a/hw/device-hotplug.c b/hw/device-hotplug.c
index e178083..5257274 100644
--- a/hw/device-hotplug.c
+++ b/hw/device-hotplug.c
@@ -28,22 +28,23 @@
#include "block_int.h"
#include "sysemu.h"
-int add_init_drive(const char *opts)
+DriveInfo *add_init_drive(const char *opts)
{
- int drive_opt_idx, drive_idx;
- int ret = -1;
+ int drive_opt_idx;
+ int fatal_error;
+ DriveInfo *dinfo;
drive_opt_idx = drive_add(NULL, "%s", opts);
if (!drive_opt_idx)
- return ret;
+ return NULL;
- drive_idx = drive_init(&drives_opt[drive_opt_idx], 0, current_machine);
- if (drive_idx == -1) {
+ dinfo = drive_init(&drives_opt[drive_opt_idx], 0, current_machine, &fatal_error);
+ if (!dinfo) {
drive_remove(drive_opt_idx);
- return ret;
+ return NULL;
}
- return drive_idx;
+ return dinfo;
}
void destroy_nic(dev_match_fn *match_fn, void *arg)
@@ -64,11 +65,11 @@ void destroy_nic(dev_match_fn *match_fn, void *arg)
void destroy_bdrvs(dev_match_fn *match_fn, void *arg)
{
- int i;
+ DriveInfo *dinfo;
struct BlockDriverState *bs;
- for (i = 0; i <= MAX_DRIVES; i++) {
- bs = drives_table[i].bdrv;
+ TAILQ_FOREACH(dinfo, &drives, next) {
+ bs = dinfo->bdrv;
if (bs) {
if (bs->private && match_fn(bs->private, arg)) {
drive_uninit(bs);
diff --git a/hw/etraxfs.c b/hw/etraxfs.c
index 94cd6bc..de31cbc 100644
--- a/hw/etraxfs.c
+++ b/hw/etraxfs.c
@@ -55,6 +55,7 @@ void bareetraxfs_init (ram_addr_t ram_size,
void *etraxfs_dmac;
struct etraxfs_dma_client *eth[2] = {NULL, NULL};
int kernel_size;
+ DriveInfo *dinfo;
int i;
ram_addr_t phys_ram;
ram_addr_t phys_flash;
@@ -79,9 +80,9 @@ void bareetraxfs_init (ram_addr_t ram_size,
phys_flash = qemu_ram_alloc(FLASH_SIZE);
- i = drive_get_index(IF_PFLASH, 0, 0);
+ dinfo = drive_get(IF_PFLASH, 0, 0);
pflash_cfi02_register(0x0, phys_flash,
- i != -1 ? drives_table[i].bdrv : NULL, (64 * 1024),
+ dinfo ? dinfo->bdrv : NULL, (64 * 1024),
FLASH_SIZE >> 16,
1, 2, 0x0000, 0x0000, 0x0000, 0x0000,
0x555, 0x2aa);
diff --git a/hw/gumstix.c b/hw/gumstix.c
index 85b95ee..8fbf64c 100644
--- a/hw/gumstix.c
+++ b/hw/gumstix.c
@@ -47,22 +47,22 @@ static void connex_init(ram_addr_t ram_size,
const char *initrd_filename, const char *cpu_model)
{
PXA2xxState *cpu;
- int index;
+ DriveInfo *dinfo;
uint32_t connex_rom = 0x01000000;
uint32_t connex_ram = 0x04000000;
cpu = pxa255_init(connex_ram);
- index = drive_get_index(IF_PFLASH, 0, 0);
- if (index == -1) {
+ dinfo = drive_get(IF_PFLASH, 0, 0);
+ if (!dinfo) {
fprintf(stderr, "A flash image must be given with the "
"'pflash' parameter\n");
exit(1);
}
if (!pflash_cfi01_register(0x00000000, qemu_ram_alloc(connex_rom),
- drives_table[index].bdrv, sector_len, connex_rom / sector_len,
+ dinfo->bdrv, sector_len, connex_rom / sector_len,
2, 0, 0, 0, 0)) {
fprintf(stderr, "qemu: Error registering flash memory.\n");
exit(1);
@@ -81,22 +81,22 @@ static void verdex_init(ram_addr_t ram_size,
const char *initrd_filename, const char *cpu_model)
{
PXA2xxState *cpu;
- int index;
+ DriveInfo *dinfo;
uint32_t verdex_rom = 0x02000000;
uint32_t verdex_ram = 0x10000000;
cpu = pxa270_init(verdex_ram, cpu_model ?: "pxa270-c0");
- index = drive_get_index(IF_PFLASH, 0, 0);
- if (index == -1) {
+ dinfo = drive_get(IF_PFLASH, 0, 0);
+ if (!dinfo) {
fprintf(stderr, "A flash image must be given with the "
"'pflash' parameter\n");
exit(1);
}
if (!pflash_cfi01_register(0x00000000, qemu_ram_alloc(verdex_rom),
- drives_table[index].bdrv, sector_len, verdex_rom / sector_len,
+ dinfo->bdrv, sector_len, verdex_rom / sector_len,
2, 0, 0, 0, 0)) {
fprintf(stderr, "qemu: Error registering flash memory.\n");
exit(1);
diff --git a/hw/mainstone.c b/hw/mainstone.c
index 151ea0e..3e517f0 100644
--- a/hw/mainstone.c
+++ b/hw/mainstone.c
@@ -77,7 +77,8 @@ static void mainstone_common_init(ram_addr_t ram_size,
target_phys_addr_t mainstone_flash_base[] = { MST_FLASH_0, MST_FLASH_1 };
PXA2xxState *cpu;
qemu_irq *mst_irq;
- int i, index;
+ DriveInfo *dinfo;
+ int i;
if (!cpu_model)
cpu_model = "pxa270-c5";
@@ -92,8 +93,8 @@ static void mainstone_common_init(ram_addr_t ram_size,
/* There are two 32MiB flash devices on the board */
for (i = 0; i < 2; i ++) {
- index = drive_get_index(IF_PFLASH, 0, i);
- if (index == -1) {
+ dinfo = drive_get(IF_PFLASH, 0, i);
+ if (!dinfo) {
fprintf(stderr, "Two flash images must be given with the "
"'pflash' parameter\n");
exit(1);
@@ -101,7 +102,7 @@ static void mainstone_common_init(ram_addr_t ram_size,
if (!pflash_cfi01_register(mainstone_flash_base[i],
qemu_ram_alloc(MAINSTONE_FLASH),
- drives_table[index].bdrv, sector_len,
+ dinfo->bdrv, sector_len,
MAINSTONE_FLASH / sector_len, 4, 0, 0, 0, 0)) {
fprintf(stderr, "qemu: Error registering flash memory.\n");
exit(1);
diff --git a/hw/mips_jazz.c b/hw/mips_jazz.c
index 82cd385..e09a6b2 100644
--- a/hw/mips_jazz.c
+++ b/hw/mips_jazz.c
@@ -235,11 +235,8 @@ void mips_jazz_init (ram_addr_t ram_size,
exit(1);
}
for (n = 0; n < MAX_FD; n++) {
- int fd = drive_get_index(IF_FLOPPY, 0, n);
- if (fd != -1)
- fds[n] = drives_table[fd].bdrv;
- else
- fds[n] = NULL;
+ DriveInfo *dinfo = drive_get(IF_FLOPPY, 0, n);
+ fds[n] = dinfo ? dinfo->bdrv : NULL;
}
fdctrl_init(rc4030[1], 0, 1, 0x80003000, fds);
diff --git a/hw/mips_malta.c b/hw/mips_malta.c
index 853ec2b..fa03bdf 100644
--- a/hw/mips_malta.c
+++ b/hw/mips_malta.c
@@ -773,7 +773,7 @@ void mips_malta_init (ram_addr_t ram_size,
uint8_t *eeprom_buf;
i2c_bus *smbus;
int i;
- int index;
+ DriveInfo *dinfo;
BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
BlockDriverState *fd[MAX_FD];
int fl_idx = 0;
@@ -827,8 +827,8 @@ void mips_malta_init (ram_addr_t ram_size,
env->CP0_Status &= ~((1 << CP0St_BEV) | (1 << CP0St_ERL));
write_bootloader(env, qemu_get_ram_ptr(bios_offset), kernel_entry);
} else {
- index = drive_get_index(IF_PFLASH, 0, fl_idx);
- if (index != -1) {
+ dinfo = drive_get(IF_PFLASH, 0, fl_idx);
+ if (dinfo) {
/* Load firmware from flash. */
bios_size = 0x400000;
fl_sectors = bios_size >> 16;
@@ -836,10 +836,10 @@ void mips_malta_init (ram_addr_t ram_size,
printf("Register parallel flash %d size " TARGET_FMT_lx " at "
"offset %08lx addr %08llx '%s' %x\n",
fl_idx, bios_size, bios_offset, 0x1e000000LL,
- bdrv_get_device_name(drives_table[index].bdrv), fl_sectors);
+ bdrv_get_device_name(dinfo->bdrv), fl_sectors);
#endif
pflash_cfi01_register(0x1e000000LL, bios_offset,
- drives_table[index].bdrv, 65536, fl_sectors,
+ dinfo->bdrv, 65536, fl_sectors,
4, 0x0000, 0x0000, 0x0000, 0x0000);
fl_idx++;
} else {
@@ -898,11 +898,8 @@ void mips_malta_init (ram_addr_t ram_size,
}
for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) {
- index = drive_get_index(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
- if (index != -1)
- hd[i] = drives_table[index].bdrv;
- else
- hd[i] = NULL;
+ dinfo = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
+ hd[i] = dinfo ? dinfo->bdrv : NULL;
}
piix4_devfn = piix4_init(pci_bus, 80);
@@ -929,11 +926,8 @@ void mips_malta_init (ram_addr_t ram_size,
if (parallel_hds[0])
parallel_init(0x378, i8259[7], parallel_hds[0]);
for(i = 0; i < MAX_FD; i++) {
- index = drive_get_index(IF_FLOPPY, 0, i);
- if (index != -1)
- fd[i] = drives_table[index].bdrv;
- else
- fd[i] = NULL;
+ dinfo = drive_get(IF_FLOPPY, 0, i);
+ fd[i] = dinfo ? dinfo->bdrv : NULL;
}
floppy_controller = fdctrl_init(i8259[6], 2, 0, 0x3f0, fd);
diff --git a/hw/mips_r4k.c b/hw/mips_r4k.c
index 7f8af74..476612c 100644
--- a/hw/mips_r4k.c
+++ b/hw/mips_r4k.c
@@ -155,8 +155,8 @@ void mips_r4k_init (ram_addr_t ram_size,
RTCState *rtc_state;
int i;
qemu_irq *i8259;
- int index;
BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
+ DriveInfo *dinfo;
/* init CPUs */
if (cpu_model == NULL) {
@@ -208,11 +208,11 @@ void mips_r4k_init (ram_addr_t ram_size,
bios_offset | IO_MEM_ROM);
load_image_targphys(filename, 0x1fc00000, BIOS_SIZE);
- } else if ((index = drive_get_index(IF_PFLASH, 0, 0)) > -1) {
+ } else if ((dinfo = drive_get(IF_PFLASH, 0, 0)) != NULL) {
uint32_t mips_rom = 0x00400000;
bios_offset = qemu_ram_alloc(mips_rom);
if (!pflash_cfi01_register(0x1fc00000, bios_offset,
- drives_table[index].bdrv, sector_len, mips_rom / sector_len,
+ dinfo->bdrv, sector_len, mips_rom / sector_len,
4, 0, 0, 0, 0)) {
fprintf(stderr, "qemu: Error registering flash memory.\n");
}
@@ -267,11 +267,8 @@ void mips_r4k_init (ram_addr_t ram_size,
}
for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) {
- index = drive_get_index(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
- if (index != -1)
- hd[i] = drives_table[index].bdrv;
- else
- hd[i] = NULL;
+ dinfo = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
+ hd[i] = dinfo ? dinfo->bdrv : NULL;
}
for(i = 0; i < MAX_IDE_BUS; i++)
diff --git a/hw/musicpal.c b/hw/musicpal.c
index 10be69b..bd659ee 100644
--- a/hw/musicpal.c
+++ b/hw/musicpal.c
@@ -1512,8 +1512,8 @@ static void musicpal_init(ram_addr_t ram_size,
qemu_irq pic[32];
DeviceState *dev;
int i;
- int index;
unsigned long flash_size;
+ DriveInfo *dinfo;
if (!cpu_model)
cpu_model = "arm926";
@@ -1549,9 +1549,9 @@ static void musicpal_init(ram_addr_t ram_size,
serial_hds[1], 1);
/* Register flash */
- index = drive_get_index(IF_PFLASH, 0, 0);
- if (index != -1) {
- flash_size = bdrv_getlength(drives_table[index].bdrv);
+ dinfo = drive_get(IF_PFLASH, 0, 0);
+ if (dinfo) {
+ flash_size = bdrv_getlength(dinfo->bdrv);
if (flash_size != 8*1024*1024 && flash_size != 16*1024*1024 &&
flash_size != 32*1024*1024) {
fprintf(stderr, "Invalid flash image size\n");
@@ -1564,7 +1564,7 @@ static void musicpal_init(ram_addr_t ram_size,
* image is smaller than 32 MB.
*/
pflash_cfi02_register(0-MP_FLASH_SIZE_MAX, qemu_ram_alloc(flash_size),
- drives_table[index].bdrv, 0x10000,
+ dinfo->bdrv, 0x10000,
(flash_size + 0xffff) >> 16,
MP_FLASH_SIZE_MAX / flash_size,
2, 0x00BF, 0x236D, 0x0000, 0x0000,
diff --git a/hw/nand.c b/hw/nand.c
index 4ad77ec..37fd524 100644
--- a/hw/nand.c
+++ b/hw/nand.c
@@ -442,16 +442,16 @@ NANDFlashState *nand_init(int manf_id, int chip_id)
{
int pagesize;
NANDFlashState *s;
- int index;
+ DriveInfo *dinfo;
if (nand_flash_ids[chip_id].size == 0) {
hw_error("%s: Unsupported NAND chip ID.\n", __FUNCTION__);
}
s = (NANDFlashState *) qemu_mallocz(sizeof(NANDFlashState));
- index = drive_get_index(IF_MTD, 0, 0);
- if (index != -1)
- s->bdrv = drives_table[index].bdrv;
+ dinfo = drive_get(IF_MTD, 0, 0);
+ if (dinfo)
+ s->bdrv = dinfo->bdrv;
s->manf_id = manf_id;
s->chip_id = chip_id;
s->size = nand_flash_ids[s->chip_id].size << 20;
diff --git a/hw/omap1.c b/hw/omap1.c
index 5af2d9f..4f99c1c 100644
--- a/hw/omap1.c
+++ b/hw/omap1.c
@@ -4629,7 +4629,7 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
ram_addr_t imif_base, emiff_base;
qemu_irq *cpu_irq;
qemu_irq dma_irqs[6];
- int sdindex;
+ DriveInfo *dinfo;
if (!core)
core = "ti925t";
@@ -4741,12 +4741,12 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
omap_dpll_init(&s->dpll[1], 0xfffed000, omap_findclk(s, "dpll2"));
omap_dpll_init(&s->dpll[2], 0xfffed100, omap_findclk(s, "dpll3"));
- sdindex = drive_get_index(IF_SD, 0, 0);
- if (sdindex == -1) {
+ dinfo = drive_get(IF_SD, 0, 0);
+ if (!dinfo) {
fprintf(stderr, "qemu: missing SecureDigital device\n");
exit(1);
}
- s->mmc = omap_mmc_init(0xfffb7800, drives_table[sdindex].bdrv,
+ s->mmc = omap_mmc_init(0xfffb7800, dinfo->bdrv,
s->irq[1][OMAP_INT_OQN], &s->drq[OMAP_DMA_MMC_TX],
omap_findclk(s, "mmc_ck"));
diff --git a/hw/omap2.c b/hw/omap2.c
index f91d678..bf2f664 100644
--- a/hw/omap2.c
+++ b/hw/omap2.c
@@ -4497,7 +4497,7 @@ struct omap_mpu_state_s *omap2420_mpu_init(unsigned long sdram_size,
qemu_irq *cpu_irq;
qemu_irq dma_irqs[4];
omap_clk gpio_clks[4];
- int sdindex;
+ DriveInfo *dinfo;
int i;
/* Core */
@@ -4646,12 +4646,12 @@ struct omap_mpu_state_s *omap2420_mpu_init(unsigned long sdram_size,
s->sdrc = omap_sdrc_init(0x68009000);
s->gpmc = omap_gpmc_init(0x6800a000, s->irq[0][OMAP_INT_24XX_GPMC_IRQ]);
- sdindex = drive_get_index(IF_SD, 0, 0);
- if (sdindex == -1) {
+ dinfo = drive_get(IF_SD, 0, 0);
+ if (!dinfo) {
fprintf(stderr, "qemu: missing SecureDigital device\n");
exit(1);
}
- s->mmc = omap2_mmc_init(omap_l4tao(s->l4, 9), drives_table[sdindex].bdrv,
+ s->mmc = omap2_mmc_init(omap_l4tao(s->l4, 9), dinfo->bdrv,
s->irq[0][OMAP_INT_24XX_MMC_IRQ],
&s->drq[OMAP24XX_DMA_MMC1_TX],
omap_findclk(s, "mmc_fclk"), omap_findclk(s, "mmc_iclk"));
diff --git a/hw/omap_sx1.c b/hw/omap_sx1.c
index 0f6ed9e..cc91855 100644
--- a/hw/omap_sx1.c
+++ b/hw/omap_sx1.c
@@ -128,7 +128,7 @@ static void sx1_init(ram_addr_t ram_size,
static uint32_t cs2val = 0x00001139;
static uint32_t cs3val = 0x00001139;
ram_addr_t phys_flash;
- int index;
+ DriveInfo *dinfo;
int fl_idx;
uint32_t flash_size = flash0_size;
@@ -152,9 +152,9 @@ static void sx1_init(ram_addr_t ram_size,
fl_idx = 0;
- if ((index = drive_get_index(IF_PFLASH, 0, fl_idx)) > -1) {
+ if ((dinfo = drive_get(IF_PFLASH, 0, fl_idx)) != NULL) {
if (!pflash_cfi01_register(OMAP_CS0_BASE, qemu_ram_alloc(flash_size),
- drives_table[index].bdrv, sector_size, flash_size / sector_size,
+ dinfo->bdrv, sector_size, flash_size / sector_size,
4, 0, 0, 0, 0)) {
fprintf(stderr, "qemu: Error registering flash memory %d.\n",
fl_idx);
@@ -163,7 +163,7 @@ static void sx1_init(ram_addr_t ram_size,
}
if ((version == 1) &&
- (index = drive_get_index(IF_PFLASH, 0, fl_idx)) > -1) {
+ (dinfo = drive_get(IF_PFLASH, 0, fl_idx)) != NULL) {
cpu_register_physical_memory(OMAP_CS1_BASE, flash1_size,
(phys_flash = qemu_ram_alloc(flash1_size)) |
IO_MEM_ROM);
@@ -172,7 +172,7 @@ static void sx1_init(ram_addr_t ram_size,
OMAP_CS1_SIZE - flash1_size, io);
if (!pflash_cfi01_register(OMAP_CS1_BASE, qemu_ram_alloc(flash1_size),
- drives_table[index].bdrv, sector_size, flash1_size / sector_size,
+ dinfo->bdrv, sector_size, flash1_size / sector_size,
4, 0, 0, 0, 0)) {
fprintf(stderr, "qemu: Error registering flash memory %d.\n",
fl_idx);
diff --git a/hw/onenand.c b/hw/onenand.c
index 7388e7c..f8f2f05 100644
--- a/hw/onenand.c
+++ b/hw/onenand.c
@@ -619,7 +619,7 @@ static CPUWriteMemoryFunc *onenand_writefn[] = {
void *onenand_init(uint32_t id, int regshift, qemu_irq irq)
{
OneNANDState *s = (OneNANDState *) qemu_mallocz(sizeof(*s));
- int bdrv_index = drive_get_index(IF_MTD, 0, 0);
+ DriveInfo *dinfo = drive_get(IF_MTD, 0, 0);
uint32_t size = 1 << (24 + ((id >> 12) & 7));
void *ram;
@@ -633,11 +633,11 @@ void *onenand_init(uint32_t id, int regshift, qemu_irq irq)
s->density_mask = (id & (1 << 11)) ? (1 << (6 + ((id >> 12) & 7))) : 0;
s->iomemtype = cpu_register_io_memory(onenand_readfn,
onenand_writefn, s);
- if (bdrv_index == -1)
+ if (!dinfo)
s->image = memset(qemu_malloc(size + (size >> 5)),
0xff, size + (size >> 5));
else
- s->bdrv = drives_table[bdrv_index].bdrv;
+ s->bdrv = dinfo->bdrv;
s->otp = memset(qemu_malloc((64 + 2) << PAGE_SHIFT),
0xff, (64 + 2) << PAGE_SHIFT);
s->ram = qemu_ram_alloc(0xc000 << s->shift);
diff --git a/hw/pc.c b/hw/pc.c
index 553ba5c..204786a 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -1099,7 +1099,7 @@ static void pc_init1(ram_addr_t ram_size,
CPUState *env;
qemu_irq *cpu_irq;
qemu_irq *i8259;
- int index;
+ DriveInfo *dinfo;
BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
BlockDriverState *fd[MAX_FD];
int using_vga = cirrus_vga_enabled || std_vga_enabled || vmsvga_enabled;
@@ -1328,11 +1328,8 @@ static void pc_init1(ram_addr_t ram_size,
}
for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) {
- index = drive_get_index(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
- if (index != -1)
- hd[i] = drives_table[index].bdrv;
- else
- hd[i] = NULL;
+ dinfo = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
+ hd[i] = dinfo ? dinfo->bdrv : NULL;
}
if (pci_enabled) {
@@ -1351,11 +1348,8 @@ static void pc_init1(ram_addr_t ram_size,
#endif
for(i = 0; i < MAX_FD; i++) {
- index = drive_get_index(IF_FLOPPY, 0, i);
- if (index != -1)
- fd[i] = drives_table[index].bdrv;
- else
- fd[i] = NULL;
+ dinfo = drive_get(IF_FLOPPY, 0, i);
+ fd[i] = dinfo ? dinfo->bdrv : NULL;
}
floppy_controller = fdctrl_init(i8259[6], 2, 0, 0x3f0, fd);
@@ -1396,12 +1390,11 @@ static void pc_init1(ram_addr_t ram_size,
/* Add virtio block devices */
if (pci_enabled) {
- int index;
int unit_id = 0;
- while ((index = drive_get_index(IF_VIRTIO, 0, unit_id)) != -1) {
+ while ((dinfo = drive_get(IF_VIRTIO, 0, unit_id)) != NULL) {
pci_dev = pci_create("virtio-blk-pci",
- drives_table[index].devaddr);
+ dinfo->devaddr);
qdev_init(&pci_dev->qdev);
unit_id++;
}
diff --git a/hw/pci-hotplug.c b/hw/pci-hotplug.c
index d0f2911..43675e2 100644
--- a/hw/pci-hotplug.c
+++ b/hw/pci-hotplug.c
@@ -52,9 +52,10 @@ void drive_hot_add(Monitor *mon, const char *pci_addr, const char *opts)
{
int dom, pci_bus;
unsigned slot;
- int drive_idx, type, bus;
+ int type, bus;
int success = 0;
PCIDevice *dev;
+ DriveInfo *dinfo;
if (pci_read_devaddr(mon, pci_addr, &dom, &pci_bus, &slot)) {
return;
@@ -66,21 +67,21 @@ void drive_hot_add(Monitor *mon, const char *pci_addr, const char *opts)
return;
}
- drive_idx = add_init_drive(opts);
- if (drive_idx < 0)
+ dinfo = add_init_drive(opts);
+ if (!dinfo)
return;
- if (drives_table[drive_idx].devaddr) {
+ if (dinfo->devaddr) {
monitor_printf(mon, "Parameter addr not supported\n");
return;
}
- type = drives_table[drive_idx].type;
+ type = dinfo->type;
bus = drive_get_max_bus (type);
switch (type) {
case IF_SCSI:
success = 1;
- lsi_scsi_attach(&dev->qdev, drives_table[drive_idx].bdrv,
- drives_table[drive_idx].unit);
+ lsi_scsi_attach(&dev->qdev, dinfo->bdrv,
+ dinfo->unit);
break;
default:
monitor_printf(mon, "Can't hot-add drive to type %d\n", type);
@@ -88,8 +89,8 @@ void drive_hot_add(Monitor *mon, const char *pci_addr, const char *opts)
if (success)
monitor_printf(mon, "OK bus %d, unit %d\n",
- drives_table[drive_idx].bus,
- drives_table[drive_idx].unit);
+ dinfo->bus,
+ dinfo->unit);
return;
}
@@ -98,7 +99,8 @@ static PCIDevice *qemu_pci_hot_add_storage(Monitor *mon,
const char *opts)
{
PCIDevice *dev;
- int type = -1, drive_idx = -1;
+ DriveInfo *dinfo;
+ int type = -1;
char buf[128];
if (get_param_value(buf, sizeof(buf), "if", opts)) {
@@ -116,10 +118,10 @@ static PCIDevice *qemu_pci_hot_add_storage(Monitor *mon,
}
if (get_param_value(buf, sizeof(buf), "file", opts)) {
- drive_idx = add_init_drive(opts);
- if (drive_idx < 0)
+ dinfo = add_init_drive(opts);
+ if (!dinfo)
return NULL;
- if (drives_table[drive_idx].devaddr) {
+ if (dinfo->devaddr) {
monitor_printf(mon, "Parameter addr not supported\n");
return NULL;
}
diff --git a/hw/petalogix_s3adsp1800_mmu.c b/hw/petalogix_s3adsp1800_mmu.c
index c2a196f..1a1cc0e 100644
--- a/hw/petalogix_s3adsp1800_mmu.c
+++ b/hw/petalogix_s3adsp1800_mmu.c
@@ -106,6 +106,7 @@ petalogix_s3adsp1800_init(ram_addr_t ram_size,
DeviceState *dev;
CPUState *env;
int kernel_size;
+ DriveInfo *dinfo;
int i;
target_phys_addr_t ddr_base = 0x90000000;
ram_addr_t phys_lmb_bram;
@@ -131,9 +132,9 @@ petalogix_s3adsp1800_init(ram_addr_t ram_size,
cpu_register_physical_memory(ddr_base, ram_size, phys_ram | IO_MEM_RAM);
phys_flash = qemu_ram_alloc(FLASH_SIZE);
- i = drive_get_index(IF_PFLASH, 0, 0);
+ dinfo = drive_get(IF_PFLASH, 0, 0);
pflash_cfi02_register(0xa0000000, phys_flash,
- i != -1 ? drives_table[i].bdrv : NULL, (64 * 1024),
+ dinfo ? dinfo->bdrv : NULL, (64 * 1024),
FLASH_SIZE >> 16,
1, 1, 0x0000, 0x0000, 0x0000, 0x0000,
0x555, 0x2aa);
diff --git a/hw/ppc405_boards.c b/hw/ppc405_boards.c
index c9a1986..f2b4a84 100644
--- a/hw/ppc405_boards.c
+++ b/hw/ppc405_boards.c
@@ -188,7 +188,7 @@ static void ref405ep_init (ram_addr_t ram_size,
int linux_boot;
int fl_idx, fl_sectors, len;
int ppc_boot_device = boot_device[0];
- int index;
+ DriveInfo *dinfo;
/* XXX: fix this */
ram_bases[0] = qemu_ram_alloc(0x08000000);
@@ -215,19 +215,19 @@ static void ref405ep_init (ram_addr_t ram_size,
#endif
fl_idx = 0;
#ifdef USE_FLASH_BIOS
- index = drive_get_index(IF_PFLASH, 0, fl_idx);
- if (index != -1) {
- bios_size = bdrv_getlength(drives_table[index].bdrv);
+ dinfo = drive_get(IF_PFLASH, 0, fl_idx);
+ if (dinfo) {
+ bios_size = bdrv_getlength(dinfo->bdrv);
bios_offset = qemu_ram_alloc(bios_size);
fl_sectors = (bios_size + 65535) >> 16;
#ifdef DEBUG_BOARD_INIT
printf("Register parallel flash %d size " ADDRX " at offset %08lx "
" addr " ADDRX " '%s' %d\n",
fl_idx, bios_size, bios_offset, -bios_size,
- bdrv_get_device_name(drives_table[index].bdrv), fl_sectors);
+ bdrv_get_device_name(dinfo->bdrv), fl_sectors);
#endif
pflash_cfi02_register((uint32_t)(-bios_size), bios_offset,
- drives_table[index].bdrv, 65536, fl_sectors, 1,
+ dinfo->bdrv, 65536, fl_sectors, 1,
2, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA);
fl_idx++;
} else
@@ -509,7 +509,7 @@ static void taihu_405ep_init(ram_addr_t ram_size,
int linux_boot;
int fl_idx, fl_sectors;
int ppc_boot_device = boot_device[0];
- int index;
+ DriveInfo *dinfo;
/* RAM is soldered to the board so the size cannot be changed */
ram_bases[0] = qemu_ram_alloc(0x04000000);
@@ -528,9 +528,9 @@ static void taihu_405ep_init(ram_addr_t ram_size,
#endif
fl_idx = 0;
#if defined(USE_FLASH_BIOS)
- index = drive_get_index(IF_PFLASH, 0, fl_idx);
- if (index != -1) {
- bios_size = bdrv_getlength(drives_table[index].bdrv);
+ dinfo = drive_get(IF_PFLASH, 0, fl_idx);
+ if (dinfo) {
+ bios_size = bdrv_getlength(dinfo->bdrv);
/* XXX: should check that size is 2MB */
// bios_size = 2 * 1024 * 1024;
fl_sectors = (bios_size + 65535) >> 16;
@@ -539,10 +539,10 @@ static void taihu_405ep_init(ram_addr_t ram_size,
printf("Register parallel flash %d size " ADDRX " at offset %08lx "
" addr " ADDRX " '%s' %d\n",
fl_idx, bios_size, bios_offset, -bios_size,
- bdrv_get_device_name(drives_table[index].bdrv), fl_sectors);
+ bdrv_get_device_name(dinfo->bdrv), fl_sectors);
#endif
pflash_cfi02_register((uint32_t)(-bios_size), bios_offset,
- drives_table[index].bdrv, 65536, fl_sectors, 1,
+ dinfo->bdrv, 65536, fl_sectors, 1,
4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA);
fl_idx++;
} else
@@ -570,9 +570,9 @@ static void taihu_405ep_init(ram_addr_t ram_size,
bios_size, bios_offset | IO_MEM_ROM);
}
/* Register Linux flash */
- index = drive_get_index(IF_PFLASH, 0, fl_idx);
- if (index != -1) {
- bios_size = bdrv_getlength(drives_table[index].bdrv);
+ dinfo = drive_get(IF_PFLASH, 0, fl_idx);
+ if (dinfo) {
+ bios_size = bdrv_getlength(dinfo->bdrv);
/* XXX: should check that size is 32MB */
bios_size = 32 * 1024 * 1024;
fl_sectors = (bios_size + 65535) >> 16;
@@ -580,11 +580,11 @@ static void taihu_405ep_init(ram_addr_t ram_size,
printf("Register parallel flash %d size " ADDRX " at offset %08lx "
" addr " ADDRX " '%s'\n",
fl_idx, bios_size, bios_offset, (target_ulong)0xfc000000,
- bdrv_get_device_name(drives_table[index].bdrv));
+ bdrv_get_device_name(dinfo->bdrv));
#endif
bios_offset = qemu_ram_alloc(bios_size);
pflash_cfi02_register(0xfc000000, bios_offset,
- drives_table[index].bdrv, 65536, fl_sectors, 1,
+ dinfo->bdrv, 65536, fl_sectors, 1,
4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA);
fl_idx++;
}
diff --git a/hw/ppc440_bamboo.c b/hw/ppc440_bamboo.c
index d9ef3ec..624e15b 100644
--- a/hw/ppc440_bamboo.c
+++ b/hw/ppc440_bamboo.c
@@ -102,6 +102,7 @@ static void bamboo_init(ram_addr_t ram_size,
target_ulong dt_base = 0;
void *fdt;
int i;
+ DriveInfo *dinfo;
/* Setup CPU. */
env = ppc440ep_init(&ram_size, &pcibus, pci_irq_nrs, 1, cpu_model);
@@ -110,8 +111,8 @@ static void bamboo_init(ram_addr_t ram_size,
int unit_id = 0;
/* Add virtio block devices. */
- while ((i = drive_get_index(IF_VIRTIO, 0, unit_id)) != -1) {
- pci_dev = pci_create("virtio-blk-pci", drives_table[i].devaddr);
+ while ((dinfo = drive_get(IF_VIRTIO, 0, unit_id)) != NULL) {
+ pci_dev = pci_create("virtio-blk-pci", dinfo->devaddr);
qdev_init(&pci_dev->qdev);
unit_id++;
}
diff --git a/hw/ppc_newworld.c b/hw/ppc_newworld.c
index 4e5043c..caab74e 100644
--- a/hw/ppc_newworld.c
+++ b/hw/ppc_newworld.c
@@ -106,7 +106,7 @@ static void ppc_core99_init (ram_addr_t ram_size,
qemu_irq *dummy_irq;
int pic_mem_index, dbdma_mem_index, cuda_mem_index, escc_mem_index;
int ppc_boot_device;
- int index;
+ DriveInfo *dinfo;
BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
void *fw_cfg;
void *dbdma;
@@ -311,11 +311,8 @@ static void ppc_core99_init (ram_addr_t ram_size,
exit(1);
}
for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) {
- index = drive_get_index(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
- if (index != -1)
- hd[i] = drives_table[index].bdrv;
- else
- hd[i] = NULL;
+ dinfo = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
+ hd[i] = dinfo ? dinfo->bdrv : NULL;
}
dbdma = DBDMA_init(&dbdma_mem_index);
pci_cmd646_ide_init(pci_bus, hd, 0);
diff --git a/hw/ppc_oldworld.c b/hw/ppc_oldworld.c
index b26e407..388db31 100644
--- a/hw/ppc_oldworld.c
+++ b/hw/ppc_oldworld.c
@@ -135,7 +135,7 @@ static void ppc_heathrow_init (ram_addr_t ram_size,
int escc_mem_index, ide_mem_index[2];
uint16_t ppc_boot_device;
BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
- int index;
+ DriveInfo *dinfo;
void *fw_cfg;
void *dbdma;
uint8_t *vga_bios_ptr;
@@ -324,31 +324,19 @@ static void ppc_heathrow_init (ram_addr_t ram_size,
}
/* First IDE channel is a MAC IDE on the MacIO bus */
- index = drive_get_index(IF_IDE, 0, 0);
- if (index == -1)
- hd[0] = NULL;
- else
- hd[0] = drives_table[index].bdrv;
- index = drive_get_index(IF_IDE, 0, 1);
- if (index == -1)
- hd[1] = NULL;
- else
- hd[1] = drives_table[index].bdrv;
+ dinfo = drive_get(IF_IDE, 0, 0);
+ hd[0] = dinfo ? dinfo->bdrv : NULL;
+ dinfo = drive_get(IF_IDE, 0, 1);
+ hd[1] = dinfo ? dinfo->bdrv : NULL;
dbdma = DBDMA_init(&dbdma_mem_index);
ide_mem_index[0] = -1;
ide_mem_index[1] = pmac_ide_init(hd, pic[0x0D], dbdma, 0x16, pic[0x02]);
/* Second IDE channel is a CMD646 on the PCI bus */
- index = drive_get_index(IF_IDE, 1, 0);
- if (index == -1)
- hd[0] = NULL;
- else
- hd[0] = drives_table[index].bdrv;
- index = drive_get_index(IF_IDE, 1, 1);
- if (index == -1)
- hd[1] = NULL;
- else
- hd[1] = drives_table[index].bdrv;
+ dinfo = drive_get(IF_IDE, 1, 0);
+ hd[0] = dinfo ? dinfo->bdrv : NULL;
+ dinfo = drive_get(IF_IDE, 1, 1);
+ hd[1] = dinfo ? dinfo->bdrv : NULL;
hd[3] = hd[2] = NULL;
pci_cmd646_ide_init(pci_bus, hd, 0);
diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c
index 7181181..27509c9 100644
--- a/hw/ppc_prep.c
+++ b/hw/ppc_prep.c
@@ -549,7 +549,7 @@ static void ppc_prep_init (ram_addr_t ram_size,
PCIBus *pci_bus;
qemu_irq *i8259;
int ppc_boot_device;
- int index;
+ DriveInfo *dinfo;
BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
BlockDriverState *fd[MAX_FD];
@@ -690,11 +690,8 @@ static void ppc_prep_init (ram_addr_t ram_size,
}
for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) {
- index = drive_get_index(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
- if (index != -1)
- hd[i] = drives_table[index].bdrv;
- else
- hd[i] = NULL;
+ dinfo = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
+ hd[i] = dinfo ? dinfo->bdrv : NULL;
}
for(i = 0; i < MAX_IDE_BUS; i++) {
@@ -707,11 +704,8 @@ static void ppc_prep_init (ram_addr_t ram_size,
// SB16_init();
for(i = 0; i < MAX_FD; i++) {
- index = drive_get_index(IF_FLOPPY, 0, i);
- if (index != -1)
- fd[i] = drives_table[index].bdrv;
- else
- fd[i] = NULL;
+ dinfo = drive_get(IF_FLOPPY, 0, i);
+ fd[i] = dinfo ? dinfo->bdrv : NULL;
}
fdctrl_init(i8259[6], 2, 0, 0x3f0, fd);
diff --git a/hw/ppce500_mpc8544ds.c b/hw/ppce500_mpc8544ds.c
index c0e367d..04c6acd 100644
--- a/hw/ppce500_mpc8544ds.c
+++ b/hw/ppce500_mpc8544ds.c
@@ -172,6 +172,7 @@ static void mpc8544ds_init(ram_addr_t ram_size,
unsigned int pci_irq_nrs[4] = {1, 2, 3, 4};
qemu_irq *irqs, *mpic, *pci_irqs;
SerialState * serial[2];
+ DriveInfo *dinfo;
/* Setup CPU */
env = cpu_ppc_init("e500v2_v30");
@@ -219,8 +220,8 @@ static void mpc8544ds_init(ram_addr_t ram_size,
int unit_id = 0;
/* Add virtio block devices. */
- while ((i = drive_get_index(IF_VIRTIO, 0, unit_id)) != -1) {
- pci_dev = pci_create("virtio-blk-pci", drives_table[i].devaddr);
+ while ((dinfo = drive_get(IF_VIRTIO, 0, unit_id)) != NULL) {
+ pci_dev = pci_create("virtio-blk-pci", dinfo->devaddr);
qdev_init(&pci_dev->qdev);
unit_id++;
}
diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c
index f2e98ff..28e9610 100644
--- a/hw/pxa2xx.c
+++ b/hw/pxa2xx.c
@@ -2034,7 +2034,7 @@ PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision)
{
PXA2xxState *s;
int iomemtype, i;
- int index;
+ DriveInfo *dinfo;
s = (PXA2xxState *) qemu_mallocz(sizeof(PXA2xxState));
if (revision && strncmp(revision, "pxa27", 5)) {
@@ -2066,12 +2066,12 @@ PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision)
s->gpio = pxa2xx_gpio_init(0x40e00000, s->env, s->pic, 121);
- index = drive_get_index(IF_SD, 0, 0);
- if (index == -1) {
+ dinfo = drive_get(IF_SD, 0, 0);
+ if (!dinfo) {
fprintf(stderr, "qemu: missing SecureDigital device\n");
exit(1);
}
- s->mmc = pxa2xx_mmci_init(0x41100000, drives_table[index].bdrv,
+ s->mmc = pxa2xx_mmci_init(0x41100000, dinfo->bdrv,
s->pic[PXA2XX_PIC_MMC], s->dma);
for (i = 0; pxa270_serial[i].io_base; i ++)
@@ -2153,7 +2153,7 @@ PXA2xxState *pxa255_init(unsigned int sdram_size)
{
PXA2xxState *s;
int iomemtype, i;
- int index;
+ DriveInfo *dinfo;
s = (PXA2xxState *) qemu_mallocz(sizeof(PXA2xxState));
@@ -2178,12 +2178,12 @@ PXA2xxState *pxa255_init(unsigned int sdram_size)
s->gpio = pxa2xx_gpio_init(0x40e00000, s->env, s->pic, 85);
- index = drive_get_index(IF_SD, 0, 0);
- if (index == -1) {
+ dinfo = drive_get(IF_SD, 0, 0);
+ if (!dinfo) {
fprintf(stderr, "qemu: missing SecureDigital device\n");
exit(1);
}
- s->mmc = pxa2xx_mmci_init(0x41100000, drives_table[index].bdrv,
+ s->mmc = pxa2xx_mmci_init(0x41100000, dinfo->bdrv,
s->pic[PXA2XX_PIC_MMC], s->dma);
for (i = 0; pxa255_serial[i].io_base; i ++)
diff --git a/hw/qdev.c b/hw/qdev.c
index 83e98bf..8f02150 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -269,13 +269,10 @@ static int next_block_unit[IF_COUNT];
BlockDriverState *qdev_init_bdrv(DeviceState *dev, BlockInterfaceType type)
{
int unit = next_block_unit[type]++;
- int index;
+ DriveInfo *dinfo;
- index = drive_get_index(type, 0, unit);
- if (index == -1) {
- return NULL;
- }
- return drives_table[index].bdrv;
+ dinfo = drive_get(type, 0, unit);
+ return dinfo ? dinfo->bdrv : NULL;
}
BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
@@ -298,14 +295,14 @@ void scsi_bus_new(DeviceState *host, SCSIAttachFn attach)
{
int bus = next_scsi_bus++;
int unit;
- int index;
+ DriveInfo *dinfo;
for (unit = 0; unit < MAX_SCSI_DEVS; unit++) {
- index = drive_get_index(IF_SCSI, bus, unit);
- if (index == -1) {
+ dinfo = drive_get(IF_SCSI, bus, unit);
+ if (!dinfo) {
continue;
}
- attach(host, drives_table[index].bdrv, unit);
+ attach(host, dinfo->bdrv, unit);
}
}
diff --git a/hw/r2d.c b/hw/r2d.c
index 8ce6832..697bcb6 100644
--- a/hw/r2d.c
+++ b/hw/r2d.c
@@ -203,6 +203,7 @@ static void r2d_init(ram_addr_t ram_size,
ram_addr_t sdram_addr;
qemu_irq *irq;
PCIBus *pci;
+ DriveInfo *dinfo;
int i;
if (!cpu_model)
@@ -225,9 +226,9 @@ static void r2d_init(ram_addr_t ram_size,
sm501_init(0x10000000, SM501_VRAM_SIZE, irq[SM501], serial_hds[2]);
/* onboard CF (True IDE mode, Master only). */
- if ((i = drive_get_index(IF_IDE, 0, 0)) != -1)
+ if ((dinfo = drive_get(IF_IDE, 0, 0)) != NULL)
mmio_ide_init(0x14001000, 0x1400080c, irq[CF_IDE], 1,
- drives_table[i].bdrv, NULL);
+ dinfo->bdrv, NULL);
/* NIC: rtl8139 on-board, and 2 slots. */
for (i = 0; i < nb_nics; i++)
diff --git a/hw/spitz.c b/hw/spitz.c
index d9ff85e..36bf534 100644
--- a/hw/spitz.c
+++ b/hw/spitz.c
@@ -744,13 +744,13 @@ static void spitz_ssp_attach(PXA2xxState *cpu)
static void spitz_microdrive_attach(PXA2xxState *cpu, int slot)
{
PCMCIACardState *md;
- int index;
BlockDriverState *bs;
+ DriveInfo *dinfo;
- index = drive_get_index(IF_IDE, 0, 0);
- if (index == -1)
+ dinfo = drive_get(IF_IDE, 0, 0);
+ if (!dinfo)
return;
- bs = drives_table[index].bdrv;
+ bs = dinfo->bdrv;
if (bdrv_is_inserted(bs) && !bdrv_is_removable(bs)) {
md = dscm1xxxx_init(bs);
pxa2xx_pcmcia_attach(cpu->pcmcia[slot], md);
diff --git a/hw/sun4m.c b/hw/sun4m.c
index f9ef298..d2ac648 100644
--- a/hw/sun4m.c
+++ b/hw/sun4m.c
@@ -442,8 +442,8 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, ram_addr_t RAM_size,
int ret;
char *filename;
BlockDriverState *fd[MAX_FD];
- int drive_index;
void *fw_cfg;
+ DriveInfo *dinfo;
/* init CPUs */
if (!cpu_model)
@@ -563,9 +563,9 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, ram_addr_t RAM_size,
if (hwdef->fd_base) {
/* there is zero or one floppy drive */
memset(fd, 0, sizeof(fd));
- drive_index = drive_get_index(IF_FLOPPY, 0, 0);
- if (drive_index != -1)
- fd[0] = drives_table[drive_index].bdrv;
+ dinfo = drive_get(IF_FLOPPY, 0, 0);
+ if (dinfo)
+ fd[0] = dinfo->bdrv;
sun4m_fdctrl_init(slavio_irq[hwdef->fd_irq], hwdef->fd_base, fd,
&fdc_tc);
@@ -1451,8 +1451,8 @@ static void sun4c_hw_init(const struct sun4c_hwdef *hwdef, ram_addr_t RAM_size,
int ret;
char *filename;
BlockDriverState *fd[MAX_FD];
- int drive_index;
void *fw_cfg;
+ DriveInfo *dinfo;
/* init CPU */
if (!cpu_model)
@@ -1547,9 +1547,9 @@ static void sun4c_hw_init(const struct sun4c_hwdef *hwdef, ram_addr_t RAM_size,
if (hwdef->fd_base != (target_phys_addr_t)-1) {
/* there is zero or one floppy drive */
memset(fd, 0, sizeof(fd));
- drive_index = drive_get_index(IF_FLOPPY, 0, 0);
- if (drive_index != -1)
- fd[0] = drives_table[drive_index].bdrv;
+ dinfo = drive_get(IF_FLOPPY, 0, 0);
+ if (dinfo)
+ fd[0] = dinfo->bdrv;
sun4m_fdctrl_init(slavio_irq[hwdef->fd_irq], hwdef->fd_base, fd,
&fdc_tc);
diff --git a/hw/sun4u.c b/hw/sun4u.c
index 9d2a7f5..1fba1a4 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -358,11 +358,11 @@ static void sun4uv_init(ram_addr_t RAM_size,
PCIBus *pci_bus, *pci_bus2, *pci_bus3;
QEMUBH *bh;
qemu_irq *irq;
- int drive_index;
BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
BlockDriverState *fd[MAX_FD];
void *fw_cfg;
ResetData *reset_info;
+ DriveInfo *dinfo;
linux_boot = (kernel_filename != NULL);
@@ -504,12 +504,9 @@ static void sun4uv_init(ram_addr_t RAM_size,
exit(1);
}
for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) {
- drive_index = drive_get_index(IF_IDE, i / MAX_IDE_DEVS,
- i % MAX_IDE_DEVS);
- if (drive_index != -1)
- hd[i] = drives_table[drive_index].bdrv;
- else
- hd[i] = NULL;
+ dinfo = drive_get(IF_IDE, i / MAX_IDE_DEVS,
+ i % MAX_IDE_DEVS);
+ hd[i] = dinfo ? dinfo->bdrv : NULL;
}
pci_cmd646_ide_init(pci_bus, hd, 1);
@@ -517,11 +514,8 @@ static void sun4uv_init(ram_addr_t RAM_size,
/* FIXME: wire up interrupts. */
i8042_init(NULL/*1*/, NULL/*12*/, 0x60);
for(i = 0; i < MAX_FD; i++) {
- drive_index = drive_get_index(IF_FLOPPY, 0, i);
- if (drive_index != -1)
- fd[i] = drives_table[drive_index].bdrv;
- else
- fd[i] = NULL;
+ dinfo = drive_get(IF_FLOPPY, 0, i);
+ fd[i] = dinfo ? dinfo->bdrv : NULL;
}
floppy_controller = fdctrl_init(NULL/*6*/, 2, 0, 0x3f0, fd);
nvram = m48t59_init(NULL/*8*/, 0, 0x0074, NVRAM_SIZE, 59);
diff --git a/hw/tosa.c b/hw/tosa.c
index b2d66f3..b932efc 100644
--- a/hw/tosa.c
+++ b/hw/tosa.c
@@ -49,13 +49,13 @@
static void tosa_microdrive_attach(PXA2xxState *cpu)
{
PCMCIACardState *md;
- int index;
BlockDriverState *bs;
+ DriveInfo *dinfo;
- index = drive_get_index(IF_IDE, 0, 0);
- if (index == -1)
+ dinfo = drive_get(IF_IDE, 0, 0);
+ if (!dinfo)
return;
- bs = drives_table[index].bdrv;
+ bs = dinfo->bdrv;
if (bdrv_is_inserted(bs) && !bdrv_is_removable(bs)) {
md = dscm1xxxx_init(bs);
pxa2xx_pcmcia_attach(cpu->pcmcia[0], md);
diff --git a/monitor.c b/monitor.c
index 342af32..4afb7d0 100644
--- a/monitor.c
+++ b/monitor.c
@@ -244,13 +244,15 @@ static void help_cmd(Monitor *mon, const char *name)
static void do_commit(Monitor *mon, const char *device)
{
- int i, all_devices;
+ int all_devices;
+ DriveInfo *dinfo;
all_devices = !strcmp(device, "all");
- for (i = 0; i < nb_drives; i++) {
- if (all_devices ||
- !strcmp(bdrv_get_device_name(drives_table[i].bdrv), device))
- bdrv_commit(drives_table[i].bdrv);
+ TAILQ_FOREACH(dinfo, &drives, next) {
+ if (!all_devices)
+ if (!strcmp(bdrv_get_device_name(dinfo->bdrv), device))
+ continue;
+ bdrv_commit(dinfo->bdrv);
}
}
diff --git a/qemu-char.c b/qemu-char.c
index 287e0cd..4a1c082 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -345,9 +345,9 @@ static int mux_proc_byte(CharDriverState *chr, MuxDriver *d, int ch)
}
case 's':
{
- int i;
- for (i = 0; i < nb_drives; i++) {
- bdrv_commit(drives_table[i].bdrv);
+ DriveInfo *dinfo;
+ TAILQ_FOREACH(dinfo, &drives, next) {
+ bdrv_commit(dinfo->bdrv);
}
}
break;
diff --git a/savevm.c b/savevm.c
index 17da35a..dc05a48 100644
--- a/savevm.c
+++ b/savevm.c
@@ -1027,12 +1027,12 @@ static int bdrv_has_snapshot(BlockDriverState *bs)
static BlockDriverState *get_bs_snapshots(void)
{
BlockDriverState *bs;
- int i;
+ DriveInfo *dinfo;
if (bs_snapshots)
return bs_snapshots;
- for(i = 0; i <= nb_drives; i++) {
- bs = drives_table[i].bdrv;
+ TAILQ_FOREACH(dinfo, &drives, next) {
+ bs = dinfo->bdrv;
if (bdrv_can_snapshot(bs))
goto ok;
}
@@ -1066,9 +1066,10 @@ static int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info,
void do_savevm(Monitor *mon, const char *name)
{
+ DriveInfo *dinfo;
BlockDriverState *bs, *bs1;
QEMUSnapshotInfo sn1, *sn = &sn1, old_sn1, *old_sn = &old_sn1;
- int must_delete, ret, i;
+ int must_delete, ret;
BlockDriverInfo bdi1, *bdi = &bdi1;
QEMUFile *f;
int saved_vm_running;
@@ -1141,8 +1142,8 @@ void do_savevm(Monitor *mon, const char *name)
/* create the snapshots */
- for(i = 0; i < nb_drives; i++) {
- bs1 = drives_table[i].bdrv;
+ TAILQ_FOREACH(dinfo, &drives, next) {
+ bs1 = dinfo->bdrv;
if (bdrv_has_snapshot(bs1)) {
if (must_delete) {
ret = bdrv_snapshot_delete(bs1, old_sn->id_str);
@@ -1169,11 +1170,12 @@ void do_savevm(Monitor *mon, const char *name)
void do_loadvm(Monitor *mon, const char *name)
{
+ DriveInfo *dinfo;
BlockDriverState *bs, *bs1;
BlockDriverInfo bdi1, *bdi = &bdi1;
QEMUSnapshotInfo sn;
QEMUFile *f;
- int i, ret;
+ int ret;
int saved_vm_running;
bs = get_bs_snapshots();
@@ -1188,8 +1190,8 @@ void do_loadvm(Monitor *mon, const char *name)
saved_vm_running = vm_running;
vm_stop(0);
- for(i = 0; i <= nb_drives; i++) {
- bs1 = drives_table[i].bdrv;
+ TAILQ_FOREACH(dinfo, &drives, next) {
+ bs1 = dinfo->bdrv;
if (bdrv_has_snapshot(bs1)) {
ret = bdrv_snapshot_goto(bs1, name);
if (ret < 0) {
@@ -1247,8 +1249,9 @@ void do_loadvm(Monitor *mon, const char *name)
void do_delvm(Monitor *mon, const char *name)
{
+ DriveInfo *dinfo;
BlockDriverState *bs, *bs1;
- int i, ret;
+ int ret;
bs = get_bs_snapshots();
if (!bs) {
@@ -1256,8 +1259,8 @@ void do_delvm(Monitor *mon, const char *name)
return;
}
- for(i = 0; i <= nb_drives; i++) {
- bs1 = drives_table[i].bdrv;
+ TAILQ_FOREACH(dinfo, &drives, next) {
+ bs1 = dinfo->bdrv;
if (bdrv_has_snapshot(bs1)) {
ret = bdrv_snapshot_delete(bs1, name);
if (ret < 0) {
@@ -1275,6 +1278,7 @@ void do_delvm(Monitor *mon, const char *name)
void do_info_snapshots(Monitor *mon)
{
+ DriveInfo *dinfo;
BlockDriverState *bs, *bs1;
QEMUSnapshotInfo *sn_tab, *sn;
int nb_sns, i;
@@ -1286,8 +1290,8 @@ void do_info_snapshots(Monitor *mon)
return;
}
monitor_printf(mon, "Snapshot devices:");
- for(i = 0; i <= nb_drives; i++) {
- bs1 = drives_table[i].bdrv;
+ TAILQ_FOREACH(dinfo, &drives, next) {
+ bs1 = dinfo->bdrv;
if (bdrv_has_snapshot(bs1)) {
if (bs == bs1)
monitor_printf(mon, " %s", bdrv_get_device_name(bs1));
diff --git a/sysemu.h b/sysemu.h
index 06dc4c6..36d6aaa 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -3,6 +3,7 @@
/* Misc. things related to the system emulator. */
#include "qemu-common.h"
+#include "sys-queue.h"
#ifdef _WIN32
#include <windows.h>
@@ -163,20 +164,19 @@ typedef struct DriveInfo {
BlockInterfaceType type;
int bus;
int unit;
- int used;
int drive_opt_idx;
BlockInterfaceErrorAction onerror;
char serial[BLOCK_SERIAL_STRLEN + 1];
+ TAILQ_ENTRY(DriveInfo) next;
} DriveInfo;
#define MAX_IDE_DEVS 2
#define MAX_SCSI_DEVS 7
#define MAX_DRIVES 32
-extern int nb_drives;
-extern DriveInfo drives_table[MAX_DRIVES+1];
+extern TAILQ_HEAD(drivelist, DriveInfo) drives;
-extern int drive_get_index(BlockInterfaceType type, int bus, int unit);
+extern DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit);
extern int drive_get_max_bus(BlockInterfaceType type);
extern void drive_uninit(BlockDriverState *bdrv);
extern void drive_remove(int index);
@@ -195,7 +195,8 @@ extern struct drive_opt drives_opt[MAX_DRIVES];
extern int nb_drives_opt;
extern int drive_add(const char *file, const char *fmt, ...);
-extern int drive_init(struct drive_opt *arg, int snapshot, void *machine);
+extern DriveInfo *drive_init(struct drive_opt *arg, int snapshot, void *machine,
+ int *fatal_error);
/* acpi */
typedef void (*qemu_system_device_hot_add_t)(int pcibus, int slot, int state);
@@ -206,7 +207,7 @@ void qemu_system_device_hot_add(int pcibus, int slot, int state);
typedef int (dev_match_fn)(void *dev_private, void *arg);
-int add_init_drive(const char *opts);
+DriveInfo *add_init_drive(const char *opts);
void destroy_nic(dev_match_fn *match_fn, void *arg);
void destroy_bdrvs(dev_match_fn *match_fn, void *arg);
diff --git a/vl.c b/vl.c
index 50665cf..4dae7ad 100644
--- a/vl.c
+++ b/vl.c
@@ -183,8 +183,7 @@ static const char *data_dir;
const char *bios_name = NULL;
/* Note: drives_table[MAX_DRIVES] is a dummy block driver if none available
to store the VM snapshots */
-DriveInfo drives_table[MAX_DRIVES+1];
-int nb_drives;
+struct drivelist drives = TAILQ_HEAD_INITIALIZER(drives);
enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB;
static DisplayState *display_state;
DisplayType display_type = DT_DEFAULT;
@@ -1878,19 +1877,6 @@ static int drive_opt_get_free_idx(void)
return -1;
}
-static int drive_get_free_idx(void)
-{
- int index;
-
- for (index = 0; index < MAX_DRIVES; index++)
- if (!drives_table[index].used) {
- drives_table[index].used = 1;
- return index;
- }
-
- return -1;
-}
-
int drive_add(const char *file, const char *fmt, ...)
{
va_list ap;
@@ -1917,54 +1903,56 @@ void drive_remove(int index)
nb_drives_opt--;
}
-int drive_get_index(BlockInterfaceType type, int bus, int unit)
+DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit)
{
- int index;
+ DriveInfo *dinfo;
/* seek interface, bus and unit */
- for (index = 0; index < MAX_DRIVES; index++)
- if (drives_table[index].type == type &&
- drives_table[index].bus == bus &&
- drives_table[index].unit == unit &&
- drives_table[index].used)
- return index;
+ TAILQ_FOREACH(dinfo, &drives, next) {
+ if (dinfo->type == type &&
+ dinfo->bus == bus &&
+ dinfo->unit == unit)
+ return dinfo;
+ }
- return -1;
+ return NULL;
}
int drive_get_max_bus(BlockInterfaceType type)
{
int max_bus;
- int index;
+ DriveInfo *dinfo;
max_bus = -1;
- for (index = 0; index < nb_drives; index++) {
- if(drives_table[index].type == type &&
- drives_table[index].bus > max_bus)
- max_bus = drives_table[index].bus;
+ TAILQ_FOREACH(dinfo, &drives, next) {
+ if(dinfo->type == type &&
+ dinfo->bus > max_bus)
+ max_bus = dinfo->bus;
}
return max_bus;
}
const char *drive_get_serial(BlockDriverState *bdrv)
{
- int index;
+ DriveInfo *dinfo;
- for (index = 0; index < nb_drives; index++)
- if (drives_table[index].bdrv == bdrv)
- return drives_table[index].serial;
+ TAILQ_FOREACH(dinfo, &drives, next) {
+ if (dinfo->bdrv == bdrv)
+ return dinfo->serial;
+ }
return "\0";
}
BlockInterfaceErrorAction drive_get_onerror(BlockDriverState *bdrv)
{
- int index;
+ DriveInfo *dinfo;
- for (index = 0; index < nb_drives; index++)
- if (drives_table[index].bdrv == bdrv)
- return drives_table[index].onerror;
+ TAILQ_FOREACH(dinfo, &drives, next) {
+ if (dinfo->bdrv == bdrv)
+ return dinfo->onerror;
+ }
return BLOCK_ERR_STOP_ENOSPC;
}
@@ -1976,19 +1964,20 @@ static void bdrv_format_print(void *opaque, const char *name)
void drive_uninit(BlockDriverState *bdrv)
{
- int i;
+ DriveInfo *dinfo;
- for (i = 0; i < MAX_DRIVES; i++)
- if (drives_table[i].bdrv == bdrv) {
- drives_table[i].bdrv = NULL;
- drives_table[i].used = 0;
- drive_remove(drives_table[i].drive_opt_idx);
- nb_drives--;
- break;
- }
+ TAILQ_FOREACH(dinfo, &drives, next) {
+ if (dinfo->bdrv != bdrv)
+ continue;
+ drive_remove(dinfo->drive_opt_idx);
+ TAILQ_REMOVE(&drives, dinfo, next);
+ qemu_free(dinfo);
+ break;
+ }
}
-int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
+DriveInfo *drive_init(struct drive_opt *arg, int snapshot, void *opaque,
+ int *fatal_error)
{
char buf[128];
char file[1024];
@@ -2007,7 +1996,7 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
int cache;
int bdrv_flags, onerror;
const char *devaddr;
- int drives_table_idx;
+ DriveInfo *dinfo;
char *str = arg->opt;
static const char * const params[] = { "bus", "unit", "if", "index",
"cyls", "heads", "secs", "trans",
@@ -2015,11 +2004,12 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
"cache", "format", "serial",
"werror", "addr",
NULL };
+ *fatal_error = 1;
if (check_params(buf, sizeof(buf), params, str) < 0) {
fprintf(stderr, "qemu: unknown parameter '%s' in '%s'\n",
buf, str);
- return -1;
+ return NULL;
}
file[0] = 0;
@@ -2047,7 +2037,7 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
bus_id = strtol(buf, NULL, 0);
if (bus_id < 0) {
fprintf(stderr, "qemu: '%s' invalid bus id\n", str);
- return -1;
+ return NULL;
}
}
@@ -2055,7 +2045,7 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
unit_id = strtol(buf, NULL, 0);
if (unit_id < 0) {
fprintf(stderr, "qemu: '%s' invalid unit id\n", str);
- return -1;
+ return NULL;
}
}
@@ -2087,7 +2077,7 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
max_devs = 0;
} else {
fprintf(stderr, "qemu: '%s' unsupported bus type '%s'\n", str, buf);
- return -1;
+ return NULL;
}
}
@@ -2095,7 +2085,7 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
index = strtol(buf, NULL, 0);
if (index < 0) {
fprintf(stderr, "qemu: '%s' invalid index\n", str);
- return -1;
+ return NULL;
}
}
@@ -2114,15 +2104,15 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
if (cyls || heads || secs) {
if (cyls < 1 || cyls > 16383) {
fprintf(stderr, "qemu: '%s' invalid physical cyls number\n", str);
- return -1;
+ return NULL;
}
if (heads < 1 || heads > 16) {
fprintf(stderr, "qemu: '%s' invalid physical heads number\n", str);
- return -1;
+ return NULL;
}
if (secs < 1 || secs > 63) {
fprintf(stderr, "qemu: '%s' invalid physical secs number\n", str);
- return -1;
+ return NULL;
}
}
@@ -2131,7 +2121,7 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
fprintf(stderr,
"qemu: '%s' trans must be used with cyls,heads and secs\n",
str);
- return -1;
+ return NULL;
}
if (!strcmp(buf, "none"))
translation = BIOS_ATA_TRANSLATION_NONE;
@@ -2141,7 +2131,7 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
translation = BIOS_ATA_TRANSLATION_AUTO;
else {
fprintf(stderr, "qemu: '%s' invalid translation type\n", str);
- return -1;
+ return NULL;
}
}
@@ -2152,12 +2142,12 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
if (cyls || secs || heads) {
fprintf(stderr,
"qemu: '%s' invalid physical CHS format\n", str);
- return -1;
+ return NULL;
}
media = MEDIA_CDROM;
} else {
fprintf(stderr, "qemu: '%s' invalid media\n", str);
- return -1;
+ return NULL;
}
}
@@ -2168,7 +2158,7 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
snapshot = 0;
else {
fprintf(stderr, "qemu: '%s' invalid snapshot option\n", str);
- return -1;
+ return NULL;
}
}
@@ -2181,7 +2171,7 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
cache = 2;
else {
fprintf(stderr, "qemu: invalid cache option\n");
- return -1;
+ return NULL;
}
}
@@ -2190,12 +2180,12 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
fprintf(stderr, "qemu: Supported formats:");
bdrv_iterate_format(bdrv_format_print, NULL);
fprintf(stderr, "\n");
- return -1;
+ return NULL;
}
drv = bdrv_find_format(buf);
if (!drv) {
fprintf(stderr, "qemu: '%s' invalid format\n", buf);
- return -1;
+ return NULL;
}
}
@@ -2211,7 +2201,7 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
if (get_param_value(buf, sizeof(serial), "werror", str)) {
if (type != IF_IDE && type != IF_SCSI && type != IF_VIRTIO) {
fprintf(stderr, "werror is no supported by this format\n");
- return -1;
+ return NULL;
}
if (!strcmp(buf, "ignore"))
onerror = BLOCK_ERR_IGNORE;
@@ -2223,7 +2213,7 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
onerror = BLOCK_ERR_REPORT;
else {
fprintf(stderr, "qemu: '%s' invalid write error action\n", buf);
- return -1;
+ return NULL;
}
}
@@ -2231,7 +2221,7 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
if (get_param_value(buf, sizeof(buf), "addr", str)) {
if (type != IF_VIRTIO) {
fprintf(stderr, "addr is not supported by in '%s'\n", str);
- return -1;
+ return NULL;
}
devaddr = strdup(buf);
}
@@ -2242,7 +2232,7 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
if (bus_id != 0 || unit_id != -1) {
fprintf(stderr,
"qemu: '%s' index cannot be used with bus and unit\n", str);
- return -1;
+ return NULL;
}
if (max_devs == 0)
{
@@ -2260,7 +2250,7 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
if (unit_id == -1) {
unit_id = 0;
- while (drive_get_index(type, bus_id, unit_id) != -1) {
+ while (drive_get(type, bus_id, unit_id) != NULL) {
unit_id++;
if (max_devs && unit_id >= max_devs) {
unit_id -= max_devs;
@@ -2274,15 +2264,17 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
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);
- return -1;
+ return NULL;
}
/*
* ignore multiple definitions
*/
- if (drive_get_index(type, bus_id, unit_id) != -1)
- return -2;
+ if (drive_get(type, bus_id, unit_id) != NULL) {
+ *fatal_error = 0;
+ return NULL;
+ }
/* init */
@@ -2295,16 +2287,16 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
snprintf(buf, sizeof(buf), "%s%s%i",
devname, mediastr, unit_id);
bdrv = bdrv_new(buf);
- drives_table_idx = drive_get_free_idx();
- drives_table[drives_table_idx].bdrv = bdrv;
- drives_table[drives_table_idx].devaddr = devaddr;
- drives_table[drives_table_idx].type = type;
- drives_table[drives_table_idx].bus = bus_id;
- drives_table[drives_table_idx].unit = unit_id;
- drives_table[drives_table_idx].onerror = onerror;
- drives_table[drives_table_idx].drive_opt_idx = arg - drives_opt;
- strncpy(drives_table[drives_table_idx].serial, serial, sizeof(serial));
- nb_drives++;
+ dinfo = qemu_mallocz(sizeof(*dinfo));
+ dinfo->bdrv = bdrv;
+ dinfo->devaddr = devaddr;
+ dinfo->type = type;
+ dinfo->bus = bus_id;
+ dinfo->unit = unit_id;
+ dinfo->onerror = onerror;
+ dinfo->drive_opt_idx = arg - drives_opt;
+ strncpy(dinfo->serial, serial, sizeof(serial));
+ TAILQ_INSERT_TAIL(&drives, dinfo, next);
switch(type) {
case IF_IDE:
@@ -2335,8 +2327,10 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
case IF_COUNT:
abort();
}
- if (!file[0])
- return -2;
+ if (!file[0]) {
+ *fatal_error = 0;
+ return NULL;
+ }
bdrv_flags = 0;
if (snapshot) {
bdrv_flags |= BDRV_O_SNAPSHOT;
@@ -2349,11 +2343,12 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
if (bdrv_open2(bdrv, file, bdrv_flags, drv) < 0) {
fprintf(stderr, "qemu: could not open disk image %s\n",
file);
- return -1;
+ return NULL;
}
if (bdrv_key_required(bdrv))
autostart = 0;
- return drives_table_idx;
+ *fatal_error = 0;
+ return dinfo;
}
static void numa_add(const char *optarg)
@@ -4872,7 +4867,6 @@ int main(int argc, char **argv, char **envp)
nb_net_clients = 0;
nb_bt_opts = 0;
- nb_drives = 0;
nb_drives_opt = 0;
nb_numa_nodes = 0;
hda_index = -1;
@@ -5735,9 +5729,12 @@ int main(int argc, char **argv, char **envp)
/* open the virtual block devices */
- for(i = 0; i < nb_drives_opt; i++)
- if (drive_init(&drives_opt[i], snapshot, machine) == -1)
- exit(1);
+ for(i = 0; i < nb_drives_opt; i++) {
+ int fatal_error;
+ if (drive_init(&drives_opt[i], snapshot, machine, &fatal_error) == NULL)
+ if (fatal_error)
+ 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
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [Qemu-devel] [PATCH v3 2/5] add support for drive ids.
2009-07-16 14:56 [Qemu-devel] [PATCH v3 0/5] cleanup drive handling Gerd Hoffmann
2009-07-16 14:57 ` [Qemu-devel] [PATCH v3 1/5] kill drives_table Gerd Hoffmann
@ 2009-07-16 14:57 ` Gerd Hoffmann
2009-07-16 14:57 ` [Qemu-devel] [PATCH v3 3/5] kill drives_opt Gerd Hoffmann
` (2 subsequent siblings)
4 siblings, 0 replies; 21+ messages in thread
From: Gerd Hoffmann @ 2009-07-16 14:57 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
-drive accepts the new id= now, allowing to explicitely name your
drives. They will show up with that name in "info block" if specified,
otherwise the existing namimg scheme is used to autogenerate one.
There is also a new function to lookup drives by name. Not used yet.
The plan is to link disk drivers and drives using the drive id instead
of passing around pointers to BlockDriveState.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
sysemu.h | 2 ++
vl.c | 50 ++++++++++++++++++++++++++++++++------------------
2 files changed, 34 insertions(+), 18 deletions(-)
diff --git a/sysemu.h b/sysemu.h
index 36d6aaa..1f7532a 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -160,6 +160,7 @@ typedef enum {
typedef struct DriveInfo {
BlockDriverState *bdrv;
+ char *id;
const char *devaddr;
BlockInterfaceType type;
int bus;
@@ -177,6 +178,7 @@ typedef struct DriveInfo {
extern TAILQ_HEAD(drivelist, DriveInfo) drives;
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(int index);
diff --git a/vl.c b/vl.c
index 4dae7ad..fd19219 100644
--- a/vl.c
+++ b/vl.c
@@ -1919,6 +1919,18 @@ DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit)
return NULL;
}
+DriveInfo *drive_get_by_id(char *id)
+{
+ DriveInfo *dinfo;
+
+ TAILQ_FOREACH(dinfo, &drives, next) {
+ if (strcmp(id, dinfo->id))
+ continue;
+ return dinfo;
+ }
+ return NULL;
+}
+
int drive_get_max_bus(BlockInterfaceType type)
{
int max_bus;
@@ -1988,7 +2000,6 @@ DriveInfo *drive_init(struct drive_opt *arg, int snapshot, void *opaque,
enum { MEDIA_DISK, MEDIA_CDROM } media;
int bus_id, unit_id;
int cyls, heads, secs, translation;
- BlockDriverState *bdrv;
BlockDriver *drv = NULL;
QEMUMachine *machine = opaque;
int max_devs;
@@ -2002,7 +2013,7 @@ DriveInfo *drive_init(struct drive_opt *arg, int snapshot, void *opaque,
"cyls", "heads", "secs", "trans",
"media", "snapshot", "file",
"cache", "format", "serial",
- "werror", "addr",
+ "werror", "addr", "id",
NULL };
*fatal_error = 1;
@@ -2278,17 +2289,20 @@ DriveInfo *drive_init(struct drive_opt *arg, int snapshot, void *opaque,
/* init */
- if (type == IF_IDE || type == IF_SCSI)
- mediastr = (media == MEDIA_CDROM) ? "-cd" : "-hd";
- if (max_devs)
- snprintf(buf, sizeof(buf), "%s%i%s%i",
- devname, bus_id, mediastr, unit_id);
- else
- snprintf(buf, sizeof(buf), "%s%s%i",
- devname, mediastr, unit_id);
- bdrv = bdrv_new(buf);
dinfo = qemu_mallocz(sizeof(*dinfo));
- dinfo->bdrv = bdrv;
+ if (!get_param_value(buf, sizeof(buf), "id", str)) {
+ /* no id supplied -> create one */
+ if (type == IF_IDE || type == IF_SCSI)
+ mediastr = (media == MEDIA_CDROM) ? "-cd" : "-hd";
+ if (max_devs)
+ snprintf(buf, sizeof(buf), "%s%i%s%i",
+ devname, bus_id, mediastr, unit_id);
+ else
+ snprintf(buf, sizeof(buf), "%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;
@@ -2305,12 +2319,12 @@ DriveInfo *drive_init(struct drive_opt *arg, int snapshot, void *opaque,
switch(media) {
case MEDIA_DISK:
if (cyls != 0) {
- bdrv_set_geometry_hint(bdrv, cyls, heads, secs);
- bdrv_set_translation_hint(bdrv, translation);
+ bdrv_set_geometry_hint(dinfo->bdrv, cyls, heads, secs);
+ bdrv_set_translation_hint(dinfo->bdrv, translation);
}
break;
case MEDIA_CDROM:
- bdrv_set_type_hint(bdrv, BDRV_TYPE_CDROM);
+ bdrv_set_type_hint(dinfo->bdrv, BDRV_TYPE_CDROM);
break;
}
break;
@@ -2318,7 +2332,7 @@ DriveInfo *drive_init(struct drive_opt *arg, int snapshot, void *opaque,
/* FIXME: This isn't really a floppy, but it's a reasonable
approximation. */
case IF_FLOPPY:
- bdrv_set_type_hint(bdrv, BDRV_TYPE_FLOPPY);
+ bdrv_set_type_hint(dinfo->bdrv, BDRV_TYPE_FLOPPY);
break;
case IF_PFLASH:
case IF_MTD:
@@ -2340,12 +2354,12 @@ DriveInfo *drive_init(struct drive_opt *arg, int snapshot, void *opaque,
bdrv_flags |= BDRV_O_NOCACHE;
else if (cache == 2) /* write-back */
bdrv_flags |= BDRV_O_CACHE_WB;
- if (bdrv_open2(bdrv, file, bdrv_flags, drv) < 0) {
+ if (bdrv_open2(dinfo->bdrv, file, bdrv_flags, drv) < 0) {
fprintf(stderr, "qemu: could not open disk image %s\n",
file);
return NULL;
}
- if (bdrv_key_required(bdrv))
+ if (bdrv_key_required(dinfo->bdrv))
autostart = 0;
*fatal_error = 0;
return dinfo;
--
1.6.2.5
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [Qemu-devel] [PATCH v3 3/5] kill drives_opt
2009-07-16 14:56 [Qemu-devel] [PATCH v3 0/5] cleanup drive handling Gerd Hoffmann
2009-07-16 14:57 ` [Qemu-devel] [PATCH v3 1/5] kill drives_table Gerd Hoffmann
2009-07-16 14:57 ` [Qemu-devel] [PATCH v3 2/5] add support for drive ids Gerd Hoffmann
@ 2009-07-16 14:57 ` Gerd Hoffmann
2009-07-16 14:57 ` [Qemu-devel] [PATCH v3 4/5] QemuOpts: framework for storing and parsing options Gerd Hoffmann
2009-07-16 14:57 ` [Qemu-devel] [PATCH v3 5/5] switch -drive to QemuOpts Gerd Hoffmann
4 siblings, 0 replies; 21+ messages in thread
From: Gerd Hoffmann @ 2009-07-16 14:57 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
cleanup pretty simliar to the drives_table removal patch:
- drop the table and make a linked list out of it.
- pass around struct pointers instead of table indices.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/device-hotplug.c | 10 +++---
sysemu.h | 24 +++++++--------
vl.c | 79 +++++++++++++++++---------------------------------
3 files changed, 43 insertions(+), 70 deletions(-)
diff --git a/hw/device-hotplug.c b/hw/device-hotplug.c
index 5257274..8f0dec8 100644
--- a/hw/device-hotplug.c
+++ b/hw/device-hotplug.c
@@ -30,17 +30,17 @@
DriveInfo *add_init_drive(const char *opts)
{
- int drive_opt_idx;
int fatal_error;
DriveInfo *dinfo;
+ DriveOpt *dopt;
- drive_opt_idx = drive_add(NULL, "%s", opts);
- if (!drive_opt_idx)
+ dopt = drive_add(NULL, "%s", opts);
+ if (!dopt)
return NULL;
- dinfo = drive_init(&drives_opt[drive_opt_idx], 0, current_machine, &fatal_error);
+ dinfo = drive_init(dopt, 0, current_machine, &fatal_error);
if (!dinfo) {
- drive_remove(drive_opt_idx);
+ drive_remove(dopt);
return NULL;
}
diff --git a/sysemu.h b/sysemu.h
index 1f7532a..88a233b 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -158,6 +158,12 @@ 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;
@@ -165,7 +171,7 @@ typedef struct DriveInfo {
BlockInterfaceType type;
int bus;
int unit;
- int drive_opt_idx;
+ DriveOpt *opt;
BlockInterfaceErrorAction onerror;
char serial[BLOCK_SERIAL_STRLEN + 1];
TAILQ_ENTRY(DriveInfo) next;
@@ -176,28 +182,20 @@ typedef struct DriveInfo {
#define MAX_DRIVES 32
extern TAILQ_HEAD(drivelist, DriveInfo) drives;
+extern TAILQ_HEAD(driveoptlist, DriveOpt) driveopts;
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(int index);
+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);
-struct drive_opt {
- const char *file;
- char opt[1024];
- int used;
-};
-
-extern struct drive_opt drives_opt[MAX_DRIVES];
-extern int nb_drives_opt;
-
-extern int drive_add(const char *file, const char *fmt, ...);
-extern DriveInfo *drive_init(struct drive_opt *arg, int snapshot, void *machine,
+extern DriveOpt *drive_add(const char *file, const char *fmt, ...);
+extern DriveInfo *drive_init(DriveOpt *arg, int snapshot, void *machine,
int *fatal_error);
/* acpi */
diff --git a/vl.c b/vl.c
index fd19219..0e41a29 100644
--- a/vl.c
+++ b/vl.c
@@ -184,6 +184,7 @@ const char *bios_name = NULL;
/* Note: drives_table[MAX_DRIVES] is a dummy block driver if none available
to store the VM snapshots */
struct drivelist drives = TAILQ_HEAD_INITIALIZER(drives);
+struct driveoptlist driveopts = TAILQ_HEAD_INITIALIZER(driveopts);
enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB;
static DisplayState *display_state;
DisplayType display_type = DT_DEFAULT;
@@ -251,8 +252,6 @@ int alt_grab = 0;
unsigned int nb_prom_envs = 0;
const char *prom_envs[MAX_PROM_ENVS];
#endif
-int nb_drives_opt;
-struct drive_opt drives_opt[MAX_DRIVES];
int nb_numa_nodes;
uint64_t node_mem[MAX_NODES];
@@ -1864,43 +1863,27 @@ static int bt_parse(const char *opt)
#define MTD_ALIAS "if=mtd"
#define SD_ALIAS "index=0,if=sd"
-static int drive_opt_get_free_idx(void)
-{
- int index;
-
- for (index = 0; index < MAX_DRIVES; index++)
- if (!drives_opt[index].used) {
- drives_opt[index].used = 1;
- return index;
- }
-
- return -1;
-}
-
-int drive_add(const char *file, const char *fmt, ...)
+DriveOpt *drive_add(const char *file, const char *fmt, ...)
{
va_list ap;
- int index = drive_opt_get_free_idx();
+ DriveOpt *dopt;
- if (nb_drives_opt >= MAX_DRIVES || index == -1) {
- fprintf(stderr, "qemu: too many drives\n");
- return -1;
- }
+ dopt = qemu_mallocz(sizeof(*dopt));
- drives_opt[index].file = file;
+ dopt->file = file;
va_start(ap, fmt);
- vsnprintf(drives_opt[index].opt,
- sizeof(drives_opt[0].opt), fmt, ap);
+ vsnprintf(dopt->opt,
+ sizeof(dopt->opt), fmt, ap);
va_end(ap);
- nb_drives_opt++;
- return index;
+ TAILQ_INSERT_TAIL(&driveopts, dopt, next);
+ return dopt;
}
-void drive_remove(int index)
+void drive_remove(DriveOpt *dopt)
{
- drives_opt[index].used = 0;
- nb_drives_opt--;
+ TAILQ_REMOVE(&driveopts, dopt, next);
+ qemu_free(dopt);
}
DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit)
@@ -1981,14 +1964,14 @@ void drive_uninit(BlockDriverState *bdrv)
TAILQ_FOREACH(dinfo, &drives, next) {
if (dinfo->bdrv != bdrv)
continue;
- drive_remove(dinfo->drive_opt_idx);
+ drive_remove(dinfo->opt);
TAILQ_REMOVE(&drives, dinfo, next);
qemu_free(dinfo);
break;
}
}
-DriveInfo *drive_init(struct drive_opt *arg, int snapshot, void *opaque,
+DriveInfo *drive_init(DriveOpt *arg, int snapshot, void *opaque,
int *fatal_error)
{
char buf[128];
@@ -2308,7 +2291,7 @@ DriveInfo *drive_init(struct drive_opt *arg, int snapshot, void *opaque,
dinfo->bus = bus_id;
dinfo->unit = unit_id;
dinfo->onerror = onerror;
- dinfo->drive_opt_idx = arg - drives_opt;
+ dinfo->opt = arg;
strncpy(dinfo->serial, serial, sizeof(serial));
TAILQ_INSERT_TAIL(&drives, dinfo, next);
@@ -4782,7 +4765,7 @@ int main(int argc, char **argv, char **envp)
int nb_net_clients;
const char *bt_opts[MAX_BT_CMDLINE];
int nb_bt_opts;
- int hda_index;
+ DriveOpt *dopt, *hda_opt = NULL;
int optind;
const char *r, *optarg;
CharDriverState *monitor_hd = NULL;
@@ -4881,9 +4864,7 @@ int main(int argc, char **argv, char **envp)
nb_net_clients = 0;
nb_bt_opts = 0;
- nb_drives_opt = 0;
nb_numa_nodes = 0;
- hda_index = -1;
nb_nics = 0;
@@ -4898,7 +4879,7 @@ int main(int argc, char **argv, char **envp)
break;
r = argv[optind];
if (r[0] != '-') {
- hda_index = drive_add(argv[optind++], HD_ALIAS, 0);
+ hda_opt = drive_add(argv[optind++], HD_ALIAS, 0);
} else {
const QEMUOption *popt;
@@ -4959,9 +4940,9 @@ int main(int argc, char **argv, char **envp)
break;
case QEMU_OPTION_hda:
if (cyls == 0)
- hda_index = drive_add(optarg, HD_ALIAS, 0);
+ hda_opt = drive_add(optarg, HD_ALIAS, 0);
else
- hda_index = drive_add(optarg, HD_ALIAS
+ hda_opt = drive_add(optarg, HD_ALIAS
",cyls=%d,heads=%d,secs=%d%s",
0, cyls, heads, secs,
translation == BIOS_ATA_TRANSLATION_LBA ?
@@ -5023,9 +5004,9 @@ int main(int argc, char **argv, char **envp)
fprintf(stderr, "qemu: invalid physical CHS format\n");
exit(1);
}
- if (hda_index != -1)
- snprintf(drives_opt[hda_index].opt,
- sizeof(drives_opt[hda_index].opt),
+ 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 ?
@@ -5727,25 +5708,19 @@ int main(int argc, char **argv, char **envp)
bdrv_init();
/* we always create the cdrom drive, even if no disk is there */
-
- if (nb_drives_opt < MAX_DRIVES)
- drive_add(NULL, CDROM_ALIAS);
+ drive_add(NULL, CDROM_ALIAS);
/* we always create at least one floppy */
-
- if (nb_drives_opt < MAX_DRIVES)
- drive_add(NULL, FD_ALIAS, 0);
+ drive_add(NULL, FD_ALIAS, 0);
/* we always create one sd slot, even if no card is in it */
-
- if (nb_drives_opt < MAX_DRIVES)
- drive_add(NULL, SD_ALIAS);
+ drive_add(NULL, SD_ALIAS);
/* open the virtual block devices */
- for(i = 0; i < nb_drives_opt; i++) {
+ TAILQ_FOREACH(dopt, &driveopts, next) {
int fatal_error;
- if (drive_init(&drives_opt[i], snapshot, machine, &fatal_error) == NULL)
+ if (drive_init(dopt, snapshot, machine, &fatal_error) == NULL)
if (fatal_error)
exit(1);
}
--
1.6.2.5
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [Qemu-devel] [PATCH v3 4/5] QemuOpts: framework for storing and parsing options.
2009-07-16 14:56 [Qemu-devel] [PATCH v3 0/5] cleanup drive handling Gerd Hoffmann
` (2 preceding siblings ...)
2009-07-16 14:57 ` [Qemu-devel] [PATCH v3 3/5] kill drives_opt Gerd Hoffmann
@ 2009-07-16 14:57 ` Gerd Hoffmann
2009-07-16 16:35 ` [Qemu-devel] " Jan Kiszka
2009-07-17 7:03 ` [Qemu-devel] " Kevin Wolf
2009-07-16 14:57 ` [Qemu-devel] [PATCH v3 5/5] switch -drive to QemuOpts Gerd Hoffmann
4 siblings, 2 replies; 21+ messages in thread
From: Gerd Hoffmann @ 2009-07-16 14:57 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
This stores device parameters in a better way than unparsed strings.
New types:
QemuOpt - one key-value pair.
QemuOpts - group of key-value pairs, belonging to one
device, i.e. one drive.
QemuOptsList - list of some kind of devices, i.e. all drives.
Functions are provided to work with these types. The plan is that some
day we will pass around QemuOpts pointers instead of strings filled with
"key1=value1,key2=value2".
Check out the next patch to see all this in action ;)
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
Makefile.target | 2 +-
qemu-opts.c | 242 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
qemu-opts.h | 36 ++++++++
3 files changed, 279 insertions(+), 1 deletions(-)
create mode 100644 qemu-opts.c
create mode 100644 qemu-opts.h
diff --git a/Makefile.target b/Makefile.target
index 1a71f3a..61e9588 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -490,7 +490,7 @@ endif #CONFIG_BSD_USER
ifndef CONFIG_USER_ONLY
obj-y = vl.o osdep.o monitor.o pci.o loader.o isa_mmio.o machine.o \
- gdbstub.o gdbstub-xml.o msix.o ioport.o
+ gdbstub.o gdbstub-xml.o msix.o ioport.o qemu-opts.o
# virtio has to be here due to weird dependency between PCI and virtio-net.
# need to fix this properly
obj-y += virtio-blk.o virtio-balloon.o virtio-net.o virtio-console.o
diff --git a/qemu-opts.c b/qemu-opts.c
new file mode 100644
index 0000000..31b87dd
--- /dev/null
+++ b/qemu-opts.c
@@ -0,0 +1,242 @@
+#include "sysemu.h"
+#include "qemu-option.h"
+#include "qemu-opts.h"
+
+struct QemuOpt {
+ const char *name;
+ const char *value;
+ QemuOpts *opts;
+ TAILQ_ENTRY(QemuOpt) next;
+};
+
+struct QemuOpts {
+ const char *id;
+ QemuOptsList *list;
+ TAILQ_HEAD(, QemuOpt) head;
+ TAILQ_ENTRY(QemuOpts) next;
+};
+
+static QemuOpt *qemu_opt_find(QemuOpts *opts, const char *name)
+{
+ QemuOpt *opt;
+
+ TAILQ_FOREACH(opt, &opts->head, next) {
+ if (strcmp(opt->name, name) != 0)
+ continue;
+ return opt;
+ }
+ return NULL;
+}
+
+const char *qemu_opt_get(QemuOpts *opts, const char *name)
+{
+ QemuOpt *opt = qemu_opt_find(opts, name);
+ return opt ? opt->value : NULL;
+}
+
+int qemu_opt_set(QemuOpts *opts, const char *name, const char *value)
+{
+ QemuOpt *opt;
+ int i;
+
+ opt = qemu_opt_find(opts, name);
+ if (!opt) {
+ for (i = 0; opts->list->valid[i] != NULL; i++) {
+ if (strcmp(opts->list->valid[i], name) == 0) {
+ break;
+ }
+ }
+ if (opts->list->valid[i] == NULL) {
+ if (i == 0) {
+ /* empty list -> allow any */;
+ } else {
+ fprintf(stderr, "option \"%s\" is not valid for %s\n",
+ name, opts->list->name);
+ return -1;
+ }
+ }
+ opt = qemu_mallocz(sizeof(*opt));
+ opt->name = qemu_strdup(name);
+ opt->opts = opts;
+ TAILQ_INSERT_TAIL(&opts->head, opt, next);
+ }
+ qemu_free((/* !const */ char*)opt->value);
+ opt->value = NULL;
+ if (value) {
+ opt->value = qemu_strdup(value);
+ }
+ return 0;
+}
+
+static void qemu_opt_del(QemuOpt *opt)
+{
+ TAILQ_REMOVE(&opt->opts->head, opt, next);
+ qemu_free((/* !const */ char*)opt->name);
+ qemu_free((/* !const */ char*)opt->value);
+ qemu_free(opt);
+}
+
+QemuOpts *qemu_opts_find(QemuOptsList *list, const char *id)
+{
+ QemuOpts *opts;
+
+ TAILQ_FOREACH(opts, &list->head, next) {
+ if (!opts->id) {
+ continue;
+ }
+ if (strcmp(opts->id, id) != 0) {
+ continue;
+ }
+ return opts;
+ }
+ return NULL;
+}
+
+QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id, int fail_if_exists)
+{
+ QemuOpts *opts = NULL;
+
+ if (id) {
+ opts = qemu_opts_find(list, id);
+ if (opts != NULL) {
+ if (fail_if_exists) {
+ fprintf(stderr, "tried to create id \"%s\" twice for \"%s\"\n",
+ id, list->name);
+ return NULL;
+ } else {
+ return opts;
+ }
+ }
+ }
+ opts = qemu_mallocz(sizeof(*opts));
+ if (id) {
+ opts->id = qemu_strdup(id);
+ }
+ opts->list = list;
+ TAILQ_INIT(&opts->head);
+ TAILQ_INSERT_TAIL(&list->head, opts, next);
+ return opts;
+}
+
+int qemu_opts_set(QemuOptsList *list, const char *id,
+ const char *name, const char *value)
+{
+ QemuOpts *opts;
+
+ opts = qemu_opts_create(list, id, 1);
+ if (opts == NULL) {
+ fprintf(stderr, "id \"%s\" not found for \"%s\"\n",
+ id, list->name);
+ return -1;
+ }
+ return qemu_opt_set(opts, name, value);
+}
+
+void qemu_opts_del(QemuOpts *opts)
+{
+ QemuOpt *opt;
+
+ for (;;) {
+ opt = TAILQ_FIRST(&opts->head);
+ if (opt == NULL)
+ break;
+ qemu_opt_del(opt);
+ }
+ TAILQ_REMOVE(&opts->list->head, opts, next);
+ qemu_free(opts);
+}
+
+int qemu_opts_print(QemuOpts *opts, void *dummy)
+{
+ QemuOpt *opt;
+
+ fprintf(stderr, "%s: %s:", opts->list->name,
+ opts->id ? opts->id : "<noid>");
+ TAILQ_FOREACH(opt, &opts->head, next) {
+ fprintf(stderr, " %s=\"%s\"", opt->name, opt->value);
+ }
+ fprintf(stderr, "\n");
+ return 0;
+}
+
+QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params)
+{
+ char option[128], value[128], *id = NULL;
+ QemuOpts *opts;
+ const char *p;
+
+ if (get_param_value(value, sizeof(value), "id", params))
+ id = qemu_strdup(value);
+ opts = qemu_opts_create(list, id, 1);
+ if (opts == NULL)
+ return NULL;
+
+ p = params;
+ for(;;) {
+ p = get_opt_name(option, sizeof(option), p, '=');
+ if (*p != '=') {
+ break;
+ }
+ p++;
+ p = get_opt_value(value, sizeof(value), p);
+ if (strcmp(option, "id") != 0) {
+ if (-1 == qemu_opt_set(opts, option, value)) {
+ qemu_opts_del(opts);
+ return NULL;
+ }
+ }
+ if (*p != ',') {
+ break;
+ }
+ p++;
+ }
+ return opts;
+}
+
+int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func, void *opaque,
+ int abort_on_failure)
+{
+ QemuOpts *opts;
+ int rc = 0;
+
+ TAILQ_FOREACH(opts, &list->head, next) {
+ rc = func(opts, opaque);
+ if (abort_on_failure && rc != 0)
+ break;
+ }
+ return rc;
+}
+
+#if 0 /* for testing only */
+
+static QemuOptsList drivetest = {
+ .name = "drivetest",
+ .head = TAILQ_HEAD_INITIALIZER(drivetest.head),
+ .valid = { "bus", "unit", "if", "index",
+ "cyls", "heads", "secs", "trans",
+ "media", "snapshot", "file",
+ "cache", "format", "serial",
+ "werror", "addr",
+ NULL },
+};
+
+void qemu_opts_drivetest_add(const char *file, const char *params)
+{
+ QemuOpts *opts;
+
+ opts = qemu_opts_parse(&drivetest, params);
+ if (!opts) {
+ fprintf(stderr, "%s: huh? duplicate? (%s)\n",
+ __FUNCTION__, params);
+ return;
+ }
+ if (file)
+ qemu_opt_set(opts, "file", file);
+}
+
+void qemu_opts_drivetest_print(void)
+{
+ qemu_opts_foreach(&drivetest, qemu_opts_print, NULL, 0);
+}
+
+#endif
diff --git a/qemu-opts.h b/qemu-opts.h
new file mode 100644
index 0000000..85a3390
--- /dev/null
+++ b/qemu-opts.h
@@ -0,0 +1,36 @@
+#ifndef QEMU_OPTS_H
+#define QEMU_OPTS_H
+
+#include "sys-queue.h"
+
+typedef struct QemuOpt QemuOpt;
+typedef struct QemuOpts QemuOpts;
+typedef struct QemuOptsList QemuOptsList;
+
+struct QemuOptsList {
+ const char *name;
+ TAILQ_HEAD(, QemuOpts) head;
+ const char *valid[];
+};
+
+const char *qemu_opt_get(QemuOpts *opts, const char *name);
+int qemu_opt_set(QemuOpts *opts, const char *name, const char *value);
+
+QemuOpts *qemu_opts_find(QemuOptsList *list, const char *id);
+QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id, int fail_if_exists);
+int qemu_opts_set(QemuOptsList *list, const char *id,
+ const char *name, const char *value);
+void qemu_opts_del(QemuOpts *opts);
+QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params);
+
+typedef int (*qemu_opts_loopfunc)(QemuOpts *opts, void *opaque);
+int qemu_opts_print(QemuOpts *opts, void *dummy);
+int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func, void *opaque,
+ int abort_on_failure);
+
+#if 0 /* for testing only */
+void qemu_opts_drivetest_add(const char *file, const char *params);
+void qemu_opts_drivetest_print(void);
+#endif
+
+#endif /* QEMU_OPTS_H */
--
1.6.2.5
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [Qemu-devel] [PATCH v3 5/5] switch -drive to QemuOpts.
2009-07-16 14:56 [Qemu-devel] [PATCH v3 0/5] cleanup drive handling Gerd Hoffmann
` (3 preceding siblings ...)
2009-07-16 14:57 ` [Qemu-devel] [PATCH v3 4/5] QemuOpts: framework for storing and parsing options Gerd Hoffmann
@ 2009-07-16 14:57 ` Gerd Hoffmann
2009-07-16 16:07 ` Anthony Liguori
4 siblings, 1 reply; 21+ messages in thread
From: Gerd Hoffmann @ 2009-07-16 14:57 UTC (permalink / raw)
To: qemu-devel; +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 <kraxel@redhat.com>
---
hw/device-hotplug.c | 12 ++--
sysemu.h | 15 +---
vl.c | 215 +++++++++++++++++++++++++++------------------------
3 files changed, 125 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 88a233b..124cf1b 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
@@ -158,12 +159,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;
@@ -171,7 +166,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;
@@ -188,15 +183,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 0e41a29..dfdea55 100644
--- a/vl.c
+++ b/vl.c
@@ -1863,27 +1863,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)
@@ -1964,20 +1973,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;
@@ -1991,22 +2000,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;
@@ -2027,23 +2024,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;
@@ -2070,51 +2067,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"))
@@ -2124,39 +2121,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"))
@@ -2169,7 +2166,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);
@@ -2183,16 +2180,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;
@@ -2211,13 +2203,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 */
@@ -2225,7 +2215,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)
@@ -2256,8 +2246,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;
}
@@ -2273,26 +2263,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) {
@@ -2324,7 +2317,7 @@ DriveInfo *drive_init(DriveOpt *arg, int snapshot, void *opaque,
case IF_COUNT:
abort();
}
- if (!file[0]) {
+ if (!file) {
*fatal_error = 0;
return NULL;
}
@@ -2348,6 +2341,27 @@ 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;
+
+ qemu_opts_print(opts, NULL);
+ 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", "1");
+ }
+ return 0;
+}
+
static void numa_add(const char *optarg)
{
char option[128];
@@ -4765,7 +4779,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;
@@ -4879,7 +4893,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;
@@ -4940,9 +4954,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 ?
@@ -5004,15 +5018,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:
@@ -5717,13 +5735,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
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] [PATCH v3 5/5] switch -drive to QemuOpts.
2009-07-16 14:57 ` [Qemu-devel] [PATCH v3 5/5] switch -drive to QemuOpts Gerd Hoffmann
@ 2009-07-16 16:07 ` Anthony Liguori
2009-07-16 18:55 ` Gerd Hoffmann
0 siblings, 1 reply; 21+ messages in thread
From: Anthony Liguori @ 2009-07-16 16:07 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: qemu-devel
Gerd Hoffmann wrote:
> 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 <kraxel@redhat.com>
>
$ x86_64-softmmu/qemu-system-x86_64 -hda ~/images/linux.img -snapshot
drive: <noid>: index="0" media="disk"
file="/home/anthony/images/linux.img" snapshot="1"
qemu: '1' invalid snapshot option
Not quite sure that's the action you were looking for...
Regards,
Anthony Liguori
> ---
> hw/device-hotplug.c | 12 ++--
> sysemu.h | 15 +---
> vl.c | 215 +++++++++++++++++++++++++++------------------------
> 3 files changed, 125 insertions(+), 117 deletions(-)
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* [Qemu-devel] Re: [PATCH v3 4/5] QemuOpts: framework for storing and parsing options.
2009-07-16 14:57 ` [Qemu-devel] [PATCH v3 4/5] QemuOpts: framework for storing and parsing options Gerd Hoffmann
@ 2009-07-16 16:35 ` Jan Kiszka
2009-07-16 18:50 ` Gerd Hoffmann
2009-07-17 7:03 ` [Qemu-devel] " Kevin Wolf
1 sibling, 1 reply; 21+ messages in thread
From: Jan Kiszka @ 2009-07-16 16:35 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: qemu-devel
Gerd Hoffmann wrote:
> This stores device parameters in a better way than unparsed strings.
>
> New types:
> QemuOpt - one key-value pair.
> QemuOpts - group of key-value pairs, belonging to one
> device, i.e. one drive.
> QemuOptsList - list of some kind of devices, i.e. all drives.
>
> Functions are provided to work with these types. The plan is that some
> day we will pass around QemuOpts pointers instead of strings filled with
> "key1=value1,key2=value2".
Will this also be able to handle the "-net <type>[,options=...]" special
case? Then it would be really great and could save us a lot of ugly code.
Jan
--
Siemens AG, Corporate Technology, CT SE 2
Corporate Competence Center Embedded Linux
^ permalink raw reply [flat|nested] 21+ messages in thread
* [Qemu-devel] Re: [PATCH v3 4/5] QemuOpts: framework for storing and parsing options.
2009-07-16 16:35 ` [Qemu-devel] " Jan Kiszka
@ 2009-07-16 18:50 ` Gerd Hoffmann
0 siblings, 0 replies; 21+ messages in thread
From: Gerd Hoffmann @ 2009-07-16 18:50 UTC (permalink / raw)
To: Jan Kiszka; +Cc: qemu-devel
On 07/16/09 18:35, Jan Kiszka wrote:
> Gerd Hoffmann wrote:
>> This stores device parameters in a better way than unparsed strings.
>>
>> New types:
>> QemuOpt - one key-value pair.
>> QemuOpts - group of key-value pairs, belonging to one
>> device, i.e. one drive.
>> QemuOptsList - list of some kind of devices, i.e. all drives.
>>
>> Functions are provided to work with these types. The plan is that some
>> day we will pass around QemuOpts pointers instead of strings filled with
>> "key1=value1,key2=value2".
>
> Will this also be able to handle the "-net<type>[,options=...]" special
> case? Then it would be really great and could save us a lot of ugly code.
I don't see fundamental problems, I've tried to make it generic enough
that it can fit for everything. If it doesn't we should fix it ;)
I think we could either have a additional 'type' field added to
QemuOpts, or we use a separate QemuOptsList for each net type.
I'd tend to use the separate list approach because the list of valid
options is linked to QemuOptsList, and each net type has a different set
of options.
cheers,
Gerd
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] [PATCH v3 5/5] switch -drive to QemuOpts.
2009-07-16 16:07 ` Anthony Liguori
@ 2009-07-16 18:55 ` Gerd Hoffmann
2009-07-16 19:03 ` Anthony Liguori
0 siblings, 1 reply; 21+ messages in thread
From: Gerd Hoffmann @ 2009-07-16 18:55 UTC (permalink / raw)
To: Anthony Liguori; +Cc: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 665 bytes --]
On 07/16/09 18:07, Anthony Liguori wrote:
> Gerd Hoffmann wrote:
>> 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 <kraxel@redhat.com>
>
> $ x86_64-softmmu/qemu-system-x86_64 -hda ~/images/linux.img -snapshot
> drive: <noid>: index="0" media="disk"
> file="/home/anthony/images/linux.img" snapshot="1"
> qemu: '1' invalid snapshot option
>
> Not quite sure that's the action you were looking for...
Quick fix (incremental) attached.
Oh, and a leftover debug line ...
cheers,
Gerd
[-- Attachment #2: fix --]
[-- Type: text/plain, Size: 714 bytes --]
diff --git a/vl.c b/vl.c
index dfdea55..7d07d69 100644
--- a/vl.c
+++ b/vl.c
@@ -2346,7 +2346,7 @@ static int drive_init_func(QemuOpts *opts, void *opaque)
QEMUMachine *machine = opaque;
int fatal_error = 0;
- qemu_opts_print(opts, NULL);
+// qemu_opts_print(opts, NULL);
if (drive_init(opts, machine, &fatal_error) == NULL) {
if (fatal_error)
return 1;
@@ -2357,7 +2357,7 @@ static int drive_init_func(QemuOpts *opts, void *opaque)
static int drive_enable_snapshot(QemuOpts *opts, void *opaque)
{
if (NULL == qemu_opt_get(opts, "snapshot")) {
- qemu_opt_set(opts, "snapshot", "1");
+ qemu_opt_set(opts, "snapshot", "on");
}
return 0;
}
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] [PATCH v3 5/5] switch -drive to QemuOpts.
2009-07-16 18:55 ` Gerd Hoffmann
@ 2009-07-16 19:03 ` Anthony Liguori
2009-07-16 19:32 ` Gerd Hoffmann
0 siblings, 1 reply; 21+ messages in thread
From: Anthony Liguori @ 2009-07-16 19:03 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: qemu-devel
Gerd Hoffmann wrote:
> Quick fix (incremental) attached.
> Oh, and a leftover debug line ...
Great, wait a day or two and please resend the series.
I've already gotten everything in staging for the 0.11 freeze. I'm
looking at pushing a tag later today after testing finishes.
One thing that bothers me is that there is a really high rate of change
in the qdev stuff. These series touch a lot of code and therefore cause
quite a lot of conflicts. That concerns me that the long term
maintenance of stable-0.11 is going to be really painful.
So I'm thinking of making an exception for some of the more intrusive
qdev changes and to continue pulling some of them in post freeze. It
would have to be handled on a case by case basis but I'm specifically
thinking of things like the Property refactoring you just did.
What do you think?
> cheers,
> Gerd
>
Regards,
Anthony Liguori
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] [PATCH v3 5/5] switch -drive to QemuOpts.
2009-07-16 19:03 ` Anthony Liguori
@ 2009-07-16 19:32 ` Gerd Hoffmann
2009-07-16 20:08 ` Anthony Liguori
0 siblings, 1 reply; 21+ messages in thread
From: Gerd Hoffmann @ 2009-07-16 19:32 UTC (permalink / raw)
To: Anthony Liguori; +Cc: qemu-devel
On 07/16/09 21:03, Anthony Liguori wrote:
> Gerd Hoffmann wrote:
>> Quick fix (incremental) attached.
>> Oh, and a leftover debug line ...
>
> Great, wait a day or two and please resend the series.
I'll be offline tomorrow, weekend and monday next week, so I can have a
closer look tuesday (merge bugfix, rebase, fixup whatever shows up).
> One thing that bothers me is that there is a really high rate of change
> in the qdev stuff. These series touch a lot of code and therefore cause
> quite a lot of conflicts. That concerns me that the long term
> maintenance of stable-0.11 is going to be really painful.
The by far worst offender is the property refactoring, and that one has
seen no fundamental changes since quite a while. Lots of little tweaks
though, mostly due to conflicts and due to devices being converted to
udev introducing build failures.
btw: blueswirl converted more sparc stuff to qdev, thus adding more
build failures with the property rework patch applied.
http://git.et.redhat.com/?p=qemu-kraxel.git;a=shortlog;h=refs/heads/qdev.v13
has fixes (four topmost patches), you might want to cherry pick them if
you find your tree not building.
All other patches are not *that* intrusive.
> So I'm thinking of making an exception for some of the more intrusive
> qdev changes and to continue pulling some of them in post freeze. It
> would have to be handled on a case by case basis but I'm specifically
> thinking of things like the Property refactoring you just did.
I see the property refactoring in your queue already.
And, yes, having that in 0.11 will most likely simplify backports alot.
cheers,
Gerd
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] [PATCH v3 5/5] switch -drive to QemuOpts.
2009-07-16 19:32 ` Gerd Hoffmann
@ 2009-07-16 20:08 ` Anthony Liguori
0 siblings, 0 replies; 21+ messages in thread
From: Anthony Liguori @ 2009-07-16 20:08 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: qemu-devel
Gerd Hoffmann wrote:
>
>> One thing that bothers me is that there is a really high rate of change
>> in the qdev stuff. These series touch a lot of code and therefore cause
>> quite a lot of conflicts. That concerns me that the long term
>> maintenance of stable-0.11 is going to be really painful.
>
> The by far worst offender is the property refactoring, and that one
> has seen no fundamental changes since quite a while. Lots of little
> tweaks though, mostly due to conflicts and due to devices being
> converted to udev introducing build failures.
>
> btw: blueswirl converted more sparc stuff to qdev, thus adding more
> build failures with the property rework patch applied.
> http://git.et.redhat.com/?p=qemu-kraxel.git;a=shortlog;h=refs/heads/qdev.v13
> has fixes (four topmost patches), you might want to cherry pick them
> if you find your tree not building.
There's more too.. I've got it all straightened out in staging.
Regards,
Anthony Liguori
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] [PATCH v3 4/5] QemuOpts: framework for storing and parsing options.
2009-07-16 14:57 ` [Qemu-devel] [PATCH v3 4/5] QemuOpts: framework for storing and parsing options Gerd Hoffmann
2009-07-16 16:35 ` [Qemu-devel] " Jan Kiszka
@ 2009-07-17 7:03 ` Kevin Wolf
2009-07-21 7:25 ` Gerd Hoffmann
2009-07-21 13:59 ` Gerd Hoffmann
1 sibling, 2 replies; 21+ messages in thread
From: Kevin Wolf @ 2009-07-17 7:03 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: qemu-devel
Gerd Hoffmann schrieb:
> This stores device parameters in a better way than unparsed strings.
>
> New types:
> QemuOpt - one key-value pair.
> QemuOpts - group of key-value pairs, belonging to one
> device, i.e. one drive.
> QemuOptsList - list of some kind of devices, i.e. all drives.
What about having the options typed like I did in qemu-option.[ch]?
In general qemu-option seems to do more parsing/checking than QemuOpts
does, on the other hand it's not yet generic enough to suit everything.
Maybe a combination of both would be the right thing?
Kevin
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] [PATCH v3 4/5] QemuOpts: framework for storing and parsing options.
2009-07-17 7:03 ` [Qemu-devel] " Kevin Wolf
@ 2009-07-21 7:25 ` Gerd Hoffmann
2009-07-21 7:42 ` Kevin Wolf
2009-07-21 13:59 ` Gerd Hoffmann
1 sibling, 1 reply; 21+ messages in thread
From: Gerd Hoffmann @ 2009-07-21 7:25 UTC (permalink / raw)
To: Kevin Wolf; +Cc: qemu-devel
On 07/17/09 09:03, Kevin Wolf wrote:
> Gerd Hoffmann schrieb:
>> This stores device parameters in a better way than unparsed strings.
>>
>> New types:
>> QemuOpt - one key-value pair.
>> QemuOpts - group of key-value pairs, belonging to one
>> device, i.e. one drive.
>> QemuOptsList - list of some kind of devices, i.e. all drives.
>
> What about having the options typed like I did in qemu-option.[ch]?
Oh, I didn't see that. I just looked at the (old) parsing code in vl.c
uses by almost everybody.
> In general qemu-option seems to do more parsing/checking than QemuOpts
> does, on the other hand it's not yet generic enough to suit everything.
> Maybe a combination of both would be the right thing?
I'll have a closer look. Who uses qemu-options? qemu-io I assume?
cheers,
Gerd
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] [PATCH v3 4/5] QemuOpts: framework for storing and parsing options.
2009-07-21 7:25 ` Gerd Hoffmann
@ 2009-07-21 7:42 ` Kevin Wolf
0 siblings, 0 replies; 21+ messages in thread
From: Kevin Wolf @ 2009-07-21 7:42 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: qemu-devel
Gerd Hoffmann schrieb:
> On 07/17/09 09:03, Kevin Wolf wrote:
>> Gerd Hoffmann schrieb:
>>> This stores device parameters in a better way than unparsed strings.
>>>
>>> New types:
>>> QemuOpt - one key-value pair.
>>> QemuOpts - group of key-value pairs, belonging to one
>>> device, i.e. one drive.
>>> QemuOptsList - list of some kind of devices, i.e. all drives.
>> What about having the options typed like I did in qemu-option.[ch]?
>
> Oh, I didn't see that. I just looked at the (old) parsing code in vl.c
> uses by almost everybody.
Actually, some parts of this parsing code have moved to qemu-option.c.
Probably they should all be moved (or replaced), but I did it only for
the functions I needed in qemu-img.
>> In general qemu-option seems to do more parsing/checking than QemuOpts
>> does, on the other hand it's not yet generic enough to suit everything.
>> Maybe a combination of both would be the right thing?
>
> I'll have a closer look. Who uses qemu-options? qemu-io I assume?
It's currently only used for image creation. Since recently, image
formats can provide driver specific options. You can find the call to
the parser in qemu-img.c in img_create() and img_check(). The definition
of the supported options are usually at the end of the block driver
source file.
Kevin
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] [PATCH v3 4/5] QemuOpts: framework for storing and parsing options.
2009-07-17 7:03 ` [Qemu-devel] " Kevin Wolf
2009-07-21 7:25 ` Gerd Hoffmann
@ 2009-07-21 13:59 ` Gerd Hoffmann
2009-07-21 15:58 ` Kevin Wolf
1 sibling, 1 reply; 21+ messages in thread
From: Gerd Hoffmann @ 2009-07-21 13:59 UTC (permalink / raw)
To: Kevin Wolf; +Cc: qemu-devel
On 07/17/09 09:03, Kevin Wolf wrote:
> Gerd Hoffmann schrieb:
>> This stores device parameters in a better way than unparsed strings.
>>
>> New types:
>> QemuOpt - one key-value pair.
>> QemuOpts - group of key-value pairs, belonging to one
>> device, i.e. one drive.
>> QemuOptsList - list of some kind of devices, i.e. all drives.
>
> What about having the options typed like I did in qemu-option.[ch]?
>
> In general qemu-option seems to do more parsing/checking than QemuOpts
> does, on the other hand it's not yet generic enough to suit everything.
Yup, qemu-options has all in one struct, which fails on multiple
instaces (i.e. two drives).
> Maybe a combination of both would be the right thing?
I think the question is here how and when we want to do the parsing.
We could do it early, when parsing/storing the values. QemuOptsList
could get a QEMUOptionParameter-like struct instead of the simple
valid[] array. QemuOpts->value would become a union. qemu_opt_set
handles parsing and stores in the union. qemu_opt_get() would move to
qemu_opt_get_$type() and it would return the value from the matching
union member.
We could do it late, when using the values. Parsing would happen
directly in qemu_opt_get_$type().
comments?
cheers,
Gerd
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] [PATCH v3 4/5] QemuOpts: framework for storing and parsing options.
2009-07-21 13:59 ` Gerd Hoffmann
@ 2009-07-21 15:58 ` Kevin Wolf
2009-07-22 6:58 ` Gerd Hoffmann
0 siblings, 1 reply; 21+ messages in thread
From: Kevin Wolf @ 2009-07-21 15:58 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: qemu-devel
Gerd Hoffmann schrieb:
> On 07/17/09 09:03, Kevin Wolf wrote:
>> Gerd Hoffmann schrieb:
>>> This stores device parameters in a better way than unparsed strings.
>>>
>>> New types:
>>> QemuOpt - one key-value pair.
>>> QemuOpts - group of key-value pairs, belonging to one
>>> device, i.e. one drive.
>>> QemuOptsList - list of some kind of devices, i.e. all drives.
>> What about having the options typed like I did in qemu-option.[ch]?
>>
>> In general qemu-option seems to do more parsing/checking than QemuOpts
>> does, on the other hand it's not yet generic enough to suit everything.
>
> Yup, qemu-options has all in one struct, which fails on multiple
> instaces (i.e. two drives).
Right, this is one of the points I thought of. Another one is that there
are some variants in use with a required first parameter that doesn't
have a name (like nic in -net nic,model=xyz). I guess, there are some
more details that are not completely covered.
>> Maybe a combination of both would be the right thing?
>
> I think the question is here how and when we want to do the parsing.
>
> We could do it early, when parsing/storing the values. QemuOptsList
> could get a QEMUOptionParameter-like struct instead of the simple
> valid[] array. QemuOpts->value would become a union. qemu_opt_set
> handles parsing and stores in the union. qemu_opt_get() would move to
> qemu_opt_get_$type() and it would return the value from the matching
> union member.
>
> We could do it late, when using the values. Parsing would happen
> directly in qemu_opt_get_$type().
I would prefer doing it in a central place, so that you don't depend on
the user to actually trigger checks. But probably both would work.
Kevin
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] [PATCH v3 4/5] QemuOpts: framework for storing and parsing options.
2009-07-21 15:58 ` Kevin Wolf
@ 2009-07-22 6:58 ` Gerd Hoffmann
2009-07-22 7:31 ` Kevin Wolf
0 siblings, 1 reply; 21+ messages in thread
From: Gerd Hoffmann @ 2009-07-22 6:58 UTC (permalink / raw)
To: Kevin Wolf; +Cc: qemu-devel
On 07/21/09 17:58, Kevin Wolf wrote:
> Gerd Hoffmann schrieb:
>> On 07/17/09 09:03, Kevin Wolf wrote:
>>> Gerd Hoffmann schrieb:
>>>> This stores device parameters in a better way than unparsed strings.
>>>>
>>>> New types:
>>>> QemuOpt - one key-value pair.
>>>> QemuOpts - group of key-value pairs, belonging to one
>>>> device, i.e. one drive.
>>>> QemuOptsList - list of some kind of devices, i.e. all drives.
>>> What about having the options typed like I did in qemu-option.[ch]?
>>>
>>> In general qemu-option seems to do more parsing/checking than QemuOpts
>>> does, on the other hand it's not yet generic enough to suit everything.
>> Yup, qemu-options has all in one struct, which fails on multiple
>> instaces (i.e. two drives).
>
> Right, this is one of the points I thought of. Another one is that there
> are some variants in use with a required first parameter that doesn't
> have a name (like nic in -net nic,model=xyz). I guess, there are some
> more details that are not completely covered.
-net is a very special beast as the list of parameters is very different
for -net nic, -net tap, -net user, ...
So it probably makes sense to have a separate QemuOptsList for each of
them instead of storing a "type=[nic|tap|user]" into a common net list.
>> We could do it early, when parsing/storing the values. QemuOptsList
>> could get a QEMUOptionParameter-like struct instead of the simple
>> valid[] array. QemuOpts->value would become a union. qemu_opt_set
>> handles parsing and stores in the union. qemu_opt_get() would move to
>> qemu_opt_get_$type() and it would return the value from the matching
>> union member.
>>
>> We could do it late, when using the values. Parsing would happen
>> directly in qemu_opt_get_$type().
>
> I would prefer doing it in a central place, so that you don't depend on
> the user to actually trigger checks. But probably both would work.
Yep, so we have one place where we catch parse errors instead of having
each callsite to check for qemu_opt_get_$type() failures.
cheers,
Gerd
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] [PATCH v3 4/5] QemuOpts: framework for storing and parsing options.
2009-07-22 6:58 ` Gerd Hoffmann
@ 2009-07-22 7:31 ` Kevin Wolf
2009-07-22 7:55 ` Gerd Hoffmann
0 siblings, 1 reply; 21+ messages in thread
From: Kevin Wolf @ 2009-07-22 7:31 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: qemu-devel
Gerd Hoffmann schrieb:
> On 07/21/09 17:58, Kevin Wolf wrote:
>> Right, this is one of the points I thought of. Another one is that there
>> are some variants in use with a required first parameter that doesn't
>> have a name (like nic in -net nic,model=xyz). I guess, there are some
>> more details that are not completely covered.
>
> -net is a very special beast as the list of parameters is very different
> for -net nic, -net tap, -net user, ...
>
> So it probably makes sense to have a separate QemuOptsList for each of
> them instead of storing a "type=[nic|tap|user]" into a common net list.
I agree, -net should be done different, so this was a bad example. But I
thought we had more of them. -boot is an option with implicit first
parameter name, and there was at least a discussion on making -smp
another one. There might be more.
Or do you want to keep the old parsing code for these options?
>>> We could do it early, when parsing/storing the values. QemuOptsList
>>> could get a QEMUOptionParameter-like struct instead of the simple
>>> valid[] array. QemuOpts->value would become a union. qemu_opt_set
>>> handles parsing and stores in the union. qemu_opt_get() would move to
>>> qemu_opt_get_$type() and it would return the value from the matching
>>> union member.
>>>
>>> We could do it late, when using the values. Parsing would happen
>>> directly in qemu_opt_get_$type().
>> I would prefer doing it in a central place, so that you don't depend on
>> the user to actually trigger checks. But probably both would work.
>
> Yep, so we have one place where we catch parse errors instead of having
> each callsite to check for qemu_opt_get_$type() failures.
Sounds great. Now it just needs to be implemented. ;-)
Kevin
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [Qemu-devel] [PATCH v3 4/5] QemuOpts: framework for storing and parsing options.
2009-07-22 7:31 ` Kevin Wolf
@ 2009-07-22 7:55 ` Gerd Hoffmann
0 siblings, 0 replies; 21+ messages in thread
From: Gerd Hoffmann @ 2009-07-22 7:55 UTC (permalink / raw)
To: Kevin Wolf; +Cc: qemu-devel
On 07/22/09 09:31, Kevin Wolf wrote:
> Gerd Hoffmann schrieb:
>> On 07/21/09 17:58, Kevin Wolf wrote:
>>> Right, this is one of the points I thought of. Another one is that there
>>> are some variants in use with a required first parameter that doesn't
>>> have a name (like nic in -net nic,model=xyz). I guess, there are some
>>> more details that are not completely covered.
>> -net is a very special beast as the list of parameters is very different
>> for -net nic, -net tap, -net user, ...
>>
>> So it probably makes sense to have a separate QemuOptsList for each of
>> them instead of storing a "type=[nic|tap|user]" into a common net list.
>
> I agree, -net should be done different, so this was a bad example. But I
> thought we had more of them. -boot is an option with implicit first
> parameter name, and there was at least a discussion on making -smp
> another one. There might be more.
>
> Or do you want to keep the old parsing code for these options?
I want QemuOpts be good enough for everybody. There should be no need
for the old parsing code long-term.
>> Yep, so we have one place where we catch parse errors instead of having
>> each callsite to check for qemu_opt_get_$type() failures.
>
> Sounds great. Now it just needs to be implemented. ;-)
Working on it ;)
cheers,
Gerd
^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2009-07-22 7:55 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-07-16 14:56 [Qemu-devel] [PATCH v3 0/5] cleanup drive handling Gerd Hoffmann
2009-07-16 14:57 ` [Qemu-devel] [PATCH v3 1/5] kill drives_table Gerd Hoffmann
2009-07-16 14:57 ` [Qemu-devel] [PATCH v3 2/5] add support for drive ids Gerd Hoffmann
2009-07-16 14:57 ` [Qemu-devel] [PATCH v3 3/5] kill drives_opt Gerd Hoffmann
2009-07-16 14:57 ` [Qemu-devel] [PATCH v3 4/5] QemuOpts: framework for storing and parsing options Gerd Hoffmann
2009-07-16 16:35 ` [Qemu-devel] " Jan Kiszka
2009-07-16 18:50 ` Gerd Hoffmann
2009-07-17 7:03 ` [Qemu-devel] " Kevin Wolf
2009-07-21 7:25 ` Gerd Hoffmann
2009-07-21 7:42 ` Kevin Wolf
2009-07-21 13:59 ` Gerd Hoffmann
2009-07-21 15:58 ` Kevin Wolf
2009-07-22 6:58 ` Gerd Hoffmann
2009-07-22 7:31 ` Kevin Wolf
2009-07-22 7:55 ` Gerd Hoffmann
2009-07-16 14:57 ` [Qemu-devel] [PATCH v3 5/5] switch -drive to QemuOpts Gerd Hoffmann
2009-07-16 16:07 ` Anthony Liguori
2009-07-16 18:55 ` Gerd Hoffmann
2009-07-16 19:03 ` Anthony Liguori
2009-07-16 19:32 ` Gerd Hoffmann
2009-07-16 20:08 ` 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).