[Libvirt-cim] [PATCH] [RFC] [CU] Turn std_indication's awesome knob to eleven

Jay Gagnon grendel at linux.vnet.ibm.com
Thu Feb 7 21:39:40 UTC 2008


# HG changeset patch
# User Jay Gagnon <grendel at 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 at 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__ = {                         \




More information about the Libvirt-cim mailing list