6
6
#include < limits.h>
7
7
8
8
#include " swss/warm_restart.h"
9
+ #include " swss/table.h"
9
10
10
11
extern " C" {
11
12
#include < sai.h>
@@ -1935,7 +1936,12 @@ void on_switch_create_in_init_view(
1935
1936
1936
1937
sai_object_id_t switch_rid;
1937
1938
1938
- sai_status_t status = sai_metadata_sai_switch_api->create_switch (&switch_rid, attr_count, attr_list);
1939
+ sai_status_t status;
1940
+
1941
+ {
1942
+ SWSS_LOG_TIMER (" cold boot: create switch" );
1943
+ status = sai_metadata_sai_switch_api->create_switch (&switch_rid, attr_count, attr_list);
1944
+ }
1939
1945
1940
1946
if (status != SAI_STATUS_SUCCESS)
1941
1947
{
@@ -3170,6 +3176,8 @@ typedef enum _syncd_restart_type_t
3170
3176
3171
3177
SYNCD_RESTART_TYPE_FAST,
3172
3178
3179
+ SYNCD_RESTART_TYPE_PRE_SHUTDOWN,
3180
+
3173
3181
} syncd_restart_type_t ;
3174
3182
3175
3183
syncd_restart_type_t handleRestartQuery (swss::NotificationConsumer &restartQuery)
@@ -3202,6 +3210,12 @@ syncd_restart_type_t handleRestartQuery(swss::NotificationConsumer &restartQuery
3202
3210
return SYNCD_RESTART_TYPE_FAST;
3203
3211
}
3204
3212
3213
+ if (op == " PRE-SHUTDOWN" )
3214
+ {
3215
+ SWSS_LOG_NOTICE (" received PRE_SHUTDOWN switch event" );
3216
+ return SYNCD_RESTART_TYPE_PRE_SHUTDOWN;
3217
+ }
3218
+
3205
3219
SWSS_LOG_WARN (" received '%s' unknown switch shutdown event, assuming COLD" , op.c_str ());
3206
3220
return SYNCD_RESTART_TYPE_COLD;
3207
3221
}
@@ -3452,6 +3466,8 @@ int syncd_main(int argc, char **argv)
3452
3466
std::shared_ptr<swss::DBConnector> dbAsic = std::make_shared<swss::DBConnector>(ASIC_DB, swss::DBConnector::DEFAULT_UNIXSOCKET, 0 );
3453
3467
std::shared_ptr<swss::DBConnector> dbNtf = std::make_shared<swss::DBConnector>(ASIC_DB, swss::DBConnector::DEFAULT_UNIXSOCKET, 0 );
3454
3468
std::shared_ptr<swss::DBConnector> dbFlexCounter = std::make_shared<swss::DBConnector>(FLEX_COUNTER_DB, swss::DBConnector::DEFAULT_UNIXSOCKET, 0 );
3469
+ std::shared_ptr<swss::DBConnector> dbState = std::make_shared<swss::DBConnector>(STATE_DB, swss::DBConnector::DEFAULT_UNIXSOCKET, 0 );
3470
+ std::unique_ptr<swss::Table> warmRestartTable = std::unique_ptr<swss::Table>(new swss::Table (dbState.get (), STATE_WARM_RESTART_TABLE_NAME));
3455
3471
3456
3472
g_redisClient = std::make_shared<swss::RedisClient>(dbAsic.get ());
3457
3473
@@ -3539,6 +3555,9 @@ int syncd_main(int argc, char **argv)
3539
3555
3540
3556
syncd_restart_type_t shutdownType = SYNCD_RESTART_TYPE_COLD;
3541
3557
3558
+ sai_switch_api_t *sai_switch_api = NULL ;
3559
+ sai_api_query (SAI_API_SWITCH, (void **)&sai_switch_api);
3560
+
3542
3561
try
3543
3562
{
3544
3563
SWSS_LOG_NOTICE (" before onSyncdStart" );
@@ -3575,7 +3594,55 @@ int syncd_main(int argc, char **argv)
3575
3594
*/
3576
3595
3577
3596
shutdownType = handleRestartQuery (*restartQuery);
3578
- break ;
3597
+ if (shutdownType != SYNCD_RESTART_TYPE_PRE_SHUTDOWN)
3598
+ {
3599
+ // break out the event handling loop to shutdown syncd
3600
+ break ;
3601
+ }
3602
+
3603
+ // Handle switch pre-shutdown and wait for the final shutdown
3604
+ // event
3605
+
3606
+ SWSS_LOG_TIMER (" warm pre-shutdown" );
3607
+
3608
+ FlexCounter::removeAllCounters ();
3609
+ stopNotificationsProcessingThread ();
3610
+
3611
+ sai_attribute_t attr;
3612
+
3613
+ attr.id = SAI_SWITCH_ATTR_RESTART_WARM;
3614
+ attr.value .booldata = true ;
3615
+
3616
+ status = sai_switch_api->set_switch_attribute (gSwitchId , &attr);
3617
+
3618
+ if (status != SAI_STATUS_SUCCESS)
3619
+ {
3620
+ SWSS_LOG_ERROR (" Failed to set SAI_SWITCH_ATTR_RESTART_WARM=true: %s for pre-shutdown" ,
3621
+ sai_serialize_status (status).c_str ());
3622
+ shutdownType = SYNCD_RESTART_TYPE_COLD;
3623
+ warmRestartTable->hset (" warm-shutdown" , " state" , " set-flag-failed" );
3624
+ continue ;
3625
+ }
3626
+
3627
+ attr.id = SAI_SWITCH_ATTR_PRE_SHUTDOWN;
3628
+ attr.value .booldata = true ;
3629
+
3630
+ status = sai_switch_api->set_switch_attribute (gSwitchId , &attr);
3631
+ if (status == SAI_STATUS_SUCCESS)
3632
+ {
3633
+ warmRestartTable->hset (" warm-shutdown" , " state" , " pre-shutdown-succeeded" );
3634
+ }
3635
+ else
3636
+ {
3637
+ SWSS_LOG_ERROR (" Failed to set SAI_SWITCH_ATTR_PRE_SHUTDOWN=true: %s" ,
3638
+ sai_serialize_status (status).c_str ());
3639
+ warmRestartTable->hset (" warm-shutdown" , " state" , " pre-shutdown-failed" );
3640
+
3641
+ // Restore cold shutdown.
3642
+ attr.id = SAI_SWITCH_ATTR_RESTART_WARM;
3643
+ attr.value .booldata = false ;
3644
+ status = sai_switch_api->set_switch_attribute (gSwitchId , &attr);
3645
+ }
3579
3646
}
3580
3647
else if (sel == flexCounter.get ())
3581
3648
{
@@ -3598,9 +3665,6 @@ int syncd_main(int argc, char **argv)
3598
3665
exit_and_notify (EXIT_FAILURE);
3599
3666
}
3600
3667
3601
- sai_switch_api_t *sai_switch_api = NULL ;
3602
- sai_api_query (SAI_API_SWITCH, (void **)&sai_switch_api);
3603
-
3604
3668
if (shutdownType == SYNCD_RESTART_TYPE_WARM)
3605
3669
{
3606
3670
const char *warmBootWriteFile = profile_get_value (0 , SAI_KEY_WARM_BOOT_WRITE_FILE);
@@ -3612,6 +3676,7 @@ int syncd_main(int argc, char **argv)
3612
3676
SWSS_LOG_WARN (" user requested warm shutdown but warmBootWriteFile is not specified, forcing cold shutdown" );
3613
3677
3614
3678
shutdownType = SYNCD_RESTART_TYPE_COLD;
3679
+ warmRestartTable->hset (" warm-shutdown" , " state" , " warm-shutdown-failed" );
3615
3680
}
3616
3681
else
3617
3682
{
@@ -3629,6 +3694,7 @@ int syncd_main(int argc, char **argv)
3629
3694
SWSS_LOG_ERROR (" Failed to set SAI_SWITCH_ATTR_RESTART_WARM=true: %s, fall back to cold restart" ,
3630
3695
sai_serialize_status (status).c_str ());
3631
3696
shutdownType = SYNCD_RESTART_TYPE_COLD;
3697
+ warmRestartTable->hset (" warm-shutdown" , " state" , " set-flag-failed" );
3632
3698
}
3633
3699
}
3634
3700
}
@@ -3662,13 +3728,25 @@ int syncd_main(int argc, char **argv)
3662
3728
// Stop notification thread before removing switch
3663
3729
stopNotificationsProcessingThread ();
3664
3730
3665
- status = sai_switch_api->remove_switch (gSwitchId );
3731
+ {
3732
+ SWSS_LOG_TIMER (" remove switch" );
3733
+ status = sai_switch_api->remove_switch (gSwitchId );
3734
+ }
3735
+
3666
3736
if (status != SAI_STATUS_SUCCESS)
3667
3737
{
3668
3738
SWSS_LOG_NOTICE (" Can't delete a switch. gSwitchId=0x%lx status=%s" , gSwitchId ,
3669
3739
sai_serialize_status (status).c_str ());
3670
3740
}
3671
3741
3742
+ if (shutdownType == SYNCD_RESTART_TYPE_WARM)
3743
+ {
3744
+ warmRestartTable->hset (" warm-shutdown" , " state" ,
3745
+ (status == SAI_STATUS_SUCCESS) ?
3746
+ " warm-shutdown-succeeded" :
3747
+ " warm-shutdown-failed" );
3748
+ }
3749
+
3672
3750
SWSS_LOG_NOTICE (" calling api uninitialize" );
3673
3751
3674
3752
status = sai_api_uninitialize ();
0 commit comments