Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ospfd: fix deferred shutdown handling #14870

Merged
merged 2 commits into from
Dec 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ospfd/ospf_ri.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ static int ospf_router_info_unregister(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_neighbor);

Expand Down
67 changes: 16 additions & 51 deletions ospfd/ospfd.c
Original file line number Diff line number Diff line change
Expand Up @@ -575,40 +575,12 @@ static struct ospf *ospf_lookup_by_name(const char *vrf_name)
return NULL;
}

/* Handle the second half of deferred shutdown. This is called either
* 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 */
/* Timer thread for deferred shutdown */
static void ospf_deferred_shutdown_timer(struct event *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
Expand All @@ -635,15 +607,12 @@ static void ospf_deferred_shutdown_check(struct ospf *ospf)
ospf_router_lsa_update_area(area);
}
timeout = ospf->stub_router_shutdown_time;
OSPF_TIMER_ON(ospf->t_deferred_shutdown,
ospf_deferred_shutdown_timer, timeout);
} else {
/* No timer needed */
ospf_deferred_shutdown_finish(ospf);
return;
ospf_finish_final(ospf);
}

OSPF_TIMER_ON(ospf->t_deferred_shutdown, ospf_deferred_shutdown_timer,
timeout);
return;
}

/* Shut down the entire process */
Expand All @@ -658,10 +627,6 @@ void ospf_terminate(void)

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))
ospf_finish(ospf);

Expand All @@ -679,9 +644,11 @@ void ospf_terminate(void)
/* Cleanup vrf info */
ospf_vrf_terminate();

route_map_finish();

keychain_terminate();

ospf_opaque_term();
list_delete(&om->ospf);

/* Deliberately go back up, hopefully to thread scheduler, as
* One or more ospf_finish()'s may have deferred shutdown to a timer
* thread
Expand All @@ -691,20 +658,17 @@ void ospf_terminate(void)
zclient_stop(zclient_sync);
zclient_free(zclient_sync);

done:
frr_fini();
}

void ospf_finish(struct ospf *ospf)
{
/* let deferred shutdown decide */
ospf_deferred_shutdown_check(ospf);

/* if ospf_deferred_shutdown returns, then ospf_finish_final is
* deferred to expiry of G-S timer thread. Return back up, hopefully
* to thread scheduler.
*/
return;
if (CHECK_FLAG(om->options, OSPF_MASTER_SHUTDOWN))
ospf_finish_final(ospf);
else {
/* let deferred shutdown decide */
ospf_deferred_shutdown_check(ospf);
}
}

/* Final cleanup of ospf instance */
Expand Down Expand Up @@ -904,6 +868,7 @@ static void ospf_finish_final(struct ospf *ospf)
EVENT_OFF(ospf->t_ase_calc);
EVENT_OFF(ospf->t_maxage);
EVENT_OFF(ospf->t_maxage_walker);
EVENT_OFF(ospf->t_deferred_shutdown);
EVENT_OFF(ospf->t_abr_task);
EVENT_OFF(ospf->t_abr_fr);
EVENT_OFF(ospf->t_asbr_check);
Expand Down
Loading