[Libvirt-cim] [PATCH 1 of 2] Add Modified to the list of available indications in ComputerSystemIndication

Jay Gagnon grendel at linux.vnet.ibm.com
Mon Jan 21 21:33:13 UTC 2008


# HG changeset patch
# User Jay Gagnon <grendel at linux.vnet.ibm.com>
# Date 1200951153 18000
# Node ID 8faf3edab86112a5a9e77faa297db21f5f38eb44
# Parent  ca8dc23eacc44970a2d79978bc9de65aaa600b92
Add Modified to the list of available indications in ComputerSystemIndication.

This is the integration of the previously discussed CSMI provider into the existing CSI provider.  Most of the integration changes are actually done to how CSI works, as CSMI featured several improvements.

The schema changes are in here too because they're just so small and simple compared to everything else that I didn't bother to break them out this time.  If keeping them separate is preferred I can do that.

Changes since last time:
Fixed up ind_args so we don't try to pass around stale pointers.
Made sure lifecycle_thread_id variable is reset when event loop exits, allowing unsubscribe/re-subscribe to happen successfully.

Signed-off-by: Jay Gagnon <grendel at linux.vnet.ibm.com>

diff -r ca8dc23eacc4 -r 8faf3edab861 schema/ComputerSystemIndication.mof
--- a/schema/ComputerSystemIndication.mof	Wed Jan 09 13:08:17 2008 +0100
+++ b/schema/ComputerSystemIndication.mof	Mon Jan 21 16:32:33 2008 -0500
@@ -14,6 +14,13 @@ class Xen_ComputerSystemDeletedIndicatio
 {
 };
 
+[Description ("Xen_ComputerSystem modified"),
+ Provider("cmpi::Virt_ComputerSystemIndication")
+]
+class Xen_ComputerSystemModifiedIndication : CIM_InstModification
+{
+};
+
 [Description ("KVM_ComputerSystem lifecycle"),
  Provider("cmpi::Virt_ComputerSystemIndication")
 ]
@@ -27,3 +34,10 @@ class KVM_ComputerSystemDeletedIndicatio
 class KVM_ComputerSystemDeletedIndication : CIM_InstDeletion
 {
 };
+
+[Description ("KVM_ComputerSystem modified"),
+ Provider("cmpi::Virt_ComputerSystemIndication")
+]
+class KVM_ComputerSystemModifiedIndication : CIM_InstModification
+{
+};
diff -r ca8dc23eacc4 -r 8faf3edab861 schema/ComputerSystemIndication.registration
--- a/schema/ComputerSystemIndication.registration	Wed Jan 09 13:08:17 2008 +0100
+++ b/schema/ComputerSystemIndication.registration	Mon Jan 21 16:32:33 2008 -0500
@@ -2,5 +2,7 @@
 # Classname Namespace ProviderName ProviderModule ProviderTypes
 Xen_ComputerSystemCreatedIndication root/virt Virt_ComputerSystemIndication Virt_ComputerSystemIndication indication method
 Xen_ComputerSystemDeletedIndication root/virt Virt_ComputerSystemIndication Virt_ComputerSystemIndication indication method
+Xen_ComputerSystemModifiedIndication root/virt Virt_ComputerSystemIndication Virt_ComputerSystemIndication indication method
 KVM_ComputerSystemCreatedIndication root/virt Virt_ComputerSystemIndication Virt_ComputerSystemIndication indication method
 KVM_ComputerSystemDeletedIndication root/virt Virt_ComputerSystemIndication Virt_ComputerSystemIndication indication method
+KVM_ComputerSystemModifiedIndication root/virt Virt_ComputerSystemIndication Virt_ComputerSystemIndication indication method
diff -r ca8dc23eacc4 -r 8faf3edab861 src/Virt_ComputerSystemIndication.c
--- a/src/Virt_ComputerSystemIndication.c	Wed Jan 09 13:08:17 2008 +0100
+++ b/src/Virt_ComputerSystemIndication.c	Mon Jan 21 16:32:33 2008 -0500
@@ -62,6 +62,108 @@ static bool lifecycle_enabled = 0;
 # define _EI_RET() return (CMPIStatus){CMPI_RC_OK, NULL}
 #endif
 
+struct dom_xml {
+        char uuid[VIR_UUID_STRING_BUFLEN];
+        char *xml;
+};
+
+struct ind_args {
+        CMPIContext *context;
+        char *ns;
+        char *classname;
+};
+
+static void free_dom_xml (struct dom_xml dom)
+{
+        free(dom.xml);
+}
+
+static void free_ind_args (struct ind_args args)
+{
+        free(args.ns);
+        free(args.classname);
+}
+
+static void cleanup_domain_list(virDomainPtr *list, int size)
+{
+        int i;
+
+        for (i = 0; i < size; i++) {
+                virDomainFree(list[i]);
+        }
+}
+
+static char *sys_name_from_xml(char *xml)
+{
+        char *tmp = NULL;
+        char *name = NULL;
+        int rc;
+
+        tmp = strstr(xml, "<name>");
+        if (tmp == NULL)
+                goto out;
+
+        rc = sscanf(tmp, "<name>%a[^<]s</name>", &name);
+        if (rc != 1)
+                name = NULL;
+
+ out:        
+        return name;
+}
+
+static CMPIStatus doms_to_xml(struct dom_xml **dom_xml_list, 
+                              virDomainPtr *dom_ptr_list,
+                              int dom_ptr_count)
+{
+        int i;
+        int rc;
+        CMPIStatus s = {CMPI_RC_OK, NULL};
+
+        *dom_xml_list = calloc(dom_ptr_count, sizeof(struct dom_xml));
+        for (i = 0; i < dom_ptr_count; i++) {
+                rc = virDomainGetUUIDString(dom_ptr_list[i], 
+                                            (*dom_xml_list)[i].uuid);
+                if (rc == -1) {
+                        cu_statusf(_BROKER, &s, 
+                                   CMPI_RC_ERR_FAILED,
+                                   "Failed to get UUID");
+                        /* If any domain fails, we fail. */
+                        break;
+                }
+
+                (*dom_xml_list)[i].xml = virDomainGetXMLDesc(dom_ptr_list[i], 
+                                                             0);
+                if ((*dom_xml_list)[i].xml == NULL) {
+                        cu_statusf(_BROKER, &s, 
+                                   CMPI_RC_ERR_FAILED,
+                                   "Failed to get xml desc");
+                        break;
+                }
+        }
+        
+        return s;
+}
+
+static bool dom_changed(struct dom_xml prev_dom, 
+                        struct dom_xml *cur_xml, 
+                        int cur_count)
+{
+        int i;
+        bool ret = false;
+        
+        for (i = 0; i < cur_count; i++) {
+                if (strcmp(cur_xml[i].uuid, prev_dom.uuid) != 0)
+                        continue;
+                
+                if (strcmp(cur_xml[i].xml, prev_dom.xml) != 0)
+                        ret = true;
+
+                break;
+        }
+        
+        return ret;
+}
+
 static bool _lifecycle_indication(const CMPIBroker *broker,
                                   const CMPIContext *ctx,
                                   const CMPIObjectPath *newsystem,
@@ -97,6 +199,45 @@ static bool _lifecycle_indication(const 
                             NAMESPACE(newsystem),
                             ind);
 
+
+        return true;
+}
+
+static bool _do_modified_indication(const CMPIBroker *broker,
+                                    const CMPIContext *ctx,
+                                    CMPIInstance *mod_inst,
+                                    char *prefix,
+                                    char *ns)
+{
+        CMPIObjectPath *ind_op;
+        CMPIInstance *ind;
+        CMPIStatus s;
+
+        ind = get_typed_instance(broker,
+                                 prefix,
+                                 "ComputerSystemModifiedIndication",
+                                 ns);
+        if (ind == NULL) {
+                CU_DEBUG("Failed to create ind");
+                return false;
+        }
+
+        ind_op = CMGetObjectPath(ind, &s);
+        if (s.rc != CMPI_RC_OK) {
+                CU_DEBUG("Failed to get ind_op");
+                return false;
+        }
+
+        CMSetProperty(ind, "PreviousInstance",
+                      (CMPIValue *)&mod_inst, CMPI_instance);
+
+        CU_DEBUG("Delivering Indication: %s\n",
+                 CMGetCharPtr(CMObjectPathToString(ind_op, NULL)));
+
+        CBDeliverIndication(_BROKER,
+                            ctx,
+                            CIM_VIRT_NS,
+                            ind);
 
         return true;
 }
@@ -177,17 +318,56 @@ static bool async_ind(CMPIContext *conte
         return _lifecycle_indication(_BROKER, context, op, type_name);
 }
 
+static bool mod_ind(CMPIContext *context,
+                    virConnectPtr conn,
+                    struct dom_xml prev_dom,
+                    char *prefix,
+                    char *ns)
+{
+        bool rc;
+        char *name = NULL;
+        CMPIInstance *mod_inst;
+
+        mod_inst = get_typed_instance(_BROKER,
+                                      prefix,
+                                      "ComputerSystem",
+                                      ns);
+
+        name = sys_name_from_xml(prev_dom.xml);
+        CU_DEBUG("Name for system: '%s'", name);
+        if (name == NULL) {
+                rc = false;
+                goto out;
+        }
+
+        CMSetProperty(mod_inst, "Name", 
+                      (CMPIValue *)name, CMPI_chars);
+        CMSetProperty(mod_inst, "UUID",
+                      (CMPIValue *)prev_dom.uuid, CMPI_chars);
+
+        rc = _do_modified_indication(_BROKER, context, mod_inst, prefix, ns);
+
+ out:
+        free(name);
+        return rc;
+}
+
 static CMPI_THREAD_RETURN lifecycle_thread(void *params)
 {
-        CMPIContext *context = (CMPIContext *)params;
+        struct ind_args *args = (struct ind_args *)params;
+        CMPIContext *context = args->context;
         CMPIStatus s;
         int prev_count;
         int cur_count;
         virDomainPtr *prev_list;
         virDomainPtr *cur_list;
+        struct dom_xml *cur_xml = NULL;
+        struct dom_xml *prev_xml = NULL;
         virConnectPtr conn;
+        char *prefix = class_prefix_name(args->classname);
+        char *ns = args->ns;
 
-        conn = lv_connect(_BROKER, &s);
+        conn = connect_by_classname(_BROKER, args->classname, &s);
         if (conn == NULL) {
                 CU_DEBUG("Failed to connect: %s", CMGetCharPtr(s.msg));
                 return NULL;
@@ -198,12 +378,20 @@ static CMPI_THREAD_RETURN lifecycle_thre
         CBAttachThread(_BROKER, context);
 
         prev_count = get_domain_list(conn, &prev_list);
+        s = doms_to_xml(&prev_xml, prev_list, prev_count);
+        if (s.rc != CMPI_RC_OK)
+                CU_DEBUG("doms_to_xml failed.  Attempting to continue.");
 
+
+        CU_DEBUG("entering event loop");
         while (lifecycle_enabled) {
                 int i;
                 bool res;
 
                 cur_count = get_domain_list(conn, &cur_list);
+                s = doms_to_xml(&cur_xml, cur_list, cur_count);
+                if (s.rc != CMPI_RC_OK)
+                        CU_DEBUG("doms_to_xml failed.");
 
                 for (i = 0; i < cur_count; i++) {
                         res = dom_in_list(cur_list[i], prev_count, prev_list);
@@ -221,15 +409,34 @@ static CMPI_THREAD_RETURN lifecycle_thre
                                           conn,
                                           virDomainGetName(prev_list[i]),
                                           CS_DELETED);
-                        virDomainFree(prev_list[i]);
                 }
 
+                for (i = 0; i < prev_count; i++) {
+                        res = dom_changed(prev_xml[i], cur_xml, cur_count);
+                        if (res) {
+                                CU_DEBUG("Domain '%s' modified.", prev_xml[i].uuid);
+                                mod_ind(context, conn, prev_xml[i], prefix, ns);
+                        }
+                        free_dom_xml(prev_xml[i]);
+                }
+
+                cleanup_domain_list(prev_list, prev_count);
+
                 free(prev_list);
+                free(prev_xml);
                 prev_list = cur_list;
+                prev_xml = cur_xml;
                 prev_count = cur_count;
 
                 wait_for_event();
         }
+        pthread_mutex_unlock(&lifecycle_mutex);
+        free_ind_args(*args);
+        free(prefix);
+        virConnectClose(conn);
+        /* Should I free args as well here, since it's malloced in activate? */
+
+        lifecycle_thread_id = 0;
 
         return NULL;
 }
@@ -241,17 +448,29 @@ static CMPIStatus ActivateFilter(CMPIInd
                                  const CMPIObjectPath* op,
                                  CMPIBoolean first)
 {
+        CU_DEBUG("ActivateFilter");
+        CMPIStatus s = {CMPI_RC_OK, NULL};
+        struct ind_args *args = malloc(sizeof(struct ind_args));
+
+        if (CMIsNullObject(op)) {
+                cu_statusf(_BROKER, &s, 
+                           CMPI_RC_ERR_FAILED,
+                           "No ObjectPath given");
+                goto out;
+        }
+        args->ns = strdup(NAMESPACE(op));
+        args->classname = strdup(CLASSNAME(op));
+
         if (lifecycle_thread_id == 0) {
-                CMPIContext *thread_context;
-
-                thread_context = CBPrepareAttachThread(_BROKER, ctx);
+                args->context = CBPrepareAttachThread(_BROKER, ctx);
 
                 lifecycle_thread_id = _BROKER->xft->newThread(lifecycle_thread,
-                                                              thread_context,
+                                                              args,
                                                               0);
         }
 
-        return (CMPIStatus){CMPI_RC_OK, NULL};
+ out:
+        return s;
 }
 
 static CMPIStatus DeActivateFilter(CMPIIndicationMI* mi,




More information about the Libvirt-cim mailing list