# HG changeset patch
# User snmishra@us.ibm.com
# Date 1252601888 25200
# Node ID c3163e536ea95f2b846eca4ca2a3cefd4ae6a4a7
# Parent  234141bf7f0368531c884334b1da5b94cc038758
Virt_VirtualSystemManagementService updated to add support for resource indication provider.

Signed-off-by: Sharad Misrha <snmishra@us.ibm.com>

diff -r 234141bf7f03 -r c3163e536ea9 src/Virt_VirtualSystemManagementService.c
--- a/src/Virt_VirtualSystemManagementService.c Thu Sep 03 12:52:47 2009 -0700
+++ b/src/Virt_VirtualSystemManagementService.c Thu Sep 10 09:58:08 2009 -0700
@@ -63,6 +63,9 @@
#define BRIDGE_TYPE "bridge"
#define NETWORK_TYPE "network"
#define USER_TYPE "user"
+#define CREATED "ResourceAllocationSettingDataCreatedIndication"
+#define DELETED "ResourceAllocationSettingDataDeletedIndication"
+#define MODIFIED "ResourceAllocationSettingDataModifiedIndication"

const static CMPIBroker *_BROKER;

@@ -442,7 +445,7 @@
        ret = cu_get_str_prop(inst, "VirtualSystemIdentifier", &val);
        if (ret != CMPI_RC_OK)
                goto out;
-
+        
        free(domain->name);
        domain->name = strdup(val);

@@ -1416,7 +1419,69 @@
        return s;
}

-static CMPIInstance *create_system(CMPIInstance *vssd,
+static CMPIStatus raise_rasd_indication(const CMPIContext *context,
+                                        const char *base_type,
+                                        CMPIInstance *prev_inst,
+                                        const CMPIObjectPath *ref,
+                                        struct inst_list *list)
+{
+        char *type;
+        CMPIStatus s = {CMPI_RC_OK, NULL};
+        CMPIInstance *instc = NULL;
+        CMPIInstance *ind = NULL;
+        CMPIObjectPath *op = NULL;
+        int i;
+
+        CU_DEBUG("raise_rasd_indication");
+
+        type = get_typed_class(CLASSNAME(ref), base_type);
+        ind = get_typed_instance(_BROKER,
+                                 CLASSNAME(ref),
+                                 base_type,
+                                 NAMESPACE(ref));
+        if (ind == NULL)  {
+                CU_DEBUG("Failed to get indication instance");
+                s.rc = CMPI_RC_ERR_FAILED;
+                goto out;
+        }
+        
+        /* PreviousInstance is set only for modify case. */
+        if (prev_inst != NULL)
+                CMSetProperty(ind,
+                              "PreviousInstance",
+                              (CMPIValue *)&prev_inst,
+                              CMPI_instance);
+
+        for (i=0; i < list->cur; i++) {
+                instc = list->list[i];
+                op = CMGetObjectPath(instc, NULL);
+                CMPIString *str = CMGetClassName(op, NULL);
+
+                CU_DEBUG("class name is %s\n", CMGetCharsPtr(str, NULL));
+
+                CMSetProperty(ind,
+                              "SourceInstance",
+                              (CMPIValue *)&instc,
+                              CMPI_instance);
+                set_source_inst_props(_BROKER, context, ref, ind);
+
+                s = stdi_raise_indication(_BROKER,
+                                          context,
+                                          type,
+                                          NAMESPACE(ref),
+                                          ind);
+        }
+
+out:
+        free(type);
+        return s;
+
+}
+
+
+
+static CMPIInstance *create_system(const CMPIContext *context,
+                                   CMPIInstance *vssd,
                                   CMPIArray *resources,
                                   const CMPIObjectPath *ref,
                                   const CMPIObjectPath *refconf,
@@ -1427,6 +1492,9 @@
        const char *msg = NULL;
        virConnectPtr conn = NULL;
        virDomainPtr dom = NULL;
+        struct inst_list list;
+        const char *props[] = {NULL};

        struct domain *domain = NULL;

+        inst_list_init(&list);
@@ -1477,18 +1544,40 @@
        CU_DEBUG("System XML:\n%s", xml);

        inst = connect_and_create(xml, ref, s);
-        if (inst != NULL)
+        if (inst != NULL) {
                update_dominfo(domain, CLASSNAME(ref));
+
+                *s = enum_rasds(_BROKER,
+                                ref,
+                                domain->name,
+                                CIM_RES_TYPE_ALL,
+                                props,
+                                &list);
+
+                if (s->rc != CMPI_RC_OK) {
+                        CU_DEBUG("Failed to enumerate rasd\n");
+                        goto out;
+                }
+
+                raise_rasd_indication(context,
+                                      CREATED,
+                                      NULL,
+                                      ref,
+                                      &list);
+        }
+

 out:
        cleanup_dominfo(&domain);
        free(xml);
        virDomainFree(dom);
        virConnectClose(conn);
+        inst_list_free(&list);

        return inst;
}

+
static bool trigger_indication(const CMPIContext *context,
                               const char *base_type,
                               const CMPIObjectPath *ref)
@@ -1530,7 +1620,7 @@
        if (s.rc != CMPI_RC_OK)
                goto out;

-        sys = create_system(vssd, res, reference, refconf, &s);
+        sys = create_system(context, vssd, res, reference, refconf, &s);
        if (sys == NULL)
                goto out;

@@ -1564,12 +1654,15 @@
        CMPIObjectPath *sys;
        virConnectPtr conn = NULL;
        virDomainPtr dom = NULL;
+        struct inst_list list;
+        const char *props[] = {NULL};

+        inst_list_init(&list);
        conn = connect_by_classname(_BROKER,
                                    CLASSNAME(reference),
                                    &status);
        if (conn == NULL) {
-                rc = -1;
+                rc = IM_RC_NOT_SUPPORTED;
                goto error;
        }

@@ -1580,6 +1672,18 @@
        if (dom_name == NULL)
                goto error;

+        status = enum_rasds(_BROKER,
+                            reference,
+                            dom_name,
+                            CIM_RES_TYPE_ALL,
+                            props,
+                            &list);
+
+        if (status.rc != CMPI_RC_OK) {
+                CU_DEBUG("Failed to enumerate rasd");
+                goto error;
+        }
+
        dom = virDomainLookupByName(conn, dom_name);
        if (dom == NULL) {
                CU_DEBUG("No such domain `%s'", dom_name);
@@ -1605,11 +1710,17 @@

error:
        if (rc == IM_RC_SYS_NOT_FOUND)
-                virt_set_status(_BROKER, &status,
+                virt_set_status(_BROKER,
+                                &status,
                                CMPI_RC_ERR_NOT_FOUND,
                                conn,
                                "Referenced domain `%s' does not exist",
                                dom_name);
+        else if (rc == IM_RC_NOT_SUPPORTED)
+                virt_set_status(_BROKER, &status,
+                                CMPI_RC_ERR_NOT_FOUND,
+                                conn,
+                                "Unable to raise resource indication");
        else if (rc == IM_RC_FAILED)
                virt_set_status(_BROKER, &status,
                                CMPI_RC_ERR_NOT_FOUND,
@@ -1617,6 +1728,7 @@
                                "Unable to retrieve domain name");
        else if (rc == IM_RC_OK) {
                status = (CMPIStatus){CMPI_RC_OK, NULL};
+                raise_rasd_indication(context, DELETED, NULL, reference, &list);
                trigger_indication(context,
                                   "ComputerSystemDeletedIndication",
                                   reference);
@@ -1625,7 +1737,7 @@
        virDomainFree(dom);
        virConnectClose(conn);
        CMReturnData(results, &rc, CMPI_uint32);
-
+        inst_list_free(&list);
        return status;
}

@@ -2071,7 +2183,8 @@
        return s;
}

-static CMPIStatus _update_resources_for(const CMPIObjectPath *ref,
+static CMPIStatus _update_resources_for(const CMPIContext *context,
+                                        const CMPIObjectPath *ref,
                                        virDomainPtr dom,
                                        const char *devid,
                                        CMPIInstance *rasd,
@@ -2081,7 +2194,14 @@
        struct domain *dominfo = NULL;
        uint16_t type;
        char *xml = NULL;
+        char *indication = NULL;
        CMPIObjectPath *op;
+        struct inst_list list;
+        CMPIInstance  *prev_inst = NULL;
+        const char *props[] = {NULL};
+        const char *inst_id;
+        int i, ret;

+        inst_list_init(&list);
        if (!get_dominfo(dom, &dominfo)) {
                virt_set_status(_BROKER, &s,
@@ -2106,6 +2225,7 @@
                goto out;
        }

+
        s = func(dominfo, rasd, type, devid, NAMESPACE(ref));
        if (s.rc != CMPI_RC_OK) {
                CU_DEBUG("Resource transform function failed");
@@ -2116,6 +2236,54 @@
        if (xml != NULL) {
                CU_DEBUG("New XML:\n%s", xml);
                connect_and_create(xml, ref, &s);
+
+                if (func == &resource_add) {
+                        indication = strdup(CREATED);
+                }
+                else if (func == &resource_del) {
+                        indication = strdup(DELETED);
+                }
+                else {
+                        indication = strdup(MODIFIED);
+
+                        s = enum_rasds(_BROKER,
+                                       ref,
+                                       dominfo->name,
+                                       type,
+                                       props,
+                                       &list);
+                        if (s.rc != CMPI_RC_OK) {
+                                CU_DEBUG("Failed to enumerate rasd");
+                                goto out;
+                        }
+
+                        for(i=0; i < list.cur; i++) {
+                                prev_inst = list.list[i];
+                                ret = cu_get_str_prop(prev_inst,
+                                                      "InstanceID",
+                                                      &inst_id);
+
+                                if (ret != CMPI_RC_OK)
+                                        continue;
+
+                                if (STREQ(inst_id,
+                                          get_fq_devid(dominfo->name,
+                                                       (char *)devid)))
+                                        break;
+                        }
+
+                }
+
+                inst_list_init(&list);
+                if (inst_list_add(&list, rasd) == 0) {
+                        CU_DEBUG("Unable to add RASD instance to the list\n");
+                        goto out;
+                }
+                raise_rasd_indication(context,
+                                      indication,
+                                      prev_inst,
+                                      ref,
+                                      &list);
        } else {
                cu_statusf(_BROKER, &s,
                           CMPI_RC_ERR_FAILED,
@@ -2125,6 +2294,8 @@
 out:
        cleanup_dominfo(&dominfo);
        free(xml);
+        free(indication);
+        inst_list_free(&list);

        return s;
}
@@ -2153,7 +2324,8 @@
        return s;
}

-static CMPIStatus _update_resource_settings(const CMPIObjectPath *ref,
+static CMPIStatus _update_resource_settings(const CMPIContext *context,
+                                            const CMPIObjectPath *ref,
                                            const char *domain,
                                            CMPIArray *resources,
                                            const CMPIResult *results,
@@ -2208,9 +2380,14 @@
                        goto end;
                }

-                s = _update_resources_for(ref, dom, devid, inst, func);
+                s = _update_resources_for(context,
+                                          ref,
+                                          dom,
+                                          devid,
+                                          inst,
+                                          func);

-        end:
+ end:
                free(name);
                free(devid);
                virDomainFree(dom);
@@ -2310,7 +2487,9 @@
                return s;
        }

-        if (cu_get_ref_arg(argsin, "AffectedConfiguration", &sys) != CMPI_RC_OK) {
+        if (cu_get_ref_arg(argsin,
+                           "AffectedConfiguration",
+                           &sys) != CMPI_RC_OK) {
                cu_statusf(_BROKER, &s,
                           CMPI_RC_ERR_INVALID_PARAMETER,
                           "Missing AffectedConfiguration parameter");
@@ -2324,11 +2503,13 @@
                return s;
        }

-        s = _update_resource_settings(reference,
+        s = _update_resource_settings(context,
+                                      reference,
                                      domain,
                                      arr,
                                      results,
                                      resource_add);
+                
        free(domain);

        return s;
@@ -2351,7 +2532,8 @@
                return s;
        }

-        return _update_resource_settings(reference,
+        return _update_resource_settings(context,
+                                         reference,
                                         NULL,
                                         arr,
                                         results,
@@ -2384,7 +2566,8 @@
        if (s.rc != CMPI_RC_OK)
                goto out;

-        s = _update_resource_settings(reference,
+        s = _update_resource_settings(context,
+                                      reference,
                                      NULL,
                                      resource_arr,
                                      results,