[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH] Make guest OS bootable when hardware failure happen
From: |
Seiji Aguchi |
Subject: |
[Qemu-devel] [PATCH] Make guest OS bootable when hardware failure happens in log disk |
Date: |
Thu, 28 Mar 2013 19:43:41 +0000 |
[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 <address@hidden>
---
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
- [Qemu-devel] [PATCH] Make guest OS bootable when hardware failure happens in log disk,
Seiji Aguchi <=