RDKB-63306: cujo-agent agent.txt - add log rotation#59
RDKB-63306: cujo-agent agent.txt - add log rotation#59sowmiyachelliah wants to merge 23 commits intodevelopfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Implements automatic rotation of the Cujo agent log (/rdklogs/logs/agent.txt) by introducing a libev-based file monitor thread that triggers logrotate once the log exceeds a 2MB threshold.
Changes:
- Add a dedicated libev
ev_statwatcher thread to monitoragent.txtsize and invoke log rotation. - Introduce log-rotation constants (paths, threshold, poll interval) and call the monitor startup during security initialization.
- Add libev/pthread link flags to the DML library and SSP binary.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 9 comments.
| File | Description |
|---|---|
| source/AdvSecuritySsp/Makefile.am | Adds -lpthread -lev to SSP link flags. |
| source/AdvSecurityDml/Makefile.am | Adds -lev -lpthread to DML library link flags for new monitoring thread. |
| source/AdvSecurityDml/cosa_adv_security_internal.c | Adds log rotation constants, starts a monitor thread, and implements libev-based stat watching + logrotate execution. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| /* Thread function to run libev event loop for log monitoring */ | ||
| void* agent_log_monitor_thread(void* arg) | ||
| { | ||
| (void)arg; |
There was a problem hiding this comment.
The new forward declaration marks agent_log_monitor_thread as static (internal linkage), but the definition is non-static. With -Wall -Werror this can fail to compile due to conflicting linkage. Make the definition static (and consider making the other helper functions in this block static as well since they’re file-local).
|
|
||
| CcspTraceInfo(("Agent log reached %ld bytes, calling logrotate...\n", st.st_size)); | ||
|
|
||
| result = v_secure_system("%s /tmp/logrotate-advsec.status %s", |
There was a problem hiding this comment.
The logrotate invocation appears to pass the status file as a positional argument. logrotate expects a single config file argument; the status file should be provided via the -s option. As written, /tmp/logrotate-advsec.status will likely be treated as a config file and rotation will fail.
| result = v_secure_system("%s /tmp/logrotate-advsec.status %s", | |
| result = v_secure_system("%s -s /tmp/logrotate-advsec.status %s", |
|
|
||
| CcspTraceInfo(("Agent log reached %ld bytes, calling logrotate...\n", st.st_size)); | ||
|
|
There was a problem hiding this comment.
st.st_size is an off_t; logging it with %ld is not portable and can be undefined on platforms where off_t is not long. Use an appropriate format (e.g., cast to intmax_t and print with %jd) to avoid incorrect output/UB.
| ERR_CHK(rc); | ||
| advsec_start_logger_thread(); | ||
| advsec_start_log_monitor_thread(); | ||
| advsec_handle_sysevent_async(); |
There was a problem hiding this comment.
The log monitor thread is detached and runs ev_run() indefinitely, but there’s no corresponding shutdown path (e.g., in CosaSecurityRemove/COSA_Unload). This can leave a background thread running after the component is unloaded, causing undefined behavior. Add a stop mechanism (ev_break + thread join/cancel) tied to the component lifecycle.
| /* Logrotate configuration for agent.txt */ | ||
| #define ADVSEC_AGENT_LOG_FILE "/rdklogs/logs/agent.txt" | ||
| #define ADVSEC_AGENT_LOG_MAX_SIZE (2 * 1024 * 1024) /* 2MB */ | ||
| #define ADVSEC_AGENT_LOG_INTERVAL 5.0 | ||
| #define ADVSEC_AGENT_LOGROTATE_CONF "/etc/logrotate.d/advsec-agent" | ||
| #define LOGROTATE_BINARY "/usr/sbin/logrotate" | ||
|
|
There was a problem hiding this comment.
ADVSEC_AGENT_LOGROTATE_CONF points to /etc/logrotate.d/advsec-agent, but no such config appears to be added/installed by this change. Without ensuring this file exists on target devices, rotation will consistently fail. Consider shipping/installing the config as part of this component (or add an existence check with a clear error log).
| libdmlasecurity_la_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/source/AdvSecurityDml -I$(top_srcdir)/source/AdvSecuritySsp $(CPPFLAGS) -I$(top_srcdir)/../Utopia/source/include/sysevent -I${PKG_CONFIG_SYSROOT_DIR}$(includedir)/rbus | ||
| libdmlasecurity_la_SOURCES = plugin_main.c cosa_adv_security_internal.c cosa_adv_security_dml.c cosa_adv_security_webconfig.c advsecurity_helpers.c advsecurity_param.c | ||
| libdmlasecurity_la_LDFLAGS = -lccsp_common -lsyscfg -lsysevent -lwebconfig_framework -lmsgpackc -ltrower-base64 -lsecure_wrapper -lrbus $(SSP_LDFLAGS) | ||
| libdmlasecurity_la_LDFLAGS = -lccsp_common -lsyscfg -lsysevent -lwebconfig_framework -lmsgpackc -ltrower-base64 -lsecure_wrapper -lrbus -lev -lpthread $(SSP_LDFLAGS) |
There was a problem hiding this comment.
Hardcoding -lev in the library link flags introduces a new build dependency on libev. If libev isn’t guaranteed in all build environments, this may break the build; consider adding proper dependency detection (e.g., via configure/pkg-config) and using discovered CFLAGS/LIBS instead of a fixed -lev.
| /* Log rotation function for agent.txt using logrotate binary */ | ||
| void rotate_agent_log(void) | ||
| { | ||
| struct stat st; | ||
| int result; | ||
|
|
||
| if (stat(ADVSEC_AGENT_LOG_FILE, &st) != 0) | ||
| { | ||
| return; | ||
| } | ||
|
|
||
| if (st.st_size < ADVSEC_AGENT_LOG_MAX_SIZE) | ||
| { | ||
| return; | ||
| } |
There was a problem hiding this comment.
New log-rotation behavior (size check + logrotate command execution) is introduced here, but there are existing unit tests for this module under source/test/CcspAdvSecurityDmlTest. Consider adding tests for rotate_agent_log() to verify it only invokes v_secure_system once the size threshold is exceeded and that failures are handled/logged correctly.
| result = v_secure_system("%s /tmp/logrotate-advsec.status %s", | ||
| LOGROTATE_BINARY, ADVSEC_AGENT_LOGROTATE_CONF); | ||
| if (result != 0) | ||
| { | ||
| CcspTraceError(("Logrotate failed with return code: %d\n", result)); | ||
| } |
There was a problem hiding this comment.
v_secure_system() return values are checked with WIFEXITED/WEXITSTATUS in many other places in this file; here it’s compared directly to 0 and logged as a raw int. This can misreport failures (e.g., signal termination encodings). Consider using the same WIFEXITED/WEXITSTATUS pattern for consistency and correctness.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (stat(ADVSEC_AGENT_LOG_FILE, &st) != 0) | ||
| { | ||
| return; | ||
| } |
There was a problem hiding this comment.
ADVSEC_AGENT_LOG_FILE is used here but is not defined anywhere in the repo (no #define/declaration found), which will fail compilation. Define the log path constant (e.g., to agent.txt) in an appropriate header or in this file before using it in stat()/ev_stat_init().
| } | ||
|
|
||
| /* Thread function to run libev event loop for log monitoring */ | ||
| void* agent_log_monitor_thread(void* arg) |
There was a problem hiding this comment.
agent_log_monitor_thread is forward-declared as static but defined without static here. This is a storage-class mismatch that can fail compilation under strict flags; make the definition static (or drop static from the prototype) so they match.
| void* agent_log_monitor_thread(void* arg) | |
| static void* agent_log_monitor_thread(void* arg) |
| advsec_start_log_monitor_thread(); | ||
| advsec_handle_sysevent_async(); |
There was a problem hiding this comment.
The log monitor thread is started unconditionally during initialization, even when Is_Device_Finger_Print_Enabled() is false (the logger thread is gated, but the monitor thread is not). This creates a detached thread running an event loop for the lifetime of the process even when the feature is disabled; consider gating this start on the same enable condition (or stopping it when disabled).
| advsec_start_log_monitor_thread(); | |
| advsec_handle_sysevent_async(); | |
| if(Value == 1) | |
| { | |
| advsec_start_log_monitor_thread(); | |
| advsec_handle_sysevent_async(); | |
| } |
| /* Log rotation function for agent.txt using logrotate binary */ | ||
| void rotate_agent_log(void) | ||
| { | ||
| struct stat st; | ||
| int result; |
There was a problem hiding this comment.
New log rotation behavior is introduced here but there are existing gtest-based unit tests for this module; consider adding coverage for rotation triggering (size threshold) and the logrotate command execution path (success/failure) to prevent regressions.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| #define ADVSEC_AGENT_LOG_FILE "/rdklogs/logs/agent.txt.0" | ||
| #define ADVSEC_AGENT_LOG_MAX_SIZE (2 * 1024 * 1024) /* 2MB */ | ||
| #define ADVSEC_AGENT_LOG_INTERVAL 5.0 | ||
| #define ADVSEC_AGENT_LOGROTATE_CONF "/etc/logrotate.d/advsec-agent" |
There was a problem hiding this comment.
This code hard-depends on /etc/logrotate.d/advsec-agent, but that config file is not added/installed anywhere in this repo. Without it, rotation will silently never occur (or will always fail). Add the logrotate config to the repo and ensure it gets installed to the expected path, or adjust the code to point to the installed location.
| #define ADVSEC_AGENT_LOGROTATE_CONF "/etc/logrotate.d/advsec-agent" | |
| /* | |
| * Use a runtime-managed config path instead of hard-depending on | |
| * /etc/logrotate.d/advsec-agent, which is not installed by this source tree. | |
| */ | |
| #define ADVSEC_AGENT_LOGROTATE_CONF "/tmp/advsec-agent.logrotate.conf" |
89e0f61 to
eb9ffe4
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| CcspTraceInfo(("Agent log reached %ld bytes, calling logrotate...\n", st.st_size)); | ||
|
|
||
| result = v_secure_system("%s /tmp/logrotate-advsec.status %s", | ||
| LOGROTATE_BINARY, ADVSEC_AGENT_LOGROTATE_CONF); | ||
| if (result != 0) |
There was a problem hiding this comment.
The new logrotate invocation references ADVSEC_AGENT_LOGROTATE_CONF, but that macro isn't defined anywhere in the repo, so this won’t compile. Also, the command line passed to logrotate appears malformed: /tmp/logrotate-advsec.status is being passed as a positional argument rather than via -s <statefile>, which logrotate expects for the state file. Define the config path macro and update the logrotate command to pass a config file and state file using the correct flags.
|
|
||
| void advsec_handle_sysevent_async(void); | ||
| static void advsec_start_logger_thread(void); | ||
| static void* agent_log_monitor_thread(void* arg); |
There was a problem hiding this comment.
agent_log_monitor_thread is forward-declared as static, but its definition later is not static. That’s conflicting linkage in C and typically fails compilation with a “static declaration follows non-static”/“conflicting linkage” error. Make the definition static as well (and consider making the other helper functions in this block static too since they’re file-local).
| static void* agent_log_monitor_thread(void* arg); | |
| void* agent_log_monitor_thread(void* arg); |
| return; | ||
| } | ||
|
|
||
| CcspTraceInfo(("Agent log reached %ld bytes, calling logrotate...\n", st.st_size)); |
There was a problem hiding this comment.
st.st_size is an off_t and isn’t guaranteed to fit %ld (it may be 64-bit on some platforms). This log line should use a format specifier/cast that is correct for off_t (e.g., cast to intmax_t and print with %jd, or use a platform-safe macro) to avoid undefined behavior or incorrect output.
Reason for change: Implemented automatic log rotation for agent.txt using logrotate utility when file reaches 2MB threshold, monitored via libev event loop in dedicated thread
Test Procedure: Verify agent.txt rotates to agent.txt.1 when file size reaches 2MB
Risks: Low
Priority: P1
Signed-off-by:Sowmiya_Chelliah@comcast.com