3838DEFAULT_POLL_INTERVAL = 200
3939DEFAULT_PORT_NUM = 32
4040DEFAULT_ACTION = 'drop'
41+ DEFAULT_PFC_HISTORY_STATUS = "disable"
4142
4243STATS_DESCRIPTION = [
4344 ('STORM DETECTED/RESTORED' , 'PFC_WD_QUEUE_STATS_DEADLOCK_DETECTED' , 'PFC_WD_QUEUE_STATS_DEADLOCK_RESTORED' ),
5051CONFIG_DESCRIPTION = [
5152 ('ACTION' , 'action' , 'drop' ),
5253 ('DETECTION TIME' , 'detection_time' , 'N/A' ),
53- ('RESTORATION TIME' , 'restoration_time' , 'infinite' )
54+ ('RESTORATION TIME' , 'restoration_time' , 'infinite' ),
55+ ('HISTORY' , 'pfc_stat_history' , 'disable' )
5456]
5557
5658STATS_HEADER = ('QUEUE' , 'STATUS' ,) + list (zip (* STATS_DESCRIPTION ))[0 ]
@@ -248,34 +250,47 @@ def config(self, ports):
248250 tablefmt = 'simple'
249251 ))
250252
251- def start (self , action , restoration_time , ports , detection_time ):
253+ def start (self , action , restoration_time , ports , detection_time , pfc_stat_history ):
252254 invalid_ports = self .get_invalid_ports (ports )
253255 if len (invalid_ports ):
254256 click .echo ("Failed to run command, invalid options:" )
255257 for opt in invalid_ports :
256258 click .echo (opt )
257259 sys .exit (1 )
258- self .start_cmd (action , restoration_time , ports , detection_time )
260+ self .start_cmd (action , restoration_time , ports , detection_time , pfc_stat_history )
259261
262+ def pfc_stat_history (self , pfc_stat_history , ports ):
263+ invalid_ports = self .get_invalid_ports (ports )
264+ if len (invalid_ports ):
265+ click .echo ("Failed to run command, invalid options:" )
266+ for opt in invalid_ports :
267+ click .echo (opt )
268+ sys .exit (1 )
269+ self .pfc_stat_history_cmd (pfc_stat_history , ports )
260270
261- def verify_pfc_enable_status_per_port (self , port , pfcwd_info ):
271+ def verify_pfc_enable_status_per_port (self , port , pfcwd_info , overwrite = True ):
262272 pfc_status = self .config_db .get_entry (PORT_QOS_MAP , port ).get ('pfc_enable' )
263273 if pfc_status is None :
264274 log .log_warning ("SKIPPED: PFC is not enabled on port: {}" .format (port ), also_print_to_console = True )
265275 return
266276
267- self .config_db .mod_entry (
268- CONFIG_DB_PFC_WD_TABLE_NAME , port , None
269- )
270- self .config_db .mod_entry (
271- CONFIG_DB_PFC_WD_TABLE_NAME , port , pfcwd_info
272- )
277+ if overwrite :
278+ # don't clear existing pfc history setting unless set explicitely
279+ cur_pfc_history = self .config_db .get_entry (
280+ CONFIG_DB_PFC_WD_TABLE_NAME , port
281+ ).get ("pfc_stat_history" , DEFAULT_PFC_HISTORY_STATUS )
273282
274- @multi_asic_util .run_on_multi_asic
275- def start_cmd (self , action , restoration_time , ports , detection_time ):
276- if os .geteuid () != 0 :
277- sys .exit ("Root privileges are required for this operation" )
283+ pfcwd_info .setdefault ("pfc_stat_history" , cur_pfc_history )
278284
285+ self .config_db .set_entry (
286+ CONFIG_DB_PFC_WD_TABLE_NAME , port , pfcwd_info
287+ )
288+ else :
289+ self .config_db .mod_entry (
290+ CONFIG_DB_PFC_WD_TABLE_NAME , port , pfcwd_info
291+ )
292+
293+ def configure_ports (self , ports , pfcwd_info , overwrite = True ):
279294 all_ports = get_all_ports (
280295 self .db , self .multi_asic .current_namespace ,
281296 self .multi_asic .display_option
@@ -284,6 +299,20 @@ def start_cmd(self, action, restoration_time, ports, detection_time):
284299 if len (ports ) == 0 :
285300 ports = all_ports
286301
302+ for port in ports :
303+ if port == "all" :
304+ for p in all_ports :
305+ self .verify_pfc_enable_status_per_port (p , pfcwd_info , overwrite )
306+ else :
307+ if port not in all_ports :
308+ continue
309+ self .verify_pfc_enable_status_per_port (port , pfcwd_info , overwrite )
310+
311+ @multi_asic_util .run_on_multi_asic
312+ def start_cmd (self , action , restoration_time , ports , detection_time , pfc_stat_history ):
313+ if os .geteuid () != 0 :
314+ sys .exit ("Root privileges are required for this operation" )
315+
287316 pfcwd_info = {
288317 'detection_time' : detection_time ,
289318 }
@@ -297,15 +326,10 @@ def start_cmd(self, action, restoration_time, ports, detection_time):
297326 "restoration time not defined; default to 2 times "
298327 "detection time: {} ms" .format (2 * detection_time )
299328 )
329+ if pfc_stat_history :
330+ pfcwd_info ["pfc_stat_history" ] = "enable"
300331
301- for port in ports :
302- if port == "all" :
303- for p in all_ports :
304- self .verify_pfc_enable_status_per_port (p , pfcwd_info )
305- else :
306- if port not in all_ports :
307- continue
308- self .verify_pfc_enable_status_per_port (port , pfcwd_info )
332+ self .configure_ports (ports , pfcwd_info , overwrite = True )
309333
310334 @multi_asic_util .run_on_multi_asic
311335 def interval (self , poll_interval ):
@@ -391,11 +415,12 @@ def start_default(self):
391415 pfcwd_info = {
392416 'detection_time' : DEFAULT_DETECTION_TIME * multiply ,
393417 'restoration_time' : DEFAULT_RESTORATION_TIME * multiply ,
394- 'action' : DEFAULT_ACTION
418+ 'action' : DEFAULT_ACTION ,
419+ 'pfc_stat_history' : DEFAULT_PFC_HISTORY_STATUS
395420 }
396421
397422 for port in active_ports :
398- self .verify_pfc_enable_status_per_port (port , pfcwd_info )
423+ self .verify_pfc_enable_status_per_port (port , pfcwd_info , overwrite = True )
399424
400425 pfcwd_info = {}
401426 pfcwd_info ['POLL_INTERVAL' ] = DEFAULT_POLL_INTERVAL * multiply
@@ -423,6 +448,15 @@ def big_red_switch(self, big_red_switch):
423448 pfcwd_info
424449 )
425450
451+ @multi_asic_util .run_on_multi_asic
452+ def pfc_stat_history_cmd (self , pfc_stat_history , ports ):
453+ if os .geteuid () != 0 :
454+ sys .exit ("Root privileges are required for this operation" )
455+
456+ pfcwd_info = {
457+ 'pfc_stat_history' : pfc_stat_history
458+ }
459+ self .configure_ports (ports , pfcwd_info , overwrite = False )
426460
427461# Show stats
428462class Show (object ):
@@ -459,20 +493,21 @@ class Start(object):
459493 '--action' , '-a' , type = click .Choice (['drop' , 'forward' , 'alert' ])
460494 )
461495 @click .option ('--restoration-time' , '-r' , type = click .IntRange (100 , 60000 ))
496+ @click .option ('--pfc-stat-history' , is_flag = True )
462497 @click .argument ('ports' , nargs = - 1 )
463498 @click .argument ('detection-time' , type = click .IntRange (100 , 5000 ))
464499 @clicommon .pass_db
465- def start (db , action , restoration_time , ports , detection_time ):
500+ def start (db , action , restoration_time , ports , detection_time , pfc_stat_history ):
466501 """
467502 Start PFC watchdog on port(s). To config all ports, use all as input.
468503
469504 Example:
470505
471- sudo pfcwd start --action drop all 400 --restoration-time 400
506+ sudo pfcwd start --action drop all 400 --restoration-time 400 --pfc-stat-history enable
472507
473508 """
474509 PfcwdCli (db ).start (
475- action , restoration_time , ports , detection_time
510+ action , restoration_time , ports , detection_time , pfc_stat_history
476511 )
477512
478513
@@ -525,7 +560,19 @@ def big_red_switch(db, big_red_switch):
525560 PfcwdCli (db ).big_red_switch (big_red_switch )
526561
527562
563+ # Enable/disable PFC WD PFC_STAT_HISTORY mode
564+ class PfcStatHistory (object ):
565+ @cli .command ('pfc_stat_history' )
566+ @click .argument ('pfc_stat_history' , type = click .Choice (['enable' , 'disable' ]))
567+ @click .argument ('ports' , nargs = - 1 )
568+ @clicommon .pass_db
569+ def pfc_stat_history (db , pfc_stat_history , ports ):
570+ """ Enable/disable PFC Historical Statistics mode on ports"""
571+ PfcwdCli (db ).pfc_stat_history (pfc_stat_history , ports )
572+
573+
528574def get_pfcwd_clis ():
575+ cli .add_command (PfcStatHistory ().pfc_stat_history )
529576 cli .add_command (BigRedSwitch ().big_red_switch )
530577 cli .add_command (CounterPoll ().counter_poll )
531578 cli .add_command (StartDefault ().start_default )
0 commit comments