[Problem] Currently, guest OS's messages can be logged to a local disk of host OS by creating chadevs with options below. -chardev file,id=charserial0,path=<log file's path> -device isa-serial,chardev=chardevserial0,id=serial0
When a hardware failure happens in the disk, qemu-kvm can't create the chardevs. In this case, guest OS doesn't boot up. Actually, there are users who don't desire that guest OS goes down due to a hardware failure of a log disk only. Therefore, qemu should offer some way to boot guest OS up even if the log disk is broken. [Solution] This patch skips error checks in case where opening a log file and creating chardev fail. Signed-off-by: Seiji Aguchi <seiji.agu...@hds.com> --- hw/qdev-properties-system.c | 2 +- hw/serial-isa.c | 11 +++++++---- hw/serial-pci.c | 27 ++++++++++++++++----------- hw/serial.c | 33 +++++++++++++++++++-------------- hw/serial.h | 2 +- vl.c | 4 +++- 6 files changed, 47 insertions(+), 32 deletions(-) diff --git a/hw/qdev-properties-system.c b/hw/qdev-properties-system.c index d9934b5..99eff4f 100644 --- a/hw/qdev-properties-system.c +++ b/hw/qdev-properties-system.c @@ -121,7 +121,7 @@ static int parse_chr(DeviceState *dev, const char *str, void **ptr) { CharDriverState *chr = qemu_chr_find(str); if (chr == NULL) { - return -ENOENT; + return 0; } if (chr->avail_connections < 1) { return -EEXIST; diff --git a/hw/serial-isa.c b/hw/serial-isa.c index a630a7d..b6cfa0d 100644 --- a/hw/serial-isa.c +++ b/hw/serial-isa.c @@ -46,6 +46,7 @@ static int serial_isa_initfn(ISADevice *dev) static int index; ISASerialState *isa = DO_UPCAST(ISASerialState, dev, dev); SerialState *s = &isa->state; + int rc; if (isa->index == -1) { isa->index = index; @@ -63,11 +64,13 @@ static int serial_isa_initfn(ISADevice *dev) s->baudbase = 115200; isa_init_irq(dev, &s->irq, isa->isairq); - serial_init_core(s); - qdev_set_legacy_instance_id(&dev->qdev, isa->iobase, 3); + rc = serial_init_core(s); + if (!rc) { + qdev_set_legacy_instance_id(&dev->qdev, isa->iobase, 3); - memory_region_init_io(&s->io, &serial_io_ops, s, "serial", 8); - isa_register_ioport(dev, &s->io, isa->iobase); + memory_region_init_io(&s->io, &serial_io_ops, s, "serial", 8); + isa_register_ioport(dev, &s->io, isa->iobase); + } return 0; } diff --git a/hw/serial-pci.c b/hw/serial-pci.c index 954657b..3e8b2d5 100644 --- a/hw/serial-pci.c +++ b/hw/serial-pci.c @@ -49,15 +49,18 @@ static int serial_pci_init(PCIDevice *dev) { PCISerialState *pci = DO_UPCAST(PCISerialState, dev, dev); SerialState *s = &pci->state; + int rc; s->baudbase = 115200; - serial_init_core(s); + rc = serial_init_core(s); - pci->dev.config[PCI_INTERRUPT_PIN] = 0x01; - s->irq = pci->dev.irq[0]; + if (!rc) { + pci->dev.config[PCI_INTERRUPT_PIN] = 0x01; + s->irq = pci->dev.irq[0]; - memory_region_init_io(&s->io, &serial_io_ops, s, "serial", 8); - pci_register_bar(&pci->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io); + memory_region_init_io(&s->io, &serial_io_ops, s, "serial", 8); + pci_register_bar(&pci->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io); + } return 0; } @@ -80,7 +83,7 @@ static int multi_serial_pci_init(PCIDevice *dev) PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev); PCIMultiSerialState *pci = DO_UPCAST(PCIMultiSerialState, dev, dev); SerialState *s; - int i; + int i, rc; switch (pc->device_id) { case 0x0003: @@ -102,11 +105,13 @@ static int multi_serial_pci_init(PCIDevice *dev) for (i = 0; i < pci->ports; i++) { s = pci->state + i; s->baudbase = 115200; - serial_init_core(s); - s->irq = pci->irqs[i]; - pci->name[i] = g_strdup_printf("uart #%d", i+1); - memory_region_init_io(&s->io, &serial_io_ops, s, pci->name[i], 8); - memory_region_add_subregion(&pci->iobar, 8 * i, &s->io); + rc = serial_init_core(s); + if (!rc) { + s->irq = pci->irqs[i]; + pci->name[i] = g_strdup_printf("uart #%d", i+1); + memory_region_init_io(&s->io, &serial_io_ops, s, pci->name[i], 8); + memory_region_add_subregion(&pci->iobar, 8 * i, &s->io); + } } return 0; } diff --git a/hw/serial.c b/hw/serial.c index 0ccc499..ab8929e 100644 --- a/hw/serial.c +++ b/hw/serial.c @@ -670,11 +670,11 @@ static void serial_reset(void *opaque) qemu_irq_lower(s->irq); } -void serial_init_core(SerialState *s) +int serial_init_core(SerialState *s) { if (!s->chr) { fprintf(stderr, "Can't create serial device, empty char device\n"); - exit(1); + return 1; } s->modem_status_poll = qemu_new_timer_ns(vm_clock, (QEMUTimerCB *) serial_update_msl, s); @@ -684,6 +684,7 @@ void serial_init_core(SerialState *s) qemu_chr_add_handlers(s->chr, serial_can_receive1, serial_receive1, serial_event, s); + return 0; } void serial_exit_core(SerialState *s) @@ -713,19 +714,20 @@ SerialState *serial_init(int base, qemu_irq irq, int baudbase, CharDriverState *chr, MemoryRegion *system_io) { SerialState *s; + int rc; s = g_malloc0(sizeof(SerialState)); s->irq = irq; s->baudbase = baudbase; s->chr = chr; - serial_init_core(s); - - vmstate_register(NULL, base, &vmstate_serial, s); - - memory_region_init_io(&s->io, &serial_io_ops, s, "serial", 8); - memory_region_add_subregion(system_io, base, &s->io); + rc = serial_init_core(s); + if (!rc) { + vmstate_register(NULL, base, &vmstate_serial, s); + memory_region_init_io(&s->io, &serial_io_ops, s, "serial", 8); + memory_region_add_subregion(system_io, base, &s->io); + } return s; } @@ -769,6 +771,7 @@ SerialState *serial_mm_init(MemoryRegion *address_space, CharDriverState *chr, enum device_endian end) { SerialState *s; + int rc; s = g_malloc0(sizeof(SerialState)); @@ -777,13 +780,15 @@ SerialState *serial_mm_init(MemoryRegion *address_space, s->baudbase = baudbase; s->chr = chr; - serial_init_core(s); - vmstate_register(NULL, base, &vmstate_serial, s); + rc = serial_init_core(s); + if (!rc) { + vmstate_register(NULL, base, &vmstate_serial, s); - memory_region_init_io(&s->io, &serial_mm_ops[end], s, - "serial", 8 << it_shift); - memory_region_add_subregion(address_space, base, &s->io); + memory_region_init_io(&s->io, &serial_mm_ops[end], s, + "serial", 8 << it_shift); + memory_region_add_subregion(address_space, base, &s->io); - serial_update_msl(s); + serial_update_msl(s); + } return s; } diff --git a/hw/serial.h b/hw/serial.h index e884499..0ba2332 100644 --- a/hw/serial.h +++ b/hw/serial.h @@ -83,7 +83,7 @@ struct SerialState { extern const VMStateDescription vmstate_serial; extern const MemoryRegionOps serial_io_ops; -void serial_init_core(SerialState *s); +int serial_init_core(SerialState *s); void serial_exit_core(SerialState *s); void serial_set_frequency(SerialState *s, uint32_t frequency); diff --git a/vl.c b/vl.c index 7643f16..62e983e 100644 --- a/vl.c +++ b/vl.c @@ -2348,7 +2348,9 @@ static int chardev_init_func(QemuOpts *opts, void *opaque) if (error_is_set(&local_err)) { fprintf(stderr, "%s\n", error_get_pretty(local_err)); error_free(local_err); - return -1; + if (strcmp("file", qemu_opt_get(opts, "backend"))) { + return -1; + } } return 0; } -- 1.7.1