[Libvirt-cim] [PATCH] Add write support for FilterList and NestedFilterList

Chip Vincent cvincent at linux.vnet.ibm.com
Tue Jun 28 14:26:19 UTC 2011


Disregard.. Found some issues. Will post a version shortly.

On 06/27/2011 06:35 PM, Chip Vincent wrote:
> # HG changeset patch
> # User Chip Vincent<cvincent at us.ibm.com>
> # Date 1309213800 14400
> # Node ID 03e3f95547078be19d8d22cac83ce38daf7510b9
> # Parent  75411f53df02159c3fa6ce5810c9446579e3d66d
> Add write support for FilterList and NestedFilterList
>
> This allows clients to create new filter lists and then associate them
> with other filter lists to create complex filters. This patch also has some
> minor bug fixes to AppliedFilterList so the new filters can be applied
> to existing NetworkPort instances. The new cimtests for the create/delete
> associations are still under construction, but you can easily test
> FilterList create/delete (foundation) with the following commands:
>
> # wbemcli ci 'http://localhost:5988/root/virt:KVM_FilterList.CreationClassName="",Name="",SystemCreationClassName="",SystemName=""' 'Name="test"'
>
> # wbemcli di 'http://localhost:5988/root/virt:KVM_FilterList.CreationClassName="KVM_FilterList",Name="test",SystemCreationClassName="KVM_HostSystem",SystemName="oc0840652111.ibm.com"'
>
> Signed-off-by: Chip Vincent<cvincent at us.ibm.com>
>
> diff --git a/libxkutil/acl_parsing.c b/libxkutil/acl_parsing.c
> --- a/libxkutil/acl_parsing.c
> +++ b/libxkutil/acl_parsing.c
> @@ -551,6 +551,57 @@
>   #endif
>   }
>
> +int create_filter(virConnectPtr conn, struct acl_filter *filter)
> +{
> +        virNWFilterPtr vfilter = NULL;
> +        char *xml = NULL;
> +
> +        if (filter == NULL)
> +                return 0;
> +
> +        xml = filter_to_xml(filter);
> +        if (xml == NULL)
> +                return 0;
> +
> +        vfilter = virNWFilterDefineXML(conn, xml);
> +
> +        free(xml);
> +
> +        if (vfilter == NULL)
> +                return 0;
> +
> +        virNWFilterFree(vfilter);
> +
> +        return 1;
> +}
> +
> +int update_filter(virConnectPtr conn, struct acl_filter *filter)
> +{
> +        if (delete_filter(conn, filter) == 0 ||
> +                create_filter(conn, filter) == 0)
> +                return 0;
> +
> +        return 1;
> +}
> +
> +int delete_filter(virConnectPtr conn, struct acl_filter *filter)
> +{
> +        virNWFilterPtr vfilter = NULL;
> +
> +        if (filter == NULL)
> +                return 0;
> +
> +        vfilter = virNWFilterLookupByUUIDString(conn, filter->uuid);
> +        if (vfilter == NULL)
> +                return 0;
> +
> +        if (virNWFilterUndefine(vfilter) != 0) {
> +                virNWFilterFree(vfilter);
> +                return 0;
> +        }
> +
> +        return 1;
> +}
>
>   int append_filter_rule(struct acl_filter *filter, struct acl_rule *rule)
>   {
> @@ -605,6 +656,28 @@
>           return 1;
>   }
>
> +int remove_filter_ref(struct acl_filter *filter, const char *name)
> +{
> +        int i;
> +        char **old_refs = NULL;
> +
> +        if ((filter == NULL) || (name == NULL))
> +                return 0;
> +
> +        /* TODO: called infrequently, but needs optimization */
> +        old_refs = filter->refs;
> +
> +        for (i = 0; i<  filter->ref_ct; i++) {
> +                if (STREQC(old_refs[i], name)) {
> +                        free(old_refs[i]);
> +                }
> +                else
> +                        append_filter_ref(filter, old_refs[i]);
> +        }
> +
> +        return 1;
> +}
> +
>   char *make_rule_id(const char *filter, int index)
>   {
>           int ret;
> diff --git a/libxkutil/acl_parsing.h b/libxkutil/acl_parsing.h
> --- a/libxkutil/acl_parsing.h
> +++ b/libxkutil/acl_parsing.h
> @@ -194,11 +194,17 @@
>   char *make_rule_id(const char *filter, int index);
>   int parse_rule_id(const char *rule_id, char **filter, int *index);
>
> +int create_filter(virConnectPtr conn, struct acl_filter *filter);
> +int update_filter(virConnectPtr conn, struct acl_filter *filter);
> +int delete_filter(virConnectPtr conn, struct acl_filter *filter);
> +
>   /** NOTE: Both append functions take parameters allocated by caller and
>    *  freed by cleanup_filter(s)
>    */
>   int append_filter_rule(struct acl_filter *filter, struct acl_rule *rule);
>   int append_filter_ref(struct acl_filter *filter, char *name);
> +int remove_filter_ref(struct acl_filter *filter, const char *name);
> +
>   #endif
>
>   /*
> diff --git a/libxkutil/xmlgen.c b/libxkutil/xmlgen.c
> --- a/libxkutil/xmlgen.c
> +++ b/libxkutil/xmlgen.c
> @@ -1360,6 +1360,59 @@
>           return xml;
>   }
>
> +char *filter_to_xml(struct acl_filter *filter)
> +{
> +        char *msg = XML_ERROR;
> +        char *xml = NULL;
> +        xmlNodePtr root = NULL;
> +        xmlNodePtr tmp = NULL;
> +        int i;
> +
> +        root = xmlNewNode(NULL, BAD_CAST "filter");
> +        if (root == NULL)
> +                goto out;
> +
> +        if (xmlNewProp(root, BAD_CAST "name", BAD_CAST filter->name) == NULL)
> +                goto out;
> +
> +        if (filter->chain != NULL)
> +                if (xmlNewProp(root, BAD_CAST "chain",
> +                        BAD_CAST filter->chain) == NULL)
> +                        goto out;
> +
> +        if (filter->uuid != NULL) {
> +                tmp = xmlNewChild(root, NULL, BAD_CAST "uuid", NULL);
> +                if (xmlNewProp(tmp, NULL, BAD_CAST filter->uuid) == NULL)
> +                        goto out;
> +        }
> +
> +        for (i = 0; i<  filter->ref_ct; i++) {
> +                tmp = xmlNewChild(root, NULL, BAD_CAST "filterref", NULL);
> +                if (xmlNewProp(tmp, BAD_CAST "filter",
> +                        BAD_CAST filter->refs[i]) == NULL)
> +                        goto out;
> +        }
> +
> +        /* TODO: Not yet supported
> +        for (i = 0; i<  filter->rule_ct; i++) {
> +                msg = rule_to_xml(root, filter->rules[i]);
> +                if (msg != NULL)
> +                        goto out;
> +        }
> +        */
> +
> +        xml = tree_to_xml(root);
> +        if (xml != NULL)
> +                msg = NULL; /* no errors */
> +
> + out:
> +        CU_DEBUG("Filter XML: %s", msg);
> +
> +        xmlFreeNode(root);
> +
> +        return xml;
> +}
> +
>   /*
>    * Local Variables:
>    * mode: C
> diff --git a/schema/NestedFilterList.registration b/schema/NestedFilterList.registration
> --- a/schema/NestedFilterList.registration
> +++ b/schema/NestedFilterList.registration
> @@ -1,3 +1,3 @@
>   # Copyright IBM Corp. 2011
>   # Classname Namespace ProviderName ProviderModule ProviderTypes
> -KVM_NestedFilterList root/virt Virt_NestedFilterList Virt_NestedFilterList association
> +KVM_NestedFilterList root/virt Virt_NestedFilterList Virt_NestedFilterList instance association
> diff --git a/src/Virt_AppliedFilterList.c b/src/Virt_AppliedFilterList.c
> --- a/src/Virt_AppliedFilterList.c
> +++ b/src/Virt_AppliedFilterList.c
> @@ -411,10 +411,6 @@
>           libvirt_cim_init(),
>           handlers);
>
> -DEFAULT_GI();
> -DEFAULT_EIN();
> -DEFAULT_EI();
> -
>   static CMPIStatus CreateInstance(
>           CMPIInstanceMI *self,
>           const CMPIContext *context,
> @@ -434,6 +430,8 @@
>           virConnectPtr conn = NULL;
>           virDomainPtr dom = NULL;
>
> +        CU_DEBUG("Reference = %s", REF2STR(reference));
> +
>           if (cu_get_ref_prop(instance, "Antecedent",
>                   &antecedent) != CMPI_RC_OK) {
>                   cu_statusf(_BROKER,&s,
> @@ -473,6 +471,8 @@
>                   goto out;
>           }
>
> +        CU_DEBUG("DeviceID = %s", device_name);
> +
>           if (parse_fq_devid(device_name,&domain_name,&net_name) == 0) {
>                   CU_DEBUG("Failed to parse devid");
>                   goto out;
> @@ -492,7 +492,11 @@
>                   goto out;
>           }
>
> -        free(device->dev.net.filter_ref);
> +        if (device->dev.net.filter_ref != NULL) {
> +                free(device->dev.net.filter_ref);
> +                device->dev.net.filter_ref = NULL;
> +        }
> +
>           device->dev.net.filter_ref = strdup(filter_name);
>
>           if (update_device(dom, device) == 0) {
> @@ -502,10 +506,10 @@
>                   goto out;
>           }
>
> +        CU_DEBUG("CreateInstance complete");
> +
>    out:
> -        free((char *)filter_name);
>           free(domain_name);
> -        free((char *)device_name);
>           free(net_name);
>
>           cleanup_filter(filter);
> @@ -535,6 +539,8 @@
>           virConnectPtr conn = NULL;
>           virDomainPtr dom = NULL;
>
> +        CU_DEBUG("Reference = %s", REF2STR(reference));
> +
>           if (cu_get_ref_path(reference, "Antecedent",
>                   &antecedent) != CMPI_RC_OK) {
>                   cu_statusf(_BROKER,&s,
> @@ -574,6 +580,8 @@
>                   goto out;
>           }
>
> +        CU_DEBUG("DeviceID = %s", device_name);
> +
>           if (parse_fq_devid(device_name,&domain_name,&net_name) == 0) {
>                   CU_DEBUG("Failed to parse devid");
>                   goto out;
> @@ -593,8 +601,10 @@
>                   goto out;
>           }
>
> -        free(device->dev.net.filter_ref);
> -        device->dev.net.filter_ref = NULL;
> +        if (device->dev.net.filter_ref != NULL) {
> +                free(device->dev.net.filter_ref);
> +                device->dev.net.filter_ref = NULL;
> +        }
>
>           if (update_device(dom, device) == 0) {
>                   cu_statusf(_BROKER,&s,
> @@ -603,10 +613,10 @@
>                   goto out;
>           }
>
> +        CU_DEBUG("CreateInstance complete");
> +
>    out:
> -        free((char *)filter_name);
>           free(domain_name);
> -        free((char *)device_name);
>           free(net_name);
>
>           cleanup_filter(filter);
> @@ -618,12 +628,15 @@
>           return s;
>   }
>
> +DEFAULT_GI();
> +DEFAULT_EIN();
> +DEFAULT_EI();
>   DEFAULT_MI();
>   DEFAULT_EQ();
>   DEFAULT_INST_CLEANUP();
>
>   STD_InstanceMIStub(,
> -        Virt_AppliedFilterEntry,
> +        Virt_AppliedFilterList,
>           _BROKER,
>           libvirt_cim_init());
>
> diff --git a/src/Virt_FilterList.c b/src/Virt_FilterList.c
> --- a/src/Virt_FilterList.c
> +++ b/src/Virt_FilterList.c
> @@ -81,6 +81,32 @@
>           return inst;
>   }
>
> +static struct acl_filter *convert_instance_to_filter(
> +        const CMPIInstance *instance,
> +        const CMPIContext *context,
> +        CMPIStatus *s)
> +{
> +        struct acl_filter *filter = NULL;
> +        const char *name = NULL;
> +
> +        if (cu_get_str_prop(instance, "Name",&name) != CMPI_RC_OK) {
> +                cu_statusf(_BROKER, s,
> +                           CMPI_RC_ERR_FAILED,
> +                           "Unable to get Name property");
> +                goto out;
> +        }
> +
> +        filter = malloc(sizeof(*filter));
> +        if (filter == NULL)
> +                goto out;
> +
> +        memset(filter, 0, sizeof(*filter));
> +        filter->name = strdup(name);
> +
> + out:
> +        return filter;
> +}
> +
>   CMPIStatus enum_filter_lists(const CMPIBroker *broker,
>                           const CMPIContext *context,
>                           const CMPIObjectPath *reference,
> @@ -230,9 +256,114 @@
>           return s;
>   }
>
> -DEFAULT_CI();
> +static CMPIStatus CreateInstance(
> +        CMPIInstanceMI *self,
> +        const CMPIContext *context,
> +        const CMPIResult *results,
> +        const CMPIObjectPath *reference,
> +        const CMPIInstance *instance)
> +{
> +        CMPIStatus s = {CMPI_RC_OK, NULL};
> +        const char *name = NULL;
> +        struct acl_filter *filter = NULL;
> +        CMPIInstance *_instance = NULL;
> +        virConnectPtr conn = NULL;
> +
> +        /**Get Name from instance rather than reference since keys
> +         * are set by this provider, not the client.
> +         */
> +        if (cu_get_str_prop(instance, "Name",&name) != CMPI_RC_OK) {
> +                cu_statusf(_BROKER,&s,
> +                           CMPI_RC_ERR_FAILED,
> +                           "Unable to get Name property");
> +                goto out;
> +        }
> +
> +        conn = connect_by_classname(_BROKER, CLASSNAME(reference),&s);
> +        if (conn == NULL)
> +                goto out;
> +
> +        get_filter_by_name(conn, name,&filter);
> +        if (filter != NULL) {
> +                cu_statusf(_BROKER,&s,
> +                        CMPI_RC_ERR_ALREADY_EXISTS,
> +                        "Instance already exists");
> +                goto out;
> +        }
> +
> +        filter = convert_instance_to_filter(instance, context,&s);
> +        if (filter == NULL) {
> +                cu_statusf(_BROKER,&s,
> +                        CMPI_RC_ERR_FAILED,
> +                        "Failed to convert instance to filter");
> +                goto out;
> +        }
> +
> +        if (create_filter(conn, filter) == 0) {
> +                cu_statusf(_BROKER,&s,
> +                        CMPI_RC_ERR_FAILED,
> +                        "Failed to create filter");
> +                goto out;
> +        }
> +
> +        _instance = convert_filter_to_instance(filter,
> +                                        _BROKER,
> +                                        context,
> +                                        reference,
> +&s);
> +
> +        if(_instance != NULL)
> +                cu_return_instance_name(results, _instance);
> +
> +        CU_DEBUG("CreateInstance complete");
> +
> + out:
> +        cleanup_filter(filter);
> +        virConnectClose(conn);
> +
> +        return s;
> +}
> +
> +static CMPIStatus DeleteInstance(
> +        CMPIInstanceMI *self,
> +        const CMPIContext *context,
> +        const CMPIResult *results,
> +        const CMPIObjectPath *reference)
> +{
> +        CMPIStatus s = {CMPI_RC_OK, NULL};
> +        const char *name = NULL;
> +        struct acl_filter *filter = NULL;
> +        virConnectPtr conn = NULL;
> +
> +        if (cu_get_str_path(reference, "Name",&name) != CMPI_RC_OK) {
> +                cu_statusf(_BROKER,&s,
> +                        CMPI_RC_ERR_NOT_FOUND,
> +                        "Unable to get Name from reference");
> +                goto out;
> +        }
> +
> +        conn = connect_by_classname(_BROKER, CLASSNAME(reference),&s);
> +        if (conn == NULL)
> +                goto out;
> +
> +        get_filter_by_name(conn, name,&filter);
> +        if (filter == NULL) {
> +                cu_statusf(_BROKER,&s,
> +                        CMPI_RC_ERR_NOT_FOUND,
> +                        "Instance does not exist");
> +                goto out;
> +        }
> +
> +        delete_filter(conn, filter);
> +
> + out:
> +        cleanup_filter(filter);
> +        virConnectClose(conn);
> +
> +        return s;
> +}
> +
>   DEFAULT_MI();
> -DEFAULT_DI();
>   DEFAULT_EQ();
>   DEFAULT_INST_CLEANUP();
>
> diff --git a/src/Virt_NestedFilterList.c b/src/Virt_NestedFilterList.c
> --- a/src/Virt_NestedFilterList.c
> +++ b/src/Virt_NestedFilterList.c
> @@ -38,6 +38,71 @@
>
>   static const CMPIBroker *_BROKER;
>
> +/* TODO: Port to libcmpiutil/args_util.c */
> +/**
> + * Get a reference property of an instance
> + *
> + * @param inst The instance
> + * @param prop The property name
> + * @param reference A pointer to a CMPIObjectPath* that will be set
> + *                  if successful
> + * @returns
> + *      - CMPI_RC_OK on success
> + *      - CMPI_RC_ERR_NO_SUCH_PROPERTY if prop is not present
> + *      - CMPI_RC_ERR_TYPE_MISMATCH if prop is not a reference
> + *      - CMPI_RC_OK otherwise
> + */
> +static CMPIrc cu_get_ref_prop(const CMPIInstance *instance,
> +                              const char *prop,
> +                              CMPIObjectPath **reference)
> +{
> +        CMPIStatus s = {CMPI_RC_OK, NULL};
> +        CMPIData value;
> +
> +        /* REQUIRE_PROPERY_DEFINED(instance, prop, value,&s); */
> +        value = CMGetProperty(instance, prop,&s);
> +        if ((s.rc != CMPI_RC_OK) || CMIsNullValue(value))
> +                return CMPI_RC_ERR_NO_SUCH_PROPERTY;
> +
> +        if ((value.type != CMPI_ref) ||  CMIsNullObject(value.value.ref))
> +                return CMPI_RC_ERR_TYPE_MISMATCH;
> +
> +        *reference = value.value.ref;
> +
> +        return CMPI_RC_OK;
> +}
> +
> +/* TODO: Port to libcmpiutil/args_util.c */
> +/**
> + * Get a reference component of an object path
> + *
> + * @param _reference The reference
> + * @param key The key name
> + * @param reference A pointer to a CMPIObjectPath* that will be set
> + *                  if successful
> + * @returns
> + *      - CMPI_RC_OK on success
> + *      - CMPI_RC_ERR_NO_SUCH_PROPERTY if prop is not present
> + *      - CMPI_RC_ERR_TYPE_MISMATCH if prop is not a reference
> + *      - CMPI_RC_OK otherwise
> + */
> +static CMPIrc cu_get_ref_path(const CMPIObjectPath *reference,
> +                              const char *key,
> +                              CMPIObjectPath **_reference)
> +{
> +        CMPIStatus s = {CMPI_RC_OK, NULL};
> +        CMPIData value;
> +
> +        /* REQUIRE_PROPERY_DEFINED(instance, prop, value,&s); */
> +        value = CMGetKey(reference, key,&s);
> +        if ((s.rc != CMPI_RC_OK) || CMIsNullValue(value))
> +                return CMPI_RC_ERR_NO_SUCH_PROPERTY;
> +
> +        /* how to parse and object path? */
> +
> +        return CMPI_RC_OK;
> +}
> +
>   /**
>    *  given a filter, find all *direct* filter_refs
>    */
> @@ -224,6 +289,203 @@
>           libvirt_cim_init(),
>           handlers);
>
> +DEFAULT_GI();
> +DEFAULT_EIN();
> +DEFAULT_EI();
> +
> +static CMPIStatus CreateInstance(
> +        CMPIInstanceMI *self,
> +        const CMPIContext *context,
> +        const CMPIResult *results,
> +        const CMPIObjectPath *reference,
> +        const CMPIInstance *instance)
> +{
> +        CMPIStatus s = {CMPI_RC_OK, NULL};
> +        CMPIObjectPath *antecedent = NULL;
> +        const char *parent_name = NULL;
> +        struct acl_filter *parent_filter = NULL;
> +        CMPIObjectPath *dependent = NULL;
> +        const char *child_name = NULL;
> +        struct acl_filter *child_filter = NULL;
> +        virConnectPtr conn = NULL;
> +
> +        CU_DEBUG("Reference = %s", REF2STR(reference));
> +
> +        conn = connect_by_classname(_BROKER, CLASSNAME(reference),&s);
> +        if (conn == NULL)
> +                goto out;
> +
> +        if (cu_get_ref_prop(instance, "Antecedent",
> +&antecedent) != CMPI_RC_OK) {
> +                cu_statusf(_BROKER,&s,
> +                        CMPI_RC_ERR_FAILED,
> +                        "Unable to get Antecedent property");
> +                goto out;
> +        }
> +
> +        if (cu_get_str_path(reference, "Name",&parent_name) != CMPI_RC_OK) {
> +                cu_statusf(_BROKER,&s,
> +                        CMPI_RC_ERR_FAILED,
> +                        "Unable to get Antecedent.Name property");
> +                goto out;
> +        }
> +
> +        get_filter_by_name(conn, parent_name,&parent_filter);
> +        if (parent_filter == NULL) {
> +                cu_statusf(_BROKER,&s,
> +                        CMPI_RC_ERR_FAILED,
> +                        "Antecedent.Name object does not exist");
> +                goto out;
> +        }
> +
> +        if (cu_get_ref_prop(instance, "Dependent",
> +&dependent) != CMPI_RC_OK) {
> +                cu_statusf(_BROKER,&s,
> +                        CMPI_RC_ERR_FAILED,
> +                        "Unable to get Dependent property");
> +                goto out;
> +        }
> +
> +        if (cu_get_str_path(reference, "Name",&child_name) != CMPI_RC_OK) {
> +                cu_statusf(_BROKER,&s,
> +                        CMPI_RC_ERR_FAILED,
> +                        "Unable to get Dependent.Name property");
> +                goto out;
> +        }
> +
> +        get_filter_by_name(conn, child_name,&child_filter);
> +        if (child_filter == NULL) {
> +                cu_statusf(_BROKER,&s,
> +                        CMPI_RC_ERR_FAILED,
> +                        "Dependent.Name object does not exist");
> +                goto out;
> +        }
> +
> +        if (append_filter_ref(parent_filter, strdup(child_name)) == 0) {
> +                free(dup);
> +                cu_statusf(_BROKER,&s,
> +                        CMPI_RC_ERR_FAILED,
> +                        "Failed to append filter reference");
> +                goto out;
> +        }
> +
> +        if (update_filter(conn, parent_filter) == 0) {
> +                cu_statusf(_BROKER,&s,
> +                        CMPI_RC_ERR_FAILED,
> +                        "Failed to update filter");
> +                goto out;
> +        }
> +
> +        CU_DEBUG("CreateInstance completed");
> +
> + out:
> +        cleanup_filter(parent_filter);
> +        cleanup_filter(child_filter);
> +        virConnectClose(conn);
> +
> +        return s;
> +}
> +
> +static CMPIStatus DeleteInstance(
> +        CMPIInstanceMI *self,
> +        const CMPIContext *context,
> +        const CMPIResult *results,
> +        const CMPIObjectPath *reference)
> +{
> +        CMPIStatus s = {CMPI_RC_OK, NULL};
> +        CMPIObjectPath *antecedent = NULL;
> +        const char *parent_name = NULL;
> +        struct acl_filter *parent_filter = NULL;
> +        CMPIObjectPath *dependent = NULL;
> +        const char *child_name = NULL;
> +        struct acl_filter *child_filter = NULL;
> +        virConnectPtr conn = NULL;
> +
> +        CU_DEBUG("Reference = %s", REF2STR(reference));
> +
> +        conn = connect_by_classname(_BROKER, CLASSNAME(reference),&s);
> +        if (conn == NULL)
> +                goto out;
> +
> +        if (cu_get_ref_path(reference, "Antecedent",
> +&antecedent) != CMPI_RC_OK) {
> +                cu_statusf(_BROKER,&s,
> +                        CMPI_RC_ERR_FAILED,
> +                        "Unable to get Antecedent property");
> +                goto out;
> +        }
> +
> +        if (cu_get_str_path(reference, "Name",&parent_name) != CMPI_RC_OK) {
> +                cu_statusf(_BROKER,&s,
> +                        CMPI_RC_ERR_FAILED,
> +                        "Unable to get Antecedent.Name property");
> +                goto out;
> +        }
> +
> +        get_filter_by_name(conn, parent_name,&parent_filter);
> +        if (parent_filter == NULL) {
> +                cu_statusf(_BROKER,&s,
> +                        CMPI_RC_ERR_FAILED,
> +                        "Antecedent.Name object does not exist");
> +                goto out;
> +        }
> +
> +        if (cu_get_ref_path(reference, "Dependent",
> +&dependent) != CMPI_RC_OK) {
> +                cu_statusf(_BROKER,&s,
> +                        CMPI_RC_ERR_FAILED,
> +                        "Unable to get Dependent property");
> +                goto out;
> +        }
> +
> +        if (cu_get_str_path(reference, "Name",&child_name) != CMPI_RC_OK) {
> +                cu_statusf(_BROKER,&s,
> +                        CMPI_RC_ERR_FAILED,
> +                        "Unable to get Dependent.Name property");
> +                goto out;
> +        }
> +
> +        get_filter_by_name(conn, child_name,&child_filter);
> +        if (child_filter == NULL) {
> +                cu_statusf(_BROKER,&s,
> +                        CMPI_RC_ERR_FAILED,
> +                        "Dependent.Name object does not exist");
> +                goto out;
> +        }
> +
> +        if (remove_filter_ref(parent_filter, child_name) == 0) {
> +                cu_statusf(_BROKER,&s,
> +                        CMPI_RC_ERR_FAILED,
> +                        "Failed to remove filter reference");
> +                goto out;
> +        }
> +
> +        if (update_filter(conn, parent_filter) == 0) {
> +                cu_statusf(_BROKER,&s,
> +                        CMPI_RC_ERR_FAILED,
> +                        "Failed to update filter");
> +                goto out;
> +        }
> +
> +        CU_DEBUG("CreateInstance completed");
> +
> + out:
> +        cleanup_filter(parent_filter);
> +        cleanup_filter(child_filter);
> +        virConnectClose(conn);
> +
> +        return s;
> +}
> +
> +DEFAULT_MI();
> +DEFAULT_EQ();
> +DEFAULT_INST_CLEANUP();
> +
> +STD_InstanceMIStub(,
> +        Virt_NestedFilterList,
> +        _BROKER,
> +        libvirt_cim_init());
> +
>   /*
>    * Local Variables:
>    * mode: C
>
> _______________________________________________
> Libvirt-cim mailing list
> Libvirt-cim at redhat.com
> https://www.redhat.com/mailman/listinfo/libvirt-cim

-- 
Chip Vincent
Open Virtualization
IBM Linux Technology Center
cvincent at linux.vnet.ibm.com




More information about the Libvirt-cim mailing list