[PATCH v2] ch: Enable callbacks for ch domain events

Praveen K Paladugu posted 1 patch 1 year, 5 months ago
Failed in applying to current master (apply log)
src/ch/ch_conf.h   |  4 +++
src/ch/ch_driver.c | 82 ++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 84 insertions(+), 2 deletions(-)
[PATCH v2] ch: Enable callbacks for ch domain events
Posted by Praveen K Paladugu 1 year, 5 months ago
From: Praveen K Paladugu <prapal@linux.microsoft.com>

Enable callbacks for define, undefine, started, booted, stopped,
destroyed events of ch guests.

Signed-off-by: Praveen K Paladugu <praveenkpaladugu@gmail.com>
---
 src/ch/ch_conf.h   |  4 +++
 src/ch/ch_driver.c | 82 ++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 84 insertions(+), 2 deletions(-)

diff --git a/src/ch/ch_conf.h b/src/ch/ch_conf.h
index a77cad7a2a..97c6c24aa5 100644
--- a/src/ch/ch_conf.h
+++ b/src/ch/ch_conf.h
@@ -24,6 +24,7 @@
 #include "virthread.h"
 #include "ch_capabilities.h"
 #include "virebtables.h"
+#include "object_event.h"
 
 #define CH_DRIVER_NAME "CH"
 #define CH_CMD "cloud-hypervisor"
@@ -75,6 +76,9 @@ struct _virCHDriver
      * then lockless thereafter */
     virCHDriverConfig *config;
 
+    /* Immutable pointer, self-locking APIs */
+    virObjectEventState *domainEventState;
+
     /* pid file FD, ensures two copies of the driver can't use the same root */
     int lockFD;
 
diff --git a/src/ch/ch_driver.c b/src/ch/ch_driver.c
index dab025edc1..d18f266387 100644
--- a/src/ch/ch_driver.c
+++ b/src/ch/ch_driver.c
@@ -28,6 +28,7 @@
 #include "ch_monitor.h"
 #include "ch_process.h"
 #include "domain_cgroup.h"
+#include "domain_event.h"
 #include "datatypes.h"
 #include "driver.h"
 #include "viraccessapicheck.h"
@@ -263,6 +264,7 @@ chDomainCreateWithFlags(virDomainPtr dom, unsigned int flags)
     virCHDriver *driver = dom->conn->privateData;
     virDomainObj *vm;
     virCHDomainObjPrivate *priv;
+    virObjectEvent *event;
     g_autofree char *managed_save_path = NULL;
     int ret = -1;
 
@@ -304,6 +306,14 @@ chDomainCreateWithFlags(virDomainPtr dom, unsigned int flags)
         ret = virCHProcessStart(driver, vm, VIR_DOMAIN_RUNNING_BOOTED);
     }
 
+    if (ret == 0) {
+        event = virDomainEventLifecycleNewFromObj(vm,
+                                                  VIR_DOMAIN_EVENT_STARTED,
+                                                  VIR_DOMAIN_EVENT_STARTED_BOOTED);
+        if (event)
+            virObjectEventStateQueue(driver->domainEventState, event);
+    }
+
  endjob:
     virDomainObjEndJob(vm);
 
@@ -323,8 +333,10 @@ chDomainDefineXMLFlags(virConnectPtr conn, const char *xml, unsigned int flags)
 {
     virCHDriver *driver = conn->privateData;
     g_autoptr(virDomainDef) vmdef = NULL;
+    g_autoptr(virDomainDef) oldDef = NULL;
     virDomainObj *vm = NULL;
     virDomainPtr dom = NULL;
+    virObjectEvent *event = NULL;
     g_autofree char *managed_save_path = NULL;
     unsigned int parse_flags = VIR_DOMAIN_DEF_PARSE_INACTIVE;
 
@@ -345,7 +357,7 @@ chDomainDefineXMLFlags(virConnectPtr conn, const char *xml, unsigned int flags)
 
     if (!(vm = virDomainObjListAdd(driver->domains, &vmdef,
                                    driver->xmlopt,
-                                   0, NULL)))
+                                   0, &oldDef)))
         goto cleanup;
 
     /* cleanup if there's any stale managedsave dir */
@@ -358,11 +370,17 @@ chDomainDefineXMLFlags(virConnectPtr conn, const char *xml, unsigned int flags)
     }
 
     vm->persistent = 1;
-
+    event = virDomainEventLifecycleNewFromObj(vm,
+                                              VIR_DOMAIN_EVENT_DEFINED,
+                                              !oldDef ?
+                                              VIR_DOMAIN_EVENT_DEFINED_ADDED :
+                                              VIR_DOMAIN_EVENT_DEFINED_UPDATED);
     dom = virGetDomain(conn, vm->def->name, vm->def->uuid, vm->def->id);
 
  cleanup:
     virDomainObjEndAPI(&vm);
+    virObjectEventStateQueue(driver->domainEventState, event);
+
     return dom;
 }
 
@@ -378,6 +396,7 @@ chDomainUndefineFlags(virDomainPtr dom,
 {
     virCHDriver *driver = dom->conn->privateData;
     virDomainObj *vm;
+    virObjectEvent *event = NULL;
     int ret = -1;
 
     virCheckFlags(0, -1);
@@ -393,6 +412,9 @@ chDomainUndefineFlags(virDomainPtr dom,
                        "%s", _("Cannot undefine transient domain"));
         goto cleanup;
     }
+    event = virDomainEventLifecycleNewFromObj(vm,
+                                              VIR_DOMAIN_EVENT_UNDEFINED,
+                                              VIR_DOMAIN_EVENT_UNDEFINED_REMOVED);
 
     vm->persistent = 0;
     if (!virDomainObjIsActive(vm)) {
@@ -403,6 +425,8 @@ chDomainUndefineFlags(virDomainPtr dom,
 
  cleanup:
     virDomainObjEndAPI(&vm);
+    virObjectEventStateQueue(driver->domainEventState, event);
+
     return ret;
 }
 
@@ -643,6 +667,7 @@ chDomainDestroyFlags(virDomainPtr dom, unsigned int flags)
 {
     virCHDriver *driver = dom->conn->privateData;
     virDomainObj *vm;
+    virObjectEvent *event = NULL;
     int ret = -1;
 
     virCheckFlags(0, -1);
@@ -662,6 +687,9 @@ chDomainDestroyFlags(virDomainPtr dom, unsigned int flags)
     if (virCHProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_DESTROYED) < 0)
         goto endjob;
 
+    event = virDomainEventLifecycleNewFromObj(vm,
+                                              VIR_DOMAIN_EVENT_STOPPED,
+                                              VIR_DOMAIN_EVENT_STOPPED_DESTROYED);
     virCHDomainRemoveInactive(driver, vm);
     ret = 0;
 
@@ -670,6 +698,8 @@ chDomainDestroyFlags(virDomainPtr dom, unsigned int flags)
 
  cleanup:
     virDomainObjEndAPI(&vm);
+    virObjectEventStateQueue(driver->domainEventState, event);
+
     return ret;
 }
 
@@ -1365,6 +1395,7 @@ static int chStateCleanup(void)
     virObjectUnref(ch_driver->xmlopt);
     virObjectUnref(ch_driver->caps);
     virObjectUnref(ch_driver->domains);
+    virObjectUnref(ch_driver->domainEventState);
     virMutexDestroy(&ch_driver->lock);
     g_clear_pointer(&ch_driver, g_free);
 
@@ -1414,6 +1445,9 @@ chStateInitialize(bool privileged,
     if (!(ch_driver->config = virCHDriverConfigNew(privileged)))
         goto cleanup;
 
+    if (!(ch_driver->domainEventState = virObjectEventStateNew()))
+        goto cleanup;
+
     if ((rv = chExtractVersion(ch_driver)) < 0) {
         if (rv == -2)
             ret = VIR_DRV_STATE_INIT_SKIPPED;
@@ -2205,6 +2239,48 @@ chDomainSetNumaParameters(virDomainPtr dom,
     return ret;
 }
 
+static int
+chConnectDomainEventRegisterAny(virConnectPtr conn,
+                                virDomainPtr dom,
+                                int eventID,
+                                virConnectDomainEventGenericCallback callback,
+                                void *opaque,
+                                virFreeCallback freecb)
+{
+    virCHDriver *driver = conn->privateData;
+    int ret = -1;
+
+    if (virConnectDomainEventRegisterAnyEnsureACL(conn) < 0)
+        return -1;
+
+    if (virDomainEventStateRegisterID(conn,
+                                      driver->domainEventState,
+                                      dom, eventID,
+                                      callback, opaque, freecb, &ret) < 0)
+        ret = -1;
+
+    return ret;
+}
+
+
+static int
+chConnectDomainEventDeregisterAny(virConnectPtr conn,
+                                  int callbackID)
+{
+    virCHDriver *driver = conn->privateData;
+
+    if (virConnectDomainEventDeregisterAnyEnsureACL(conn) < 0)
+        return -1;
+
+    if (virObjectEventStateDeregisterID(conn,
+                                        driver->domainEventState,
+                                        callbackID, true) < 0)
+        return -1;
+
+    return 0;
+}
+
+
 /* Function Tables */
 static virHypervisorDriver chHypervisorDriver = {
     .name = "CH",
@@ -2262,6 +2338,8 @@ static virHypervisorDriver chHypervisorDriver = {
     .domainHasManagedSaveImage = chDomainHasManagedSaveImage,   /* 10.2.0 */
     .domainRestore = chDomainRestore,                       /* 10.2.0 */
     .domainRestoreFlags = chDomainRestoreFlags,             /* 10.2.0 */
+    .connectDomainEventRegisterAny = chConnectDomainEventRegisterAny, /* 10.8.0 */
+    .connectDomainEventDeregisterAny = chConnectDomainEventDeregisterAny, /* 10.8.0 */
 };
 
 static virConnectDriver chConnectDriver = {
-- 
2.44.0
Re: [PATCH v2] ch: Enable callbacks for ch domain events
Posted by Michal Prívozník 1 year, 2 months ago
On 9/10/24 21:22, Praveen K Paladugu wrote:
> From: Praveen K Paladugu <prapal@linux.microsoft.com>
> 
> Enable callbacks for define, undefine, started, booted, stopped,
> destroyed events of ch guests.
> 
> Signed-off-by: Praveen K Paladugu <praveenkpaladugu@gmail.com>
> ---
>  src/ch/ch_conf.h   |  4 +++
>  src/ch/ch_driver.c | 82 ++++++++++++++++++++++++++++++++++++++++++++--
>  2 files changed, 84 insertions(+), 2 deletions(-)
> 
> diff --git a/src/ch/ch_conf.h b/src/ch/ch_conf.h
> index a77cad7a2a..97c6c24aa5 100644
> --- a/src/ch/ch_conf.h
> +++ b/src/ch/ch_conf.h
> @@ -24,6 +24,7 @@
>  #include "virthread.h"
>  #include "ch_capabilities.h"
>  #include "virebtables.h"
> +#include "object_event.h"
>  
>  #define CH_DRIVER_NAME "CH"
>  #define CH_CMD "cloud-hypervisor"
> @@ -75,6 +76,9 @@ struct _virCHDriver
>       * then lockless thereafter */
>      virCHDriverConfig *config;
>  
> +    /* Immutable pointer, self-locking APIs */
> +    virObjectEventState *domainEventState;
> +
>      /* pid file FD, ensures two copies of the driver can't use the same root */
>      int lockFD;
>  
> diff --git a/src/ch/ch_driver.c b/src/ch/ch_driver.c
> index dab025edc1..d18f266387 100644
> --- a/src/ch/ch_driver.c
> +++ b/src/ch/ch_driver.c
> @@ -28,6 +28,7 @@
>  #include "ch_monitor.h"
>  #include "ch_process.h"
>  #include "domain_cgroup.h"
> +#include "domain_event.h"
>  #include "datatypes.h"
>  #include "driver.h"
>  #include "viraccessapicheck.h"
> @@ -263,6 +264,7 @@ chDomainCreateWithFlags(virDomainPtr dom, unsigned int flags)
>      virCHDriver *driver = dom->conn->privateData;
>      virDomainObj *vm;
>      virCHDomainObjPrivate *priv;
> +    virObjectEvent *event;
>      g_autofree char *managed_save_path = NULL;
>      int ret = -1;
>  
> @@ -304,6 +306,14 @@ chDomainCreateWithFlags(virDomainPtr dom, unsigned int flags)
>          ret = virCHProcessStart(driver, vm, VIR_DOMAIN_RUNNING_BOOTED);
>      }
>  
> +    if (ret == 0) {
> +        event = virDomainEventLifecycleNewFromObj(vm,
> +                                                  VIR_DOMAIN_EVENT_STARTED,
> +                                                  VIR_DOMAIN_EVENT_STARTED_BOOTED);
> +        if (event)
> +            virObjectEventStateQueue(driver->domainEventState, event);

No need to check for event != NULL; virObjectEventStateQueue() already
does that. Speaking of the variable - it's sufficient to declare it
inside the this block.

Reviewed-by: Michal Privoznik <mprivozn@redhat.com>

and merged.

Michal
Re: [PATCH v2] ch: Enable callbacks for ch domain events
Posted by Praveen K Paladugu 1 year, 4 months ago
bubbling up this patch for review.

On 9/10/2024 2:22 PM, Praveen K Paladugu wrote:
> From: Praveen K Paladugu <prapal@linux.microsoft.com>
> 
> Enable callbacks for define, undefine, started, booted, stopped,
> destroyed events of ch guests.
> 
> Signed-off-by: Praveen K Paladugu <praveenkpaladugu@gmail.com>
> ---
>   src/ch/ch_conf.h   |  4 +++
>   src/ch/ch_driver.c | 82 ++++++++++++++++++++++++++++++++++++++++++++--
>   2 files changed, 84 insertions(+), 2 deletions(-)
> 
> diff --git a/src/ch/ch_conf.h b/src/ch/ch_conf.h
> index a77cad7a2a..97c6c24aa5 100644
> --- a/src/ch/ch_conf.h
> +++ b/src/ch/ch_conf.h
> @@ -24,6 +24,7 @@
>   #include "virthread.h"
>   #include "ch_capabilities.h"
>   #include "virebtables.h"
> +#include "object_event.h"
>   
>   #define CH_DRIVER_NAME "CH"
>   #define CH_CMD "cloud-hypervisor"
> @@ -75,6 +76,9 @@ struct _virCHDriver
>        * then lockless thereafter */
>       virCHDriverConfig *config;
>   
> +    /* Immutable pointer, self-locking APIs */
> +    virObjectEventState *domainEventState;
> +
>       /* pid file FD, ensures two copies of the driver can't use the same root */
>       int lockFD;
>   
> diff --git a/src/ch/ch_driver.c b/src/ch/ch_driver.c
> index dab025edc1..d18f266387 100644
> --- a/src/ch/ch_driver.c
> +++ b/src/ch/ch_driver.c
> @@ -28,6 +28,7 @@
>   #include "ch_monitor.h"
>   #include "ch_process.h"
>   #include "domain_cgroup.h"
> +#include "domain_event.h"
>   #include "datatypes.h"
>   #include "driver.h"
>   #include "viraccessapicheck.h"
> @@ -263,6 +264,7 @@ chDomainCreateWithFlags(virDomainPtr dom, unsigned int flags)
>       virCHDriver *driver = dom->conn->privateData;
>       virDomainObj *vm;
>       virCHDomainObjPrivate *priv;
> +    virObjectEvent *event;
>       g_autofree char *managed_save_path = NULL;
>       int ret = -1;
>   
> @@ -304,6 +306,14 @@ chDomainCreateWithFlags(virDomainPtr dom, unsigned int flags)
>           ret = virCHProcessStart(driver, vm, VIR_DOMAIN_RUNNING_BOOTED);
>       }
>   
> +    if (ret == 0) {
> +        event = virDomainEventLifecycleNewFromObj(vm,
> +                                                  VIR_DOMAIN_EVENT_STARTED,
> +                                                  VIR_DOMAIN_EVENT_STARTED_BOOTED);
> +        if (event)
> +            virObjectEventStateQueue(driver->domainEventState, event);
> +    }
> +
>    endjob:
>       virDomainObjEndJob(vm);
>   
> @@ -323,8 +333,10 @@ chDomainDefineXMLFlags(virConnectPtr conn, const char *xml, unsigned int flags)
>   {
>       virCHDriver *driver = conn->privateData;
>       g_autoptr(virDomainDef) vmdef = NULL;
> +    g_autoptr(virDomainDef) oldDef = NULL;
>       virDomainObj *vm = NULL;
>       virDomainPtr dom = NULL;
> +    virObjectEvent *event = NULL;
>       g_autofree char *managed_save_path = NULL;
>       unsigned int parse_flags = VIR_DOMAIN_DEF_PARSE_INACTIVE;
>   
> @@ -345,7 +357,7 @@ chDomainDefineXMLFlags(virConnectPtr conn, const char *xml, unsigned int flags)
>   
>       if (!(vm = virDomainObjListAdd(driver->domains, &vmdef,
>                                      driver->xmlopt,
> -                                   0, NULL)))
> +                                   0, &oldDef)))
>           goto cleanup;
>   
>       /* cleanup if there's any stale managedsave dir */
> @@ -358,11 +370,17 @@ chDomainDefineXMLFlags(virConnectPtr conn, const char *xml, unsigned int flags)
>       }
>   
>       vm->persistent = 1;
> -
> +    event = virDomainEventLifecycleNewFromObj(vm,
> +                                              VIR_DOMAIN_EVENT_DEFINED,
> +                                              !oldDef ?
> +                                              VIR_DOMAIN_EVENT_DEFINED_ADDED :
> +                                              VIR_DOMAIN_EVENT_DEFINED_UPDATED);
>       dom = virGetDomain(conn, vm->def->name, vm->def->uuid, vm->def->id);
>   
>    cleanup:
>       virDomainObjEndAPI(&vm);
> +    virObjectEventStateQueue(driver->domainEventState, event);
> +
>       return dom;
>   }
>   
> @@ -378,6 +396,7 @@ chDomainUndefineFlags(virDomainPtr dom,
>   {
>       virCHDriver *driver = dom->conn->privateData;
>       virDomainObj *vm;
> +    virObjectEvent *event = NULL;
>       int ret = -1;
>   
>       virCheckFlags(0, -1);
> @@ -393,6 +412,9 @@ chDomainUndefineFlags(virDomainPtr dom,
>                          "%s", _("Cannot undefine transient domain"));
>           goto cleanup;
>       }
> +    event = virDomainEventLifecycleNewFromObj(vm,
> +                                              VIR_DOMAIN_EVENT_UNDEFINED,
> +                                              VIR_DOMAIN_EVENT_UNDEFINED_REMOVED);
>   
>       vm->persistent = 0;
>       if (!virDomainObjIsActive(vm)) {
> @@ -403,6 +425,8 @@ chDomainUndefineFlags(virDomainPtr dom,
>   
>    cleanup:
>       virDomainObjEndAPI(&vm);
> +    virObjectEventStateQueue(driver->domainEventState, event);
> +
>       return ret;
>   }
>   
> @@ -643,6 +667,7 @@ chDomainDestroyFlags(virDomainPtr dom, unsigned int flags)
>   {
>       virCHDriver *driver = dom->conn->privateData;
>       virDomainObj *vm;
> +    virObjectEvent *event = NULL;
>       int ret = -1;
>   
>       virCheckFlags(0, -1);
> @@ -662,6 +687,9 @@ chDomainDestroyFlags(virDomainPtr dom, unsigned int flags)
>       if (virCHProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_DESTROYED) < 0)
>           goto endjob;
>   
> +    event = virDomainEventLifecycleNewFromObj(vm,
> +                                              VIR_DOMAIN_EVENT_STOPPED,
> +                                              VIR_DOMAIN_EVENT_STOPPED_DESTROYED);
>       virCHDomainRemoveInactive(driver, vm);
>       ret = 0;
>   
> @@ -670,6 +698,8 @@ chDomainDestroyFlags(virDomainPtr dom, unsigned int flags)
>   
>    cleanup:
>       virDomainObjEndAPI(&vm);
> +    virObjectEventStateQueue(driver->domainEventState, event);
> +
>       return ret;
>   }
>   
> @@ -1365,6 +1395,7 @@ static int chStateCleanup(void)
>       virObjectUnref(ch_driver->xmlopt);
>       virObjectUnref(ch_driver->caps);
>       virObjectUnref(ch_driver->domains);
> +    virObjectUnref(ch_driver->domainEventState);
>       virMutexDestroy(&ch_driver->lock);
>       g_clear_pointer(&ch_driver, g_free);
>   
> @@ -1414,6 +1445,9 @@ chStateInitialize(bool privileged,
>       if (!(ch_driver->config = virCHDriverConfigNew(privileged)))
>           goto cleanup;
>   
> +    if (!(ch_driver->domainEventState = virObjectEventStateNew()))
> +        goto cleanup;
> +
>       if ((rv = chExtractVersion(ch_driver)) < 0) {
>           if (rv == -2)
>               ret = VIR_DRV_STATE_INIT_SKIPPED;
> @@ -2205,6 +2239,48 @@ chDomainSetNumaParameters(virDomainPtr dom,
>       return ret;
>   }
>   
> +static int
> +chConnectDomainEventRegisterAny(virConnectPtr conn,
> +                                virDomainPtr dom,
> +                                int eventID,
> +                                virConnectDomainEventGenericCallback callback,
> +                                void *opaque,
> +                                virFreeCallback freecb)
> +{
> +    virCHDriver *driver = conn->privateData;
> +    int ret = -1;
> +
> +    if (virConnectDomainEventRegisterAnyEnsureACL(conn) < 0)
> +        return -1;
> +
> +    if (virDomainEventStateRegisterID(conn,
> +                                      driver->domainEventState,
> +                                      dom, eventID,
> +                                      callback, opaque, freecb, &ret) < 0)
> +        ret = -1;
> +
> +    return ret;
> +}
> +
> +
> +static int
> +chConnectDomainEventDeregisterAny(virConnectPtr conn,
> +                                  int callbackID)
> +{
> +    virCHDriver *driver = conn->privateData;
> +
> +    if (virConnectDomainEventDeregisterAnyEnsureACL(conn) < 0)
> +        return -1;
> +
> +    if (virObjectEventStateDeregisterID(conn,
> +                                        driver->domainEventState,
> +                                        callbackID, true) < 0)
> +        return -1;
> +
> +    return 0;
> +}
> +
> +
>   /* Function Tables */
>   static virHypervisorDriver chHypervisorDriver = {
>       .name = "CH",
> @@ -2262,6 +2338,8 @@ static virHypervisorDriver chHypervisorDriver = {
>       .domainHasManagedSaveImage = chDomainHasManagedSaveImage,   /* 10.2.0 */
>       .domainRestore = chDomainRestore,                       /* 10.2.0 */
>       .domainRestoreFlags = chDomainRestoreFlags,             /* 10.2.0 */
> +    .connectDomainEventRegisterAny = chConnectDomainEventRegisterAny, /* 10.8.0 */
> +    .connectDomainEventDeregisterAny = chConnectDomainEventDeregisterAny, /* 10.8.0 */
>   };
>   
>   static virConnectDriver chConnectDriver = {

-- 
Regards,
Praveen K Paladugu
Re: [PATCH v2] ch: Enable callbacks for ch domain events
Posted by Praveen K Paladugu 1 year, 4 months ago
Ping for review/merge.

On 9/26/2024 11:29 AM, Praveen K Paladugu wrote:
> bubbling up this patch for review.
> 
> On 9/10/2024 2:22 PM, Praveen K Paladugu wrote:
>> From: Praveen K Paladugu <prapal@linux.microsoft.com>
>>
>> Enable callbacks for define, undefine, started, booted, stopped,
>> destroyed events of ch guests.
>>
>> Signed-off-by: Praveen K Paladugu <praveenkpaladugu@gmail.com>
>> ---
>>   src/ch/ch_conf.h   |  4 +++
>>   src/ch/ch_driver.c | 82 ++++++++++++++++++++++++++++++++++++++++++++--
>>   2 files changed, 84 insertions(+), 2 deletions(-)
>>
>> diff --git a/src/ch/ch_conf.h b/src/ch/ch_conf.h
>> index a77cad7a2a..97c6c24aa5 100644
>> --- a/src/ch/ch_conf.h
>> +++ b/src/ch/ch_conf.h
>> @@ -24,6 +24,7 @@
>>   #include "virthread.h"
>>   #include "ch_capabilities.h"
>>   #include "virebtables.h"
>> +#include "object_event.h"
>>   #define CH_DRIVER_NAME "CH"
>>   #define CH_CMD "cloud-hypervisor"
>> @@ -75,6 +76,9 @@ struct _virCHDriver
>>        * then lockless thereafter */
>>       virCHDriverConfig *config;
>> +    /* Immutable pointer, self-locking APIs */
>> +    virObjectEventState *domainEventState;
>> +
>>       /* pid file FD, ensures two copies of the driver can't use the 
>> same root */
>>       int lockFD;
>> diff --git a/src/ch/ch_driver.c b/src/ch/ch_driver.c
>> index dab025edc1..d18f266387 100644
>> --- a/src/ch/ch_driver.c
>> +++ b/src/ch/ch_driver.c
>> @@ -28,6 +28,7 @@
>>   #include "ch_monitor.h"
>>   #include "ch_process.h"
>>   #include "domain_cgroup.h"
>> +#include "domain_event.h"
>>   #include "datatypes.h"
>>   #include "driver.h"
>>   #include "viraccessapicheck.h"
>> @@ -263,6 +264,7 @@ chDomainCreateWithFlags(virDomainPtr dom, unsigned 
>> int flags)
>>       virCHDriver *driver = dom->conn->privateData;
>>       virDomainObj *vm;
>>       virCHDomainObjPrivate *priv;
>> +    virObjectEvent *event;
>>       g_autofree char *managed_save_path = NULL;
>>       int ret = -1;
>> @@ -304,6 +306,14 @@ chDomainCreateWithFlags(virDomainPtr dom, 
>> unsigned int flags)
>>           ret = virCHProcessStart(driver, vm, VIR_DOMAIN_RUNNING_BOOTED);
>>       }
>> +    if (ret == 0) {
>> +        event = virDomainEventLifecycleNewFromObj(vm,
>> +                                                  
>> VIR_DOMAIN_EVENT_STARTED,
>> +                                                  
>> VIR_DOMAIN_EVENT_STARTED_BOOTED);
>> +        if (event)
>> +            virObjectEventStateQueue(driver->domainEventState, event);
>> +    }
>> +
>>    endjob:
>>       virDomainObjEndJob(vm);
>> @@ -323,8 +333,10 @@ chDomainDefineXMLFlags(virConnectPtr conn, const 
>> char *xml, unsigned int flags)
>>   {
>>       virCHDriver *driver = conn->privateData;
>>       g_autoptr(virDomainDef) vmdef = NULL;
>> +    g_autoptr(virDomainDef) oldDef = NULL;
>>       virDomainObj *vm = NULL;
>>       virDomainPtr dom = NULL;
>> +    virObjectEvent *event = NULL;
>>       g_autofree char *managed_save_path = NULL;
>>       unsigned int parse_flags = VIR_DOMAIN_DEF_PARSE_INACTIVE;
>> @@ -345,7 +357,7 @@ chDomainDefineXMLFlags(virConnectPtr conn, const 
>> char *xml, unsigned int flags)
>>       if (!(vm = virDomainObjListAdd(driver->domains, &vmdef,
>>                                      driver->xmlopt,
>> -                                   0, NULL)))
>> +                                   0, &oldDef)))
>>           goto cleanup;
>>       /* cleanup if there's any stale managedsave dir */
>> @@ -358,11 +370,17 @@ chDomainDefineXMLFlags(virConnectPtr conn, const 
>> char *xml, unsigned int flags)
>>       }
>>       vm->persistent = 1;
>> -
>> +    event = virDomainEventLifecycleNewFromObj(vm,
>> +                                              VIR_DOMAIN_EVENT_DEFINED,
>> +                                              !oldDef ?
>> +                                              
>> VIR_DOMAIN_EVENT_DEFINED_ADDED :
>> +                                              
>> VIR_DOMAIN_EVENT_DEFINED_UPDATED);
>>       dom = virGetDomain(conn, vm->def->name, vm->def->uuid, vm->def- 
>> >id);
>>    cleanup:
>>       virDomainObjEndAPI(&vm);
>> +    virObjectEventStateQueue(driver->domainEventState, event);
>> +
>>       return dom;
>>   }
>> @@ -378,6 +396,7 @@ chDomainUndefineFlags(virDomainPtr dom,
>>   {
>>       virCHDriver *driver = dom->conn->privateData;
>>       virDomainObj *vm;
>> +    virObjectEvent *event = NULL;
>>       int ret = -1;
>>       virCheckFlags(0, -1);
>> @@ -393,6 +412,9 @@ chDomainUndefineFlags(virDomainPtr dom,
>>                          "%s", _("Cannot undefine transient domain"));
>>           goto cleanup;
>>       }
>> +    event = virDomainEventLifecycleNewFromObj(vm,
>> +                                              
>> VIR_DOMAIN_EVENT_UNDEFINED,
>> +                                              
>> VIR_DOMAIN_EVENT_UNDEFINED_REMOVED);
>>       vm->persistent = 0;
>>       if (!virDomainObjIsActive(vm)) {
>> @@ -403,6 +425,8 @@ chDomainUndefineFlags(virDomainPtr dom,
>>    cleanup:
>>       virDomainObjEndAPI(&vm);
>> +    virObjectEventStateQueue(driver->domainEventState, event);
>> +
>>       return ret;
>>   }
>> @@ -643,6 +667,7 @@ chDomainDestroyFlags(virDomainPtr dom, unsigned 
>> int flags)
>>   {
>>       virCHDriver *driver = dom->conn->privateData;
>>       virDomainObj *vm;
>> +    virObjectEvent *event = NULL;
>>       int ret = -1;
>>       virCheckFlags(0, -1);
>> @@ -662,6 +687,9 @@ chDomainDestroyFlags(virDomainPtr dom, unsigned 
>> int flags)
>>       if (virCHProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_DESTROYED) < 0)
>>           goto endjob;
>> +    event = virDomainEventLifecycleNewFromObj(vm,
>> +                                              VIR_DOMAIN_EVENT_STOPPED,
>> +                                              
>> VIR_DOMAIN_EVENT_STOPPED_DESTROYED);
>>       virCHDomainRemoveInactive(driver, vm);
>>       ret = 0;
>> @@ -670,6 +698,8 @@ chDomainDestroyFlags(virDomainPtr dom, unsigned 
>> int flags)
>>    cleanup:
>>       virDomainObjEndAPI(&vm);
>> +    virObjectEventStateQueue(driver->domainEventState, event);
>> +
>>       return ret;
>>   }
>> @@ -1365,6 +1395,7 @@ static int chStateCleanup(void)
>>       virObjectUnref(ch_driver->xmlopt);
>>       virObjectUnref(ch_driver->caps);
>>       virObjectUnref(ch_driver->domains);
>> +    virObjectUnref(ch_driver->domainEventState);
>>       virMutexDestroy(&ch_driver->lock);
>>       g_clear_pointer(&ch_driver, g_free);
>> @@ -1414,6 +1445,9 @@ chStateInitialize(bool privileged,
>>       if (!(ch_driver->config = virCHDriverConfigNew(privileged)))
>>           goto cleanup;
>> +    if (!(ch_driver->domainEventState = virObjectEventStateNew()))
>> +        goto cleanup;
>> +
>>       if ((rv = chExtractVersion(ch_driver)) < 0) {
>>           if (rv == -2)
>>               ret = VIR_DRV_STATE_INIT_SKIPPED;
>> @@ -2205,6 +2239,48 @@ chDomainSetNumaParameters(virDomainPtr dom,
>>       return ret;
>>   }
>> +static int
>> +chConnectDomainEventRegisterAny(virConnectPtr conn,
>> +                                virDomainPtr dom,
>> +                                int eventID,
>> +                                virConnectDomainEventGenericCallback 
>> callback,
>> +                                void *opaque,
>> +                                virFreeCallback freecb)
>> +{
>> +    virCHDriver *driver = conn->privateData;
>> +    int ret = -1;
>> +
>> +    if (virConnectDomainEventRegisterAnyEnsureACL(conn) < 0)
>> +        return -1;
>> +
>> +    if (virDomainEventStateRegisterID(conn,
>> +                                      driver->domainEventState,
>> +                                      dom, eventID,
>> +                                      callback, opaque, freecb, &ret) 
>> < 0)
>> +        ret = -1;
>> +
>> +    return ret;
>> +}
>> +
>> +
>> +static int
>> +chConnectDomainEventDeregisterAny(virConnectPtr conn,
>> +                                  int callbackID)
>> +{
>> +    virCHDriver *driver = conn->privateData;
>> +
>> +    if (virConnectDomainEventDeregisterAnyEnsureACL(conn) < 0)
>> +        return -1;
>> +
>> +    if (virObjectEventStateDeregisterID(conn,
>> +                                        driver->domainEventState,
>> +                                        callbackID, true) < 0)
>> +        return -1;
>> +
>> +    return 0;
>> +}
>> +
>> +
>>   /* Function Tables */
>>   static virHypervisorDriver chHypervisorDriver = {
>>       .name = "CH",
>> @@ -2262,6 +2338,8 @@ static virHypervisorDriver chHypervisorDriver = {
>>       .domainHasManagedSaveImage = chDomainHasManagedSaveImage,   /* 
>> 10.2.0 */
>>       .domainRestore = chDomainRestore,                       /* 
>> 10.2.0 */
>>       .domainRestoreFlags = chDomainRestoreFlags,             /* 
>> 10.2.0 */
>> +    .connectDomainEventRegisterAny = 
>> chConnectDomainEventRegisterAny, /* 10.8.0 */
>> +    .connectDomainEventDeregisterAny = 
>> chConnectDomainEventDeregisterAny, /* 10.8.0 */
>>   };
>>   static virConnectDriver chConnectDriver = {
> 

-- 
Regards,
Praveen K Paladugu
Re: [PATCH v2] ch: Enable callbacks for ch domain events
Posted by Praveen K Paladugu 1 year, 2 months ago
bubbling up patch for review.

On 10/7/2024 11:09 AM, Praveen K Paladugu wrote:
> Ping for review/merge.
> 
> On 9/26/2024 11:29 AM, Praveen K Paladugu wrote:
>> bubbling up this patch for review.
>>
>> On 9/10/2024 2:22 PM, Praveen K Paladugu wrote:
>>> From: Praveen K Paladugu <prapal@linux.microsoft.com>
>>>
>>> Enable callbacks for define, undefine, started, booted, stopped,
>>> destroyed events of ch guests.
>>>
>>> Signed-off-by: Praveen K Paladugu <praveenkpaladugu@gmail.com>
>>> ---
>>>   src/ch/ch_conf.h   |  4 +++
>>>   src/ch/ch_driver.c | 82 ++++++++++++++++++++++++++++++++++++++++++++--
>>>   2 files changed, 84 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/src/ch/ch_conf.h b/src/ch/ch_conf.h
>>> index a77cad7a2a..97c6c24aa5 100644
>>> --- a/src/ch/ch_conf.h
>>> +++ b/src/ch/ch_conf.h
>>> @@ -24,6 +24,7 @@
>>>   #include "virthread.h"
>>>   #include "ch_capabilities.h"
>>>   #include "virebtables.h"
>>> +#include "object_event.h"
>>>   #define CH_DRIVER_NAME "CH"
>>>   #define CH_CMD "cloud-hypervisor"
>>> @@ -75,6 +76,9 @@ struct _virCHDriver
>>>        * then lockless thereafter */
>>>       virCHDriverConfig *config;
>>> +    /* Immutable pointer, self-locking APIs */
>>> +    virObjectEventState *domainEventState;
>>> +
>>>       /* pid file FD, ensures two copies of the driver can't use the 
>>> same root */
>>>       int lockFD;
>>> diff --git a/src/ch/ch_driver.c b/src/ch/ch_driver.c
>>> index dab025edc1..d18f266387 100644
>>> --- a/src/ch/ch_driver.c
>>> +++ b/src/ch/ch_driver.c
>>> @@ -28,6 +28,7 @@
>>>   #include "ch_monitor.h"
>>>   #include "ch_process.h"
>>>   #include "domain_cgroup.h"
>>> +#include "domain_event.h"
>>>   #include "datatypes.h"
>>>   #include "driver.h"
>>>   #include "viraccessapicheck.h"
>>> @@ -263,6 +264,7 @@ chDomainCreateWithFlags(virDomainPtr dom, 
>>> unsigned int flags)
>>>       virCHDriver *driver = dom->conn->privateData;
>>>       virDomainObj *vm;
>>>       virCHDomainObjPrivate *priv;
>>> +    virObjectEvent *event;
>>>       g_autofree char *managed_save_path = NULL;
>>>       int ret = -1;
>>> @@ -304,6 +306,14 @@ chDomainCreateWithFlags(virDomainPtr dom, 
>>> unsigned int flags)
>>>           ret = virCHProcessStart(driver, vm, 
>>> VIR_DOMAIN_RUNNING_BOOTED);
>>>       }
>>> +    if (ret == 0) {
>>> +        event = virDomainEventLifecycleNewFromObj(vm,
>>> + VIR_DOMAIN_EVENT_STARTED,
>>> + VIR_DOMAIN_EVENT_STARTED_BOOTED);
>>> +        if (event)
>>> +            virObjectEventStateQueue(driver->domainEventState, event);
>>> +    }
>>> +
>>>    endjob:
>>>       virDomainObjEndJob(vm);
>>> @@ -323,8 +333,10 @@ chDomainDefineXMLFlags(virConnectPtr conn, const 
>>> char *xml, unsigned int flags)
>>>   {
>>>       virCHDriver *driver = conn->privateData;
>>>       g_autoptr(virDomainDef) vmdef = NULL;
>>> +    g_autoptr(virDomainDef) oldDef = NULL;
>>>       virDomainObj *vm = NULL;
>>>       virDomainPtr dom = NULL;
>>> +    virObjectEvent *event = NULL;
>>>       g_autofree char *managed_save_path = NULL;
>>>       unsigned int parse_flags = VIR_DOMAIN_DEF_PARSE_INACTIVE;
>>> @@ -345,7 +357,7 @@ chDomainDefineXMLFlags(virConnectPtr conn, const 
>>> char *xml, unsigned int flags)
>>>       if (!(vm = virDomainObjListAdd(driver->domains, &vmdef,
>>>                                      driver->xmlopt,
>>> -                                   0, NULL)))
>>> +                                   0, &oldDef)))
>>>           goto cleanup;
>>>       /* cleanup if there's any stale managedsave dir */
>>> @@ -358,11 +370,17 @@ chDomainDefineXMLFlags(virConnectPtr conn, 
>>> const char *xml, unsigned int flags)
>>>       }
>>>       vm->persistent = 1;
>>> -
>>> +    event = virDomainEventLifecycleNewFromObj(vm,
>>> +                                              VIR_DOMAIN_EVENT_DEFINED,
>>> +                                              !oldDef ?
>>> + VIR_DOMAIN_EVENT_DEFINED_ADDED :
>>> + VIR_DOMAIN_EVENT_DEFINED_UPDATED);
>>>       dom = virGetDomain(conn, vm->def->name, vm->def->uuid, vm->def- 
>>> >id);
>>>    cleanup:
>>>       virDomainObjEndAPI(&vm);
>>> +    virObjectEventStateQueue(driver->domainEventState, event);
>>> +
>>>       return dom;
>>>   }
>>> @@ -378,6 +396,7 @@ chDomainUndefineFlags(virDomainPtr dom,
>>>   {
>>>       virCHDriver *driver = dom->conn->privateData;
>>>       virDomainObj *vm;
>>> +    virObjectEvent *event = NULL;
>>>       int ret = -1;
>>>       virCheckFlags(0, -1);
>>> @@ -393,6 +412,9 @@ chDomainUndefineFlags(virDomainPtr dom,
>>>                          "%s", _("Cannot undefine transient domain"));
>>>           goto cleanup;
>>>       }
>>> +    event = virDomainEventLifecycleNewFromObj(vm,
>>> + VIR_DOMAIN_EVENT_UNDEFINED,
>>> + VIR_DOMAIN_EVENT_UNDEFINED_REMOVED);
>>>       vm->persistent = 0;
>>>       if (!virDomainObjIsActive(vm)) {
>>> @@ -403,6 +425,8 @@ chDomainUndefineFlags(virDomainPtr dom,
>>>    cleanup:
>>>       virDomainObjEndAPI(&vm);
>>> +    virObjectEventStateQueue(driver->domainEventState, event);
>>> +
>>>       return ret;
>>>   }
>>> @@ -643,6 +667,7 @@ chDomainDestroyFlags(virDomainPtr dom, unsigned 
>>> int flags)
>>>   {
>>>       virCHDriver *driver = dom->conn->privateData;
>>>       virDomainObj *vm;
>>> +    virObjectEvent *event = NULL;
>>>       int ret = -1;
>>>       virCheckFlags(0, -1);
>>> @@ -662,6 +687,9 @@ chDomainDestroyFlags(virDomainPtr dom, unsigned 
>>> int flags)
>>>       if (virCHProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_DESTROYED) 
>>> < 0)
>>>           goto endjob;
>>> +    event = virDomainEventLifecycleNewFromObj(vm,
>>> +                                              VIR_DOMAIN_EVENT_STOPPED,
>>> + VIR_DOMAIN_EVENT_STOPPED_DESTROYED);
>>>       virCHDomainRemoveInactive(driver, vm);
>>>       ret = 0;
>>> @@ -670,6 +698,8 @@ chDomainDestroyFlags(virDomainPtr dom, unsigned 
>>> int flags)
>>>    cleanup:
>>>       virDomainObjEndAPI(&vm);
>>> +    virObjectEventStateQueue(driver->domainEventState, event);
>>> +
>>>       return ret;
>>>   }
>>> @@ -1365,6 +1395,7 @@ static int chStateCleanup(void)
>>>       virObjectUnref(ch_driver->xmlopt);
>>>       virObjectUnref(ch_driver->caps);
>>>       virObjectUnref(ch_driver->domains);
>>> +    virObjectUnref(ch_driver->domainEventState);
>>>       virMutexDestroy(&ch_driver->lock);
>>>       g_clear_pointer(&ch_driver, g_free);
>>> @@ -1414,6 +1445,9 @@ chStateInitialize(bool privileged,
>>>       if (!(ch_driver->config = virCHDriverConfigNew(privileged)))
>>>           goto cleanup;
>>> +    if (!(ch_driver->domainEventState = virObjectEventStateNew()))
>>> +        goto cleanup;
>>> +
>>>       if ((rv = chExtractVersion(ch_driver)) < 0) {
>>>           if (rv == -2)
>>>               ret = VIR_DRV_STATE_INIT_SKIPPED;
>>> @@ -2205,6 +2239,48 @@ chDomainSetNumaParameters(virDomainPtr dom,
>>>       return ret;
>>>   }
>>> +static int
>>> +chConnectDomainEventRegisterAny(virConnectPtr conn,
>>> +                                virDomainPtr dom,
>>> +                                int eventID,
>>> +                                virConnectDomainEventGenericCallback 
>>> callback,
>>> +                                void *opaque,
>>> +                                virFreeCallback freecb)
>>> +{
>>> +    virCHDriver *driver = conn->privateData;
>>> +    int ret = -1;
>>> +
>>> +    if (virConnectDomainEventRegisterAnyEnsureACL(conn) < 0)
>>> +        return -1;
>>> +
>>> +    if (virDomainEventStateRegisterID(conn,
>>> +                                      driver->domainEventState,
>>> +                                      dom, eventID,
>>> +                                      callback, opaque, freecb, 
>>> &ret) < 0)
>>> +        ret = -1;
>>> +
>>> +    return ret;
>>> +}
>>> +
>>> +
>>> +static int
>>> +chConnectDomainEventDeregisterAny(virConnectPtr conn,
>>> +                                  int callbackID)
>>> +{
>>> +    virCHDriver *driver = conn->privateData;
>>> +
>>> +    if (virConnectDomainEventDeregisterAnyEnsureACL(conn) < 0)
>>> +        return -1;
>>> +
>>> +    if (virObjectEventStateDeregisterID(conn,
>>> +                                        driver->domainEventState,
>>> +                                        callbackID, true) < 0)
>>> +        return -1;
>>> +
>>> +    return 0;
>>> +}
>>> +
>>> +
>>>   /* Function Tables */
>>>   static virHypervisorDriver chHypervisorDriver = {
>>>       .name = "CH",
>>> @@ -2262,6 +2338,8 @@ static virHypervisorDriver chHypervisorDriver = {
>>>       .domainHasManagedSaveImage = chDomainHasManagedSaveImage,   /* 
>>> 10.2.0 */
>>>       .domainRestore = chDomainRestore,                       /* 
>>> 10.2.0 */
>>>       .domainRestoreFlags = chDomainRestoreFlags,             /* 
>>> 10.2.0 */
>>> +    .connectDomainEventRegisterAny = 
>>> chConnectDomainEventRegisterAny, /* 10.8.0 */
>>> +    .connectDomainEventDeregisterAny = 
>>> chConnectDomainEventDeregisterAny, /* 10.8.0 */
>>>   };
>>>   static virConnectDriver chConnectDriver = {
>>
> 

-- 
Regards,
Praveen K Paladugu