detect: remove old live reload implementation

Remove code that ran the reload in it's own thread. Simplify the
signal handling.
pull/1389/head
Victor Julien 11 years ago
parent 0c263105cd
commit b1c54a8673

@ -647,325 +647,6 @@ static int DetectEngineReloadThreads(DetectEngineCtx *new_de_ctx)
return -1;
}
static void *DetectEngineLiveRuleSwap(void *arg)
{
SCEnter();
int i = 0;
int no_of_detect_tvs = 0;
DetectEngineCtx *old_de_ctx = NULL;
ThreadVars *tv = NULL;
if (SCSetThreadName("LiveRuleSwap") < 0) {
SCLogWarning(SC_ERR_THREAD_INIT, "Unable to set thread name");
}
SCLogNotice("rule reload starting");
ThreadVars *tv_local = (ThreadVars *)arg;
/* block usr2. usr2 to be handled by the main thread only */
UtilSignalBlock(SIGUSR2);
if (tv_local->thread_setup_flags != 0)
TmThreadSetupOptions(tv_local);
/* release TmThreadSpawn */
TmThreadsSetFlag(tv_local, THV_INIT_DONE);
ConfDeInit();
ConfInit();
/* re-load the yaml file */
if (conf_filename != NULL) {
if (ConfYamlLoadFile(conf_filename) != 0) {
/* Error already displayed. */
exit(EXIT_FAILURE);
}
ConfNode *file;
ConfNode *includes = ConfGetNode("include");
if (includes != NULL) {
TAILQ_FOREACH(file, &includes->head, next) {
char *ifile = ConfLoadCompleteIncludePath(file->val);
SCLogInfo("Live Rule Swap: Including: %s", ifile);
if (ConfYamlLoadFile(ifile) != 0) {
/* Error already displayed. */
exit(EXIT_FAILURE);
}
}
}
} /* if (conf_filename != NULL) */
#if 0
ConfDump();
#endif
SCMutexLock(&tv_root_lock);
tv = tv_root[TVT_PPT];
while (tv) {
/* obtain the slots for this TV */
TmSlot *slots = tv->tm_slots;
while (slots != NULL) {
TmModule *tm = TmModuleGetById(slots->tm_id);
if (suricata_ctl_flags != 0) {
TmThreadsSetFlag(tv_local, THV_CLOSED);
SCLogInfo("rule reload interupted by engine shutdown");
UtilSignalHandlerSetup(SIGUSR2, SignalHandlerSigusr2);
SCMutexUnlock(&tv_root_lock);
pthread_exit(NULL);
}
if (!(tm->flags & TM_FLAG_DETECT_TM)) {
slots = slots->slot_next;
continue;
}
no_of_detect_tvs++;
break;
}
tv = tv->next;
}
if (no_of_detect_tvs == 0) {
TmThreadsSetFlag(tv_local, THV_CLOSED);
UtilSignalHandlerSetup(SIGUSR2, SignalHandlerSigusr2);
SCLogInfo("===== Live rule swap FAILURE =====");
pthread_exit(NULL);
}
DetectEngineThreadCtx *old_det_ctx[no_of_detect_tvs];
DetectEngineThreadCtx *new_det_ctx[no_of_detect_tvs];
ThreadVars *detect_tvs[no_of_detect_tvs];
memset(old_det_ctx, 0x00, (no_of_detect_tvs * sizeof(DetectEngineThreadCtx *)));
memset(new_det_ctx, 0x00, (no_of_detect_tvs * sizeof(DetectEngineThreadCtx *)));
memset(detect_tvs, 0x00, (no_of_detect_tvs * sizeof(ThreadVars *)));
SCMutexUnlock(&tv_root_lock);
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL) {
SCLogError(SC_ERR_LIVE_RULE_SWAP, "Allocation failure in live "
"swap. Let's get out of here.");
goto error;
}
if (SigLoadSignatures(de_ctx, NULL, FALSE) < 0) {
SCLogError(SC_ERR_NO_RULES_LOADED, "Loading signatures failed.");
if (de_ctx->failure_fatal)
exit(EXIT_FAILURE);
DetectEngineCtxFree(de_ctx);
SCLogError(SC_ERR_LIVE_RULE_SWAP, "Failure encountered while "
"loading new ruleset with live swap.");
SCLogError(SC_ERR_LIVE_RULE_SWAP, "rule reload failed");
TmThreadsSetFlag(tv_local, THV_CLOSED);
UtilSignalHandlerSetup(SIGUSR2, SignalHandlerSigusr2);
pthread_exit(NULL);
}
SCThresholdConfInitContext(de_ctx, NULL);
/* start the process of swapping detect threads ctxs */
SCMutexLock(&tv_root_lock);
/* all receive threads are part of packet processing threads */
tv = tv_root[TVT_PPT];
while (tv) {
/* obtain the slots for this TV */
TmSlot *slots = tv->tm_slots;
while (slots != NULL) {
TmModule *tm = TmModuleGetById(slots->tm_id);
if (suricata_ctl_flags != 0) {
TmThreadsSetFlag(tv_local, THV_CLOSED);
SCLogInfo("rule reload interupted by engine shutdown");
UtilSignalHandlerSetup(SIGUSR2, SignalHandlerSigusr2);
SCMutexUnlock(&tv_root_lock);
pthread_exit(NULL);
}
if (!(tm->flags & TM_FLAG_DETECT_TM)) {
slots = slots->slot_next;
continue;
}
old_det_ctx[i] = SC_ATOMIC_GET(slots->slot_data);
detect_tvs[i] = tv;
TmEcode r = DetectEngineThreadCtxInitForLiveRuleSwap(tv, (void *)de_ctx,
(void **)&new_det_ctx[i]);
i++;
if (r == TM_ECODE_FAILED) {
SCLogError(SC_ERR_LIVE_RULE_SWAP, "Detect engine thread init "
"failure in live rule swap. Let's get out of here");
SCMutexUnlock(&tv_root_lock);
goto error;
}
SCLogDebug("live rule swap created new det_ctx - %p and de_ctx "
"- %p\n", new_det_ctx, de_ctx);
break;
}
tv = tv->next;
}
i = 0;
tv = tv_root[TVT_PPT];
while (tv) {
TmSlot *slots = tv->tm_slots;
while (slots != NULL) {
if (suricata_ctl_flags != 0) {
TmThreadsSetFlag(tv_local, THV_CLOSED);
SCLogInfo("rule reload interupted by engine shutdown");
UtilSignalHandlerSetup(SIGUSR2, SignalHandlerSigusr2);
SCMutexUnlock(&tv_root_lock);
pthread_exit(NULL);
}
TmModule *tm = TmModuleGetById(slots->tm_id);
if (!(tm->flags & TM_FLAG_DETECT_TM)) {
slots = slots->slot_next;
continue;
}
SCLogDebug("swapping new det_ctx - %p with older one - %p",
new_det_ctx[i], SC_ATOMIC_GET(slots->slot_data));
(void)SC_ATOMIC_SET(slots->slot_data, new_det_ctx[i++]);
break;
}
tv = tv->next;
}
SCMutexUnlock(&tv_root_lock);
SCLogInfo("Live rule swap has swapped %d old det_ctx's with new ones, "
"along with the new de_ctx", no_of_detect_tvs);
for (i = 0; i < no_of_detect_tvs; i++) {
int break_out = 0;
int pseudo_pkt_inserted = 0;
usleep(1000);
while (SC_ATOMIC_GET(new_det_ctx[i]->so_far_used_by_detect) != 1) {
if (suricata_ctl_flags != 0) {
break_out = 1;
break;
}
if (pseudo_pkt_inserted == 0) {
pseudo_pkt_inserted = 1;
if (detect_tvs[i]->inq != NULL) {
Packet *p = PacketGetFromAlloc();
if (p != NULL) {
p->flags |= PKT_PSEUDO_STREAM_END;
PacketQueue *q = &trans_q[detect_tvs[i]->inq->id];
SCMutexLock(&q->mutex_q);
PacketEnqueue(q, p);
SCCondSignal(&q->cond_q);
SCMutexUnlock(&q->mutex_q);
}
}
}
usleep(1000);
}
if (break_out)
break;
SCLogDebug("new_det_ctx - %p used by detect engine", new_det_ctx[i]);
}
/* this is to make sure that if someone initiated shutdown during a live
* rule swap, the live rule swap won't clean up the old det_ctx and
* de_ctx, till all detect threads have stopped working and sitting
* silently after setting RUNNING_DONE flag and while waiting for
* THV_DEINIT flag */
if (i != no_of_detect_tvs) {
ThreadVars *tv = tv_root[TVT_PPT];
while (tv) {
/* obtain the slots for this TV */
TmSlot *slots = tv->tm_slots;
while (slots != NULL) {
TmModule *tm = TmModuleGetById(slots->tm_id);
if (!(tm->flags & TM_FLAG_DETECT_TM)) {
slots = slots->slot_next;
continue;
}
while (!TmThreadsCheckFlag(tv, THV_RUNNING_DONE)) {
usleep(100);
}
slots = slots->slot_next;
}
tv = tv->next;
}
}
/* free all the ctxs */
old_de_ctx = old_det_ctx[0]->de_ctx;
for (i = 0; i < no_of_detect_tvs; i++) {
SCLogDebug("Freeing old_det_ctx - %p used by detect",
old_det_ctx[i]);
DetectEngineThreadCtxDeinit(NULL, old_det_ctx[i]);
}
DetectEngineCtxFree(old_de_ctx);
SRepReloadComplete();
/* reset the handler */
UtilSignalHandlerSetup(SIGUSR2, SignalHandlerSigusr2);
TmThreadsSetFlag(tv_local, THV_CLOSED);
SCLogNotice("rule reload complete");
pthread_exit(NULL);
error:
for (i = 0; i < no_of_detect_tvs; i++) {
if (new_det_ctx[i] != NULL)
DetectEngineThreadCtxDeinit(NULL, new_det_ctx[i]);
}
DetectEngineCtxFree(de_ctx);
TmThreadsSetFlag(tv_local, THV_CLOSED);
UtilSignalHandlerSetup(SIGUSR2, SignalHandlerSigusr2);
SCLogInfo("===== Live rule swap FAILURE =====");
pthread_exit(NULL);
}
void DetectEngineSpawnLiveRuleSwapMgmtThread(void)
{
SCEnter();
SCLogDebug("Spawning mgmt thread for live rule swap");
ThreadVars *tv = TmThreadCreateMgmtThread("DetectEngineLiveRuleSwap",
DetectEngineLiveRuleSwap, 0);
if (tv == NULL) {
SCLogError(SC_ERR_THREAD_CREATE, "Live rule swap thread spawn failed");
exit(EXIT_FAILURE);
}
TmThreadSetCPU(tv, MANAGEMENT_CPU_SET);
if (TmThreadSpawn(tv) != 0) {
SCLogError(SC_ERR_THREAD_SPAWN, "TmThreadSpawn failed for "
"DetectEngineLiveRuleSwap");
exit(EXIT_FAILURE);
}
SCReturn;
}
static DetectEngineCtx *DetectEngineCtxInitReal(int minimal)
{
DetectEngineCtx *de_ctx;

@ -55,7 +55,6 @@ extern DetectEngineAppInspectionEngine *app_inspection_engine[FLOW_PROTO_DEFAULT
/* prototypes */
void DetectEngineRegisterAppInspectionEngines(void);
void DetectEngineSpawnLiveRuleSwapMgmtThread(void);
DetectEngineCtx *DetectEngineCtxInit(void);
DetectEngineCtx *DetectEngineCtxInitMinimal(void);
void DetectEngineCtxFree(DetectEngineCtx *);

@ -279,15 +279,11 @@ static void SignalHandlerSigterm(/*@unused@*/ int sig)
void SignalHandlerSigusr2Disabled(int sig)
{
SCLogInfo("Live rule reload not enabled in config.");
return;
}
void SignalHandlerSigusr2StartingUp(int sig)
{
SCLogInfo("Live rule reload only possible after engine completely started.");
return;
}
void SignalHandlerSigusr2DelayedDetect(int sig)
@ -298,42 +294,14 @@ void SignalHandlerSigusr2DelayedDetect(int sig)
void SignalHandlerSigusr2SigFileStartup(int sig)
{
SCLogInfo("Live rule reload not possible if -s or -S option used at runtime.");
return;
}
void SignalHandlerSigusr2Idle(int sig)
{
if (run_mode == RUNMODE_UNKNOWN || run_mode == RUNMODE_UNITTEST) {
SCLogInfo("Ruleset load signal USR2 triggered for wrong runmode");
return;
}
SCLogInfo("Ruleset load in progress. New ruleset load "
"allowed after current is done");
return;
}
/**
* SIGUSR2 handler. Just set sigusr2_count. The main loop will act on
* it.
*/
void SignalHandlerSigusr2(int sig)
{
#if 0
if (run_mode == RUNMODE_UNKNOWN || run_mode == RUNMODE_UNITTEST) {
SCLogInfo("Ruleset load signal USR2 triggered for wrong runmode");
return;
}
if (suricata_ctl_flags != 0) {
SCLogInfo("Live rule swap no longer possible. Engine in shutdown mode.");
return;
}
UtilSignalHandlerSetup(SIGUSR2, SignalHandlerSigusr2Idle);
DetectEngineSpawnLiveRuleSwapMgmtThread();
return;
#endif
sigusr2_count = 1;
}
@ -2476,20 +2444,6 @@ int main(int argc, char **argv)
SCPrintElapsedTime(&suri);
if (suri.rule_reload == 1) {
/* wait if live rule swap is in progress */
if (UtilSignalIsHandler(SIGUSR2, SignalHandlerSigusr2Idle)) {
SCLogInfo("Live rule swap in progress. Waiting for it to end "
"before we shut the engine/threads down");
while (UtilSignalIsHandler(SIGUSR2, SignalHandlerSigusr2Idle)) {
/* sleep for 0.5 seconds */
usleep(500000);
}
SCLogInfo("Received notification that live rule swap is done. "
"Continuing with engine/threads shutdown");
}
}
/* before TmThreadKillThreads, as otherwise that kills it
* but more slowly */
if (suri.run_mode != RUNMODE_UNIX_SOCKET) {

Loading…
Cancel
Save