diff --git a/orchagent/Makefile.am b/orchagent/Makefile.am index e2bd73ff4e9..24249c5ff2e 100644 --- a/orchagent/Makefile.am +++ b/orchagent/Makefile.am @@ -1,4 +1,4 @@ -INCLUDES = -I $(top_srcdir) +INCLUDES = -I $(top_srcdir) -I $(top_srcdir)/warmrestart CFLAGS_SAI = -I /usr/include/sai @@ -66,12 +66,14 @@ orchagent_SOURCES = \ switchorch.h \ swssnet.h \ tunneldecaporch.h \ - crmorch.h + crmorch.h \ request_parser.h \ vrforch.h \ dtelorch.h \ countercheckorch.h \ - flexcounterorch.h + flexcounterorch.h \ + $(top_srcdir)/warmrestart/warm_restart.cpp \ + $(top_srcdir)/warmrestart/warm_restart.h orchagent_CFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_SAI) orchagent_CPPFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_SAI) diff --git a/orchagent/aclorch.cpp b/orchagent/aclorch.cpp index 1922942d37b..2589e4507c0 100644 --- a/orchagent/aclorch.cpp +++ b/orchagent/aclorch.cpp @@ -1291,7 +1291,7 @@ bool AclRuleDTelFlowWatchListEntry::validateAddAction(string attr_name, string a sai_object_id_t session_oid; if (!m_pDTelOrch || - (attr_name != ACTION_DTEL_FLOW_OP && + (attr_name != ACTION_DTEL_FLOW_OP && attr_name != ACTION_DTEL_INT_SESSION && attr_name != ACTION_DTEL_FLOW_SAMPLE_PERCENT && attr_name != ACTION_DTEL_REPORT_ALL_PACKETS)) @@ -1356,7 +1356,7 @@ bool AclRuleDTelFlowWatchListEntry::validateAddAction(string attr_name, string a value.aclaction.parameter.booldata = (attr_value == DTEL_ENABLED) ? true : false; value.aclaction.enable = (attr_value == DTEL_ENABLED) ? true : false; } - + m_actions[aclDTelActionLookup[attr_name]] = value; return true; @@ -1514,7 +1514,7 @@ bool AclRuleDTelDropWatchListEntry::validateAddAction(string attr_name, string a value.aclaction.parameter.booldata = (attr_value == DTEL_ENABLED) ? true : false; value.aclaction.enable = (attr_value == DTEL_ENABLED) ? true : false; - + m_actions[aclDTelActionLookup[attr_name]] = value; return true; @@ -1693,8 +1693,8 @@ void AclOrch::init(vector& connectors, PortsOrch *portOrch, Mirr // initialized before thread start. auto interv = timespec { .tv_sec = COUNTERS_READ_INTERVAL, .tv_nsec = 0 }; auto timer = new SelectableTimer(interv); - auto executor = new ExecutableTimer(timer, this); - Orch::addExecutor("", executor); + auto executor = new ExecutableTimer(timer, this, "ACL_POLL_TIMER"); + Orch::addExecutor(executor); timer->start(); } @@ -2320,7 +2320,7 @@ sai_status_t AclOrch::bindAclTable(sai_object_id_t table_oid, AclTable &aclTable sai_status_t status = SAI_STATUS_SUCCESS; SWSS_LOG_INFO("%s table %s to ports", bind ? "Bind" : "Unbind", aclTable.id.c_str()); - + if (aclTable.ports.empty()) { if (bind) @@ -2431,7 +2431,7 @@ sai_status_t AclOrch::createDTelWatchListTables() SWSS_LOG_INFO("Successfully created ACL table %s, oid: %lX", flowWLTable.description.c_str(), table_oid); /* Create Drop watchlist ACL table */ - + table_attrs.clear(); dropWLTable.id = TABLE_TYPE_DTEL_DROP_WATCHLIST; diff --git a/orchagent/countercheckorch.cpp b/orchagent/countercheckorch.cpp index f404c07e51d..aa46758626b 100644 --- a/orchagent/countercheckorch.cpp +++ b/orchagent/countercheckorch.cpp @@ -30,8 +30,8 @@ CounterCheckOrch::CounterCheckOrch(DBConnector *db, vector &tableNames): auto interv = timespec { .tv_sec = COUNTER_CHECK_POLL_TIMEOUT_SEC, .tv_nsec = 0 }; auto timer = new SelectableTimer(interv); - auto executor = new ExecutableTimer(timer, this); - Orch::addExecutor("MC_COUNTERS_POLL", executor); + auto executor = new ExecutableTimer(timer, this, "MC_COUNTERS_POLL"); + Orch::addExecutor(executor); timer->start(); } diff --git a/orchagent/crmorch.cpp b/orchagent/crmorch.cpp index e7e89eac836..56f7e5bb380 100644 --- a/orchagent/crmorch.cpp +++ b/orchagent/crmorch.cpp @@ -162,8 +162,11 @@ CrmOrch::CrmOrch(DBConnector *db, string tableName): m_resourcesMap.emplace(res.first, CrmResourceEntry(res.second, CRM_THRESHOLD_TYPE_DEFAULT, CRM_THRESHOLD_LOW_DEFAULT, CRM_THRESHOLD_HIGH_DEFAULT)); } - auto executor = new ExecutableTimer(m_timer.get(), this); - Orch::addExecutor("CRM_COUNTERS_POLL", executor); + // The CRM stats needs to be populated again + m_countersCrmTable->del(CRM_COUNTERS_TABLE_KEY); + + auto executor = new ExecutableTimer(m_timer.get(), this, "CRM_COUNTERS_POLL"); + Orch::addExecutor(executor); m_timer->start(); } @@ -333,7 +336,7 @@ void CrmOrch::decCrmAclUsedCounter(CrmResourceType resource, sai_acl_stage_t sta { m_resourcesMap.at(resource).countersMap[getCrmAclKey(stage, point)].usedCounter--; - // Remove ACL table related counters + // Remove ACL table related counters if (resource == CrmResourceType::CRM_ACL_TABLE) { auto & cntMap = m_resourcesMap.at(CrmResourceType::CRM_ACL_TABLE).countersMap; diff --git a/orchagent/fdborch.cpp b/orchagent/fdborch.cpp index 7d265d35377..f5ee04ce21f 100644 --- a/orchagent/fdborch.cpp +++ b/orchagent/fdborch.cpp @@ -26,14 +26,14 @@ FdbOrch::FdbOrch(DBConnector *db, string tableName, PortsOrch *port) : { m_portsOrch->attach(this); m_flushNotificationsConsumer = new NotificationConsumer(db, "FLUSHFDBREQUEST"); - auto flushNotifier = new Notifier(m_flushNotificationsConsumer, this); - Orch::addExecutor("", flushNotifier); + auto flushNotifier = new Notifier(m_flushNotificationsConsumer, this, "FLUSHFDBREQUEST"); + Orch::addExecutor(flushNotifier); /* Add FDB notifications support from ASIC */ DBConnector *notificationsDb = new DBConnector(ASIC_DB, DBConnector::DEFAULT_UNIXSOCKET, 0); m_fdbNotificationConsumer = new swss::NotificationConsumer(notificationsDb, "NOTIFICATIONS"); - auto fdbNotifier = new Notifier(m_fdbNotificationConsumer, this); - Orch::addExecutor("FDB_NOTIFICATIONS", fdbNotifier); + auto fdbNotifier = new Notifier(m_fdbNotificationConsumer, this, "FDB_NOTIFICATIONS"); + Orch::addExecutor(fdbNotifier); } void FdbOrch::update(sai_fdb_event_t type, const sai_fdb_entry_t* entry, sai_object_id_t bridge_port_id) @@ -53,6 +53,14 @@ void FdbOrch::update(sai_fdb_event_t type, const sai_fdb_entry_t* entry, sai_obj return; } + // we already have such entries + if (m_entries.find(update.entry) != m_entries.end()) + { + SWSS_LOG_INFO("FdbOrch notification: mac %s is already in bv_id 0x%lx", + update.entry.mac.to_string().c_str(), entry->bv_id); + break; + } + update.add = true; { diff --git a/orchagent/main.cpp b/orchagent/main.cpp index 0c54b1a2ae2..0f15928b4d3 100644 --- a/orchagent/main.cpp +++ b/orchagent/main.cpp @@ -23,6 +23,7 @@ extern "C" { #include "saihelper.h" #include "notifications.h" #include +#include "warm_restart.h" using namespace std; using namespace swss; @@ -78,11 +79,29 @@ void sighup_handler(int signo) } } +void syncd_apply_view() +{ + SWSS_LOG_NOTICE("Notify syncd APPLY_VIEW"); + + sai_status_t status; + sai_attribute_t attr; + attr.id = SAI_REDIS_SWITCH_ATTR_NOTIFY_SYNCD; + attr.value.s32 = SAI_REDIS_NOTIFY_SYNCD_APPLY_VIEW; + status = sai_switch_api->set_switch_attribute(gSwitchId, &attr); + + if (status != SAI_STATUS_SUCCESS) + { + SWSS_LOG_ERROR("Failed to notify syncd APPLY_VIEW %d", status); + exit(EXIT_FAILURE); + } +} + int main(int argc, char **argv) { swss::Logger::linkToDbNative("orchagent"); SWSS_LOG_ENTER(); + WarmStart::checkWarmStart("orchagent"); if (signal(SIGHUP, sighup_handler) == SIG_ERR) { @@ -262,16 +281,9 @@ int main(int argc, char **argv) exit(EXIT_FAILURE); } - SWSS_LOG_NOTICE("Notify syncd APPLY_VIEW"); - - attr.id = SAI_REDIS_SWITCH_ATTR_NOTIFY_SYNCD; - attr.value.s32 = SAI_REDIS_NOTIFY_SYNCD_APPLY_VIEW; - status = sai_switch_api->set_switch_attribute(gSwitchId, &attr); - - if (status != SAI_STATUS_SUCCESS) + if (!WarmStart::isWarmStart()) { - SWSS_LOG_ERROR("Failed to notify syncd APPLY_VIEW %d", status); - exit(EXIT_FAILURE); + syncd_apply_view(); } orchDaemon->start(); diff --git a/orchagent/notifier.h b/orchagent/notifier.h index 6113c805271..ca9011f23df 100644 --- a/orchagent/notifier.h +++ b/orchagent/notifier.h @@ -2,8 +2,8 @@ class Notifier : public Executor { public: - Notifier(NotificationConsumer *select, Orch *orch) - : Executor(select, orch) + Notifier(NotificationConsumer *select, Orch *orch, const string &name) + : Executor(select, orch, name) { } diff --git a/orchagent/orch.cpp b/orchagent/orch.cpp index 937c226b4fe..3645f9d913f 100644 --- a/orchagent/orch.cpp +++ b/orchagent/orch.cpp @@ -185,6 +185,30 @@ void Consumer::drain() m_orch->doTask(*this); } +string Consumer::dumpTuple(KeyOpFieldsValuesTuple &tuple) +{ + string s = getTableName() + getConsumerTable()->getTableNameSeparator() + kfvKey(tuple) + + "|" + kfvOp(tuple); + for (auto i = kfvFieldsValues(tuple).begin(); i != kfvFieldsValues(tuple).end(); i++) + { + s += "|" + fvField(*i) + ":" + fvValue(*i); + } + + return s; +} + +void Consumer::dumpPendingTasks(vector &ts) +{ + for (auto &tm : m_toSync) + { + KeyOpFieldsValuesTuple& tuple = tm.second; + + string s = dumpTuple(tuple); + + ts.push_back(s); + } +} + size_t Orch::addExistingData(const string& tableName) { auto consumer = dynamic_cast(getExecutor(tableName)); @@ -224,7 +248,7 @@ bool Orch::bake() { continue; } - + size_t refilled = consumer->refillToSync(); SWSS_LOG_NOTICE("Add warm input: %s, %zd", executorName.c_str(), refilled); } @@ -326,6 +350,21 @@ void Orch::doTask() } } +void Orch::dumpPendingTasks(vector &ts) +{ + for(auto &it : m_consumerMap) + { + Consumer* consumer = dynamic_cast(it.second.get()); + if (consumer == NULL) + { + SWSS_LOG_DEBUG("Executor is not a Consumer"); + continue; + } + + consumer->dumpPendingTasks(ts); + } +} + void Orch::logfileReopen() { gRecordOfs.close(); @@ -347,12 +386,7 @@ void Orch::logfileReopen() void Orch::recordTuple(Consumer &consumer, KeyOpFieldsValuesTuple &tuple) { - string s = consumer.getTableName() + ":" + kfvKey(tuple) - + "|" + kfvOp(tuple); - for (auto i = kfvFieldsValues(tuple).begin(); i != kfvFieldsValues(tuple).end(); i++) - { - s += "|" + fvField(*i) + ":" + fvValue(*i); - } + string s = consumer.dumpTuple(tuple); gRecordOfs << getTimestamp() << "|" << s << endl; @@ -366,13 +400,7 @@ void Orch::recordTuple(Consumer &consumer, KeyOpFieldsValuesTuple &tuple) string Orch::dumpTuple(Consumer &consumer, KeyOpFieldsValuesTuple &tuple) { - string s = consumer.getTableName() + ":" + kfvKey(tuple) - + "|" + kfvOp(tuple); - for (auto i = kfvFieldsValues(tuple).begin(); i != kfvFieldsValues(tuple).end(); i++) - { - s += "|" + fvField(*i) + ":" + fvValue(*i); - } - + string s = consumer.dumpTuple(tuple); return s; } @@ -461,24 +489,24 @@ void Orch::addConsumer(DBConnector *db, string tableName, int pri) { if (db->getDbId() == CONFIG_DB || db->getDbId() == STATE_DB) { - addExecutor(tableName, new Consumer(new SubscriberStateTable(db, tableName, TableConsumable::DEFAULT_POP_BATCH_SIZE, pri), this)); + addExecutor(new Consumer(new SubscriberStateTable(db, tableName, TableConsumable::DEFAULT_POP_BATCH_SIZE, pri), this, tableName)); } else { - addExecutor(tableName, new Consumer(new ConsumerStateTable(db, tableName, gBatchSize, pri), this)); + addExecutor(new Consumer(new ConsumerStateTable(db, tableName, gBatchSize, pri), this, tableName)); } } -void Orch::addExecutor(string executorName, Executor* executor) +void Orch::addExecutor(Executor* executor) { auto inserted = m_consumerMap.emplace(std::piecewise_construct, - std::forward_as_tuple(executorName), + std::forward_as_tuple(executor->getName()), std::forward_as_tuple(executor)); // If there is duplication of executorName in m_consumerMap, logic error if (!inserted.second) { - SWSS_LOG_THROW("Duplicated executorName in m_consumerMap: %s", executorName.c_str()); + SWSS_LOG_THROW("Duplicated executorName in m_consumerMap: %s", executor->getName().c_str()); } } diff --git a/orchagent/orch.h b/orchagent/orch.h index 14fde1c78a6..48239af8237 100644 --- a/orchagent/orch.h +++ b/orchagent/orch.h @@ -68,9 +68,10 @@ class Orch; class Executor : public Selectable { public: - Executor(Selectable *selectable, Orch *orch) + Executor(Selectable *selectable, Orch *orch, const string &name) : m_selectable(selectable) , m_orch(orch) + , m_name(name) { } @@ -91,18 +92,26 @@ class Executor : public Selectable virtual void execute() { } virtual void drain() { } + virtual string getName() const + { + return m_name; + } + protected: Selectable *m_selectable; Orch *m_orch; + // Name for Executor + string m_name; + // Get the underlying selectable Selectable *getSelectable() const { return m_selectable; } }; class Consumer : public Executor { public: - Consumer(ConsumerTableBase *select, Orch *orch) - : Executor(select, orch) + Consumer(ConsumerTableBase *select, Orch *orch, const string &name) + : Executor(select, orch, name) { } @@ -116,6 +125,14 @@ class Consumer : public Executor { return getConsumerTable()->getTableName(); } + int getDbId() const + { + return getConsumerTable()->getDbId(); + } + + string dumpTuple(KeyOpFieldsValuesTuple &tuple); + void dumpPendingTasks(vector &ts); + size_t refillToSync(); size_t refillToSync(Table* table); void execute(); @@ -124,7 +141,7 @@ class Consumer : public Executor { /* Store the latest 'golden' status */ // TODO: hide? SyncMap m_toSync; - + protected: // Returns: the number of entries added to m_toSync size_t addToSync(std::deque &entries); @@ -162,7 +179,7 @@ class Orch // Prepare for warm start if Redis contains valid input data // otherwise fallback to cold start virtual bool bake(); - + /* Iterate all consumers in m_consumerMap and run doTask(Consumer) */ void doTask(); @@ -173,6 +190,8 @@ class Orch /* TODO: refactor recording */ static void recordTuple(Consumer &consumer, KeyOpFieldsValuesTuple &tuple); + + void dumpPendingTasks(vector &ts); protected: ConsumerMap m_consumerMap; @@ -184,7 +203,7 @@ class Orch ref_resolve_status resolveFieldRefArray(type_map&, const string&, KeyOpFieldsValuesTuple&, vector&); /* Note: consumer will be owned by this class */ - void addExecutor(string executorName, Executor* executor); + void addExecutor(Executor* executor); Executor *getExecutor(string executorName); private: void addConsumer(DBConnector *db, string tableName, int pri = default_orch_pri); diff --git a/orchagent/orchdaemon.cpp b/orchagent/orchdaemon.cpp index 1df3d038ebc..63de2326f28 100644 --- a/orchagent/orchdaemon.cpp +++ b/orchagent/orchdaemon.cpp @@ -3,6 +3,7 @@ #include "orchdaemon.h" #include "logger.h" #include +#include "warm_restart.h" #define SAI_SWITCH_ATTR_CUSTOM_RANGE_BASE SAI_SWITCH_ATTR_CUSTOM_RANGE_START #include "sairedis.h" @@ -16,7 +17,7 @@ using namespace swss; extern sai_switch_api_t* sai_switch_api; extern sai_object_id_t gSwitchId; - +extern void syncd_apply_view(); /* * Global orch daemon variables */ @@ -28,6 +29,7 @@ RouteOrch *gRouteOrch; AclOrch *gAclOrch; CrmOrch *gCrmOrch; BufferOrch *gBufferOrch; +SwitchOrch *gSwitchOrch; OrchDaemon::OrchDaemon(DBConnector *applDb, DBConnector *configDb, DBConnector *stateDb) : m_applDb(applDb), @@ -50,7 +52,7 @@ bool OrchDaemon::init() string platform = getenv("platform") ? getenv("platform") : ""; - SwitchOrch *switch_orch = new SwitchOrch(m_applDb, APP_SWITCH_TABLE_NAME); + gSwitchOrch = new SwitchOrch(m_applDb, APP_SWITCH_TABLE_NAME); const int portsorch_base_pri = 40; @@ -117,7 +119,15 @@ bool OrchDaemon::init() CFG_DTEL_EVENT_TABLE_NAME }; - m_orchList = { switch_orch, gCrmOrch, gBufferOrch, gPortsOrch, gIntfsOrch, gNeighOrch, gRouteOrch, copp_orch, tunnel_decap_orch, qos_orch, mirror_orch }; + /* + * The order of the orch list is important for state restore of warm start and + * the queued processing in m_toSync map after gPortsOrch->isInitDone() is set. + * + * For the multiple consumers in ports_tables, tasks for LAG_TABLE is processed before VLAN_TABLE + * when iterating ConsumerMap. + * That is ensured implicitly by the order of map key, "LAG_TABLE" is smaller than "VLAN_TABLE" in lexicographic order. + */ + m_orchList = { gSwitchOrch, gCrmOrch, gBufferOrch, gPortsOrch, gIntfsOrch, gNeighOrch, gRouteOrch, copp_orch, tunnel_decap_orch, qos_orch}; bool initialize_dtel = false; if (platform == BFN_PLATFORM_SUBSTRING || platform == VS_PLATFORM_SUBSTRING) @@ -153,13 +163,13 @@ bool OrchDaemon::init() gAclOrch = new AclOrch(acl_table_connectors, gPortsOrch, mirror_orch, gNeighOrch, gRouteOrch); } - m_orchList.push_back(gAclOrch); m_orchList.push_back(gFdbOrch); + m_orchList.push_back(mirror_orch); + m_orchList.push_back(gAclOrch); m_orchList.push_back(vrf_orch); m_select = new Select(); - vector flex_counter_tables = { CFG_FLEX_COUNTER_TABLE_NAME }; @@ -275,11 +285,7 @@ void OrchDaemon::start() { SWSS_LOG_ENTER(); - // Try warm start - for (Orch *o : m_orchList) - { - o->bake(); - } + warmRestoreAndSyncUp(); for (Orch *o : m_orchList) { @@ -323,3 +329,90 @@ void OrchDaemon::start() flush(); } } + +/* + * Try to perform orchagent state restore and dynamic states sync up if + * warm start reqeust is detected. + */ +void OrchDaemon::warmRestoreAndSyncUp() +{ + if (!WarmStart::isWarmStart()) + { + return; + } + + WarmStart::setWarmStartState("orchagent", WarmStart::INIT); + + for (Orch *o : m_orchList) + { + o->bake(); + } + + /* + * First iteration is to handle all the existing data in predefined order. + */ + for (Orch *o : m_orchList) + { + o->doTask(); + } + /* + * Drain remaining data that are out of order like LAG_MEMBER_TABLE and VLAN_MEMBER_TABLE + * since they were checked before LAG_TABLE and VLAN_TABLE. + */ + for (Orch *o : m_orchList) + { + o->doTask(); + } + + /* + * At this point, all the pre-existing data should have been processed properly, and + * orchagent should be in exact same state of pre-shutdown. + * Perform restore validation as needed. + */ + warmRestoreValidation(); + + SWSS_LOG_NOTICE("Orchagent state restore done"); + syncd_apply_view(); + + /* TODO: perform port and fdb state sync up*/ + + /* + * Note. Arp sync up is handled in neighsyncd. + * The "RECONCILED" state of orchagent doesn't mean the state related to neighbor is up to date. + */ + WarmStart::setWarmStartState("orchagent", WarmStart::RECONCILED); +} + +/* + * Get tasks to sync for consumers of each orch being managed by this orch daemon + */ +void OrchDaemon::getTaskToSync(vector &ts) +{ + for (Orch *o : m_orchList) + { + o->dumpPendingTasks(ts); + } +} + + +/* Perform basic validation after start restore for warm start */ +bool OrchDaemon::warmRestoreValidation() +{ + /* + * No pending task should exist for any of the consumer at this point. + * All the prexisting data in appDB and configDb have been read and processed. + */ + vector ts; + getTaskToSync(ts); + if (ts.size() != 0) + { + // TODO: Update this section accordingly once pre-warmStart consistency validation is ready. + SWSS_LOG_NOTICE("There are pending consumer tasks after restore: "); + for(auto &s : ts) + { + SWSS_LOG_NOTICE("%s", s.c_str()); + } + } + WarmStart::setWarmStartState("orchagent", WarmStart::RESTORED); + return true; +} diff --git a/orchagent/orchdaemon.h b/orchagent/orchdaemon.h index 0213c246749..53210b74772 100644 --- a/orchagent/orchdaemon.h +++ b/orchagent/orchdaemon.h @@ -34,6 +34,9 @@ class OrchDaemon bool init(); void start(); + void warmRestoreAndSyncUp(); + void getTaskToSync(vector &ts); + bool warmRestoreValidation(); private: DBConnector *m_applDb; DBConnector *m_configDb; diff --git a/orchagent/pfcwdorch.cpp b/orchagent/pfcwdorch.cpp index 5278d76bc73..de892e30d4f 100644 --- a/orchagent/pfcwdorch.cpp +++ b/orchagent/pfcwdorch.cpp @@ -619,7 +619,7 @@ PfcWdSwOrch::PfcWdSwOrch( vector &tableNames, const vector &portStatIds, const vector &queueStatIds, - const vector &queueAttrIds, + const vector &queueAttrIds, int pollInterval): PfcWdOrch(db, tableNames), m_flexCounterDb(new DBConnector(FLEX_COUNTER_DB, DBConnector::DEFAULT_UNIXSOCKET, 0)), @@ -668,13 +668,13 @@ PfcWdSwOrch::PfcWdSwOrch( auto consumer = new swss::NotificationConsumer( PfcWdSwOrch::getCountersDb().get(), "PFC_WD"); - auto wdNotification = new Notifier(consumer, this); - Orch::addExecutor("PFC_WD", wdNotification); + auto wdNotification = new Notifier(consumer, this, "PFC_WD"); + Orch::addExecutor(wdNotification); auto interv = timespec { .tv_sec = COUNTER_CHECK_POLL_TIMEOUT_SEC, .tv_nsec = 0 }; auto timer = new SelectableTimer(interv); - auto executor = new ExecutableTimer(timer, this); - Orch::addExecutor("PFC_WD_COUNTERS_POLL", executor); + auto executor = new ExecutableTimer(timer, this, "PFC_WD_COUNTERS_POLL"); + Orch::addExecutor(executor); timer->start(); } diff --git a/orchagent/portsorch.cpp b/orchagent/portsorch.cpp index 1bb4c3a8a32..0074798aa47 100644 --- a/orchagent/portsorch.cpp +++ b/orchagent/portsorch.cpp @@ -245,8 +245,8 @@ PortsOrch::PortsOrch(DBConnector *db, vector &tableNames) /* Add port oper status notification support */ DBConnector *notificationsDb = new DBConnector(ASIC_DB, DBConnector::DEFAULT_UNIXSOCKET, 0); m_portStatusNotificationConsumer = new swss::NotificationConsumer(notificationsDb, "NOTIFICATIONS"); - auto portStatusNotificatier = new Notifier(m_portStatusNotificationConsumer, this); - Orch::addExecutor("PORT_STATUS_NOTIFICATIONS", portStatusNotificatier); + auto portStatusNotificatier = new Notifier(m_portStatusNotificationConsumer, this, "PORT_STATUS_NOTIFICATIONS"); + Orch::addExecutor(portStatusNotificatier); } void PortsOrch::removeDefaultVlanMembers() @@ -695,7 +695,7 @@ bool PortsOrch::setPortPvid(Port &port, sai_uint32_t pvid) if (port.m_rif_id) { - SWSS_LOG_ERROR("pvid setting for router interface is not allowed"); + SWSS_LOG_ERROR("pvid setting for router interface %s is not allowed", port.m_alias.c_str()); return false; } @@ -1205,7 +1205,9 @@ bool PortsOrch::bake() if (m_portCount != keys.size() - 2) { // Invalid port table - SWSS_LOG_ERROR("Invalid port table: m_portCount"); + SWSS_LOG_ERROR("Invalid port table: m_portCount, expecting %u, got %lu", + m_portCount, keys.size() - 2); + cleanPortTable(keys); return false; } diff --git a/orchagent/timer.h b/orchagent/timer.h index e30a973d2f7..732f8f4ebf7 100644 --- a/orchagent/timer.h +++ b/orchagent/timer.h @@ -8,8 +8,8 @@ namespace swss { class ExecutableTimer : public Executor { public: - ExecutableTimer(SelectableTimer *timer, Orch *orch) - : Executor(timer, orch) + ExecutableTimer(SelectableTimer *timer, Orch *orch, const string &name) + : Executor(timer, orch, name) { }