summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomas Bzatek <tbzatek@redhat.com>2013-11-15 17:45:36 +0100
committerTomas Bzatek <tbzatek@redhat.com>2014-01-07 15:24:38 +0100
commitee65d4aadefe4dc356fda7ae241c812bfa3c0f87 (patch)
treef99257589d56f8b0ce875fd76dad7d235e4dc090
parent102a3fd01d91daa051b3654057c08f1ab38cbdce (diff)
downloadopenlmi-providers-ee65d4aadefe4dc356fda7ae241c812bfa3c0f87.tar.gz
openlmi-providers-ee65d4aadefe4dc356fda7ae241c812bfa3c0f87.tar.xz
openlmi-providers-ee65d4aadefe4dc356fda7ae241c812bfa3c0f87.zip
indmanager: Introduce common filter checker
The filter checker code was kinda duplicate across providers and no special plans have been made for it. This change makes passing a filter checker callback during indication manager creation no longer mandatory and default filter checker will be used when NULL. However, the list of acceptable classes need to be registered before first use. This change also brings greater flexibility of the filter query which may now consist of multiple limit conditions.
-rw-r--r--src/account/LMI_AccountInstanceCreationIndicationProvider.c3
-rw-r--r--src/account/LMI_AccountInstanceDeletionIndicationProvider.c3
-rw-r--r--src/account/indication_common.c41
-rw-r--r--src/account/indication_common.h11
-rw-r--r--src/indmanager/ind_manager.c72
-rw-r--r--src/indmanager/ind_manager.h7
-rw-r--r--src/journald/LMI_JournalLogRecordInstanceCreationIndicationProvider.c3
-rw-r--r--src/journald/instutil.c31
-rw-r--r--src/journald/instutil.h5
9 files changed, 93 insertions, 83 deletions
diff --git a/src/account/LMI_AccountInstanceCreationIndicationProvider.c b/src/account/LMI_AccountInstanceCreationIndicationProvider.c
index 383bb98..989eaae 100644
--- a/src/account/LMI_AccountInstanceCreationIndicationProvider.c
+++ b/src/account/LMI_AccountInstanceCreationIndicationProvider.c
@@ -42,8 +42,9 @@ static bool creation_watcher(void **data)
static void LMI_AccountInstanceCreationIndicationInitialize(const CMPIContext *ctx)
{
lmi_init(provider_name, _cb, ctx, provider_config_defaults);
- im = im_create_manager(NULL, filter_checker, true, creation_watcher,
+ im = im_create_manager(NULL, NULL, true, creation_watcher,
IM_IND_CREATION, _cb, &im_err);
+ im_register_filter_classes(im, &account_allowed_classes[0], &im_err);
}
static CMPIStatus LMI_AccountInstanceCreationIndicationIndicationCleanup(
diff --git a/src/account/LMI_AccountInstanceDeletionIndicationProvider.c b/src/account/LMI_AccountInstanceDeletionIndicationProvider.c
index f0de0c6..ee86e6e 100644
--- a/src/account/LMI_AccountInstanceDeletionIndicationProvider.c
+++ b/src/account/LMI_AccountInstanceDeletionIndicationProvider.c
@@ -45,8 +45,9 @@ static bool deletion_watcher(void **data)
static void LMI_AccountInstanceDeletionIndicationInitialize(const CMPIContext *ctx)
{
lmi_init(provider_name, _cb, ctx, provider_config_defaults);
- im = im_create_manager(NULL, filter_checker, true, deletion_watcher,
+ im = im_create_manager(NULL, NULL, true, deletion_watcher,
IM_IND_DELETION, _cb, &im_err);
+ im_register_filter_classes(im, &account_allowed_classes[0], &im_err);
}
static CMPIStatus LMI_AccountInstanceDeletionIndicationIndicationCleanup(
diff --git a/src/account/indication_common.c b/src/account/indication_common.c
index 17d570f..f5caa75 100644
--- a/src/account/indication_common.c
+++ b/src/account/indication_common.c
@@ -34,15 +34,6 @@
#include "indication_common.h"
#include <globals.h>
-#include "LMI_Account.h"
-#include "LMI_Group.h"
-#include "LMI_Identity.h"
-static const char* allowed_classes[] = {
- LMI_Account_ClassName,
- LMI_Group_ClassName,
- LMI_Identity_ClassName,
- NULL };
-
#define EVENT_SIZE (sizeof(struct inotify_event))
#define BUF_LEN (10 * EVENT_SIZE + NAME_MAX + 1)
#define WATCH_PATH "/etc/"
@@ -51,38 +42,6 @@ static const char* allowed_classes[] = {
#define SETTLE_DELAY 1000 * 250 /* usec */
-bool filter_checker(const CMPISelectExp *filter)
-{
- /*
- * Support only simple conditions and only on allowed_classes
- * and type of `sourceinstance ISA allowed_class'
- */
- CMPIStatus st;
- CMPISelectCond *sec = CMGetDoc(filter, &st);
- if (!sec) return false;
- CMPICount count = CMGetSubCondCountAndType(sec, NULL, &st);
- if (count != 1) return false;
- CMPISubCond *sub = CMGetSubCondAt(sec, 0, &st);
- if (!sub) return false;
- count = CMGetPredicateCount(sub, &st);
- if (count != 1) return false;
- CMPIPredicate *pred = CMGetPredicateAt(sub, 0, &st);
- if (!pred) return false;
- CMPIType type;
- CMPIPredOp op;
- CMPIString *lhs = NULL;
- CMPIString *rhs = NULL;
- st = CMGetPredicateData(pred, &type, &op, &lhs, &rhs);
- if (st.rc != CMPI_RC_OK || op != CMPI_PredOp_Isa) return false;
- const char *rhs_str = CMGetCharsPtr(rhs, &st);
- if (!rhs_str) return false;
- unsigned i = 0;
- while (allowed_classes[i]) {
- if (strcasecmp(rhs_str, allowed_classes[i++]) == 0) return true;
- }
- return false;
-}
-
/*
* Returns last modification time for specified file name
*/
diff --git a/src/account/indication_common.h b/src/account/indication_common.h
index 06eaa7b..b3fe9e6 100644
--- a/src/account/indication_common.h
+++ b/src/account/indication_common.h
@@ -18,13 +18,22 @@
* Authors: Roman Rakus <rrakus@redhat.com>
*/
+#include "LMI_Account.h"
+#include "LMI_Group.h"
+#include "LMI_Identity.h"
+
typedef struct {
int wd;
int inotify_fd;
struct timespec last_pwd, last_grp;
} AccountIndication;
-bool filter_checker(const CMPISelectExp *filter);
+static const char* account_allowed_classes[] = {
+ LMI_Account_ClassName,
+ LMI_Group_ClassName,
+ LMI_Identity_ClassName,
+ NULL};
+
bool watcher_init(AccountIndication *ind);
bool watcher(AccountIndication *ind, void **data);
void watcher_destroy(AccountIndication *ind);
diff --git a/src/indmanager/ind_manager.c b/src/indmanager/ind_manager.c
index 446137d..cae141b 100644
--- a/src/indmanager/ind_manager.c
+++ b/src/indmanager/ind_manager.c
@@ -795,10 +795,6 @@ IMManager* im_create_manager(IMInstGather gather, IMFilterChecker f_checker,
*err = IM_ERR_GATHER;
return NULL;
}
- if (!f_checker) {
- *err = IM_ERR_FILTER_CHECKER;
- return NULL;
- }
if (!watcher) {
*err = IM_ERR_WATCHER;
return NULL;
@@ -866,6 +862,50 @@ bool im_destroy_manager(IMManager *manager, const CMPIContext *ctx,
return true;
}
+static bool default_ind_filter_cb(IMManager *manager, const CMPISelectExp *filter)
+{
+ /* Looks for a class to be subscribed and matches it against a list of
+ * allowed classes. Filter query may contain more conditions, only those
+ * with a ISA operator are looked for.
+ */
+ CMPIStatus st;
+ unsigned int i;
+
+ CMPISelectCond *sec = CMGetDoc(filter, &st);
+ if (!sec)
+ return false;
+ CMPICount count = CMGetSubCondCountAndType(sec, NULL, &st);
+ if (count != 1)
+ return false;
+ CMPISubCond *sub = CMGetSubCondAt(sec, 0, &st);
+ if (!sub)
+ return false;
+ count = CMGetPredicateCount(sub, &st);
+ if (count == 0)
+ return false;
+
+ for (i = 0; i < count; i++) {
+ CMPIType type;
+ CMPIPredOp op;
+ CMPIString *lhs = NULL;
+ CMPIString *rhs = NULL;
+ CMPIPredicate *pred = CMGetPredicateAt(sub, i, &st);
+ if (!pred)
+ return false;
+ st = CMGetPredicateData(pred, &type, &op, &lhs, &rhs);
+ if (st.rc != CMPI_RC_OK || op != CMPI_PredOp_Isa)
+ continue;
+ const char *rhs_str = CMGetCharsPtr(rhs, &st);
+ if (!rhs_str)
+ continue;
+ while (manager->f_allowed_classes[i]) {
+ if (strcasecmp(rhs_str, manager->f_allowed_classes[i++]) == 0)
+ return true;
+ }
+ }
+ return false;
+}
+
bool im_verify_filter(IMManager *manager, const CMPISelectExp *filter,
const CMPIContext *ctx, IMError *err)
{
@@ -880,9 +920,18 @@ bool im_verify_filter(IMManager *manager, const CMPISelectExp *filter,
*err = IM_ERR_FILTER;
return NULL;
}
+ if (!filter && !manager->f_allowed_classes) {
+ *err = IM_ERR_FILTER_CHECKER;
+ return NULL;
+ }
manager->ctx_main = ctx;
- DEBUG("Verifying filter. Manager = %p, filter checker = %p", manager, manager->f_checker);
- return manager->f_checker(filter);
+ if (manager->f_checker) {
+ DEBUG("Verifying filter. Manager = %p, filter checker = %p", manager, manager->f_checker);
+ return manager->f_checker(filter);
+ } else {
+ DEBUG("Verifying filter. Manager = %p, using default filter checker", manager);
+ return default_ind_filter_cb(manager, filter);
+ }
}
/*
@@ -1009,6 +1058,17 @@ bool im_add_filter(IMManager *manager, CMPISelectExp *filter,
return true;
}
+bool im_register_filter_classes(IMManager *manager,
+ const char** allowed_classes, IMError *err)
+{
+ if (!manager) {
+ *err = IM_ERR_MANAGER;
+ return false;
+ }
+ manager->f_allowed_classes = allowed_classes;
+ return true;
+}
+
/*
* Decrease reference count for polled enumerations. If count is 0, remove
* the whole enumerations.
diff --git a/src/indmanager/ind_manager.h b/src/indmanager/ind_manager.h
index 01aa2e5..383f4b6 100644
--- a/src/indmanager/ind_manager.h
+++ b/src/indmanager/ind_manager.h
@@ -131,6 +131,7 @@ struct _IMManager {
IMFilterChecker f_checker;
// filters container
IMFilters *filters;
+ const char** f_allowed_classes;
// others
IMIndType type;
bool running;
@@ -196,6 +197,12 @@ bool im_add_filter(IMManager *manager, CMPISelectExp *filter,
bool im_remove_filter(IMManager *manager, const CMPISelectExp *filter,
const CMPIContext *ctx, IMError *err);
+// Register list of classes to be used with a default filter checker
+// when callback not given during im_create_manager()
+// The allowed_classes array should be kept accessible all the time
+bool im_register_filter_classes(IMManager *manager,
+ const char** allowed_classes, IMError *err);
+
// Start indications.
// Return true when correctly started, false if not and
// appropriate IMError is set,
diff --git a/src/journald/LMI_JournalLogRecordInstanceCreationIndicationProvider.c b/src/journald/LMI_JournalLogRecordInstanceCreationIndicationProvider.c
index 19dceda..c252383 100644
--- a/src/journald/LMI_JournalLogRecordInstanceCreationIndicationProvider.c
+++ b/src/journald/LMI_JournalLogRecordInstanceCreationIndicationProvider.c
@@ -34,8 +34,9 @@ static IMError im_err = IM_ERR_OK;
static void LMI_JournalLogRecordInstanceCreationIndicationInitialize(const CMPIContext *ctx)
{
lmi_init(JOURNAL_CIM_LOG_NAME, _cb, ctx, provider_config_defaults);
- im = im_create_manager(ind_gather, ind_filter_cb, false, ind_watcher,
+ im = im_create_manager(ind_gather, NULL, false, ind_watcher,
IM_IND_CREATION, _cb, &im_err);
+ im_register_filter_classes(im, &journald_allowed_classes[0], &im_err);
}
static CMPIStatus LMI_JournalLogRecordInstanceCreationIndicationIndicationCleanup(
diff --git a/src/journald/instutil.c b/src/journald/instutil.c
index 527c517..0de1e7f 100644
--- a/src/journald/instutil.c
+++ b/src/journald/instutil.c
@@ -377,37 +377,6 @@ bool ind_gather(const IMManager *manager, CMPIInstance **old, CMPIInstance **new
return true;
}
-bool ind_filter_cb(const CMPISelectExp *filter)
-{
- /* TODO: copied from account/indication_common.c, may require generalization */
-
- /*
- * Support only simple conditions and only on allowed_classes
- * and type of `sourceinstance ISA allowed_class'
- */
- CMPIStatus st;
- CMPISelectCond *sec = CMGetDoc(filter, &st);
- if (!sec) return false;
- CMPICount count = CMGetSubCondCountAndType(sec, NULL, &st);
- if (count != 1) return false;
- CMPISubCond *sub = CMGetSubCondAt(sec, 0, &st);
- if (!sub) return false;
- count = CMGetPredicateCount(sub, &st);
- if (count != 1) return false;
- CMPIPredicate *pred = CMGetPredicateAt(sub, 0, &st);
- if (!pred) return false;
- CMPIType type;
- CMPIPredOp op;
- CMPIString *lhs = NULL;
- CMPIString *rhs = NULL;
- st = CMGetPredicateData(pred, &type, &op, &lhs, &rhs);
- if (st.rc != CMPI_RC_OK || op != CMPI_PredOp_Isa) return false;
- const char *rhs_str = CMGetCharsPtr(rhs, &st);
- if (!rhs_str) return false;
- if (strcasecmp(rhs_str, LMI_JournalLogRecord_ClassName) == 0) return true;
- return false;
-}
-
/* --------------------------------------------------------------------------- */
/* TODO: count references to the journal struct -- someone may cancel the iteration
diff --git a/src/journald/instutil.h b/src/journald/instutil.h
index 1ea96a2..23c76af 100644
--- a/src/journald/instutil.h
+++ b/src/journald/instutil.h
@@ -28,6 +28,10 @@
#include <ind_manager.h>
#include "LMI_JournalLogRecord.h"
+static const char* journald_allowed_classes[] = {
+ LMI_JournalLogRecord_ClassName,
+ NULL};
+
int create_LMI_JournalLogRecordRef(sd_journal *j, LMI_JournalLogRecordRef *ref, const CMPIBroker *_cb);
int create_LMI_JournalLogRecord(sd_journal *j, LMI_JournalLogRecord *rec, const CMPIBroker *_cb);
@@ -35,7 +39,6 @@ int match_journal_record(sd_journal *j, const char *message, const char *code_fu
void ind_init();
bool ind_watcher(void **data);
-bool ind_filter_cb(const CMPISelectExp *filter);
bool ind_gather(const IMManager *manager, CMPIInstance **old, CMPIInstance **new, void *data);
void ind_destroy();