
# HG changeset patch # User Jay Gagnon <grendel@linux.vnet.ibm.com> # Date 1202420200 18000 # Node ID 7feaabeb36cea13611d6dc045cd2bd946528032b # Parent 60ecfe23d68caaa9dda1f115289f168ea8f4a297 [RFC] [CU] Turn std_indication's awesome knob to eleven This is the prototype of a new std_indication that will handle Enable/DisableIndications and Activate/DeactivateFilter correctly, even on a per-indication basis when one provider handles more than one indication. Those functions will also now have default_foo equivalents in std_indication, as many providers (especially raise-style ones) will have no special needs there. The hope is that this will *require* minimal change from existing Indicatio providers, but *allow* for code reduction in most, and of course new providers should try to utilize this. Signed-off-by: Jay Gagnon <grendel@linux.vnet.ibm.com> diff -r 60ecfe23d68c -r 7feaabeb36ce instance_util.c --- a/instance_util.c Tue Feb 05 16:01:32 2008 -0500 +++ b/instance_util.c Thu Feb 07 16:36:40 2008 -0500 @@ -251,6 +251,27 @@ CMPIInstance *cu_dup_instance(const CMPI out: return dest; +} + +char *classname_from_inst(const CMPIBroker *broker, + CMPIInstance *inst, + CMPIStatus *s) +{ + char *ret = NULL; + + CMPIObjectPath *ref; + ref = CMGetObjectPath(inst, s); + if ((s->rc != CMPI_RC_OK) || CMIsNullObject(ref)) { + cu_statusf(broker, s, + CMPI_RC_ERR_FAILED, + "Could not get objectpath from instance"); + goto out; + } + + ret = strdup(CLASSNAME(ref)); + + out: + return ret; } /* diff -r 60ecfe23d68c -r 7feaabeb36ce libcmpiutil.h --- a/libcmpiutil.h Tue Feb 05 16:01:32 2008 -0500 +++ b/libcmpiutil.h Thu Feb 07 16:36:40 2008 -0500 @@ -413,6 +413,19 @@ CMPIStatus cu_validate_ref(const CMPIBro CMPIStatus cu_validate_ref(const CMPIBroker *broker, const CMPIObjectPath *ref, const CMPIInstance *inst); + +/** + * Returns the classname from an instance without forcing user to get + * ObjectPath first. + * + * @param broker A pointer to the current broker + * @param inst Instance to examine + * @param s An out pointer for returning status if error occurs + * @returns Classname of instance (must be freed), NULL on failure + */ +char *classname_from_inst(const CMPIBroker *broker, + CMPIInstance *inst, + CMPIStatus *s); #define DEFAULT_EIN(pn) \ static CMPIStatus pn##EnumInstanceNames(CMPIInstanceMI *self, \ diff -r 60ecfe23d68c -r 7feaabeb36ce std_indication.c --- a/std_indication.c Tue Feb 05 16:01:32 2008 -0500 +++ b/std_indication.c Thu Feb 07 16:36:40 2008 -0500 @@ -32,6 +32,45 @@ #include "std_indication.h" +static struct std_ind_state *get_ind_state(struct std_ind_state **list, + char *ind_name) +{ + int i; + struct std_ind_state *state = NULL; + + for (i = 0; list[i] != NULL; i++) { + if (STREQC((list[i])->ind_name, ind_name)) { + state = list[i]; + break; + } + } + + if (state == NULL) + CU_DEBUG("get_ind_state: failed to find %s", ind_name); + + return state; +} + +static bool is_ind_enabled(struct std_indication_ctx *ctx, + char *ind_name, + CMPIStatus *s) +{ + bool ret = false; + struct std_ind_state *state; + + state = get_ind_state(ctx->ind_states, ind_name); + if (state == NULL) { + cu_statusf(ctx->brkr, s, + CMPI_RC_ERR_FAILED, + "No std_ind_state for %s", ind_name); + goto out; + } + + ret = state->enabled; + out: + return ret; +} + static CMPIStatus trigger(struct std_indication_ctx *ctx, const CMPIContext *context) { @@ -61,20 +100,85 @@ static CMPIStatus raise(struct std_indic const CMPIContext *context, const CMPIArgs *argsin) { + bool enabled; CMPIInstance *inst; - - if (!ctx->enabled) { - CU_DEBUG("Indication disabled, not raising."); - return (CMPIStatus) {CMPI_RC_OK, NULL}; - } - - if (cu_get_inst_arg(argsin, "Indication", &inst) != CMPI_RC_OK) - return (CMPIStatus){CMPI_RC_ERR_FAILED, NULL}; - + CMPIStatus s = {CMPI_RC_OK, NULL}; + char *ind_name = NULL; + + if (cu_get_inst_arg(argsin, "Indication", &inst) != CMPI_RC_OK) { + cu_statusf(ctx->brkr, &s, + CMPI_RC_ERR_FAILED, + "Could not get indication to raise"); + goto out; + } + + ind_name = classname_from_inst(ctx->brkr, inst, &s); + if (s.rc != CMPI_RC_OK || ind_name == NULL) { + cu_statusf(ctx->brkr, &s, + CMPI_RC_ERR_FAILED, + "Couldn't get indication name for enable check."); + } + + enabled = is_ind_enabled(ctx, ind_name, &s); + if (s.rc != CMPI_RC_OK) { + CU_DEBUG("Problem checking enabled: '%s'", CMGetCharPtr(s.msg)); + goto out; + } + if (!enabled) { + CU_DEBUG("%s disabled, not raising", ind_name); + goto out; + } + + CU_DEBUG("Calling appropriate raise function"); if (ctx->handler->raise_fn == NULL) - return default_raise(ctx->brkr, context, inst); - - return ctx->handler->raise_fn(ctx->brkr, context, inst); + s = default_raise(ctx->brkr, context, inst); + else + s = ctx->handler->raise_fn(ctx->brkr, context, inst); + + out: + free(ind_name); + return s; +} + +CMPIStatus stdi_set_ind_state_prop(struct std_indication_ctx *ctx, + char *ind_name, + int prop, + bool value) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + struct std_ind_state *state; + + CU_DEBUG("In stdi_set_ind_state_prop"); + + state = get_ind_state(ctx->ind_states, ind_name); + if (state == NULL) { + CU_DEBUG("state == NULL, exiting"); + cu_statusf(ctx->brkr, &s, + CMPI_RC_ERR_FAILED, + "Provider has no indication '%s'", ind_name); + goto out; + } + + CU_DEBUG("entering switch"); + switch (prop) { + case STDI_PROP_FILTER: + state->filter_active = value; + CU_DEBUG("Filter: %s set to %d", ind_name, value); + break; + case STDI_PROP_ENABLE: + state->enabled = value; + CU_DEBUG("Enable: %s set to %d", ind_name, value); + break; + default: + CU_DEBUG("default case"); + cu_statusf(ctx->brkr, &s, + CMPI_RC_ERR_FAILED, + "Invalid indication state property: %d", prop); + goto out; + } + + out: + return s; } CMPIStatus stdi_handler(CMPIMethodMI *self, diff -r 60ecfe23d68c -r 7feaabeb36ce std_indication.h --- a/std_indication.h Tue Feb 05 16:01:32 2008 -0500 +++ b/std_indication.h Thu Feb 07 16:36:40 2008 -0500 @@ -58,22 +58,36 @@ typedef CMPIStatus (*raise_indication_t) typedef CMPIStatus (*trigger_indication_t)(const CMPIContext *ctx); +enum {STDI_PROP_FILTER, + STDI_PROP_ENABLE}; + struct std_indication_handler { raise_indication_t raise_fn; trigger_indication_t trigger_fn; }; +struct std_ind_state { + char *ind_name; + bool filter_active; + bool enabled; +}; + struct std_indication_ctx { const CMPIBroker *brkr; struct std_indication_handler *handler; - bool enabled; + struct std_ind_state **ind_states; }; -#define STDI_IndicationMIStub(pfx, pn, _broker, hook, _handler) \ +CMPIStatus stdi_set_ind_state_prop(struct std_indication_ctx *ctx, + char *ind_name, + int prop, + bool state); + +#define STDI_IndicationMIStub(pfx, pn, _broker, hook, _handler, states) \ static struct std_indication_ctx _ctx = { \ .brkr = NULL, \ .handler = _handler, \ - .enabled = false, \ + .ind_states = states, \ }; \ \ static CMPIIndicationMIFT indMIFT__ = { \