2016-06-08 22:38:50 +02:00
|
|
|
/** Hook-releated functions.
|
2014-08-31 14:43:28 +00:00
|
|
|
*
|
|
|
|
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
2016-02-09 05:33:19 +01:00
|
|
|
* @copyright 2014-2016, Institute for Automation of Complex Power Systems, EONERC
|
2016-06-08 23:21:42 +02:00
|
|
|
* This file is part of VILLASnode. All Rights Reserved. Proprietary and confidential.
|
2015-08-07 01:11:43 +02:00
|
|
|
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
2015-06-02 21:53:04 +02:00
|
|
|
*********************************************************************************/
|
2015-03-18 16:13:18 +01:00
|
|
|
|
2014-08-31 14:43:28 +00:00
|
|
|
#include <string.h>
|
2015-09-28 19:18:39 +02:00
|
|
|
#include <math.h>
|
2016-11-20 12:59:37 -05:00
|
|
|
#include <libconfig.h>
|
2014-08-31 14:43:28 +00:00
|
|
|
|
2015-06-10 15:05:36 +02:00
|
|
|
#include "timing.h"
|
2015-05-06 11:38:57 +02:00
|
|
|
#include "config.h"
|
2014-08-31 14:43:28 +00:00
|
|
|
#include "msg.h"
|
2016-11-20 13:11:37 -05:00
|
|
|
#include "hook.h"
|
2015-03-18 16:13:18 +01:00
|
|
|
#include "path.h"
|
|
|
|
#include "utils.h"
|
2015-12-13 00:42:59 +01:00
|
|
|
#include "node.h"
|
2017-03-05 10:06:32 -04:00
|
|
|
#include "plugin.h"
|
2015-06-10 15:10:51 +02:00
|
|
|
|
2017-03-17 01:08:48 -03:00
|
|
|
int hook_init(struct hook *h, struct hook_type *vt, struct super_node *sn)
|
2016-10-22 20:42:05 -04:00
|
|
|
{
|
2017-03-17 01:08:48 -03:00
|
|
|
int ret;
|
|
|
|
|
2016-10-22 20:42:05 -04:00
|
|
|
struct hook_info i = {
|
2017-03-12 17:01:24 -03:00
|
|
|
.nodes = &sn->nodes,
|
|
|
|
.paths = &sn->paths
|
2016-10-22 20:42:05 -04:00
|
|
|
};
|
|
|
|
|
2017-03-17 01:08:48 -03:00
|
|
|
assert(h->state == STATE_DESTROYED);
|
|
|
|
|
|
|
|
h->_vt = vt;
|
2017-03-17 02:52:59 -03:00
|
|
|
h->priority = vt->priority;
|
2017-03-17 01:08:48 -03:00
|
|
|
|
|
|
|
ret = hook_run(h, HOOK_INIT, &i);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
h->state = STATE_INITIALIZED;
|
|
|
|
|
|
|
|
return 0;
|
2016-10-22 20:42:05 -04:00
|
|
|
}
|
2016-01-15 15:34:28 +01:00
|
|
|
|
2017-03-17 01:08:48 -03:00
|
|
|
int hook_parse(struct hook *h, config_setting_t *cfg)
|
2016-01-15 15:34:28 +01:00
|
|
|
{
|
2017-03-17 01:08:48 -03:00
|
|
|
int ret;
|
2017-03-17 02:52:59 -03:00
|
|
|
|
2017-03-17 01:08:48 -03:00
|
|
|
assert(h->state != STATE_DESTROYED);
|
|
|
|
|
2017-03-17 02:52:59 -03:00
|
|
|
h->cfg = cfg;
|
2017-03-17 01:08:48 -03:00
|
|
|
|
2017-03-17 02:52:59 -03:00
|
|
|
config_setting_lookup_int(h->cfg, "priority", &h->priority);
|
2017-03-17 01:08:48 -03:00
|
|
|
|
|
|
|
/* Parse hook arguments */
|
|
|
|
ret = hook_run(h, HOOK_PARSE, NULL);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
h->state = STATE_PARSED;
|
|
|
|
|
|
|
|
return 0;
|
2016-10-22 20:42:05 -04:00
|
|
|
}
|
|
|
|
|
2017-03-17 01:08:48 -03:00
|
|
|
int hook_destroy(struct hook *h)
|
2016-10-22 20:42:05 -04:00
|
|
|
{
|
2017-03-17 01:08:48 -03:00
|
|
|
int ret;
|
|
|
|
|
|
|
|
assert(h->state != STATE_DESTROYED);
|
2016-10-22 20:42:05 -04:00
|
|
|
|
2017-03-17 01:08:48 -03:00
|
|
|
ret = hook_run(h, HOOK_DESTROY, NULL);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
h->state = HOOK_DESTROYED;
|
2016-10-22 20:42:05 -04:00
|
|
|
|
|
|
|
return 0;
|
2016-01-15 15:34:28 +01:00
|
|
|
}
|
|
|
|
|
2017-03-17 01:08:48 -03:00
|
|
|
int hook_cmp_priority(const void *a, const void *b)
|
|
|
|
{
|
2016-01-14 22:59:57 +01:00
|
|
|
struct hook *ha = (struct hook *) a;
|
|
|
|
struct hook *hb = (struct hook *) b;
|
|
|
|
|
2017-03-17 02:52:59 -03:00
|
|
|
return ha->priority - hb->priority;
|
2016-01-14 22:59:57 +01:00
|
|
|
}
|
|
|
|
|
2017-03-17 01:08:48 -03:00
|
|
|
int hook_run(struct hook *h, int when, struct hook_info *i)
|
2016-02-07 14:24:58 +01:00
|
|
|
{
|
2017-03-17 02:52:59 -03:00
|
|
|
debug(LOG_HOOK | 22, "Running hook '%s' when=%u, prio=%u, cnt=%zu", plugin_name(h->_vt), when, h->priority, i ? i->count : 0);
|
2016-10-22 20:42:05 -04:00
|
|
|
|
2017-03-17 01:08:48 -03:00
|
|
|
return h->_vt->when & when ? h->_vt->cb(h, when, i) : 0;
|
2015-10-12 16:16:25 +02:00
|
|
|
}
|
|
|
|
|
2016-10-30 22:52:06 -04:00
|
|
|
void * hook_storage(struct hook *h, int when, size_t len, ctor_cb_t ctor, dtor_cb_t dtor)
|
2015-10-09 13:30:41 +02:00
|
|
|
{
|
|
|
|
switch (when) {
|
2016-06-08 22:38:50 +02:00
|
|
|
case HOOK_INIT:
|
|
|
|
h->_vd = alloc(len);
|
2016-10-30 22:52:06 -04:00
|
|
|
|
|
|
|
if (ctor)
|
|
|
|
ctor(h->_vd);
|
|
|
|
|
2015-10-09 13:30:41 +02:00
|
|
|
break;
|
|
|
|
|
2016-10-22 20:42:05 -04:00
|
|
|
case HOOK_DESTROY:
|
2016-10-30 22:52:06 -04:00
|
|
|
if (dtor)
|
|
|
|
dtor(h->_vd);
|
|
|
|
|
2016-06-08 22:38:50 +02:00
|
|
|
free(h->_vd);
|
|
|
|
h->_vd = NULL;
|
2015-10-09 13:30:41 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2016-06-08 22:38:50 +02:00
|
|
|
return h->_vd;
|
2016-11-20 12:59:37 -05:00
|
|
|
}
|
|
|
|
|
2017-03-17 02:52:59 -03:00
|
|
|
int hook_parse_list(struct list *list, config_setting_t *cfg, struct super_node *sn)
|
2017-03-05 10:06:32 -04:00
|
|
|
{
|
2017-03-12 17:13:37 -03:00
|
|
|
struct hook h;
|
2017-03-17 02:52:59 -03:00
|
|
|
struct plugin *p;
|
2016-11-20 12:59:37 -05:00
|
|
|
|
2017-03-17 02:52:59 -03:00
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (!config_setting_is_group(cfg))
|
|
|
|
cerror(cfg, "Hooks must be configured with an object");
|
|
|
|
|
|
|
|
int priority = 10;
|
|
|
|
for (int i = 0; i < config_setting_length(cfg); i++) {
|
|
|
|
config_setting_t *cfg_hook = config_setting_get_elem(cfg, i);
|
|
|
|
|
|
|
|
const char *name = config_setting_name(cfg_hook);
|
|
|
|
|
|
|
|
p = plugin_lookup(PLUGIN_TYPE_HOOK, name);
|
|
|
|
if (!p)
|
|
|
|
continue; /* We ignore all non hook settings in this libconfig object setting */
|
|
|
|
|
|
|
|
if (!config_setting_is_group(cfg_hook))
|
|
|
|
cerror(cfg_hook, "The 'hooks' setting must be an array of strings.");
|
|
|
|
|
|
|
|
ret = hook_init(&h, &p->hook, sn);
|
|
|
|
if (ret)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
h.priority = priority++;
|
|
|
|
|
|
|
|
ret = hook_parse(&h, cfg_hook);
|
|
|
|
if (ret)
|
|
|
|
continue;
|
2016-11-20 12:59:37 -05:00
|
|
|
|
2017-03-17 02:52:59 -03:00
|
|
|
list_push(list, memdup(&h, sizeof(h)));
|
2016-11-20 12:59:37 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
return list_length(list);
|
2015-10-09 13:30:41 +02:00
|
|
|
}
|