/** \param loader -1 for auto select
* \retval loader_id or negative in case of error */
-int DetectLoaderQueueTask(int loader_id, LoaderFunc Func, void *func_ctx)
+int DetectLoaderQueueTask(int loader_id, LoaderFunc Func, void *func_ctx, LoaderFreeFunc FreeFunc)
{
if (loader_id == -1) {
loader_id = cur_loader;
t->Func = Func;
t->ctx = func_ctx;
+ t->FreeFunc = FreeFunc;
SCMutexLock(&loader->m);
TAILQ_INSERT_TAIL(&loader->task_list, t, next);
int r = task->Func(task->ctx, ftd->instance);
loader->result |= r;
TAILQ_REMOVE(&loader->task_list, task, next);
- SCFree(task->ctx);
+ task->FreeFunc(task->ctx);
SCFree(task);
}
* \param loader_id id of the loader that executed the task
*/
typedef int (*LoaderFunc)(void *ctx, int loader_id);
+typedef void (*LoaderFreeFunc)(void *ctx);
typedef struct DetectLoaderTask_ {
LoaderFunc Func;
void *ctx;
+ LoaderFreeFunc FreeFunc;
TAILQ_ENTRY(DetectLoaderTask_) next;
} DetectLoaderTask;
TAILQ_HEAD(, DetectLoaderTask_) task_list;
} DetectLoaderControl;
-int DetectLoaderQueueTask(int loader_id, LoaderFunc Func, void *func_ctx);
+int DetectLoaderQueueTask(int loader_id, LoaderFunc Func, void *func_ctx, LoaderFreeFunc FreeFunc);
int DetectLoadersSync(void);
void DetectLoadersInit(void);
typedef struct TenantLoaderCtx_ {
uint32_t tenant_id;
int reload_cnt; /**< used by reload */
- const char *yaml;
+ char *yaml; /**< heap alloc'd copy of file path for the yaml */
} TenantLoaderCtx;
+static void DetectLoaderFreeTenant(void *ctx)
+{
+ TenantLoaderCtx *t = (TenantLoaderCtx *)ctx;
+ if (t->yaml != NULL) {
+ SCFree(t->yaml);
+ }
+ SCFree(t);
+}
+
static int DetectLoaderFuncLoadTenant(void *vctx, int loader_id)
{
TenantLoaderCtx *ctx = (TenantLoaderCtx *)vctx;
return -ENOMEM;
t->tenant_id = tenant_id;
- t->yaml = yaml;
+ t->yaml = SCStrdup(yaml);
+ if (t->yaml == NULL) {
+ SCFree(t);
+ return -ENOMEM;
+ }
- return DetectLoaderQueueTask(-1, DetectLoaderFuncLoadTenant, t);
+ return DetectLoaderQueueTask(-1, DetectLoaderFuncLoadTenant, t, DetectLoaderFreeTenant);
}
static int DetectLoaderFuncReloadTenant(void *vctx, int loader_id)
return -ENOMEM;
t->tenant_id = tenant_id;
- t->yaml = yaml;
+ t->yaml = SCStrdup(yaml);
+ if (t->yaml == NULL) {
+ SCFree(t);
+ return -ENOMEM;
+ }
t->reload_cnt = reload_cnt;
SCLogDebug("loader_id %d", loader_id);
- return DetectLoaderQueueTask(loader_id, DetectLoaderFuncReloadTenant, t);
+ return DetectLoaderQueueTask(
+ loader_id, DetectLoaderFuncReloadTenant, t, DetectLoaderFreeTenant);
}
/** \brief Load a tenant and wait for loading to complete
ConfNode *tenant_node = NULL;
if (tenants_root_node != NULL) {
+ const char *path = NULL;
+ ConfNode *path_node = ConfGetNode("multi-detect.config-path");
+ if (path_node) {
+ path = path_node->val;
+ SCLogConfig("tenants config path: %s", path);
+ }
+
TAILQ_FOREACH(tenant_node, &tenants_root_node->head, next) {
ConfNode *id_node = ConfNodeLookupChild(tenant_node, "id");
if (id_node == NULL) {
}
SCLogDebug("tenant id: %u, %s", tenant_id, yaml_node->val);
+ char yaml_path[PATH_MAX] = "";
+ if (path) {
+ PathMerge(yaml_path, PATH_MAX, path, yaml_node->val);
+ } else {
+ strlcpy(yaml_path, yaml_node->val, sizeof(yaml_path));
+ }
+ SCLogDebug("tenant path: %s", yaml_path);
+
/* setup the yaml in this loop so that it's not done by the loader
* threads. ConfYamlLoadFileWithPrefix is not thread safe. */
char prefix[64];
snprintf(prefix, sizeof(prefix), "multi-detect.%u", tenant_id);
- if (ConfYamlLoadFileWithPrefix(yaml_node->val, prefix) != 0) {
- SCLogError("failed to load yaml %s", yaml_node->val);
+ if (ConfYamlLoadFileWithPrefix(yaml_path, prefix) != 0) {
+ SCLogError("failed to load yaml %s", yaml_path);
goto bad_tenant;
}
- int r = DetectLoaderSetupLoadTenant(tenant_id, yaml_node->val);
+ int r = DetectLoaderSetupLoadTenant(tenant_id, yaml_path);
if (r < 0) {
/* error logged already */
goto bad_tenant;