[Libvirt-cim] [PATCH 1 of 3] [CU] Turn std_indication's awesome knob to eleven

Jay Gagnon grendel at linux.vnet.ibm.com
Mon Feb 25 20:54:29 UTC 2008


# HG changeset patch
# User Jay Gagnon <grendel at linux.vnet.ibm.com>
# Date 1203957417 18000
# Node ID f30365d472ed40da0af04d7ea3671ba3ac113580
# Parent  af61b6c75b143067444f4eefe694d1e9709d2ccb
[CU] Turn std_indication's awesome knob to eleven

The new std_indication handles Enable/DisableIndications and Activate/DeactivateFilter correctly, even on a per-indication basis when one provider handles more than one indication.  Those functions also now have default_foo equivalents in std_indication, as many providers (especially raise-style ones) will have no special needs there.

Changes required to make it work:
new struct to track which of a providers indications are active in the filter
little macro to make declaring the new filter struct nice and clean
new std_indication_ctx members for filters and global (per-provider) enabled flags
stdi_foo functions that do the default behavior and dispatch work
moving ind_args and CMPI_EI_VOID ifdef into std_indication

My apologies for:
how much there is in this one patch
the reordering going on in std_indication.h, which I know isn't very PCO, I have some ready-made excuses for those that require them :)

Signed-off-by: Jay Gagnon <grendel at linux.vnet.ibm.com>

diff -r af61b6c75b14 -r f30365d472ed std_indication.c
--- a/std_indication.c	Wed Feb 13 08:26:56 2008 -0800
+++ b/std_indication.c	Mon Feb 25 11:36:57 2008 -0500
@@ -32,10 +32,65 @@
 
 #include "std_indication.h"
 
+void stdi_free_ind_args (struct ind_args **args)
+{
+        free((*args)->ns);
+        free((*args)->classname);
+        free(*args);
+        *args = NULL;
+}
+
+static struct std_ind_filter *get_ind_filter(struct std_ind_filter **list,
+                                             const char *ind_name)
+{
+        int i;
+        struct std_ind_filter *filter = NULL;
+
+        for (i = 0; list[i] != NULL; i++) {
+                if (STREQC((list[i])->ind_name, ind_name)) {
+                        filter = list[i];
+                        break;
+                }
+        }
+        
+        if (filter == NULL)
+                CU_DEBUG("get_ind_filter: failed to find %s", ind_name);
+
+        return filter;
+}
+
+static bool is_ind_enabled(struct std_indication_ctx *ctx,
+                           const char *ind_name,
+                           CMPIStatus *s)
+{
+        bool ret = false;
+        struct std_ind_filter *filter;
+
+        if (!ctx->enabled) {
+                CU_DEBUG("Indications disabled for this provider");
+                ret = false;
+                goto out;
+        }
+
+        filter = get_ind_filter(ctx->filters, ind_name);
+        if (filter == NULL) {
+                cu_statusf(ctx->brkr, s,
+                           CMPI_RC_ERR_FAILED,
+                           "No std_ind_filter for %s", ind_name);
+                goto out;
+        }
+        
+        ret = filter->active;
+        if (!ret)
+                CU_DEBUG("Indication '%s' not in active filter", ind_name);
+ out:
+        return ret;
+}
+
 static CMPIStatus trigger(struct std_indication_ctx *ctx,
                           const CMPIContext *context)
 {
-        if (ctx->handler->trigger_fn == NULL)
+        if (ctx->handler == NULL || ctx->handler->trigger_fn == NULL)
                 return (CMPIStatus){CMPI_RC_OK, NULL};
 
         return ctx->handler->trigger_fn(context);
@@ -61,20 +116,171 @@ 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};
-
-        if (ctx->handler->raise_fn == NULL)
-                return default_raise(ctx->brkr, context, inst);
-
-        return ctx->handler->raise_fn(ctx->brkr, context, inst);
+        CMPIStatus s = {CMPI_RC_OK, NULL};
+        const 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(inst);
+        if (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)
+                goto out;
+
+        if (ctx->handler == NULL || ctx->handler->raise_fn == NULL)
+                s = default_raise(ctx->brkr, context, inst);
+        else
+                s = ctx->handler->raise_fn(ctx->brkr, context, inst);
+
+ out:
+        return s;
+}
+CMPIStatus stdi_deliver(const CMPIBroker *broker,
+                        const CMPIContext *ctx,
+                        struct ind_args *args,
+                        CMPIInstance *ind)
+{
+        bool enabled;
+        const char *ind_name;
+        CMPIStatus s = {CMPI_RC_OK, NULL};
+
+        ind_name = classname_from_inst(ind);
+        if (ind_name == NULL) {
+                cu_statusf(broker, &s,
+                           CMPI_RC_ERR_FAILED,
+                           "Couldn't get indication name for enable check.");
+        }
+
+        enabled = is_ind_enabled(args->_ctx, ind_name, &s);
+        if (s.rc != CMPI_RC_OK) {
+                CU_DEBUG("Problem checking enabled: '%s'", CMGetCharPtr(s.msg));
+                goto out;
+        }
+
+        if (enabled)
+                s = CBDeliverIndication(broker, ctx, args->ns, ind);
+
+ out:
+        return s;
+}
+
+CMPIStatus stdi_set_ind_filter_state(struct std_indication_ctx *ctx,
+                                     char *ind_name,
+                                     bool state)
+{
+        CMPIStatus s = {CMPI_RC_OK, NULL};
+        struct std_ind_filter *filter;
+
+        filter = get_ind_filter(ctx->filters, ind_name);
+        if (filter == NULL) {
+                cu_statusf(ctx->brkr, &s,
+                           CMPI_RC_ERR_FAILED,
+                           "Provider has no indication '%s'", ind_name);
+                goto out;
+        }
+        
+        filter->active = state;
+
+ out:
+        return s;
+}
+
+CMPIStatus stdi_activate_filter(CMPIIndicationMI* mi,
+                                const CMPIContext* ctx,
+                                const CMPISelectExp* se,
+                                const char *ns,
+                                const CMPIObjectPath* op,
+                                CMPIBoolean first)
+{
+        CMPIStatus s = {CMPI_RC_OK, NULL};
+        struct std_indication_ctx *_ctx;
+        _ctx = (struct std_indication_ctx *)mi->hdl;
+        char *cn = NULL;
+        
+        _ctx = (struct std_indication_ctx *)mi->hdl;
+        cn = CLASSNAME(op);
+        s = stdi_set_ind_filter_state(_ctx, cn, true);
+
+        if (_ctx->handler != NULL && _ctx->handler->activate_fn != NULL) {
+                CU_DEBUG("Calling handler->activate_fn");
+                s = _ctx->handler->activate_fn(mi, ctx, se, ns, op, first);
+                goto out;
+        }
+
+ out:
+        return s;
+}
+
+CMPIStatus stdi_deactivate_filter(CMPIIndicationMI* mi,
+                                  const CMPIContext* ctx,
+                                  const CMPISelectExp* se,
+                                  const  char *ns,
+                                  const CMPIObjectPath* op,
+                                  CMPIBoolean last)
+{
+        CMPIStatus s = {CMPI_RC_OK, NULL};
+        struct std_indication_ctx *_ctx;
+        _ctx = (struct std_indication_ctx *)mi->hdl;
+        char *cn = NULL;
+
+        _ctx = (struct std_indication_ctx *)mi->hdl;
+        cn = CLASSNAME(op);
+        s = stdi_set_ind_filter_state(_ctx, cn, false);
+
+        if (_ctx->handler != NULL && _ctx->handler->deactivate_fn != NULL) {
+                s = _ctx->handler->deactivate_fn(mi, ctx, se, ns, op, last);
+                goto out;
+        }
+
+ out:
+        return s;
+}
+
+_EI_RTYPE stdi_enable_indications (CMPIIndicationMI* mi,
+                                   const CMPIContext *ctx)
+{
+        struct std_indication_ctx *_ctx;
+        _ctx = (struct std_indication_ctx *)mi->hdl;
+
+        CU_DEBUG("enabling indications");
+        _ctx->enabled = true;
+
+        if (_ctx->handler != NULL && _ctx->handler->enable_fn != NULL)
+                return _ctx->handler->enable_fn(mi, ctx);
+
+        _EI_RET();
+}
+
+_EI_RTYPE stdi_disable_indications (CMPIIndicationMI* mi,
+                                    const CMPIContext *ctx)
+{
+        struct std_indication_ctx *_ctx;
+        _ctx = (struct std_indication_ctx *)mi->hdl;
+
+        CU_DEBUG("disabling indications");
+        _ctx->enabled = false;
+
+        if (_ctx->handler != NULL && _ctx->handler->disable_fn != NULL)
+                return _ctx->handler->disable_fn(mi, ctx);
+
+        _EI_RET();
 }
 
 CMPIStatus stdi_handler(CMPIMethodMI *self,
diff -r af61b6c75b14 -r f30365d472ed std_indication.h
--- a/std_indication.h	Wed Feb 13 08:26:56 2008 -0800
+++ b/std_indication.h	Mon Feb 25 11:36:57 2008 -0500
@@ -26,8 +26,74 @@
 #include <cmpimacs.h>
 #include <stdio.h>
 
+#include "config.h"
+
 #include "libcmpiutil.h"
 #include "std_invokemethod.h"
+
+#ifdef CMPI_EI_VOID
+# define _EI_RTYPE void
+# define _EI_RET() return
+#else
+# define _EI_RTYPE CMPIStatus
+# define _EI_RET() return (CMPIStatus){CMPI_RC_OK, NULL}
+#endif
+
+typedef CMPIStatus (*raise_indication_t)(const CMPIBroker *broker,
+                                         const CMPIContext *ctx,
+                                         const CMPIInstance *ind);
+
+typedef CMPIStatus (*trigger_indication_t)(const CMPIContext *ctx);
+
+typedef CMPIStatus (*activate_function_t) (CMPIIndicationMI* mi,
+                                           const CMPIContext* ctx,
+                                           const CMPISelectExp* se,
+                                           const char *ns,
+                                           const CMPIObjectPath* op,
+                                           CMPIBoolean first);
+
+typedef CMPIStatus (*deactivate_function_t) (CMPIIndicationMI* mi,
+                                             const CMPIContext* ctx,
+                                             const CMPISelectExp* se,
+                                             const  char *ns,
+                                             const CMPIObjectPath* op,
+                                             CMPIBoolean last);
+
+typedef _EI_RTYPE (*enable_function_t) (CMPIIndicationMI* mi,
+                                        const CMPIContext *ctx);
+
+typedef _EI_RTYPE (*disable_function_t) (CMPIIndicationMI* mi,
+                                         const CMPIContext *ctx);
+
+struct std_indication_handler {
+        raise_indication_t raise_fn;
+        trigger_indication_t trigger_fn;
+        activate_function_t activate_fn;
+        deactivate_function_t deactivate_fn;
+        enable_function_t enable_fn;
+        disable_function_t disable_fn;
+};
+
+struct std_ind_filter {
+        char *ind_name;
+        bool active;
+};
+
+struct std_indication_ctx {
+        const CMPIBroker *brkr;
+        struct std_indication_handler *handler;
+        struct std_ind_filter **filters;
+        bool enabled;
+};
+
+struct ind_args {
+        CMPIContext *context;
+        char *ns;
+        char *classname;
+        struct std_indication_ctx *_ctx;
+};
+
+void stdi_free_ind_args (struct ind_args **args);
 
 CMPIStatus stdi_trigger_indication(const CMPIBroker *broker,
                                    const CMPIContext *context,
@@ -39,6 +105,31 @@ CMPIStatus stdi_raise_indication(const C
                                  const char *type,
                                  const char *ns,
                                  const CMPIInstance *ind);
+
+CMPIStatus stdi_deliver(const CMPIBroker *broker,
+                        const CMPIContext *ctx,
+                        struct ind_args *args,
+                        CMPIInstance *ind);
+
+CMPIStatus stdi_activate_filter(CMPIIndicationMI* mi,
+                                const CMPIContext* ctx,
+                                const CMPISelectExp* se,
+                                const char *ns,
+                                const CMPIObjectPath* op,
+                                CMPIBoolean first);
+
+CMPIStatus stdi_deactivate_filter(CMPIIndicationMI* mi,
+                                  const CMPIContext* ctx,
+                                  const CMPISelectExp* se,
+                                  const  char *ns,
+                                  const CMPIObjectPath* op,
+                                  CMPIBoolean last);
+
+_EI_RTYPE stdi_enable_indications (CMPIIndicationMI* mi,
+                                   const CMPIContext *ctx);
+
+_EI_RTYPE stdi_disable_indications (CMPIIndicationMI* mi,
+                                    const CMPIContext *ctx);
 
 CMPIStatus stdi_handler(CMPIMethodMI *self,
                         const CMPIContext *context,
@@ -52,27 +143,22 @@ CMPIStatus stdi_cleanup(CMPIMethodMI *se
                         const CMPIContext *context,
                         CMPIBoolean terminating);
 
-typedef CMPIStatus (*raise_indication_t)(const CMPIBroker *broker,
-                                         const CMPIContext *ctx,
-                                         const CMPIInstance *ind);
-
-typedef CMPIStatus (*trigger_indication_t)(const CMPIContext *ctx);
-
-struct std_indication_handler {
-        raise_indication_t raise_fn;
-        trigger_indication_t trigger_fn;
-};
-
-struct std_indication_ctx {
-        const CMPIBroker *brkr;
-        struct std_indication_handler *handler;
-        bool enabled;
-};
-
-#define STDI_IndicationMIStub(pfx, pn, _broker, hook, _handler)         \
-        static struct std_indication_ctx _ctx = {                       \
+CMPIStatus stdi_set_ind_filter_state(struct std_indication_ctx *ctx,
+                                     char *ind_name,
+                                     bool state);
+
+/* This doesn't work, but should be made to. */
+#define DECLARE_FILTER(ident, name)                     \
+        static struct std_ind_filter ident = {          \
+                .ind_name = name,                       \
+                .active = false,                        \
+        };                                              \
+
+#define STDI_IndicationMIStub(pfx, pn, _broker, hook, _handler, filters)\
+        static struct std_indication_ctx pn##_ctx = {                   \
                 .brkr = NULL,                                           \
                 .handler = _handler,                                    \
+                .filters = filters,                                     \
                 .enabled = false,                                       \
         };                                                              \
                                                                         \
@@ -83,9 +169,10 @@ struct std_indication_ctx {
                 pfx##IndicationCleanup,                                 \
                 pfx##AuthorizeFilter,                                   \
                 pfx##MustPoll,                                          \
-                pfx##ActivateFilter,                                    \
-                pfx##DeActivateFilter,                                  \
-                CMIndicationMIStubExtensions(pfx)                       \
+                stdi_activate_filter,                                   \
+                stdi_deactivate_filter,                                 \
+                stdi_enable_indications,                                \
+                stdi_disable_indications,                               \
         };                                                              \
         CMPIIndicationMI *                                              \
         pn##_Create_IndicationMI(const CMPIBroker *,                    \
@@ -96,10 +183,10 @@ struct std_indication_ctx {
                                   const CMPIContext *ctx,               \
                                   CMPIStatus *rc) {                     \
                 static CMPIIndicationMI mi = {                          \
-                        &_ctx,                                          \
+                        &pn##_ctx,                                      \
                         &indMIFT__,                                     \
                 };                                                      \
-                _ctx.brkr = brkr;                                       \
+                pn##_ctx.brkr = brkr;                                   \
                 _broker = brkr;                                         \
                 hook;                                                   \
                 return &mi;                                             \
@@ -121,10 +208,10 @@ struct std_indication_ctx {
                                            const CMPIContext *ctx,      \
                                            CMPIStatus *rc) {            \
                 static CMPIMethodMI mi = {                              \
-                        &_ctx,                                          \
+                        &pn##_ctx,                                      \
                         &methMIFT__,                                    \
                 };                                                      \
-                _ctx.brkr = brkr;                                       \
+                pn##_ctx.brkr = brkr;                                   \
                 _broker = brkr;                                         \
                 hook;                                                   \
                 return &mi;                                             \




More information about the Libvirt-cim mailing list