From f06aabc32a1789e50b6c2b59f0f2a294210b562d Mon Sep 17 00:00:00 2001 From: Jeff Lucovsky Date: Fri, 8 Apr 2022 09:39:35 -0400 Subject: [PATCH] log: Add hash table for thread/slot mappings Issue: 5198 This commit adds a hash table to manage thread id to slot mappings. This ensures that each thread will have its own slot (file output device) --- src/util-logopenfile.c | 41 ++++++++++++++++++++++++++++++++++++++++- src/util-logopenfile.h | 12 ++++++++++-- 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/src/util-logopenfile.c b/src/util-logopenfile.c index 9dfa662daa..b6d3732cb3 100644 --- a/src/util-logopenfile.c +++ b/src/util-logopenfile.c @@ -1,5 +1,5 @@ /* vi: set et ts=4: */ -/* Copyright (C) 2007-2021 Open Information Security Foundation +/* Copyright (C) 2007-2022 Open Information Security Foundation * * You can copy, redistribute or modify this Program under the terms of * the GNU General Public License version 2 as published by the Free @@ -323,6 +323,33 @@ static void SCLogFileClose(LogFileCtx *log_ctx) SCMutexUnlock(&log_ctx->fp_mutex); } +static char ThreadSlotHashCompareFunc( + void *data1, uint16_t datalen1, void *data2, uint16_t datalen2) +{ + ThreadSlotHashEntry *p1 = (ThreadSlotHashEntry *)data1; + ThreadSlotHashEntry *p2 = (ThreadSlotHashEntry *)data2; + + if (p1 == NULL || p2 == NULL) + return 0; + + return p1->thread_id == p2->thread_id; +} +static uint32_t ThreadSlotHashFunc(HashTable *ht, void *data, uint16_t datalen) +{ + const ThreadSlotHashEntry *ent = (ThreadSlotHashEntry *)data; + + return ent->thread_id % ht->array_size; +} + +static void ThreadSlotHashFreeFunc(void *data) +{ + ThreadSlotHashEntry *thread_ent = (ThreadSlotHashEntry *)data; + + if (thread_ent) { + SCFree(thread_ent); + } +} + bool SCLogOpenThreadedFile( const char *log_path, const char *append, LogFileCtx *parent_ctx, int slot_count) { @@ -332,6 +359,12 @@ bool SCLogOpenThreadedFile( return false; } + parent_ctx->threads->ht = HashTableInit( + 255, ThreadSlotHashFunc, ThreadSlotHashCompareFunc, ThreadSlotHashFreeFunc); + if (!parent_ctx->threads->ht) { + FatalError("Unable to initialize thread/slot table"); + } + parent_ctx->threads->append = SCStrdup(append == NULL ? DEFAULT_LOG_MODE_APPEND : append); if (!parent_ctx->threads->append) { SCLogError("Unable to allocate threads append setting"); @@ -363,6 +396,9 @@ error_exit: if (parent_ctx->threads->append) { SCFree(parent_ctx->threads->append); } + if (parent_ctx->threads->ht) { + HashTableFree(parent_ctx->threads->ht); + } SCFree(parent_ctx->threads); parent_ctx->threads = NULL; return false; @@ -845,6 +881,9 @@ int LogFileFreeCtx(LogFileCtx *lf_ctx) SCFree(lf_ctx->threads->lf_slots); if (lf_ctx->threads->append) SCFree(lf_ctx->threads->append); + if (lf_ctx->threads->ht) { + HashTableFree(lf_ctx->threads->ht); + } SCFree(lf_ctx->threads); } else { if (lf_ctx->type != LOGFILE_TYPE_PLUGIN) { diff --git a/src/util-logopenfile.h b/src/util-logopenfile.h index 7f0d65ff03..153e3ccdf0 100644 --- a/src/util-logopenfile.h +++ b/src/util-logopenfile.h @@ -27,6 +27,7 @@ #include "threads.h" #include "conf.h" /* ConfNode */ #include "util-buffer.h" +#include "util-hash.h" #ifdef HAVE_LIBHIREDIS #include "util-log-redis.h" @@ -47,11 +48,18 @@ typedef struct SyslogSetup_ { int alert_syslog_level; } SyslogSetup; +typedef struct ThreadSlotHashEntry_ { + uint64_t thread_id; + int slot; /* table slot */ +} ThreadSlotHashEntry; + struct LogFileCtx_; typedef struct LogThreadedFileCtx_ { - int slot_count; SCMutex mutex; - struct LogFileCtx_ **lf_slots; + int slot_count; /* Allocated slot count */ + struct LogFileCtx_ **lf_slots; /* Slots */ + int last_slot; /* Last slot allocated */ + HashTable *ht; char *append; } LogThreadedFileCtx;