Skip to content

Commit d363262

Browse files
committed
Warm reboot for PortsOrch
Signed-off-by: Qi Luo <[email protected]>
1 parent 902239a commit d363262

6 files changed

Lines changed: 138 additions & 23 deletions

File tree

orchagent/orch.cpp

Lines changed: 57 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,10 @@ vector<Selectable *> Orch::getSelectables()
6666
return selectables;
6767
}
6868

69-
void Consumer::execute()
69+
void Consumer::addToSync(std::deque<KeyOpFieldsValuesTuple> &entries)
7070
{
7171
SWSS_LOG_ENTER();
7272

73-
std::deque<KeyOpFieldsValuesTuple> entries;
74-
getConsumerTable()->pops(entries);
75-
7673
/* Nothing popped */
7774
if (entries.empty())
7875
{
@@ -123,6 +120,16 @@ void Consumer::execute()
123120
m_toSync[key] = KeyOpFieldsValuesTuple(key, op, existing_values);
124121
}
125122
}
123+
}
124+
125+
void Consumer::execute()
126+
{
127+
SWSS_LOG_ENTER();
128+
129+
std::deque<KeyOpFieldsValuesTuple> entries;
130+
getConsumerTable()->pops(entries);
131+
132+
addToSync(entries);
126133

127134
drain();
128135
}
@@ -133,6 +140,48 @@ void Consumer::drain()
133140
m_orch->doTask(*this);
134141
}
135142

143+
// TODO: Table should be const
144+
void Orch::addExistingData(Table *table)
145+
{
146+
string tableName = table->getTableName();
147+
Consumer* consumer;
148+
auto it = m_consumerMap.begin();
149+
150+
while (it != m_consumerMap.end())
151+
{
152+
consumer = (Consumer*)(it->second.get());
153+
if (tableName == consumer->getTableName())
154+
{
155+
break;
156+
}
157+
it++;
158+
}
159+
160+
if (it == m_consumerMap.end())
161+
{
162+
return;
163+
}
164+
165+
std::deque<KeyOpFieldsValuesTuple> entries;
166+
vector<string> keys;
167+
table->getKeys(keys);
168+
for (const auto &key: keys)
169+
{
170+
KeyOpFieldsValuesTuple kco;
171+
172+
kfvKey(kco) = key;
173+
kfvOp(kco) = SET_COMMAND;
174+
175+
if (!table->get(key, kfvFieldsValues(kco)))
176+
{
177+
continue;
178+
}
179+
entries.push_back(kco);
180+
}
181+
182+
consumer->addToSync(entries);
183+
}
184+
136185
/*
137186
- Validates reference has proper format which is [table_name:object_name]
138187
- validates table_name exists
@@ -364,6 +413,10 @@ void Orch::addConsumer(DBConnector *db, string tableName, int pri)
364413
{
365414
addExecutor(tableName, new Consumer(new SubscriberStateTable(db, tableName, TableConsumable::DEFAULT_POP_BATCH_SIZE, pri), this));
366415
}
416+
else if (tableName == APP_PORT_TABLE_NAME)
417+
{
418+
addExecutor(tableName, new Consumer(new ConsumerTable(db, tableName, gBatchSize, pri), this));
419+
}
367420
else
368421
{
369422
addExecutor(tableName, new Consumer(new ConsumerStateTable(db, tableName, gBatchSize, pri), this));

orchagent/orch.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ class Consumer : public Executor {
116116
return getConsumerTable()->getTableName();
117117
}
118118

119+
void addToSync(std::deque<KeyOpFieldsValuesTuple> &entries);
119120
void execute();
120121
void drain();
121122

@@ -149,6 +150,9 @@ class Orch
149150

150151
vector<Selectable*> getSelectables();
151152

153+
// add the existing data to the consumer todo task list.
154+
void addExistingData(Table *table);
155+
152156
/* Iterate all consumers in m_consumerMap and run doTask(Consumer) */
153157
void doTask();
154158

orchagent/portsorch.cpp

Lines changed: 62 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,9 @@ PortsOrch::PortsOrch(DBConnector *db, vector<table_name_with_pri_t> &tableNames)
245245
m_portStatusNotificationConsumer = new swss::NotificationConsumer(notificationsDb, "NOTIFICATIONS");
246246
auto portStatusNotificatier = new Notifier(m_portStatusNotificationConsumer, this);
247247
Orch::addExecutor("PORT_STATUS_NOTIFICATIONS", portStatusNotificatier);
248+
249+
// Try warm start
250+
bake();
248251
}
249252

250253
void PortsOrch::removeDefaultVlanMembers()
@@ -1177,6 +1180,64 @@ bool PortsOrch::initPort(const string &alias, const set<int> &lane_set)
11771180
return true;
11781181
}
11791182

1183+
bool PortsOrch::bake()
1184+
{
1185+
SWSS_LOG_ENTER();
1186+
1187+
// Check the APP_DB port table for warm reboot
1188+
vector<FieldValueTuple> tuples;
1189+
bool foundPortConfigDone = m_portTable->get("PortConfigDone", tuples);
1190+
SWSS_LOG_NOTICE("foundPortConfigDone = %d", foundPortConfigDone);
1191+
1192+
bool foundPortInitDone = m_portTable->get("PortInitDone", tuples);
1193+
SWSS_LOG_NOTICE("foundPortInitDone = %d", foundPortInitDone);
1194+
1195+
vector<string> keys;
1196+
m_portTable->getKeys(keys);
1197+
SWSS_LOG_NOTICE("m_portTable->getKeys %zd", keys.size());
1198+
1199+
if (!foundPortConfigDone || !foundPortInitDone)
1200+
{
1201+
SWSS_LOG_NOTICE("No port table, fallback to cold start");
1202+
cleanPortTable(keys);
1203+
return false;
1204+
}
1205+
1206+
doPortConfigDoneTask(tuples);
1207+
if (m_portCount != keys.size() - 2)
1208+
{
1209+
// Invalid port table
1210+
SWSS_LOG_ERROR("Invalid port table: m_portCount");
1211+
cleanPortTable(keys);
1212+
return false;
1213+
}
1214+
1215+
addExistingData(m_portTable.get());
1216+
return true;
1217+
}
1218+
1219+
// Clean up port table
1220+
void PortsOrch::cleanPortTable(const vector<string>& keys)
1221+
{
1222+
for (auto& key : keys)
1223+
{
1224+
m_portTable->del(key);
1225+
}
1226+
}
1227+
1228+
void PortsOrch::doPortConfigDoneTask(const vector<FieldValueTuple>& tuples)
1229+
{
1230+
m_portConfigDone = true;
1231+
1232+
for (auto i : tuples)
1233+
{
1234+
if (fvField(i) == "count")
1235+
{
1236+
m_portCount = to_uint<uint32_t>(fvValue(i));
1237+
}
1238+
}
1239+
}
1240+
11801241
void PortsOrch::doPortTask(Consumer &consumer)
11811242
{
11821243
SWSS_LOG_ENTER();
@@ -1191,15 +1252,7 @@ void PortsOrch::doPortTask(Consumer &consumer)
11911252

11921253
if (alias == "PortConfigDone")
11931254
{
1194-
m_portConfigDone = true;
1195-
1196-
for (auto i : kfvFieldsValues(t))
1197-
{
1198-
if (fvField(i) == "count")
1199-
{
1200-
m_portCount = to_uint<uint32_t>(fvValue(i));
1201-
}
1202-
}
1255+
doPortConfigDoneTask(kfvFieldsValues(t));
12031256
}
12041257

12051258
/* Get notification from application */

orchagent/portsorch.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ class PortsOrch : public Orch, public Subject
5656
bool isInitDone();
5757

5858
map<string, Port>& getAllPorts();
59+
bool bake();
60+
void cleanPortTable(const vector<string>& keys);
61+
void doPortConfigDoneTask(const vector<FieldValueTuple>& tuples);
5962
bool getBridgePort(sai_object_id_t id, Port &port);
6063
bool getPort(string alias, Port &port);
6164
bool getPort(sai_object_id_t id, Port &port);

portsyncd/linksync.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#define __LINKSYNC__
33

44
#include "dbconnector.h"
5-
#include "producerstatetable.h"
5+
#include "producertable.h"
66
#include "netmsg.h"
77

88
#include <map>
@@ -19,7 +19,7 @@ class LinkSync : public NetMsg
1919
virtual void onMsg(int nlmsg_type, struct nl_object *obj);
2020

2121
private:
22-
ProducerStateTable m_portTableProducer;
22+
ProducerTable m_portTableProducer;
2323
Table m_portTable, m_statePortTable;
2424

2525
std::map<unsigned int, std::string> m_ifindexNameMap;

portsyncd/portsyncd.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "netdispatcher.h"
1212
#include "netlink.h"
1313
#include "producerstatetable.h"
14+
#include "producertable.h"
1415
#include "portsyncd/linksync.h"
1516
#include "subscriberstatetable.h"
1617
#include "exec.h"
@@ -38,10 +39,11 @@ void usage()
3839
cout << " use configDB data if not specified" << endl;
3940
}
4041

41-
void handlePortConfigFile(ProducerStateTable &p, string file);
42-
void handlePortConfigFromConfigDB(ProducerStateTable &p, DBConnector &cfgDb);
42+
// TODO: find a common base class for ProducerTable and ProducerStateTable
43+
void handlePortConfigFile(ProducerTable &p, string file);
44+
void handlePortConfigFromConfigDB(ProducerTable &p, DBConnector &cfgDb);
4345
void handleVlanIntfFile(string file);
44-
void handlePortConfig(ProducerStateTable &p, map<string, KeyOpFieldsValuesTuple> &port_cfg_map);
46+
void handlePortConfig(ProducerTable &p, map<string, KeyOpFieldsValuesTuple> &port_cfg_map);
4547

4648
int main(int argc, char **argv)
4749
{
@@ -69,7 +71,7 @@ int main(int argc, char **argv)
6971
DBConnector cfgDb(CONFIG_DB, DBConnector::DEFAULT_UNIXSOCKET, 0);
7072
DBConnector appl_db(APPL_DB, DBConnector::DEFAULT_UNIXSOCKET, 0);
7173
DBConnector state_db(STATE_DB, DBConnector::DEFAULT_UNIXSOCKET, 0);
72-
ProducerStateTable p(&appl_db, APP_PORT_TABLE_NAME);
74+
ProducerTable p(&appl_db, APP_PORT_TABLE_NAME);
7375
SubscriberStateTable portCfg(&cfgDb, CFG_PORT_TABLE_NAME);
7476

7577
LinkSync sync(&appl_db, &state_db);
@@ -157,15 +159,15 @@ int main(int argc, char **argv)
157159
return 1;
158160
}
159161

160-
static void notifyPortConfigDone(ProducerStateTable &p)
162+
static void notifyPortConfigDone(ProducerTable &p)
161163
{
162164
/* Notify that all ports added */
163165
FieldValueTuple finish_notice("count", to_string(g_portSet.size()));
164166
vector<FieldValueTuple> attrs = { finish_notice };
165167
p.set("PortConfigDone", attrs);
166168
}
167169

168-
void handlePortConfigFromConfigDB(ProducerStateTable &p, DBConnector &cfgDb)
170+
void handlePortConfigFromConfigDB(ProducerTable &p, DBConnector &cfgDb)
169171
{
170172
cout << "Get port configuration from ConfigDB..." << endl;
171173

@@ -188,7 +190,7 @@ void handlePortConfigFromConfigDB(ProducerStateTable &p, DBConnector &cfgDb)
188190
notifyPortConfigDone(p);
189191
}
190192

191-
void handlePortConfigFile(ProducerStateTable &p, string file)
193+
void handlePortConfigFile(ProducerTable &p, string file)
192194
{
193195
cout << "Read port configuration file..." << endl;
194196

@@ -273,7 +275,7 @@ void handlePortConfigFile(ProducerStateTable &p, string file)
273275
notifyPortConfigDone(p);
274276
}
275277

276-
void handlePortConfig(ProducerStateTable &p, map<string, KeyOpFieldsValuesTuple> &port_cfg_map)
278+
void handlePortConfig(ProducerTable &p, map<string, KeyOpFieldsValuesTuple> &port_cfg_map)
277279
{
278280

279281
auto it = port_cfg_map.begin();

0 commit comments

Comments
 (0)