On 30.05.2018 15:08, Igor Mammedov wrote: > On Thu, 17 May 2018 10:15:17 +0200 > David Hildenbrand <da...@redhat.com> wrote: > >> For multi stage hotplug handlers, we'll have to do some error handling >> in some hotplug functions, so let's use a local error variable (except >> for unplug requests). > I'd split out introducing local error into separate patch > so patch would do a single thing. > >> Also, add code to pass control to the final stage hotplug handler at the >> parent bus. > But I don't agree with generic > "} else if (dev->parent_bus && dev->parent_bus->hotplug_handler) {" > forwarding, it's done by 3/14 for generic case and in case of > special device that needs bus handler called from machine one, > I'd suggest to do forwarding explicitly for that device only > like we do with acpi_dev.
I decided to do it that way because it is generic and results in nicer recovery handling (e.g. in case pc_dimm plug fails, we can simply rollback all (for now MemoryDevice) previous plug operations). IMHO, the resulting code is easier to read. >From this handling it is clear that "if we reach the hotplug handler, and it is not some special device plugged by the machine (CPU, PC_DIMM), pass it on to the actual hotplug handler if any exists" > > >> Signed-off-by: David Hildenbrand <da...@redhat.com> >> --- >> hw/i386/pc.c | 39 +++++++++++++++++++++++++++++++-------- >> 1 file changed, 31 insertions(+), 8 deletions(-) >> >> diff --git a/hw/i386/pc.c b/hw/i386/pc.c >> index d768930d02..510076e156 100644 >> --- a/hw/i386/pc.c >> +++ b/hw/i386/pc.c >> @@ -2007,19 +2007,32 @@ static void pc_cpu_pre_plug(HotplugHandler >> *hotplug_dev, >> static void pc_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev, >> DeviceState *dev, Error **errp) >> { >> + Error *local_err = NULL; >> + >> + /* final stage hotplug handler */ >> if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { >> - pc_cpu_pre_plug(hotplug_dev, dev, errp); >> + pc_cpu_pre_plug(hotplug_dev, dev, &local_err); >> + } else if (dev->parent_bus && dev->parent_bus->hotplug_handler) { >> + hotplug_handler_pre_plug(dev->parent_bus->hotplug_handler, dev, >> + &local_err); >> } >> + error_propagate(errp, local_err); >> } >> >> static void pc_machine_device_plug_cb(HotplugHandler *hotplug_dev, >> DeviceState *dev, Error **errp) >> { >> + Error *local_err = NULL; >> + >> + /* final stage hotplug handler */ >> if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { >> - pc_dimm_plug(hotplug_dev, dev, errp); >> + pc_dimm_plug(hotplug_dev, dev, &local_err); >> } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { >> - pc_cpu_plug(hotplug_dev, dev, errp); >> + pc_cpu_plug(hotplug_dev, dev, &local_err); >> + } else if (dev->parent_bus && dev->parent_bus->hotplug_handler) { >> + hotplug_handler_plug(dev->parent_bus->hotplug_handler, dev, >> &local_err); >> } >> + error_propagate(errp, local_err); >> } >> >> static void pc_machine_device_unplug_request_cb(HotplugHandler *hotplug_dev, >> @@ -2029,7 +2042,10 @@ static void >> pc_machine_device_unplug_request_cb(HotplugHandler *hotplug_dev, >> pc_dimm_unplug_request(hotplug_dev, dev, errp); >> } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { >> pc_cpu_unplug_request_cb(hotplug_dev, dev, errp); >> - } else { >> + } else if (dev->parent_bus && dev->parent_bus->hotplug_handler) { >> + hotplug_handler_unplug_request(dev->parent_bus->hotplug_handler, >> dev, >> + errp); >> + } else if (!dev->parent_bus) { >> error_setg(errp, "acpi: device unplug request for not supported >> device" >> " type: %s", object_get_typename(OBJECT(dev))); >> } >> @@ -2038,14 +2054,21 @@ static void >> pc_machine_device_unplug_request_cb(HotplugHandler *hotplug_dev, >> static void pc_machine_device_unplug_cb(HotplugHandler *hotplug_dev, >> DeviceState *dev, Error **errp) >> { >> + Error *local_err = NULL; >> + >> + /* final stage hotplug handler */ >> if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { >> - pc_dimm_unplug(hotplug_dev, dev, errp); >> + pc_dimm_unplug(hotplug_dev, dev, &local_err); >> } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { >> - pc_cpu_unplug_cb(hotplug_dev, dev, errp); >> - } else { >> - error_setg(errp, "acpi: device unplug for not supported device" >> + pc_cpu_unplug_cb(hotplug_dev, dev, &local_err); >> + } else if (dev->parent_bus && dev->parent_bus->hotplug_handler) { >> + hotplug_handler_unplug(dev->parent_bus->hotplug_handler, dev, >> + &local_err); >> + } else if (!dev->parent_bus) { >> + error_setg(&local_err, "acpi: device unplug for not supported >> device" >> " type: %s", object_get_typename(OBJECT(dev))); >> } >> + error_propagate(errp, local_err); >> } >> >> static HotplugHandler *pc_get_hotpug_handler(MachineState *machine, > -- Thanks, David / dhildenb