@@ -207,6 +207,53 @@ sai_object_id_t vs_create_real_object_id(
207
207
return object_id;
208
208
}
209
209
210
+ void vs_update_real_object_ids (
211
+ _In_ const std::shared_ptr<SwitchState> warmBootState)
212
+ {
213
+ SWSS_LOG_ENTER ();
214
+
215
+ /*
216
+ * Since we loaded state from warm boot, we need to update real object id's
217
+ * in case a new object will be created. We need this so new objects will
218
+ * not have the same ID as existing ones.
219
+ */
220
+
221
+ for (auto oh: warmBootState->objectHash )
222
+ {
223
+ sai_object_type_t ot = oh.first ;
224
+
225
+ if (ot == SAI_OBJECT_TYPE_NULL)
226
+ continue ;
227
+
228
+ auto oi = sai_metadata_get_object_type_info (ot);
229
+
230
+ if (oi == NULL )
231
+ {
232
+ SWSS_LOG_THROW (" failed to find object type info for object type: %d" , ot);
233
+ }
234
+
235
+ if (oi->isnonobjectid )
236
+ continue ;
237
+
238
+ for (auto o: oh.second )
239
+ {
240
+ sai_object_id_t oid;
241
+
242
+ sai_deserialize_object_id (o.first , oid);
243
+
244
+ // lower 32 bits on VS is real id on specific object type
245
+ uint64_t real_id = oid & ((uint64_t )-1 ) >> (64 - OT_POSITION);
246
+
247
+ if (real_ids[ot] <= real_id)
248
+ {
249
+ real_ids[ot] = real_id + 1 ; // +1 since this will be next object number
250
+ }
251
+
252
+ SWSS_LOG_INFO (" update %s:%s real id to from %lu to %lu" , oi->objecttypename , o.first .c_str (), real_id, real_ids[ot]);
253
+ }
254
+ }
255
+ }
256
+
210
257
void vs_free_real_object_id (
211
258
_In_ sai_object_id_t object_id)
212
259
{
@@ -218,6 +265,108 @@ void vs_free_real_object_id(
218
265
}
219
266
}
220
267
268
+ std::shared_ptr<SwitchState> vs_read_switch_database_for_warm_restart (
269
+ _In_ sai_object_id_t switch_id)
270
+ {
271
+ SWSS_LOG_ENTER ();
272
+
273
+ if (g_warm_boot_read_file == NULL )
274
+ {
275
+ SWSS_LOG_ERROR (" warm boot read file is NULL" );
276
+ return nullptr ;
277
+ }
278
+
279
+ std::ifstream dumpFile;
280
+
281
+ dumpFile.open (g_warm_boot_read_file);
282
+
283
+ if (!dumpFile.is_open ())
284
+ {
285
+ SWSS_LOG_ERROR (" failed to open: %s, switching to cold boot" , g_warm_boot_read_file);
286
+
287
+ g_vs_boot_type = SAI_VS_COLD_BOOT;
288
+
289
+ return nullptr ;
290
+ }
291
+
292
+ std::shared_ptr<SwitchState> ss = std::make_shared<SwitchState>(switch_id);
293
+
294
+ size_t count = 1 ; // count is 1 since switch_id was inserted to objectHash in SwitchState constructor
295
+
296
+ std::string line;
297
+ while (std::getline (dumpFile, line))
298
+ {
299
+ // line format: OBJECT_TYPE OBJECT_ID ATTR_ID ATTR_VALUE
300
+ std::istringstream iss (line);
301
+
302
+ std::string str_object_type;
303
+ std::string str_object_id;
304
+ std::string str_attr_id;
305
+ std::string str_attr_value;
306
+
307
+ iss >> str_object_type >> str_object_id >> str_attr_id >> str_attr_value;
308
+
309
+ sai_object_meta_key_t meta_key;
310
+
311
+ sai_deserialize_object_meta_key (str_object_type + " :" + str_object_id, meta_key);
312
+
313
+ auto &objectHash = ss->objectHash .at (meta_key.objecttype );
314
+
315
+ if (objectHash.find (str_object_id) == objectHash.end ())
316
+ {
317
+ count++;
318
+
319
+ objectHash[str_object_id] = {};
320
+ }
321
+
322
+ if (str_attr_id == " NULL" )
323
+ {
324
+ // skip empty attributes
325
+ continue ;
326
+ }
327
+
328
+ if (meta_key.objecttype == SAI_OBJECT_TYPE_SWITCH)
329
+ {
330
+ if (meta_key.objectkey .key .object_id != switch_id)
331
+ {
332
+ SWSS_LOG_THROW (" created switch id is %s but warm boot serialized is %s" ,
333
+ sai_serialize_object_id (switch_id).c_str (),
334
+ str_object_id.c_str ());
335
+ }
336
+ }
337
+
338
+ auto meta = sai_metadata_get_attr_metadata_by_attr_id_name (str_attr_id.c_str ());
339
+
340
+ if (meta == NULL )
341
+ {
342
+ SWSS_LOG_THROW (" failed to find metadata for %s" , str_attr_id.c_str ());
343
+ }
344
+
345
+ // populate attributes
346
+
347
+ sai_attribute_t attr;
348
+
349
+ attr.id = meta->attrid ;
350
+
351
+ sai_deserialize_attr_value (str_attr_value.c_str (), *meta, attr, false );
352
+
353
+ auto a = std::make_shared<SaiAttrWrap>(meta_key.objecttype , &attr);
354
+
355
+ objectHash[str_object_id][a->getAttrMetadata ()->attridname ] = a;
356
+
357
+ // free possible list attributes
358
+ sai_deserialize_free_attribute_value (meta->attrvaluetype , attr);
359
+ }
360
+
361
+ // NOTE notification pointers should be restored by attr_list when creating switch
362
+
363
+ dumpFile.close ();
364
+
365
+ SWSS_LOG_NOTICE (" loaded %zu objects from: %s" , count, g_warm_boot_read_file);
366
+
367
+ return ss;
368
+ }
369
+
221
370
sai_status_t internal_vs_generic_create (
222
371
_In_ sai_object_type_t object_type,
223
372
_In_ const std::string &serialized_object_id,
@@ -229,20 +378,32 @@ sai_status_t internal_vs_generic_create(
229
378
230
379
if (object_type == SAI_OBJECT_TYPE_SWITCH)
231
380
{
381
+ std::shared_ptr<SwitchState> warmBootState = nullptr ;
382
+
383
+ if (g_vs_boot_type == SAI_VS_WARM_BOOT)
384
+ {
385
+ warmBootState = vs_read_switch_database_for_warm_restart (switch_id);
386
+ }
387
+
232
388
switch (g_vs_switch_type)
233
389
{
234
390
case SAI_VS_SWITCH_TYPE_BCM56850:
235
- init_switch_BCM56850 (switch_id);
391
+ init_switch_BCM56850 (switch_id, warmBootState );
236
392
break ;
237
393
238
394
case SAI_VS_SWITCH_TYPE_MLNX2700:
239
- init_switch_MLNX2700 (switch_id);
395
+ init_switch_MLNX2700 (switch_id, warmBootState );
240
396
break ;
241
397
242
398
default :
243
399
SWSS_LOG_WARN (" unknown switch type: %d" , g_vs_switch_type);
244
400
return SAI_STATUS_FAILURE;
245
401
}
402
+
403
+ if (warmBootState != nullptr )
404
+ {
405
+ vs_update_real_object_ids (warmBootState);
406
+ }
246
407
}
247
408
248
409
auto &objectHash = g_switch_state_map.at (switch_id)->objectHash .at (object_type);
0 commit comments