Skip to content

Commit

Permalink
[Config] Update config command of kdump (sonic-net#1700)
Browse files Browse the repository at this point in the history
Signed-off-by: Yong Zhao yozhao@microsoft.com

What I did
This PR aims to update the config command of Kdump (Linux kernel dump) mechanism.

How I did it
Before updating the value of a field in the table of KDUMP, we need decide whether the KDUMP table and corresponding field does exist in the table.

How to verify it
I verifies this on device str-msn2700-03 and unit test passed.

    tests/kdump_test.py::TestKdump::test_config_kdump_disable PASSED                                                                                                 
    tests/kdump_test.py::TestKdump::test_config_kdump_enable PASSED                                                                                                  
    tests/kdump_test.py::TestKdump::test_config_kdump_memory PASSED                                                                                                  
    tests/kdump_test.py::TestKdump::test_config_kdump_num_dumps PASSED
  • Loading branch information
yozhao101 authored Aug 22, 2021
1 parent 4cb3b72 commit cd3ee78
Show file tree
Hide file tree
Showing 3 changed files with 160 additions and 39 deletions.
120 changes: 81 additions & 39 deletions config/kdump.py
Original file line number Diff line number Diff line change
@@ -1,44 +1,86 @@
import os
import sys

import click
import utilities_common.cli as clicommon
from swsscommon.swsscommon import ConfigDBConnector
from utilities_common.cli import AbbreviationGroup, pass_db


@click.group(cls=clicommon.AbbreviationGroup, name="kdump")
#
# 'kdump' group ('sudo config kdump ...')
#
@click.group(cls=AbbreviationGroup, name="kdump")
def kdump():
""" Configure kdump """
if os.geteuid() != 0:
exit("Root privileges are required for this operation")

@kdump.command()
def disable():
"""Disable kdump operation"""
config_db = ConfigDBConnector()
if config_db is not None:
config_db.connect()
config_db.mod_entry("KDUMP", "config", {"enabled": "false"})

@kdump.command()
def enable():
"""Enable kdump operation"""
config_db = ConfigDBConnector()
if config_db is not None:
config_db.connect()
config_db.mod_entry("KDUMP", "config", {"enabled": "true"})

@kdump.command()
"""Configure the KDUMP mechanism"""
pass


def check_kdump_table_existence(kdump_table):
"""Checks whether the 'KDUMP' table is configured in Config DB.
Args:
kdump_table: A dictionary represents the key-value pair in sub-table
of 'KDUMP'.
Returns:
None.
"""
if not kdump_table:
click.echo("Unable to retrieve 'KDUMP' table from Config DB.")
sys.exit(1)

if "config" not in kdump_table:
click.echo("Unable to retrieve key 'config' from KDUMP table.")
sys.exit(2)


#
# 'disable' command ('sudo config kdump disable')
#
@kdump.command(name="disable", short_help="Disable the KDUMP mechanism")
@pass_db
def kdump_disable(db):
"""Disable the KDUMP mechanism"""
kdump_table = db.cfgdb.get_table("KDUMP")
check_kdump_table_existence(kdump_table)

db.cfgdb.mod_entry("KDUMP", "config", {"enabled": "false"})


#
# 'enable' command ('sudo config kdump enable')
#
@kdump.command(name="enable", short_help="Enable the KDUMP mechanism")
@pass_db
def kdump_enable(db):
"""Enable the KDUMP mechanism"""
kdump_table = db.cfgdb.get_table("KDUMP")
check_kdump_table_existence(kdump_table)

db.cfgdb.mod_entry("KDUMP", "config", {"enabled": "true"})


#
# 'memory' command ('sudo config kdump memory ...')
#
@kdump.command(name="memory", short_help="Configure the memory for KDUMP mechanism")
@click.argument('kdump_memory', metavar='<kdump_memory>', required=True)
def memory(kdump_memory):
"""Set memory allocated for kdump capture kernel"""
config_db = ConfigDBConnector()
if config_db is not None:
config_db.connect()
config_db.mod_entry("KDUMP", "config", {"memory": kdump_memory})

@kdump.command('num-dumps')
@pass_db
def kdump_memory(db, kdump_memory):
"""Reserve memory for kdump capture kernel"""
kdump_table = db.cfgdb.get_table("KDUMP")
check_kdump_table_existence(kdump_table)

db.cfgdb.mod_entry("KDUMP", "config", {"memory": kdump_memory})


#
# 'num_dumps' command ('sudo config keump num_dumps ...')
#
@kdump.command(name="num_dumps", short_help="Configure the maximum dump files of KDUMP mechanism")
@click.argument('kdump_num_dumps', metavar='<kdump_num_dumps>', required=True, type=int)
def num_dumps(kdump_num_dumps):
"""Set max number of dump files for kdump"""
config_db = ConfigDBConnector()
if config_db is not None:
config_db.connect()
config_db.mod_entry("KDUMP", "config", {"num_dumps": kdump_num_dumps})
@pass_db
def kdump_num_dumps(db, kdump_num_dumps):
"""Set maximum number of dump files for kdump"""
kdump_table = db.cfgdb.get_table("KDUMP")
check_kdump_table_existence(kdump_table)

db.cfgdb.mod_entry("KDUMP", "config", {"num_dumps": kdump_num_dumps})
74 changes: 74 additions & 0 deletions tests/kdump_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import importlib

from click.testing import CliRunner
from utilities_common.db import Db


class TestKdump(object):
@classmethod
def setup_class(cls):
print("SETUP")

def test_config_kdump_disable(self, get_cmd_module):
(config, show) = get_cmd_module
db = Db()
runner = CliRunner()
result = runner.invoke(config.config.commands["kdump"].commands["disable"], obj=db)
print(result.exit_code)
assert result.exit_code == 0

# Delete the 'KDUMP' table.
db.cfgdb.delete_table("KDUMP")

result = runner.invoke(config.config.commands["kdump"].commands["disable"], obj=db)
print(result.exit_code)
assert result.exit_code == 1

def test_config_kdump_enable(self, get_cmd_module):
(config, show) = get_cmd_module
db = Db()
runner = CliRunner()
result = runner.invoke(config.config.commands["kdump"].commands["enable"], obj=db)
print(result.exit_code)
assert result.exit_code == 0

# Delete the 'KDUMP' table.
db.cfgdb.delete_table("KDUMP")

result = runner.invoke(config.config.commands["kdump"].commands["enable"], obj=db)
print(result.exit_code)
assert result.exit_code == 1

def test_config_kdump_memory(self, get_cmd_module):
(config, show) = get_cmd_module
db = Db()
runner = CliRunner()
result = runner.invoke(config.config.commands["kdump"].commands["memory"], ["256MB"], obj=db)
print(result.exit_code)
assert result.exit_code == 0

# Delete the 'KDUMP' table.
db.cfgdb.delete_table("KDUMP")

result = runner.invoke(config.config.commands["kdump"].commands["memory"], ["256MB"], obj=db)
print(result.exit_code)
assert result.exit_code == 1

def test_config_kdump_num_dumps(self, get_cmd_module):
(config, show) = get_cmd_module
db = Db()
runner = CliRunner()
result = runner.invoke(config.config.commands["kdump"].commands["num_dumps"], ["10"], obj=db)
print(result.exit_code)
assert result.exit_code == 0

# Delete the 'KDUMP' table.
db.cfgdb.delete_table("KDUMP")

result = runner.invoke(config.config.commands["kdump"].commands["num_dumps"], ["10"], obj=db)
print(result.exit_code)
assert result.exit_code == 1

@classmethod
def teardown_class(cls):
print("TEARDOWN")
5 changes: 5 additions & 0 deletions tests/mock_tables/config_db.json
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,11 @@
"DEBUG_COUNTER_DROP_REASON|DEBUG_2|IP_HEADER_ERROR": {},
"DEBUG_COUNTER_DROP_REASON|DEBUG_2|NO_L3_HEADER": {},
"DEBUG_COUNTER_DROP_REASON|lowercase_counter|L2_ANY": {},
"KDUMP|config": {
"enabled": "false",
"memory": "256MB",
"num_dumps": "3"
},
"FEATURE|bgp": {
"state": "enabled",
"auto_restart": "enabled",
Expand Down

0 comments on commit cd3ee78

Please sign in to comment.