[PATCH 0 of 3] #2 - Enhance std association logic for reference lists and input parameter handling

This patch set fixes: - enhance the std_assoc struct to support lists for source, target and association classnames - fixed a wrong error return for a NULL handler - reworked check for input parameter: assocClass, resultClass, role, resultRole

# HG changeset patch # User Heidi Eckhart <heidieck@linux.vnet.ibm.com> # Date 1196283440 -3600 # Node ID 85f916da818a0d078d21efbb09df724e9cbf31dc # Parent 074c037c19ce46559f36a3fd06b943f5fe3c6009 Enhance handling of association's references The source and target classnames of std_assoc are now lists, containing all supported classnames. This approach frees the provider from listing all possible combinations as instances of std_assoc. Signed-off-by: Heidi Eckhart <heidieck@linux.vnet.ibm.com> diff -r 074c037c19ce -r 85f916da818a std_association.c --- a/std_association.c Tue Nov 27 16:29:13 2007 -0500 +++ b/std_association.c Wed Nov 28 21:57:20 2007 +0100 @@ -61,18 +61,44 @@ static bool match_class(const CMPIBroker static bool match_class(const CMPIBroker *broker, const char *ns, const char *test_class, - const char *comp_class) + char **comp_class_list) { CMPIObjectPath *rop; + char *comp_class; + int i; rop = CMNewObjectPath(broker, ns, test_class, NULL); - if ((test_class == NULL) || - (comp_class == NULL) || - match_op(broker, rop, comp_class)) - return true; - else - return false; + for (i = 0; comp_class_list[i]; i++) { + comp_class = comp_class_list[i]; + + if ((test_class == NULL) || + (comp_class == NULL) || + match_op(broker, rop, comp_class)) + return true; + } + + return false; +} + +static bool match_source_class(const CMPIBroker *broker, + const CMPIObjectPath *ref, + struct std_assoc *ptr) +{ + char *source_class; + int i; + + for (i = 0; ptr->source_class[i]; i++) { + source_class = ptr->source_class[i]; + + if (CMClassPathIsA(broker, + ref, + source_class, + NULL)) + return true; + } + + return false; } static CMPIStatus filter_results(struct inst_list *list, @@ -113,13 +139,13 @@ std_assoc_get_handler(const struct std_a std_assoc_get_handler(const struct std_assoc_ctx *ctx, const CMPIObjectPath *ref) { - struct std_assoc *ptr; + struct std_assoc *ptr = NULL; int i; for (i = 0; ctx->handlers[i]; i++) { ptr = ctx->handlers[i]; - if (CMClassPathIsA(ctx->brkr, ref, ptr->source_class, NULL)) + if (match_source_class(ctx->brkr, ref, ptr)) return ptr; } diff -r 074c037c19ce -r 85f916da818a std_association.h --- a/std_association.h Tue Nov 27 16:29:13 2007 -0500 +++ b/std_association.h Wed Nov 28 21:57:20 2007 +0100 @@ -37,13 +37,13 @@ typedef CMPIInstance *(*make_ref_t)(cons struct std_assoc *); struct std_assoc { - char *source_class; + char **source_class; char *source_prop; - char *target_class; + char **target_class; char *target_prop; - char *assoc_class; + char **assoc_class; assoc_handler_t handler; make_ref_t make_ref;

# HG changeset patch # User Heidi Eckhart <heidieck@linux.vnet.ibm.com> # Date 1196283441 -3600 # Node ID 53d512fbf05747b7bca5c189b0d6ab5e7e63f90b # Parent 85f916da818a0d078d21efbb09df724e9cbf31dc Removed error messages that cause wrong error returns The case that no handler was found for a request caused an error as return. This is wrong as the not-found handler tells only, that the provider is not responsible for the given request. In scenarios with a general request causing the call of several association providers that return valid instances, the former behavior causes a wrong result, as the CIMOM would return the error and revoke all valid results. Signed-off-by: Heidi Eckhart <heidieck@linux.vnet.ibm.com> diff -r 85f916da818a -r 53d512fbf057 std_association.c --- a/std_association.c Wed Nov 28 21:57:20 2007 +0100 +++ b/std_association.c Wed Nov 28 21:57:21 2007 +0100 @@ -170,9 +170,6 @@ static CMPIStatus do_assoc(struct std_as handler = std_assoc_get_handler(ctx, ref); if (handler == NULL) { CU_DEBUG("No handler found."); - cu_statusf(ctx->brkr, &s, - CMPI_RC_ERR_FAILED, - "Unable to handle this association"); goto out; } @@ -269,9 +266,7 @@ static CMPIStatus do_ref(struct std_asso handler = std_assoc_get_handler(ctx, ref); if (handler == NULL) { - cu_statusf(ctx->brkr, &s, - CMPI_RC_ERR_FAILED, - "Unable to handle this association"); + CU_DEBUG("No handler found."); goto out; }

# HG changeset patch # User Heidi Eckhart <heidieck@linux.vnet.ibm.com> # Date 1196285921 -3600 # Node ID 1936036d498363aa3ca9b9cfb773cae5ee95c339 # Parent 53d512fbf05747b7bca5c189b0d6ab5e7e63f90b Enhance handling of input parameter of std_association logic Signed-off-by: Heidi Eckhart <heidieck@linux.vnet.ibm.com> diff -r 53d512fbf057 -r 1936036d4983 std_association.c --- a/std_association.c Wed Nov 28 21:57:21 2007 +0100 +++ b/std_association.c Wed Nov 28 22:38:41 2007 +0100 @@ -67,14 +67,17 @@ static bool match_class(const CMPIBroker char *comp_class; int i; - rop = CMNewObjectPath(broker, ns, test_class, NULL); - + if (test_class == NULL) + return true; + + if (comp_class_list == NULL) + return true; + for (i = 0; comp_class_list[i]; i++) { comp_class = comp_class_list[i]; - - if ((test_class == NULL) || - (comp_class == NULL) || - match_op(broker, rop, comp_class)) + rop = CMNewObjectPath(broker, ns, comp_class, NULL); + + if (CMClassPathIsA(broker, rop, test_class, NULL)) return true; } @@ -137,18 +140,83 @@ out: static struct std_assoc * std_assoc_get_handler(const struct std_assoc_ctx *ctx, + struct std_assoc_info *info, const CMPIObjectPath *ref) { struct std_assoc *ptr = NULL; int i; + bool rc; + + CU_DEBUG("Calling Provider: '%s'", + info->provider_name); for (i = 0; ctx->handlers[i]; i++) { ptr = ctx->handlers[i]; if (match_source_class(ctx->brkr, ref, ptr)) - return ptr; - } - + break; + } + + if (!ptr) + goto out; + + if (info->assoc_class) { + CU_DEBUG("Check client's assocClass: '%s'", + info->assoc_class); + + rc = match_class(ctx->brkr, + NAMESPACE(ref), + info->assoc_class, + ptr->assoc_class); + + if (!rc) { + CU_DEBUG("AssocClass not valid."); + goto out; + } + CU_DEBUG("AssocClass valid."); + } + + if (info->result_class) { + CU_DEBUG("Check client's resultClass: '%s'", + info->result_class); + + rc = match_class(ctx->brkr, + NAMESPACE(ref), + info->result_class, + ptr->target_class); + + if (!rc) { + CU_DEBUG("ResultClass not valid."); + goto out; + } + CU_DEBUG("ResultClass valid."); + } + + if (info->role) { + CU_DEBUG("Check client's role: '%s'", + info->role); + + if (!STREQC(info->role, ptr->source_prop)) { + CU_DEBUG("Role not valid."); + goto out; + } + CU_DEBUG("Role valid."); + } + + if (info->result_role) { + CU_DEBUG("Check client's resultRole: '%s'", + info->result_role); + + if (!STREQC(info->result_role, ptr->target_prop)) { + CU_DEBUG("ResultRole not valid."); + goto out; + } + CU_DEBUG("ResultRole valid."); + } + + return ptr; + + out: return NULL; } @@ -158,57 +226,21 @@ static CMPIStatus do_assoc(struct std_as const CMPIObjectPath *ref, bool names_only) { + CMPIStatus s = {CMPI_RC_OK, NULL}; struct inst_list list; - CMPIStatus s; struct std_assoc *handler; - bool rc; inst_list_init(&list); CU_DEBUG("Getting handler..."); - - handler = std_assoc_get_handler(ctx, ref); + handler = std_assoc_get_handler(ctx, info, ref); if (handler == NULL) { CU_DEBUG("No handler found."); goto out; } - - CU_DEBUG("OK.\n\tsource: '%s'\n\ttarget: '%s'\n\tassoc_class: '%s'", - handler->source_class, - handler->target_class, - handler->assoc_class); - CU_DEBUG("Calling match_class: \n\tinfo->result_class: '%s'", - info->result_class); - - rc = match_class(ctx->brkr, - NAMESPACE(ref), - info->result_class, - handler->target_class); - if (!rc) { - CU_DEBUG("Match_class failed."); - cu_statusf(ctx->brkr, &s, - CMPI_RC_ERR_FAILED, - "Result class is not valid for this association"); - goto out; - } - CU_DEBUG("Match_class succeeded."); - - CU_DEBUG("Calling match_class: \n\tinfo->assoc_class: '%s'", - info->assoc_class); - rc = match_class(ctx->brkr, - NAMESPACE(ref), - info->assoc_class, - handler->assoc_class); - if (!rc) { - CU_DEBUG("Match_class failed."); - cu_statusf(ctx->brkr, &s, - CMPI_RC_ERR_FAILED, - "Association class given is not valid for" - "this association"); - goto out; - } - CU_DEBUG("Match_class succeeded, calling handler->handler..."); - + CU_DEBUG("Getting handler succeeded."); + + CU_DEBUG("Calling handler->handler..."); s = handler->handler(ref, info, &list); if (s.rc != CMPI_RC_OK) { @@ -256,32 +288,22 @@ static CMPIStatus do_ref(struct std_asso const CMPIObjectPath *ref, bool names_only) { + CMPIStatus s = {CMPI_RC_OK, NULL}; struct inst_list list; - CMPIStatus s; - int i; struct std_assoc *handler; - bool rc; + int i; inst_list_init(&list); - handler = std_assoc_get_handler(ctx, ref); + CU_DEBUG("Getting handler..."); + handler = std_assoc_get_handler(ctx, info, ref); if (handler == NULL) { CU_DEBUG("No handler found."); goto out; } - - rc = match_class(ctx->brkr, - NAMESPACE(ref), - info->result_class, - handler->assoc_class); - if (!rc) { - cu_statusf(ctx->brkr, &s, - CMPI_RC_ERR_FAILED, - "Result class is not valid for this association"); - goto out; - } - - + CU_DEBUG("Getting handler succeeded."); + + CU_DEBUG("Calling handler->handler..."); s = handler->handler(ref, info, &list); if ((s.rc != CMPI_RC_OK) || (list.list == NULL)) goto out;

HE> This patch set fixes: I'm happy with this now, but I don't want to commit it until we have a patch set to fix all the associations in libvirt-cim. Otherwise our libcmpiutil tip won't work with libvirt-cim tip. If you have a patch set already, please send it on, or send whatever you have done so far. I'll be glad to finish up the conversions tomorrow. Thanks Heidi! -- Dan Smith IBM Linux Technology Center Open Hypervisor Team email: danms@us.ibm.com
participants (2)
-
Dan Smith
-
Heidi Eckhart