[libvirt] [PATCH] Add support for SUSPEND_DISK event

Peter Krempa pkrempa at redhat.com
Mon Oct 15 09:16:51 UTC 2012


On 10/12/12 21:28, Martin Kletzander wrote:
> This patch adds support for SUSPEND_DISK event; both lifecycle and
> separated.  The support is added for QEMU, machines are changed to
> PMSUSPENDED, but as QEMU sends SHUTDOWN afterwards, the state changes
> to shut-off.  This and much more needs to be done in order for libvirt
> to work with transient devices, wake-ups etc.  This patch is not
> aiming for that functionality.
> ---
>   daemon/remote.c                                    | 25 +++++++++++
>   examples/domain-events/events-c/event-test.c       | 22 +++++++++-
>   examples/domain-events/events-python/event-test.py |  3 +-
>   include/libvirt/libvirt.h.in                       | 29 +++++++++++++
>   python/libvirt-override-virConnect.py              |  9 ++++
>   python/libvirt-override.c                          | 50 ++++++++++++++++++++++
>   src/conf/domain_event.c                            | 32 +++++++++++++-
>   src/conf/domain_event.h                            |  4 ++
>   src/libvirt_private.syms                           |  2 +
>   src/qemu/qemu_monitor.c                            | 10 +++++
>   src/qemu/qemu_monitor.h                            |  3 ++
>   src/qemu/qemu_monitor_json.c                       |  9 ++++
>   src/qemu/qemu_process.c                            | 47 ++++++++++++++++++++
>   src/remote/remote_driver.c                         | 31 ++++++++++++++
>   src/remote/remote_protocol.x                       |  7 ++-
>   src/remote_protocol-structs                        |  4 ++
>   16 files changed, 282 insertions(+), 5 deletions(-)
>


One philosophical question on start:

Shouldn't this event be called PMSsuspendToDisk or something like that 
to stay consistent with the previous S3 event naming?



> diff --git a/python/libvirt-override.c b/python/libvirt-override.c
> index 81099b1..bc73ad0 100644
> --- a/python/libvirt-override.c
> +++ b/python/libvirt-override.c
> @@ -5812,6 +5812,53 @@ libvirt_virConnectDomainEventBalloonChangeCallback(virConnectPtr conn ATTRIBUTE_
>       return ret;
>   }
>
> +static int
> +libvirt_virConnectDomainEventSuspendDiskCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
> +                                               virDomainPtr dom,
> +                                               int reason,
> +                                               void *opaque)

Bad indentation.

> +{
> +    PyObject *pyobj_cbData = (PyObject*)opaque;
> +    PyObject *pyobj_dom;
> +    PyObject *pyobj_ret;
> +    PyObject *pyobj_conn;
> +    PyObject *dictKey;
> +    int ret = -1;
> +
> +    LIBVIRT_ENSURE_THREAD_STATE;
> +    /* Create a python instance of this virDomainPtr */
> +    virDomainRef(dom);
> +
> +    pyobj_dom = libvirt_virDomainPtrWrap(dom);
> +    Py_INCREF(pyobj_cbData);
> +
> +    dictKey = libvirt_constcharPtrWrap("conn");
> +    pyobj_conn = PyDict_GetItem(pyobj_cbData, dictKey);
> +    Py_DECREF(dictKey);
> +
> +    /* Call the Callback Dispatcher */
> +    pyobj_ret = PyObject_CallMethod(pyobj_conn,
> +                                    (char*)"_dispatchDomainEventSuspendDiskCallback",
> +                                    (char*)"OiO",
> +                                    pyobj_dom,
> +                                    reason,
> +                                    pyobj_cbData);
> +
> +    Py_DECREF(pyobj_cbData);
> +    Py_DECREF(pyobj_dom);
> +
> +    if(!pyobj_ret) {
> +        DEBUG("%s - ret:%p\n", __FUNCTION__, pyobj_ret);
> +        PyErr_Print();
> +    } else {
> +        Py_DECREF(pyobj_ret);
> +        ret = 0;
> +    }
> +
> +    LIBVIRT_RELEASE_THREAD_STATE;
> +    return ret;
> +}
> +
>   static PyObject *
>   libvirt_virConnectDomainEventRegisterAny(ATTRIBUTE_UNUSED PyObject * self,
>                                            PyObject * args)
> @@ -5884,6 +5931,9 @@ libvirt_virConnectDomainEventRegisterAny(ATTRIBUTE_UNUSED PyObject * self,
>       case VIR_DOMAIN_EVENT_ID_BALLOON_CHANGE:
>           cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventBalloonChangeCallback);
>           break;
> +    case VIR_DOMAIN_EVENT_ID_SUSPEND_DISK:
> +        cb = VIR_DOMAIN_EVENT_CALLBACK(libvirt_virConnectDomainEventSuspendDiskCallback);
> +        break;
>       }
>
>       if (!cb) {
> diff --git a/src/conf/domain_event.c b/src/conf/domain_event.c
> index 7da4a1e..c7010c8 100644
> --- a/src/conf/domain_event.c
> +++ b/src/conf/domain_event.c
> @@ -1,7 +1,7 @@
>   /*
>    * domain_event.c: domain event queue processing helpers
>    *
> - * Copyright (C) 2010-2011 Red Hat, Inc.
> + * Copyright (C) 2010-2012 Red Hat, Inc.
>    * Copyright (C) 2008 VirtualIron
>    *
>    * This library is free software; you can redistribute it and/or
> @@ -1107,10 +1107,10 @@ virDomainEventPMSuspendNew(int id, const char *name,
>       virDomainEventPtr ev =
>           virDomainEventNewInternal(VIR_DOMAIN_EVENT_ID_PMSUSPEND,
>                                     id, name, uuid);
> -
>       return ev;
>   }
>
> +
>   virDomainEventPtr
>   virDomainEventPMSuspendNewFromObj(virDomainObjPtr obj)
>   {

Remove the whitespace change in this hunk.


> diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
> index 54b3a99..f4dc94f 100644
> --- a/src/qemu/qemu_monitor.h
> +++ b/src/qemu/qemu_monitor.h
> @@ -136,6 +136,8 @@ struct _qemuMonitorCallbacks {
>       int (*domainBalloonChange)(qemuMonitorPtr mon,
>                                  virDomainObjPtr vm,
>                                  unsigned long long actual);
> +    int (*domainSuspendDisk)(qemuMonitorPtr mon,
> +                             virDomainObjPtr vm);
>   };
>
>   char *qemuMonitorEscapeArg(const char *in);
> @@ -213,6 +215,7 @@ int qemuMonitorEmitBlockJob(qemuMonitorPtr mon,
>                               int status);
>   int qemuMonitorEmitBalloonChange(qemuMonitorPtr mon,
>                                    unsigned long long actual);
> +int qemuMonitorEmitSuspendDisk(qemuMonitorPtr mon);
>
>   int qemuMonitorStartCPUs(qemuMonitorPtr mon,
>                            virConnectPtr conn);
> diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
> index bd52ce4..d0fd23a 100644
> --- a/src/qemu/qemu_monitor_json.c
> +++ b/src/qemu/qemu_monitor_json.c
> @@ -70,6 +70,7 @@ static void qemuMonitorJSONHandlePMSuspend(qemuMonitorPtr mon, virJSONValuePtr d
>   static void qemuMonitorJSONHandleBlockJobCompleted(qemuMonitorPtr mon, virJSONValuePtr data);
>   static void qemuMonitorJSONHandleBlockJobCanceled(qemuMonitorPtr mon, virJSONValuePtr data);
>   static void qemuMonitorJSONHandleBalloonChange(qemuMonitorPtr mon, virJSONValuePtr data);
> +static void qemuMonitorJSONHandleSuspendDisk(qemuMonitorPtr mon, virJSONValuePtr data);
>
>   typedef struct {
>       const char *type;
> @@ -91,6 +92,7 @@ static qemuEventHandler eventHandlers[] = {
>       { "SPICE_INITIALIZED", qemuMonitorJSONHandleSPICEInitialize, },
>       { "STOP", qemuMonitorJSONHandleStop, },
>       { "SUSPEND", qemuMonitorJSONHandlePMSuspend, },
> +    { "SUSPEND_DISK", qemuMonitorJSONHandleSuspendDisk, },

Hm, here it's apparent that the SUSPEND event is called PMSuspend where 
the SUSPEND_DISK lacks that. Should we unify this?

>       { "VNC_CONNECTED", qemuMonitorJSONHandleVNCConnect, },
>       { "VNC_DISCONNECTED", qemuMonitorJSONHandleVNCDisconnect, },
>       { "VNC_INITIALIZED", qemuMonitorJSONHandleVNCInitialize, },
> @@ -891,6 +893,13 @@ qemuMonitorJSONHandleBalloonChange(qemuMonitorPtr mon,
>       qemuMonitorEmitBalloonChange(mon, actual);
>   }
>
> +static void
> +qemuMonitorJSONHandleSuspendDisk(qemuMonitorPtr mon,
> +                                 virJSONValuePtr data ATTRIBUTE_UNUSED)
> +{
> +    qemuMonitorEmitSuspendDisk(mon);
> +}
> +
>   int
>   qemuMonitorJSONHumanCommandWithFd(qemuMonitorPtr mon,
>                                     const char *cmd_str,

ACK when the naming issue is resolved somehow (my opinion is to change 
it to be uniform) and with the two issues fixed.

Peter




More information about the libvir-list mailing list