Merge pull request #14870 from opensourcerouting/ospfd-shutdown-leaks

ospfd: fix deferred shutdown handling
This commit is contained in:
Russ White 2023-12-05 14:02:35 -05:00 committed by GitHub
commit 03e3b34b4d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 17 additions and 51 deletions

View file

@ -153,6 +153,7 @@ static int ospf_router_info_unregister(void)
void ospf_router_info_term(void) void ospf_router_info_term(void)
{ {
list_delete(&OspfRI.area_info);
list_delete(&OspfRI.pce_info.pce_domain); list_delete(&OspfRI.pce_info.pce_domain);
list_delete(&OspfRI.pce_info.pce_neighbor); list_delete(&OspfRI.pce_info.pce_neighbor);

View file

@ -575,40 +575,12 @@ static struct ospf *ospf_lookup_by_name(const char *vrf_name)
return NULL; return NULL;
} }
/* Handle the second half of deferred shutdown. This is called either /* Timer thread for deferred shutdown */
* from the deferred-shutdown timer thread, or directly through
* ospf_deferred_shutdown_check.
*
* Function is to cleanup G-R state, if required then call ospf_finish_final
* to complete shutdown of this ospf instance. Possibly exit if the
* whole process is being shutdown and this was the last OSPF instance.
*/
static void ospf_deferred_shutdown_finish(struct ospf *ospf)
{
ospf->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED;
EVENT_OFF(ospf->t_deferred_shutdown);
ospf_finish_final(ospf);
/* *ospf is now invalid */
/* ospfd being shut-down? If so, was this the last ospf instance? */
if (CHECK_FLAG(om->options, OSPF_MASTER_SHUTDOWN)
&& (listcount(om->ospf) == 0)) {
route_map_finish();
frr_fini();
exit(0);
}
return;
}
/* Timer thread for G-R */
static void ospf_deferred_shutdown_timer(struct event *t) static void ospf_deferred_shutdown_timer(struct event *t)
{ {
struct ospf *ospf = EVENT_ARG(t); struct ospf *ospf = EVENT_ARG(t);
ospf_deferred_shutdown_finish(ospf); ospf_finish_final(ospf);
} }
/* Check whether deferred-shutdown must be scheduled, otherwise call /* Check whether deferred-shutdown must be scheduled, otherwise call
@ -635,15 +607,12 @@ static void ospf_deferred_shutdown_check(struct ospf *ospf)
ospf_router_lsa_update_area(area); ospf_router_lsa_update_area(area);
} }
timeout = ospf->stub_router_shutdown_time; timeout = ospf->stub_router_shutdown_time;
OSPF_TIMER_ON(ospf->t_deferred_shutdown,
ospf_deferred_shutdown_timer, timeout);
} else { } else {
/* No timer needed */ /* No timer needed */
ospf_deferred_shutdown_finish(ospf); ospf_finish_final(ospf);
return;
} }
OSPF_TIMER_ON(ospf->t_deferred_shutdown, ospf_deferred_shutdown_timer,
timeout);
return;
} }
/* Shut down the entire process */ /* Shut down the entire process */
@ -658,10 +627,6 @@ void ospf_terminate(void)
SET_FLAG(om->options, OSPF_MASTER_SHUTDOWN); SET_FLAG(om->options, OSPF_MASTER_SHUTDOWN);
/* Skip some steps if OSPF not actually running */
if (listcount(om->ospf) == 0)
goto done;
for (ALL_LIST_ELEMENTS(om->ospf, node, nnode, ospf)) for (ALL_LIST_ELEMENTS(om->ospf, node, nnode, ospf))
ospf_finish(ospf); ospf_finish(ospf);
@ -679,9 +644,11 @@ void ospf_terminate(void)
/* Cleanup vrf info */ /* Cleanup vrf info */
ospf_vrf_terminate(); ospf_vrf_terminate();
route_map_finish();
keychain_terminate(); keychain_terminate();
ospf_opaque_term();
list_delete(&om->ospf);
/* Deliberately go back up, hopefully to thread scheduler, as /* Deliberately go back up, hopefully to thread scheduler, as
* One or more ospf_finish()'s may have deferred shutdown to a timer * One or more ospf_finish()'s may have deferred shutdown to a timer
* thread * thread
@ -691,20 +658,17 @@ void ospf_terminate(void)
zclient_stop(zclient_sync); zclient_stop(zclient_sync);
zclient_free(zclient_sync); zclient_free(zclient_sync);
done:
frr_fini(); frr_fini();
} }
void ospf_finish(struct ospf *ospf) void ospf_finish(struct ospf *ospf)
{ {
/* let deferred shutdown decide */ if (CHECK_FLAG(om->options, OSPF_MASTER_SHUTDOWN))
ospf_deferred_shutdown_check(ospf); ospf_finish_final(ospf);
else {
/* if ospf_deferred_shutdown returns, then ospf_finish_final is /* let deferred shutdown decide */
* deferred to expiry of G-S timer thread. Return back up, hopefully ospf_deferred_shutdown_check(ospf);
* to thread scheduler. }
*/
return;
} }
/* Final cleanup of ospf instance */ /* Final cleanup of ospf instance */
@ -904,6 +868,7 @@ static void ospf_finish_final(struct ospf *ospf)
EVENT_OFF(ospf->t_ase_calc); EVENT_OFF(ospf->t_ase_calc);
EVENT_OFF(ospf->t_maxage); EVENT_OFF(ospf->t_maxage);
EVENT_OFF(ospf->t_maxage_walker); EVENT_OFF(ospf->t_maxage_walker);
EVENT_OFF(ospf->t_deferred_shutdown);
EVENT_OFF(ospf->t_abr_task); EVENT_OFF(ospf->t_abr_task);
EVENT_OFF(ospf->t_abr_fr); EVENT_OFF(ospf->t_abr_fr);
EVENT_OFF(ospf->t_asbr_check); EVENT_OFF(ospf->t_asbr_check);