33#include " orchdaemon.h"
44#include " logger.h"
55#include < sairedis.h>
6+ #include < limits.h>
7+ #include " notificationproducer.h"
68
79#define SAI_SWITCH_ATTR_CUSTOM_RANGE_BASE SAI_SWITCH_ATTR_CUSTOM_RANGE_START
810#include " sairedis.h"
@@ -27,6 +29,7 @@ RouteOrch *gRouteOrch;
2729AclOrch *gAclOrch ;
2830CrmOrch *gCrmOrch ;
2931BufferOrch *gBufferOrch ;
32+ SwitchOrch *gSwitchOrch ;
3033
3134OrchDaemon::OrchDaemon (DBConnector *applDb, DBConnector *configDb, DBConnector *stateDb) :
3235 m_applDb(applDb),
@@ -49,7 +52,7 @@ bool OrchDaemon::init()
4952
5053 string platform = getenv (" platform" ) ? getenv (" platform" ) : " " ;
5154
52- SwitchOrch *switch_orch = new SwitchOrch (m_applDb, APP_SWITCH_TABLE_NAME);
55+ gSwitchOrch = new SwitchOrch (m_applDb, APP_SWITCH_TABLE_NAME);
5356
5457 const int portsorch_base_pri = 40 ;
5558
@@ -116,7 +119,7 @@ bool OrchDaemon::init()
116119 CFG_DTEL_EVENT_TABLE_NAME
117120 };
118121
119- m_orchList = { switch_orch , gCrmOrch , gBufferOrch , gPortsOrch , intfs_orch, gNeighOrch , gRouteOrch , copp_orch, tunnel_decap_orch, qos_orch, mirror_orch };
122+ m_orchList = { gSwitchOrch , gCrmOrch , gBufferOrch , gPortsOrch , intfs_orch, gNeighOrch , gRouteOrch , copp_orch, tunnel_decap_orch, qos_orch, mirror_orch };
120123
121124 bool initialize_dtel = false ;
122125 if (platform == BFN_PLATFORM_SUBSTRING || platform == VS_PLATFORM_SUBSTRING)
@@ -320,5 +323,69 @@ void OrchDaemon::start()
320323 * is a good chance to flush the pipeline before next select happened.
321324 */
322325 flush ();
326+
327+ /*
328+ * Asked to check warm restart readiness.
329+ * Not doing this under Select::TIMEOUT condition because of
330+ * the existence of finer granularity ExecutableTimer with select
331+ */
332+ if (gSwitchOrch ->checkRestartReady ())
333+ {
334+ bool ret = warmRestartCheckReply ();
335+ if (ret)
336+ {
337+ // Orchagent is ready to perform warm restart, stop processing any new db data.
338+ // Should sleep here or continue handling timers and etc.??
339+ SWSS_LOG_WARN (" Orchagent is frozen for warm restart!" );
340+ sleep (UINT_MAX);
341+ }
342+ }
343+
344+ }
345+ }
346+
347+ /*
348+ * Get tasks to sync for consumers of each orch being managed by this orch daemon
349+ */
350+ void OrchDaemon::getTaskToSync (vector<string> &ts)
351+ {
352+ for (Orch *o : m_orchList)
353+ {
354+ o->dumpToSyncTasks (ts);
323355 }
324356}
357+
358+ /*
359+ * Reply with "READY" notification if no pending tasks, and return true.
360+ * Ortherwise reply with "NOT_READY" notification and return false.
361+ * Further consideration is needed as to when orchagent is treated as warm restart ready.
362+ * For now, no pending task should exist in any orch agent.
363+ */
364+ bool OrchDaemon::warmRestartCheckReply ()
365+ {
366+ NotificationProducer restartRequestReply (m_applDb, " RESTARTCHECKREPLY" );
367+ std::vector<swss::FieldValueTuple> values;
368+ std::string op = " READY" ;
369+ bool ret = true ;
370+
371+ vector<string> ts;
372+ getTaskToSync (ts);
373+
374+ if (ts.size () != 0 )
375+ {
376+ SWSS_LOG_ERROR (" WarmRestart not ready with pending tasks: " );
377+ for (auto &s : ts)
378+ {
379+ SWSS_LOG_NOTICE (" %s" , s.c_str ());
380+ }
381+ op = " NOT_READY" ;
382+ ret = false ;
383+ }
384+
385+ SWSS_LOG_NOTICE (" Restart check result: %s" , op.c_str ());
386+
387+ restartRequestReply.send (op, op, values);
388+ gSwitchOrch ->checkRestartReadyDone ();
389+ return ret;
390+ }
391+
0 commit comments