Skip to content

Commit

Permalink
added sighup and sigterm signals
Browse files Browse the repository at this point in the history
  • Loading branch information
kanza-latif committed Sep 24, 2024
1 parent d3c0ee0 commit 82aca30
Showing 1 changed file with 100 additions and 65 deletions.
165 changes: 100 additions & 65 deletions scripts/hostcfgd
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ from shutil import copy2
from datetime import datetime
from sonic_py_common import device_info
from sonic_py_common.general import check_output_pipe
# from swsscommon.swsscommon import ConfigDBConnector, DBConnector, Table
from swsscommon.swsscommon import ConfigDBConnector, DBConnector, Table
from swsscommon import swsscommon
from sonic_installer import bootloader
hostcfg_file_path = os.path.abspath(__file__)
Expand Down Expand Up @@ -1716,86 +1716,121 @@ class FipsCfg(object):
syslog.syslog(syslog.LOG_INFO, f'FipsCfg: update the FIPS enforce option {self.enforce}.')
loader.set_fips(image, self.enforce)


class Memory_StatisticsCfg(object):
class MemoryStatsCfg(object):
"""
Memory Stats Config Daemon
Handles changes in MEMORY_STATS table.
1) Handle enabling or disabling the feature
2) Handle change of retention period
3) Handle change of sampling interval
"""

def __init__(self, CfgDb):
self.config_db = CfgDb

def __init__(self):
self.cache = {}
self.memory_statistics_defaults = {
"enabled": "false",
"retention_time": "15 days",
"sampling_interval": "5 minutes"
}

def load(self, memory_statistics_table):
"""
Load memory statistics configuration when the daemon starts.

def load(self, memory_stats_config: dict):
"""Memory stats configuration
Force load memory statistics configuration.
Args:
memory_stats_config: Configured memory statistics settings.
"""
syslog.syslog(syslog.LOG_INFO, "Memory_StatisticsCfg init ...")
memory_statistics_conf = memory_statistics_table.get("config", {})

# Apply default configurations if not present
for row, value in self.memory_statistics_defaults.items():
if not memory_statistics_conf.get(row):
self.config_db.mod_entry("MEMORY_STATISTICS", "config", {row: value})

# Apply configurations to ensure they are set correctly on startup
self.apply_configuration(memory_statistics_conf)

def apply_configuration(self, config):
"""
Apply the memory statistics configuration settings.
Args:
config: Configuration data for memory statistics.
"""
# Determine if the feature is enabled or disabled
enabled = config.get("enabled", self.memory_statistics_defaults["enabled"]).lower() == "true"
retention_time = config.get("retention_time", self.memory_statistics_defaults["retention_time"])
sampling_interval = config.get("sampling_interval", self.memory_statistics_defaults["sampling_interval"])

# Enable or disable memory statistics
if enabled:
self.run_cmd(["sonic-memory_statistics-config", "--enable"])
else:
self.run_cmd(["sonic-memory_statistics-config", "--disable"])

# Set retention time and sampling interval
self.run_cmd(["sonic-memory_statistics-config", "--retention_time", retention_time])
self.run_cmd(["sonic-memory_statistics-config", "--sampling_interval", sampling_interval])

def memory_statistics_update(self, key, data):
syslog.syslog(syslog.LOG_INFO, 'MemoryStatsCfg: load initial')

if not memory_stats_config:
memory_stats_config = {}

# Force load memory statistics settings.
enable_data = memory_stats_config.get("enable", {})
retention_data = memory_stats_config.get("retention", {})
sampling_data = memory_stats_config.get("sampling", {})

self.memory_stats_message("enable", enable_data)
self.memory_stats_message("retention", retention_data)
self.memory_stats_message("sampling", sampling_data)

def memory_stats_message(self, key, data):
"""
Handle updates to the memory statistics configuration.
Apply memory stats settings handler.
Args:
key: Key identifying the config type.
data: Updated configuration data.
"""
syslog.syslog(syslog.LOG_INFO, "Memory_Statistics global configuration update")
if key == "config":
self.apply_configuration(data)

def run_cmd(self, cmd):
"""
Execute a shell command and return the output.
Args:
cmd: List of command arguments.
key: DB table's key that was triggered change.
data: Read table data.
"""
if type(data) != dict:
# Nothing to handle
return

update_required = False
# Check with cache
for k, v in data.items():
if v != self.cache.get(k):
update_required = True
break

if not update_required:
return

try:
output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
syslog.syslog(syslog.LOG_INFO, output.decode('utf-8'))
# If the disable flag is set, stop the daemon.
if key == "enable" and not data.get("enabled", True):
self.shutdown_memorystats()
else:
# Signal the memory stats daemon to reload configuration
self.reload_memory_stats_daemon()
except Exception as e:
syslog.syslog(syslog.LOG_ERR, f'MemoryStatsCfg: Failed to manage memory-stats-daemon: {e}')
return

# Update cache
for k, v in data.items():
self.cache[k] = v

def reload_memory_stats_daemon(self):
"""Reload the memory stats daemon"""
syslog.syslog(syslog.LOG_INFO, 'MemoryStatsCfg: Reloading memory-stats-daemon')
try:
subprocess.run(["systemctl", "reload", "memory-stats-daemon"], check=True)
syslog.syslog(syslog.LOG_INFO, 'MemoryStatsCfg: memory-stats-daemon successfully reloaded')
except subprocess.CalledProcessError as e:
syslog.syslog(syslog.LOG_ERR, e.output.decode('utf-8'))

syslog.syslog(syslog.LOG_ERR, f"MemoryStatsCfg: Failed to reload memory-stats-daemon: {e}")
raise

# Additional methods for handling signals
def get_memorystats_pid(self):
"""Get the PID of the memorystatsd process."""
try:
for proc in psutil.process_iter(['name']):
if proc.info['name'] == 'memorystatsd':
return proc.pid
except psutil.NoSuchProcess:
return None
return None

def reload_memorystats(self):
"""Send SIGHUP to reload configuration."""
pid = self.get_memorystats_pid()
if pid:
os.kill(pid, signal.SIGHUP)

def shutdown_memorystats(self):
"""Send SIGTERM to gracefully shut down memorystatsd."""
pid = self.get_memorystats_pid()
if pid:
os.kill(pid, signal.SIGTERM)

def monitor_config_changes(self):
"""Monitor configuration changes from ConfigDB."""
while True:
config = configdb.get_memory_stats_config()

# Handle changes in retention_period, sampling_interval, or enable/disable feature
if config.get('changed'): # Assuming 'changed' is a flag indicating a change
if config.get('enabled', True): # If 'enabled' is True, reload the daemon
self.reload_memorystats()
else:
# If 'enabled' is False, disable the feature by sending SIGTERM to the daemon
self.shutdown_memorystats()

time.sleep(5) # Polling interval

class SerialConsoleCfg:

Expand Down

0 comments on commit 82aca30

Please sign in to comment.