@@ -207,6 +207,53 @@ sai_object_id_t vs_create_real_object_id(
207207 return object_id;
208208}
209209
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+
210257void vs_free_real_object_id (
211258 _In_ sai_object_id_t object_id)
212259{
@@ -218,6 +265,108 @@ void vs_free_real_object_id(
218265 }
219266}
220267
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+
221370sai_status_t internal_vs_generic_create (
222371 _In_ sai_object_type_t object_type,
223372 _In_ const std::string &serialized_object_id,
@@ -229,20 +378,32 @@ sai_status_t internal_vs_generic_create(
229378
230379 if (object_type == SAI_OBJECT_TYPE_SWITCH)
231380 {
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+
232388 switch (g_vs_switch_type)
233389 {
234390 case SAI_VS_SWITCH_TYPE_BCM56850:
235- init_switch_BCM56850 (switch_id);
391+ init_switch_BCM56850 (switch_id, warmBootState );
236392 break ;
237393
238394 case SAI_VS_SWITCH_TYPE_MLNX2700:
239- init_switch_MLNX2700 (switch_id);
395+ init_switch_MLNX2700 (switch_id, warmBootState );
240396 break ;
241397
242398 default :
243399 SWSS_LOG_WARN (" unknown switch type: %d" , g_vs_switch_type);
244400 return SAI_STATUS_FAILURE;
245401 }
402+
403+ if (warmBootState != nullptr )
404+ {
405+ vs_update_real_object_ids (warmBootState);
406+ }
246407 }
247408
248409 auto &objectHash = g_switch_state_map.at (switch_id)->objectHash .at (object_type);
0 commit comments