From 82284205991f4985f22f3e588da50b039ab74479 Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Thu, 9 Aug 2018 21:43:06 +0000 Subject: [PATCH 1/4] Warm reboot for BufferOrch Signed-off-by: Qi Luo --- orchagent/bufferorch.cpp | 17 +++++++++++++++++ orchagent/bufferorch.h | 1 + orchagent/orch.cpp | 23 ++++++++++++++++++----- 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/orchagent/bufferorch.cpp b/orchagent/bufferorch.cpp index ef77aa862a..3fe278dae4 100644 --- a/orchagent/bufferorch.cpp +++ b/orchagent/bufferorch.cpp @@ -30,8 +30,25 @@ BufferOrch::BufferOrch(DBConnector *db, vector &tableNames) : Orch(db, t SWSS_LOG_ENTER(); initTableHandlers(); initBufferReadyLists(db); + + // Try warm start + bake(); }; +bool BufferOrch::bake() +{ + SWSS_LOG_ENTER(); + + addExistingData(CFG_BUFFER_POOL_TABLE_NAME); + addExistingData(CFG_BUFFER_PROFILE_TABLE_NAME); + addExistingData(CFG_BUFFER_QUEUE_TABLE_NAME); + addExistingData(CFG_BUFFER_PG_TABLE_NAME); + addExistingData(CFG_BUFFER_PORT_INGRESS_PROFILE_LIST_NAME); + addExistingData(CFG_BUFFER_PORT_EGRESS_PROFILE_LIST_NAME); + + return true; +} + void BufferOrch::initTableHandlers() { SWSS_LOG_ENTER(); diff --git a/orchagent/bufferorch.h b/orchagent/bufferorch.h index 23f56e6147..7f68c661ab 100644 --- a/orchagent/bufferorch.h +++ b/orchagent/bufferorch.h @@ -28,6 +28,7 @@ class BufferOrch : public Orch { public: BufferOrch(DBConnector *db, vector &tableNames); + bool bake(); bool isPortReady(const std::string& port_name) const; static type_map m_buffer_type_maps; private: diff --git a/orchagent/orch.cpp b/orchagent/orch.cpp index f86dd849ce..2fdb116abf 100644 --- a/orchagent/orch.cpp +++ b/orchagent/orch.cpp @@ -147,10 +147,23 @@ void Consumer::refillToSync(Table* table) void Consumer::refillToSync() { - auto db = getConsumerTable()->getDbConnector(); - string tableName = getConsumerTable()->getTableName(); - auto table = Table(db, tableName); - refillToSync(&table); + ConsumerTableBase *consumerTable = getConsumerTable(); + + auto subTable = dynamic_cast(consumerTable); + if (subTable != NULL) + { + std::deque entries; + subTable->pops(entries); + addToSync(entries); + } + else + { + // consumerTable is either ConsumerStateTable or ConsumerTable + auto db = consumerTable->getDbConnector(); + string tableName = consumerTable->getTableName(); + auto table = Table(db, tableName); + refillToSync(&table); + } } void Consumer::execute() @@ -173,7 +186,7 @@ void Consumer::drain() bool Orch::addExistingData(const string& tableName) { - Consumer* consumer = dynamic_cast(getExecutor(tableName)); + auto consumer = dynamic_cast(getExecutor(tableName)); if (consumer == NULL) { SWSS_LOG_ERROR("No consumer %s in Orch", tableName.c_str()); From e65828f7eb7d792e0028d04b06e4ebc53d362565 Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Fri, 10 Aug 2018 00:35:33 +0000 Subject: [PATCH 2/4] Add log for warm reboot Signed-off-by: Qi Luo --- orchagent/bufferorch.cpp | 24 +++++++++++++++++------- orchagent/orch.cpp | 29 ++++++++++++++--------------- orchagent/orch.h | 13 ++++++++----- 3 files changed, 39 insertions(+), 27 deletions(-) diff --git a/orchagent/bufferorch.cpp b/orchagent/bufferorch.cpp index 3fe278dae4..45a2c4a320 100644 --- a/orchagent/bufferorch.cpp +++ b/orchagent/bufferorch.cpp @@ -39,13 +39,23 @@ bool BufferOrch::bake() { SWSS_LOG_ENTER(); - addExistingData(CFG_BUFFER_POOL_TABLE_NAME); - addExistingData(CFG_BUFFER_PROFILE_TABLE_NAME); - addExistingData(CFG_BUFFER_QUEUE_TABLE_NAME); - addExistingData(CFG_BUFFER_PG_TABLE_NAME); - addExistingData(CFG_BUFFER_PORT_INGRESS_PROFILE_LIST_NAME); - addExistingData(CFG_BUFFER_PORT_EGRESS_PROFILE_LIST_NAME); - + size_t init_cfg_numbers[] = { + addExistingData(CFG_BUFFER_POOL_TABLE_NAME), + addExistingData(CFG_BUFFER_PROFILE_TABLE_NAME), + addExistingData(CFG_BUFFER_QUEUE_TABLE_NAME), + addExistingData(CFG_BUFFER_PG_TABLE_NAME), + addExistingData(CFG_BUFFER_PORT_INGRESS_PROFILE_LIST_NAME), + addExistingData(CFG_BUFFER_PORT_EGRESS_PROFILE_LIST_NAME), + }; + + SWSS_LOG_NOTICE("addExistingData: %zd %zd %zd %zd %zd %zd", + init_cfg_numbers[0], + init_cfg_numbers[1], + init_cfg_numbers[2], + init_cfg_numbers[3], + init_cfg_numbers[4], + init_cfg_numbers[5] + ); return true; } diff --git a/orchagent/orch.cpp b/orchagent/orch.cpp index 2fdb116abf..ed411bff20 100644 --- a/orchagent/orch.cpp +++ b/orchagent/orch.cpp @@ -66,14 +66,14 @@ vector Orch::getSelectables() return selectables; } -void Consumer::addToSync(std::deque &entries) +size_t Consumer::addToSync(std::deque &entries) { SWSS_LOG_ENTER(); /* Nothing popped */ if (entries.empty()) { - return; + return 0; } for (auto& entry: entries) @@ -120,10 +120,11 @@ void Consumer::addToSync(std::deque &entries) m_toSync[key] = KeyOpFieldsValuesTuple(key, op, existing_values); } } + return entries.size(); } // TODO: Table should be const -void Consumer::refillToSync(Table* table) +size_t Consumer::refillToSync(Table* table) { std::deque entries; vector keys; @@ -142,10 +143,10 @@ void Consumer::refillToSync(Table* table) entries.push_back(kco); } - addToSync(entries); + return addToSync(entries); } -void Consumer::refillToSync() +size_t Consumer::refillToSync() { ConsumerTableBase *consumerTable = getConsumerTable(); @@ -154,7 +155,7 @@ void Consumer::refillToSync() { std::deque entries; subTable->pops(entries); - addToSync(entries); + return addToSync(entries); } else { @@ -162,7 +163,7 @@ void Consumer::refillToSync() auto db = consumerTable->getDbConnector(); string tableName = consumerTable->getTableName(); auto table = Table(db, tableName); - refillToSync(&table); + return refillToSync(&table); } } @@ -184,32 +185,30 @@ void Consumer::drain() m_orch->doTask(*this); } -bool Orch::addExistingData(const string& tableName) +size_t Orch::addExistingData(const string& tableName) { auto consumer = dynamic_cast(getExecutor(tableName)); if (consumer == NULL) { SWSS_LOG_ERROR("No consumer %s in Orch", tableName.c_str()); - return false; + return 0; } - consumer->refillToSync(); - return true; + return consumer->refillToSync(); } // TODO: Table should be const -bool Orch::addExistingData(Table *table) +size_t Orch::addExistingData(Table *table) { string tableName = table->getTableName(); Consumer* consumer = dynamic_cast(getExecutor(tableName)); if (consumer == NULL) { SWSS_LOG_ERROR("No consumer %s in Orch", tableName.c_str()); - return false; + return 0; } - consumer->refillToSync(table); - return true; + return consumer->refillToSync(table); } /* diff --git a/orchagent/orch.h b/orchagent/orch.h index 902192f16b..cb13cf10c3 100644 --- a/orchagent/orch.h +++ b/orchagent/orch.h @@ -116,15 +116,18 @@ class Consumer : public Executor { return getConsumerTable()->getTableName(); } - void addToSync(std::deque &entries); - void refillToSync(); - void refillToSync(Table* table); + size_t refillToSync(); + size_t refillToSync(Table* table); void execute(); void drain(); /* 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); }; typedef map> ConsumerMap; @@ -153,8 +156,8 @@ class Orch vector getSelectables(); // add the existing table data (left by warm reboot) to the consumer todo task list. - bool addExistingData(Table *table); - bool addExistingData(const string& tableName); + size_t addExistingData(Table *table); + size_t addExistingData(const string& tableName); /* Iterate all consumers in m_consumerMap and run doTask(Consumer) */ void doTask(); From 1acd88591f4b86f2d8e484f8021f0ad281dfbb94 Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Fri, 10 Aug 2018 19:56:17 +0000 Subject: [PATCH 3/4] Add bake() interface Signed-off-by: Qi Luo --- orchagent/bufferorch.cpp | 27 --------------------------- orchagent/bufferorch.h | 1 - orchagent/orch.cpp | 21 +++++++++++++++++++++ orchagent/orch.h | 4 ++++ orchagent/portsorch.h | 2 +- 5 files changed, 26 insertions(+), 29 deletions(-) diff --git a/orchagent/bufferorch.cpp b/orchagent/bufferorch.cpp index 45a2c4a320..ef77aa862a 100644 --- a/orchagent/bufferorch.cpp +++ b/orchagent/bufferorch.cpp @@ -30,35 +30,8 @@ BufferOrch::BufferOrch(DBConnector *db, vector &tableNames) : Orch(db, t SWSS_LOG_ENTER(); initTableHandlers(); initBufferReadyLists(db); - - // Try warm start - bake(); }; -bool BufferOrch::bake() -{ - SWSS_LOG_ENTER(); - - size_t init_cfg_numbers[] = { - addExistingData(CFG_BUFFER_POOL_TABLE_NAME), - addExistingData(CFG_BUFFER_PROFILE_TABLE_NAME), - addExistingData(CFG_BUFFER_QUEUE_TABLE_NAME), - addExistingData(CFG_BUFFER_PG_TABLE_NAME), - addExistingData(CFG_BUFFER_PORT_INGRESS_PROFILE_LIST_NAME), - addExistingData(CFG_BUFFER_PORT_EGRESS_PROFILE_LIST_NAME), - }; - - SWSS_LOG_NOTICE("addExistingData: %zd %zd %zd %zd %zd %zd", - init_cfg_numbers[0], - init_cfg_numbers[1], - init_cfg_numbers[2], - init_cfg_numbers[3], - init_cfg_numbers[4], - init_cfg_numbers[5] - ); - return true; -} - void BufferOrch::initTableHandlers() { SWSS_LOG_ENTER(); diff --git a/orchagent/bufferorch.h b/orchagent/bufferorch.h index 7f68c661ab..23f56e6147 100644 --- a/orchagent/bufferorch.h +++ b/orchagent/bufferorch.h @@ -28,7 +28,6 @@ class BufferOrch : public Orch { public: BufferOrch(DBConnector *db, vector &tableNames); - bool bake(); bool isPortReady(const std::string& port_name) const; static type_map m_buffer_type_maps; private: diff --git a/orchagent/orch.cpp b/orchagent/orch.cpp index ed411bff20..48b8e5b427 100644 --- a/orchagent/orch.cpp +++ b/orchagent/orch.cpp @@ -211,6 +211,27 @@ size_t Orch::addExistingData(Table *table) return consumer->refillToSync(table); } +bool Orch::bake() +{ + SWSS_LOG_ENTER(); + + for(auto &it : m_consumerMap) + { + string executorName = it.first; + auto executor = it.second; + auto consumer = dynamic_cast(executor.get()); + if (consumer == NULL) + { + continue; + } + + size_t refilled = consumer->refillToSync(); + SWSS_LOG_NOTICE("Add warm input: %s, %zd", executorName.c_str(), refilled); + } + + return true; +} + /* - Validates reference has proper format which is [table_name:object_name] - validates table_name exists diff --git a/orchagent/orch.h b/orchagent/orch.h index cb13cf10c3..14fde1c78a 100644 --- a/orchagent/orch.h +++ b/orchagent/orch.h @@ -159,6 +159,10 @@ class Orch size_t addExistingData(Table *table); size_t addExistingData(const string& tableName); + // 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(); diff --git a/orchagent/portsorch.h b/orchagent/portsorch.h index 2a73ccb6c1..fc1d2ae52b 100644 --- a/orchagent/portsorch.h +++ b/orchagent/portsorch.h @@ -56,7 +56,7 @@ class PortsOrch : public Orch, public Subject bool isInitDone(); map& getAllPorts(); - bool bake(); + bool bake() override; void cleanPortTable(const vector& keys); bool getBridgePort(sai_object_id_t id, Port &port); bool getPort(string alias, Port &port); From 1146af18079c697b1806d26a3a148c639519565b Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Fri, 10 Aug 2018 20:05:14 +0000 Subject: [PATCH 4/4] OrchDaemon supports warm start Signed-off-by: Qi Luo --- orchagent/orchdaemon.cpp | 6 ++++++ orchagent/portsorch.cpp | 3 --- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/orchagent/orchdaemon.cpp b/orchagent/orchdaemon.cpp index 26bd446da2..787a07584c 100644 --- a/orchagent/orchdaemon.cpp +++ b/orchagent/orchdaemon.cpp @@ -274,6 +274,12 @@ void OrchDaemon::start() { SWSS_LOG_ENTER(); + // Try warm start + for (Orch *o : m_orchList) + { + o->bake(); + } + for (Orch *o : m_orchList) { m_select->addSelectables(o->getSelectables()); diff --git a/orchagent/portsorch.cpp b/orchagent/portsorch.cpp index 8d6f58988c..74c23723fc 100644 --- a/orchagent/portsorch.cpp +++ b/orchagent/portsorch.cpp @@ -245,9 +245,6 @@ PortsOrch::PortsOrch(DBConnector *db, vector &tableNames) m_portStatusNotificationConsumer = new swss::NotificationConsumer(notificationsDb, "NOTIFICATIONS"); auto portStatusNotificatier = new Notifier(m_portStatusNotificationConsumer, this); Orch::addExecutor("PORT_STATUS_NOTIFICATIONS", portStatusNotificatier); - - // Try warm start - bake(); } void PortsOrch::removeDefaultVlanMembers()