-
Notifications
You must be signed in to change notification settings - Fork 1
Feature/simplify lib coverity #44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR simplifies the uploadSTBLogs library structure by flattening nested structures within RuntimeContext and consolidating related source files. The changes remove nested groupings (paths, device, settings, endpoints, flags, retry) in favor of direct field access, and merge several implementation files (strategies, log collection, cleanup) to reduce complexity.
Key changes:
- Flattened RuntimeContext structure from nested groups to direct fields (e.g.,
ctx->paths.log_path→ctx->log_path) - Consolidated strategy implementations from separate files (strategy_dcm.c, strategy_ondemand.c, strategy_reboot.c) into single strategies.c
- Merged log_collector.c into archive_manager.c and cleanup_manager.c into cleanup_handler.c
- Added new public API function
uploadstblogs_run()for external component integration - Updated all test files to match the new flattened structure
- Modified build system to create both library and binary
Reviewed changes
Copilot reviewed 44 out of 45 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| uploadstblogs/src/strategies.c | New consolidated file combining DCM, Ondemand, and Reboot strategy implementations |
| uploadstblogs/src/uploadstblogs.c | Added uploadstblogs_run() API and separated main() with conditional compilation |
| uploadstblogs/src/validation.c | Added conditional check for rrd_flag when validating PREV_LOG_PATH |
| uploadstblogs/src/context_manager.c | Updated all structure field accesses to use flattened RuntimeContext |
| uploadstblogs/src/archive_manager.c | Merged log_collector.c functions into archive_manager.c |
| uploadstblogs/src/cleanup_handler.c | Merged cleanup_manager.c functions into cleanup_handler.c |
| uploadstblogs/src/event_manager.c | Added rrd_flag check in emit_no_logs_reboot() |
| uploadstblogs/unittest/*.cpp | Updated all test files to use flattened RuntimeContext fields |
| uploadstblogs/src/Makefile.am | Updated to build both library and binary, simplified binary build |
| uploadstblogs/include/uploadstblogs.h | Added uploadstblogs_run() and uploadstblogs_execute() API documentation |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 44 out of 45 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (ctx->rrd_flag == 0) { | ||
| // Check PREV_LOG_PATH - critical for upload (matches script behavior) | ||
| if (strlen(ctx->paths.prev_log_path) > 0) { | ||
| if (!dir_exists(ctx->paths.prev_log_path)) { | ||
| RDK_LOG(RDK_LOG_ERROR, LOG_UPLOADSTB, "[%s:%d] The Previous Logs folder is missing: %s\n", | ||
| __FUNCTION__, __LINE__, ctx->paths.prev_log_path); | ||
| if (strlen(ctx->prev_log_path) > 0) { | ||
| if (!dir_exists(ctx->prev_log_path)) { | ||
| RDK_LOG(RDK_LOG_ERROR, LOG_UPLOADSTB, "[%s:%d] The Previous Logs folder is missing: %s\n", | ||
| __FUNCTION__, __LINE__, ctx->prev_log_path); | ||
| // Script sends MAINT_LOGUPLOAD_ERROR=5 when PREV_LOG_PATH is missing | ||
| emit_folder_missing_error(); | ||
| all_valid = false; | ||
| } else { | ||
| RDK_LOG(RDK_LOG_DEBUG, LOG_UPLOADSTB, "[%s:%d] PREV_LOG_PATH exists: %s\n", | ||
| __FUNCTION__, __LINE__, ctx->paths.prev_log_path); | ||
| emit_folder_missing_error(); | ||
| all_valid = false; | ||
| } else { | ||
| RDK_LOG(RDK_LOG_DEBUG, LOG_UPLOADSTB, "[%s:%d] PREV_LOG_PATH exists: %s\n", | ||
| __FUNCTION__, __LINE__, ctx->prev_log_path); | ||
| } | ||
| } | ||
| } |
Copilot
AI
Jan 7, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the validation.c file, the condition for checking PREV_LOG_PATH is now wrapped with if (ctx->rrd_flag == 0), but some paths within this block still use the old nested structure ctx->paths.prev_log_path instead of the flattened ctx->prev_log_path. This creates an inconsistency where the code won't compile correctly.
| if (!dir_exists(ctx->paths.prev_log_path)) { | ||
| RDK_LOG(RDK_LOG_ERROR, LOG_UPLOADSTB, | ||
| "[%s:%d] PREV_LOG_PATH does not exist: %s\n", | ||
| __FUNCTION__, __LINE__, ctx->paths.prev_log_path); | ||
| return -1; | ||
| } | ||
|
|
||
| if (!has_log_files(ctx->paths.prev_log_path)) { | ||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] No .txt or .log files in PREV_LOG_PATH, aborting\n", __FUNCTION__, __LINE__); | ||
| emit_no_logs_reboot(ctx); | ||
| return -1; | ||
| } | ||
|
|
||
| // Check system uptime and sleep if needed | ||
| // Script lines 818-836: if uptime < 900s, sleep 330s | ||
| double uptime_seconds = 0.0; | ||
| if (get_system_uptime(&uptime_seconds)) { | ||
| if (uptime_seconds < 900.0) { | ||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] System uptime %.0f seconds < 900s, sleeping for 330s\n", | ||
| __FUNCTION__, __LINE__, uptime_seconds); | ||
|
|
||
| // Script checks ENABLE_MAINTENANCE but both paths result in 330s sleep | ||
| // For simplicity, just sleep (background job with wait has same effect) | ||
| #ifndef L2_TEST_ENABLED | ||
| sleep(330); | ||
| #endif | ||
|
|
||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] Done sleeping\n", __FUNCTION__, __LINE__); | ||
| } else { | ||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] Device uptime %.0f seconds >= 900s, skipping sleep\n", | ||
| __FUNCTION__, __LINE__, uptime_seconds); | ||
| } | ||
| } else { | ||
| RDK_LOG(RDK_LOG_WARN, LOG_UPLOADSTB, | ||
| "[%s:%d] Failed to get system uptime, skipping sleep\n", | ||
| __FUNCTION__, __LINE__); | ||
| } | ||
|
|
||
| // Delete old backup files (3+ days old) | ||
| // Remove old timestamp directories and logbackup directories | ||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] Cleaning old backups (3+ days)\n", __FUNCTION__, __LINE__); | ||
|
|
||
| int removed = remove_old_directories(ctx->paths.log_path, "*-*-*-*-*M-", 3); | ||
| if (removed > 0) { | ||
| RDK_LOG(RDK_LOG_DEBUG, LOG_UPLOADSTB, | ||
| "[%s:%d] Removed %d old timestamp directories\n", | ||
| __FUNCTION__, __LINE__, removed); | ||
| } | ||
|
|
||
| removed = remove_old_directories(ctx->paths.log_path, "*-*-*-*-*M-logbackup", 3); | ||
| if (removed > 0) { | ||
| RDK_LOG(RDK_LOG_DEBUG, LOG_UPLOADSTB, | ||
| "[%s:%d] Removed %d old logbackup directories\n", | ||
| __FUNCTION__, __LINE__, removed); | ||
| } | ||
|
|
||
| // Create timestamp for permanent log path | ||
| char timestamp[64]; | ||
| time_t now = time(NULL); | ||
| struct tm* tm_info = localtime(&now); | ||
| strftime(timestamp, sizeof(timestamp), "%m-%d-%y-%I-%M%p-logbackup", tm_info); | ||
|
|
||
| char perm_log_path[MAX_PATH_LENGTH]; | ||
| int written = snprintf(perm_log_path, sizeof(perm_log_path), "%s/%s", | ||
| ctx->paths.log_path, timestamp); | ||
|
|
||
| if (written >= (int)sizeof(perm_log_path)) { | ||
| RDK_LOG(RDK_LOG_ERROR, LOG_UPLOADSTB, | ||
| "[%s:%d] Permanent log path too long\n", __FUNCTION__, __LINE__); | ||
| return -1; | ||
| } | ||
|
|
||
| // Store for use in cleanup phase | ||
| strncpy(perm_log_path_storage, perm_log_path, sizeof(perm_log_path_storage) - 1); | ||
| perm_log_path_storage[sizeof(perm_log_path_storage) - 1] = '\0'; | ||
|
|
||
| // Log to lastlog_path | ||
| char lastlog_path_file[MAX_PATH_LENGTH]; | ||
| written = snprintf(lastlog_path_file, sizeof(lastlog_path_file), "%s/lastlog_path", | ||
| ctx->paths.telemetry_path); | ||
|
|
||
| if (written >= (int)sizeof(lastlog_path_file)) { | ||
| RDK_LOG(RDK_LOG_ERROR, LOG_UPLOADSTB, | ||
| "[%s:%d] Lastlog path file too long\n", __FUNCTION__, __LINE__); | ||
| return -1; | ||
| } | ||
|
|
||
| FILE* fp = fopen(lastlog_path_file, "a"); | ||
| if (fp) { | ||
| fprintf(fp, "%s\n", perm_log_path); | ||
| fclose(fp); | ||
| RDK_LOG(RDK_LOG_DEBUG, LOG_UPLOADSTB, | ||
| "[%s:%d] Logged to lastlog_path: %s\n", | ||
| __FUNCTION__, __LINE__, perm_log_path); | ||
| } | ||
|
|
||
| // Delete old tar file if exists | ||
| char old_tar[MAX_PATH_LENGTH]; | ||
| written = snprintf(old_tar, sizeof(old_tar), "%s/logs.tar.gz", ctx->paths.prev_log_path); | ||
|
|
||
| if (written >= (int)sizeof(old_tar)) { | ||
| RDK_LOG(RDK_LOG_ERROR, LOG_UPLOADSTB, | ||
| "[%s:%d] Old tar path too long\n", __FUNCTION__, __LINE__); | ||
| return -1; | ||
| } | ||
|
|
||
| if (file_exists(old_tar)) { | ||
| RDK_LOG(RDK_LOG_DEBUG, LOG_UPLOADSTB, | ||
| "[%s:%d] Removing old tar file: %s\n", | ||
| __FUNCTION__, __LINE__, old_tar); | ||
| remove_file(old_tar); | ||
| } | ||
|
|
||
| // Add timestamps to all files in PREV_LOG_PATH | ||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] Adding timestamps to files in PREV_LOG_PATH\n", | ||
| __FUNCTION__, __LINE__); | ||
|
|
||
| int ret = add_timestamp_to_files(ctx->paths.prev_log_path); | ||
| if (ret != 0) { | ||
| RDK_LOG(RDK_LOG_WARN, LOG_UPLOADSTB, | ||
| "[%s:%d] Failed to add timestamps to some files\n", | ||
| __FUNCTION__, __LINE__); | ||
| // Continue anyway, not critical | ||
| } | ||
|
|
||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] REBOOT/NON_DCM: Setup phase complete\n", __FUNCTION__, __LINE__); | ||
|
|
||
| return 0; | ||
| } | ||
|
|
||
| /** | ||
| * @brief Archive phase for REBOOT/NON_DCM strategy | ||
| * | ||
| * Shell script equivalent (uploadLogOnReboot lines 853-869): | ||
| * - Collect PCAP files to PREV_LOG_PATH if mediaclient | ||
| * - Create tar.gz archive from PREV_LOG_PATH | ||
| * - Sleep 60 seconds | ||
| */ | ||
| static int reboot_archive(RuntimeContext* ctx, SessionState* session) | ||
| { | ||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] REBOOT/NON_DCM: Starting archive phase\n", __FUNCTION__, __LINE__); | ||
|
|
||
| // Collect PCAP files directly to PREV_LOG_PATH if mediaclient | ||
| if (ctx->settings.include_pcap) { | ||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] Collecting PCAP file to PREV_LOG_PATH\n", __FUNCTION__, __LINE__); | ||
| int count = collect_pcap_logs(ctx, ctx->paths.prev_log_path); | ||
| if (count > 0) { | ||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] Collected %d PCAP file\n", __FUNCTION__, __LINE__, count); | ||
| } | ||
| } | ||
|
|
||
| // Create archive from PREV_LOG_PATH (files already have timestamps) | ||
| int ret = create_archive(ctx, session, ctx->paths.prev_log_path); | ||
| if (ret != 0) { | ||
| RDK_LOG(RDK_LOG_ERROR, LOG_UPLOADSTB, | ||
| "[%s:%d] Failed to create archive\n", __FUNCTION__, __LINE__); | ||
| return -1; | ||
| } | ||
| #ifndef L2_TEST_ENABLED | ||
| sleep(60); | ||
| #endif | ||
|
|
||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] REBOOT/NON_DCM: Archive phase complete\n", __FUNCTION__, __LINE__); | ||
|
|
||
| return 0; | ||
| } | ||
|
|
||
| /** | ||
| * @brief Upload phase for REBOOT/NON_DCM strategy | ||
| * | ||
| * Shell script equivalent (uploadLogOnReboot lines 853-890): | ||
| * - Check reboot reason and RFC settings | ||
| * - Upload main logs if allowed | ||
| * - Upload DRI logs if directory exists | ||
| * - Clear old packet captures | ||
| */ | ||
| static int reboot_upload(RuntimeContext* ctx, SessionState* session) | ||
| { | ||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] REBOOT/NON_DCM: Starting upload phase\n", __FUNCTION__, __LINE__); | ||
|
|
||
| // Check reboot reason and RFC settings (matches script logic) | ||
| // Script: if [ "$uploadLog" == "true" ] || [ -z "$reboot_reason" -a "$DISABLE_UPLOAD_LOGS_UNSHEDULED_REBOOT" == "false" ] | ||
| // Note: When DCM_FLAG=0 (Non-DCM), script ALWAYS passes "true" regardless of UploadOnReboot value | ||
| // When DCM_FLAG=1 (DCM mode), upload_on_reboot determines the behavior | ||
| bool should_upload = false; | ||
| const char* reboot_info_path = "/opt/secure/reboot/previousreboot.info"; | ||
|
|
||
| // Non-DCM mode (DCM_FLAG=0): Always upload (script line 999: uploadLogOnReboot true) | ||
| if (ctx->flags.dcm_flag == 0) { | ||
| should_upload = true; | ||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] Non-DCM mode (dcm_flag=0), will always upload logs\n", | ||
| __FUNCTION__, __LINE__); | ||
| } | ||
| // DCM mode (DCM_FLAG=1): Check upload_on_reboot flag | ||
| else if (ctx->flags.upload_on_reboot) { | ||
| should_upload = true; | ||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] DCM mode: Upload enabled from settings (upload_on_reboot=true)\n", | ||
| __FUNCTION__, __LINE__); | ||
| } else { | ||
| // Check reboot reason file for scheduled reboot (grep -i "Scheduled Reboot\|MAINTENANCE_REBOOT") | ||
| bool is_scheduled_reboot = false; | ||
| FILE* reboot_file = fopen(reboot_info_path, "r"); | ||
| if (reboot_file) { | ||
| char line[512]; | ||
| while (fgets(line, sizeof(line), reboot_file)) { | ||
| // Look for "Scheduled Reboot" or "MAINTENANCE_REBOOT" (case insensitive) | ||
| if (strcasestr(line, "Scheduled Reboot") || strcasestr(line, "MAINTENANCE_REBOOT")) { | ||
| is_scheduled_reboot = true; | ||
| break; | ||
| } | ||
| } | ||
| fclose(reboot_file); | ||
| } | ||
|
|
||
| // Get RFC setting for unscheduled reboot upload via RBUS | ||
| bool disable_unscheduled_upload = false; | ||
| if (!rbus_get_bool_param("Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.UploadLogsOnUnscheduledReboot.Disable", | ||
| &disable_unscheduled_upload)) { | ||
| RDK_LOG(RDK_LOG_WARN, LOG_UPLOADSTB, | ||
| "[%s:%d] Failed to get UploadLogsOnUnscheduledReboot.Disable RFC, assuming false\n", | ||
| __FUNCTION__, __LINE__); | ||
| disable_unscheduled_upload = false; | ||
| } | ||
|
|
||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] Reboot reason check - Scheduled: %d, Disable unscheduled RFC: %d\n", | ||
| __FUNCTION__, __LINE__, is_scheduled_reboot, disable_unscheduled_upload); | ||
|
|
||
| // Upload if: reboot reason is empty (unscheduled) AND RFC doesn't disable it | ||
| // Script logic: [ -z "$reboot_reason" -a "$DISABLE_UPLOAD_LOGS_UNSHEDULED_REBOOT" == "false" ] | ||
| if (!is_scheduled_reboot && !disable_unscheduled_upload) { | ||
| should_upload = true; | ||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] Unscheduled reboot and RFC allows upload\n", __FUNCTION__, __LINE__); | ||
| } | ||
| } | ||
|
|
||
| if (!should_upload) { | ||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] Upload not allowed based on reboot reason and RFC settings\n", | ||
| __FUNCTION__, __LINE__); | ||
| return 0; | ||
| } | ||
|
|
||
| // Construct full archive path using session archive filename | ||
| char archive_path[MAX_PATH_LENGTH]; | ||
| int written = snprintf(archive_path, sizeof(archive_path), "%s/%s", | ||
| ctx->paths.prev_log_path, session->archive_file); | ||
|
|
||
| if (written >= (int)sizeof(archive_path)) { | ||
| RDK_LOG(RDK_LOG_ERROR, LOG_UPLOADSTB, | ||
| "[%s:%d] Archive path too long\n", __FUNCTION__, __LINE__); | ||
| return -1; | ||
| } | ||
|
|
||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] Uploading main logs: %s\n", | ||
| __FUNCTION__, __LINE__, archive_path); | ||
|
|
||
| // Upload main logs (session->success is set by execute_upload_cycle) | ||
| int ret = upload_archive(ctx, session, archive_path); | ||
|
|
||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] Main log upload complete (result=%d)\n", | ||
| __FUNCTION__, __LINE__, ret); | ||
|
|
||
| // Upload DRI logs if directory exists (using separate session to avoid state corruption) | ||
| if (ctx->settings.include_dri && dir_exists(ctx->paths.dri_log_path)) { | ||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] DRI log directory exists, uploading DRI logs\n", | ||
| __FUNCTION__, __LINE__); | ||
|
|
||
| // Generate DRI archive filename: {MAC}_DRI_Logs_{timestamp}.tgz | ||
| char dri_filename[MAX_FILENAME_LENGTH]; | ||
| if (!generate_archive_name(dri_filename, sizeof(dri_filename), | ||
| ctx->device.mac_address, "DRI_Logs")) { | ||
| RDK_LOG(RDK_LOG_ERROR, LOG_UPLOADSTB, | ||
| "[%s:%d] Failed to generate DRI archive filename\n", | ||
| __FUNCTION__, __LINE__); | ||
| } else { | ||
| char dri_archive[MAX_PATH_LENGTH]; | ||
| int written = snprintf(dri_archive, sizeof(dri_archive), "%s/%s", | ||
| ctx->paths.prev_log_path, dri_filename); | ||
|
|
||
| if (written >= (int)sizeof(dri_archive)) { | ||
| RDK_LOG(RDK_LOG_ERROR, LOG_UPLOADSTB, | ||
| "[%s:%d] DRI archive path too long\n", __FUNCTION__, __LINE__); | ||
| } else { | ||
| // Create DRI archive | ||
| int dri_ret = create_dri_archive(ctx, dri_archive); | ||
|
|
||
| if (dri_ret == 0) { | ||
| #ifndef L2_TEST_ENABLED | ||
| sleep(60); | ||
| #endif | ||
|
|
||
| // Upload DRI logs using separate session state | ||
| SessionState dri_session = *session; // Copy current session config | ||
| dri_session.direct_attempts = 0; // Reset attempt counters | ||
| dri_session.codebig_attempts = 0; | ||
| dri_ret = upload_archive(ctx, &dri_session, dri_archive); | ||
|
|
||
| // Send telemetry for DRI upload (matches script lines 883, 886) | ||
| // Script sends SYST_INFO_PDRILogUpload for both success and failure | ||
| t2_count_notify("SYST_INFO_PDRILogUpload"); | ||
|
|
||
| if (dri_ret == 0) { | ||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] DRI log upload succeeded, removing DRI directory\n", | ||
| __FUNCTION__, __LINE__); | ||
| remove_directory(ctx->paths.dri_log_path); | ||
| } else { | ||
| RDK_LOG(RDK_LOG_WARN, LOG_UPLOADSTB, | ||
| "[%s:%d] DRI log upload failed\n", __FUNCTION__, __LINE__); | ||
| } | ||
|
|
||
| // Clean up DRI archive | ||
| remove_file(dri_archive); | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // Clear old packet captures | ||
| if (ctx->settings.include_pcap) { | ||
| RDK_LOG(RDK_LOG_DEBUG, LOG_UPLOADSTB, | ||
| "[%s:%d] Clearing old packet captures\n", __FUNCTION__, __LINE__); | ||
| clear_old_packet_captures(ctx->paths.log_path); | ||
| } | ||
|
|
||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] REBOOT/NON_DCM: Upload phase complete\n", __FUNCTION__, __LINE__); | ||
|
|
||
| return ret; | ||
| } | ||
|
|
||
| /** | ||
| * @brief Cleanup phase for REBOOT/NON_DCM strategy | ||
| * | ||
| * Shell script equivalent (uploadLogOnReboot lines 893-906): | ||
| * - Always runs (regardless of upload success) | ||
| * - Delete tar file | ||
| * - Remove timestamps from filenames (restore original names) | ||
| * - Create permanent backup directory | ||
| * - Move all files to permanent backup | ||
| * - Clean PREV_LOG_PATH | ||
| */ | ||
| static int reboot_cleanup(RuntimeContext* ctx, SessionState* session, bool upload_success) | ||
| { | ||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] REBOOT/NON_DCM: Starting cleanup phase (upload_success=%d)\n", | ||
| __FUNCTION__, __LINE__, upload_success); | ||
|
|
||
| sleep(5); | ||
|
|
||
| // Delete tar file | ||
| char tar_path[MAX_PATH_LENGTH]; | ||
| int written = snprintf(tar_path, sizeof(tar_path), "%s/%s", | ||
| ctx->paths.prev_log_path, session->archive_file); | ||
|
|
||
| if (written >= (int)sizeof(tar_path)) { | ||
| RDK_LOG(RDK_LOG_ERROR, LOG_UPLOADSTB, | ||
| "[%s:%d] Tar path too long\n", __FUNCTION__, __LINE__); | ||
| return -1; | ||
| } | ||
|
|
||
| if (file_exists(tar_path)) { | ||
| RDK_LOG(RDK_LOG_DEBUG, LOG_UPLOADSTB, | ||
| "[%s:%d] Removing tar file: %s\n", | ||
| __FUNCTION__, __LINE__, tar_path); | ||
| remove_file(tar_path); | ||
| } | ||
|
|
||
| // Remove timestamps from filenames (restore original names) | ||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] Removing timestamps from filenames\n", __FUNCTION__, __LINE__); | ||
|
|
||
| int ret = remove_timestamp_from_files(ctx->paths.prev_log_path); | ||
| if (ret != 0) { | ||
| RDK_LOG(RDK_LOG_WARN, LOG_UPLOADSTB, | ||
| "[%s:%d] Failed to remove timestamps from some files\n", | ||
| __FUNCTION__, __LINE__); | ||
| // Continue anyway | ||
| } | ||
|
|
||
| // Get permanent backup path (stored in setup phase) | ||
| const char* perm_log_path = perm_log_path_storage; | ||
|
|
||
| // Create permanent backup directory | ||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] Creating permanent backup directory: %s\n", | ||
| __FUNCTION__, __LINE__, perm_log_path); | ||
|
|
||
| if (!create_directory(perm_log_path)) { | ||
| RDK_LOG(RDK_LOG_ERROR, LOG_UPLOADSTB, | ||
| "[%s:%d] Failed to create permanent backup directory\n", | ||
| __FUNCTION__, __LINE__); | ||
| return -1; | ||
| } | ||
|
|
||
| // Move all files from PREV_LOG_PATH to permanent backup | ||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] Moving files to permanent backup\n", __FUNCTION__, __LINE__); | ||
|
|
||
| ret = move_directory_contents(ctx->paths.prev_log_path, perm_log_path); | ||
| if (ret != 0) { | ||
| RDK_LOG(RDK_LOG_WARN, LOG_UPLOADSTB, | ||
| "[%s:%d] Failed to move some files to permanent backup\n", | ||
| __FUNCTION__, __LINE__); | ||
| } | ||
|
|
||
| // Clean PREV_LOG_PATH | ||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] Cleaning PREV_LOG_PATH\n", __FUNCTION__, __LINE__); | ||
|
|
||
| clean_directory(ctx->paths.prev_log_path); | ||
|
|
||
| // Recreate PREV_LOG_BACKUP_PATH for next boot cycle | ||
| // Script lines 900-902: rm -rf + mkdir -p PREV_LOG_BACKUP_PATH | ||
| // PREV_LOG_BACKUP_PATH = $LOG_PATH/PreviousLogs_backup/ | ||
| char prev_log_backup_path[MAX_PATH_LENGTH]; | ||
| written = snprintf(prev_log_backup_path, sizeof(prev_log_backup_path), "%s/PreviousLogs_backup", | ||
| ctx->paths.log_path); | ||
|
|
||
| if (written >= (int)sizeof(prev_log_backup_path)) { | ||
| RDK_LOG(RDK_LOG_ERROR, LOG_UPLOADSTB, | ||
| "[%s:%d] PREV_LOG_BACKUP_PATH too long\n", __FUNCTION__, __LINE__); | ||
| } else { | ||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] Recreating PREV_LOG_BACKUP_PATH for next boot: %s\n", | ||
| __FUNCTION__, __LINE__, prev_log_backup_path); | ||
|
|
||
| if (dir_exists(prev_log_backup_path)) { | ||
| remove_directory(prev_log_backup_path); | ||
| } | ||
|
|
||
| if (!create_directory(prev_log_backup_path)) { | ||
| RDK_LOG(RDK_LOG_WARN, LOG_UPLOADSTB, | ||
| "[%s:%d] Failed to create PREV_LOG_BACKUP_PATH\n", __FUNCTION__, __LINE__); | ||
| } | ||
| } | ||
|
|
||
| // If DCM mode with upload_on_reboot=false, add permanent path to DCM batch list | ||
| // Script line 1019: echo $PERM_LOG_PATH >> $DCM_UPLOAD_LIST | ||
| if (ctx->flags.dcm_flag == 1 && ctx->flags.upload_on_reboot == 0) { | ||
| char dcm_upload_list[MAX_PATH_LENGTH]; | ||
| int written = snprintf(dcm_upload_list, sizeof(dcm_upload_list), "%s/dcm_upload", ctx->paths.log_path); | ||
|
|
||
| if (written >= (int)sizeof(dcm_upload_list)) { | ||
| RDK_LOG(RDK_LOG_ERROR, LOG_UPLOADSTB, | ||
| "[%s:%d] DCM upload list path too long\n", __FUNCTION__, __LINE__); | ||
| } else { | ||
| FILE* fp = fopen(dcm_upload_list, "a"); | ||
| if (fp) { | ||
| fprintf(fp, "%s\n", perm_log_path); | ||
| fclose(fp); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] REBOOT/NON_DCM: Cleanup phase complete. Logs backed up to: %s\n", | ||
| __FUNCTION__, __LINE__, perm_log_path); | ||
|
|
||
| return 0; | ||
| } |
Copilot
AI
Jan 7, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The strategy_reboot.c file still uses the old nested structure ctx->paths.* in multiple places (e.g., lines 88-92, 135-147, 172-212, 239-250, etc.) instead of the flattened structure used elsewhere in the codebase. This creates an inconsistency with the refactoring done in other files where ctx.paths.prev_log_path was changed to ctx.prev_log_path.
| if (ctx->include_pcap) { | ||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] Collecting PCAP file to PREV_LOG_PATH\n", __FUNCTION__, __LINE__); | ||
| int count = collect_pcap_logs(ctx, ctx->prev_log_path); | ||
| if (count > 0) { | ||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] Collected %d PCAP file\n", __FUNCTION__, __LINE__, count); | ||
| } | ||
| } | ||
|
|
||
| // Create archive from PREV_LOG_PATH (files already have timestamps) | ||
| int ret = create_archive(ctx, session, ctx->prev_log_path); | ||
| if (ret != 0) { | ||
| RDK_LOG(RDK_LOG_ERROR, LOG_UPLOADSTB, | ||
| "[%s:%d] Failed to create archive\n", __FUNCTION__, __LINE__); | ||
| return -1; | ||
| } | ||
| #ifndef L2_TEST_ENABLED | ||
| sleep(60); | ||
| #endif | ||
|
|
||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] REBOOT/NON_DCM: Archive phase complete\n", __FUNCTION__, __LINE__); | ||
|
|
||
| return 0; | ||
| } | ||
|
|
||
| /** | ||
| * @brief Upload phase for REBOOT/NON_DCM strategy | ||
| * | ||
| * Shell script equivalent (uploadLogOnReboot lines 853-890): | ||
| * - Check reboot reason and RFC settings | ||
| * - Upload main logs if allowed | ||
| * - Upload DRI logs if directory exists | ||
| * - Clear old packet captures | ||
| */ | ||
| static int reboot_upload(RuntimeContext* ctx, SessionState* session) | ||
| { | ||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] REBOOT/NON_DCM: Starting upload phase\n", __FUNCTION__, __LINE__); | ||
|
|
||
| // Check reboot reason and RFC settings (matches script logic) | ||
| // Script: if [ "$uploadLog" == "true" ] || [ -z "$reboot_reason" -a "$DISABLE_UPLOAD_LOGS_UNSHEDULED_REBOOT" == "false" ] | ||
| // Note: When DCM_FLAG=0 (Non-DCM), script ALWAYS passes "true" regardless of UploadOnReboot value | ||
| // When DCM_FLAG=1 (DCM mode), upload_on_reboot determines the behavior | ||
| bool should_upload = false; | ||
| const char* reboot_info_path = "/opt/secure/reboot/previousreboot.info"; | ||
|
|
||
| // Non-DCM mode (DCM_FLAG=0): Always upload (script line 999: uploadLogOnReboot true) | ||
| if (ctx->dcm_flag == 0) { | ||
| should_upload = true; | ||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] Non-DCM mode (dcm_flag=0), will always upload logs\n", | ||
| __FUNCTION__, __LINE__); | ||
| } | ||
| // DCM mode (DCM_FLAG=1): Check upload_on_reboot flag | ||
| else if (ctx->upload_on_reboot) { | ||
| should_upload = true; | ||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] DCM mode: Upload enabled from settings (upload_on_reboot=true)\n", | ||
| __FUNCTION__, __LINE__); | ||
| } else { | ||
| // Check reboot reason file for scheduled reboot (grep -i "Scheduled Reboot\|MAINTENANCE_REBOOT") | ||
| bool is_scheduled_reboot = false; | ||
| FILE* reboot_file = fopen(reboot_info_path, "r"); | ||
| if (reboot_file) { | ||
| char line[512]; | ||
| while (fgets(line, sizeof(line), reboot_file)) { | ||
| // Look for "Scheduled Reboot" or "MAINTENANCE_REBOOT" (case insensitive) | ||
| if (strcasestr(line, "Scheduled Reboot") || strcasestr(line, "MAINTENANCE_REBOOT")) { | ||
| is_scheduled_reboot = true; | ||
| break; | ||
| } | ||
| } | ||
| fclose(reboot_file); | ||
| } | ||
|
|
||
| // Get RFC setting for unscheduled reboot upload via RBUS | ||
| bool disable_unscheduled_upload = false; | ||
| if (!rbus_get_bool_param("Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.UploadLogsOnUnscheduledReboot.Disable", | ||
| &disable_unscheduled_upload)) { | ||
| RDK_LOG(RDK_LOG_WARN, LOG_UPLOADSTB, | ||
| "[%s:%d] Failed to get UploadLogsOnUnscheduledReboot.Disable RFC, assuming false\n", | ||
| __FUNCTION__, __LINE__); | ||
| disable_unscheduled_upload = false; | ||
| } | ||
|
|
||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] Reboot reason check - Scheduled: %d, Disable unscheduled RFC: %d\n", | ||
| __FUNCTION__, __LINE__, is_scheduled_reboot, disable_unscheduled_upload); | ||
|
|
||
| // Upload if: reboot reason is empty (unscheduled) AND RFC doesn't disable it | ||
| // Script logic: [ -z "$reboot_reason" -a "$DISABLE_UPLOAD_LOGS_UNSHEDULED_REBOOT" == "false" ] | ||
| if (!is_scheduled_reboot && !disable_unscheduled_upload) { | ||
| should_upload = true; | ||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] Unscheduled reboot and RFC allows upload\n", __FUNCTION__, __LINE__); | ||
| } | ||
| } | ||
|
|
||
| if (!should_upload) { | ||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] Upload not allowed based on reboot reason and RFC settings\n", | ||
| __FUNCTION__, __LINE__); | ||
| return 0; | ||
| } | ||
|
|
||
| // Construct full archive path using session archive filename | ||
| char archive_path[MAX_PATH_LENGTH]; | ||
| int written = snprintf(archive_path, sizeof(archive_path), "%s/%s", | ||
| ctx->prev_log_path, session->archive_file); | ||
|
|
||
| if (written >= (int)sizeof(archive_path)) { | ||
| RDK_LOG(RDK_LOG_ERROR, LOG_UPLOADSTB, | ||
| "[%s:%d] Archive path too long\n", __FUNCTION__, __LINE__); | ||
| return -1; | ||
| } | ||
|
|
||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] Uploading main logs: %s\n", | ||
| __FUNCTION__, __LINE__, archive_path); | ||
|
|
||
| // Upload main logs (session->success is set by execute_upload_cycle) | ||
| int ret = upload_archive(ctx, session, archive_path); | ||
|
|
||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] Main log upload complete (result=%d)\n", | ||
| __FUNCTION__, __LINE__, ret); | ||
|
|
||
| // Upload DRI logs if directory exists (using separate session to avoid state corruption) | ||
| if (ctx->include_dri && dir_exists(ctx->dri_log_path)) { | ||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] DRI log directory exists, uploading DRI logs\n", | ||
| __FUNCTION__, __LINE__); | ||
|
|
||
| // Generate DRI archive filename: {MAC}_DRI_Logs_{timestamp}.tgz | ||
| char dri_filename[MAX_FILENAME_LENGTH]; | ||
| if (!generate_archive_name(dri_filename, sizeof(dri_filename), | ||
| ctx->mac_address, "DRI_Logs")) { | ||
| RDK_LOG(RDK_LOG_ERROR, LOG_UPLOADSTB, | ||
| "[%s:%d] Failed to generate DRI archive filename\n", | ||
| __FUNCTION__, __LINE__); | ||
| } else { | ||
| char dri_archive[MAX_PATH_LENGTH]; | ||
| int written = snprintf(dri_archive, sizeof(dri_archive), "%s/%s", | ||
| ctx->prev_log_path, dri_filename); | ||
|
|
||
| if (written >= (int)sizeof(dri_archive)) { | ||
| RDK_LOG(RDK_LOG_ERROR, LOG_UPLOADSTB, | ||
| "[%s:%d] DRI archive path too long\n", __FUNCTION__, __LINE__); | ||
| } else { | ||
| // Create DRI archive | ||
| int dri_ret = create_dri_archive(ctx, dri_archive); | ||
|
|
||
| if (dri_ret == 0) { | ||
| sleep(60); | ||
|
|
||
| // Upload DRI logs using separate session state | ||
| SessionState dri_session = *session; // Copy current session config | ||
| dri_session.direct_attempts = 0; // Reset attempt counters | ||
| dri_session.codebig_attempts = 0; | ||
| dri_ret = upload_archive(ctx, &dri_session, dri_archive); | ||
|
|
||
| // Send telemetry for DRI upload (matches script lines 883, 886) | ||
| // Script sends SYST_INFO_PDRILogUpload for both success and failure | ||
| t2_count_notify("SYST_INFO_PDRILogUpload"); | ||
|
|
||
| if (dri_ret == 0) { | ||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] DRI log upload succeeded, removing DRI directory\n", | ||
| __FUNCTION__, __LINE__); | ||
| remove_directory(ctx->dri_log_path); | ||
| } else { | ||
| RDK_LOG(RDK_LOG_WARN, LOG_UPLOADSTB, | ||
| "[%s:%d] DRI log upload failed\n", __FUNCTION__, __LINE__); | ||
| } | ||
|
|
||
| // Clean up DRI archive | ||
| remove_file(dri_archive); | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // Clear old packet captures | ||
| if (ctx->include_pcap) { | ||
| RDK_LOG(RDK_LOG_DEBUG, LOG_UPLOADSTB, | ||
| "[%s:%d] Clearing old packet captures\n", __FUNCTION__, __LINE__); | ||
| clear_old_packet_captures(ctx->log_path); | ||
| } | ||
|
|
||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] REBOOT/NON_DCM: Upload phase complete\n", __FUNCTION__, __LINE__); | ||
|
|
||
| return ret; | ||
| } | ||
|
|
||
| /** | ||
| * @brief Cleanup phase for REBOOT/NON_DCM strategy | ||
| * | ||
| * Shell script equivalent (uploadLogOnReboot lines 893-906): | ||
| * - Always runs (regardless of upload success) | ||
| * - Delete tar file | ||
| * - Remove timestamps from filenames (restore original names) | ||
| * - Create permanent backup directory | ||
| * - Move all files to permanent backup | ||
| * - Clean PREV_LOG_PATH | ||
| */ | ||
| static int reboot_cleanup(RuntimeContext* ctx, SessionState* session, bool upload_success) | ||
| { | ||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] REBOOT/NON_DCM: Starting cleanup phase (upload_success=%d)\n", | ||
| __FUNCTION__, __LINE__, upload_success); | ||
| #ifndef L2_TEST_ENABLED | ||
| sleep(5); | ||
| #endif | ||
| // Delete tar file | ||
| char tar_path[MAX_PATH_LENGTH]; | ||
| int written = snprintf(tar_path, sizeof(tar_path), "%s/%s", | ||
| ctx->prev_log_path, session->archive_file); | ||
|
|
||
| if (written >= (int)sizeof(tar_path)) { | ||
| RDK_LOG(RDK_LOG_ERROR, LOG_UPLOADSTB, | ||
| "[%s:%d] Tar path too long\n", __FUNCTION__, __LINE__); | ||
| return -1; | ||
| } | ||
|
|
||
| if (file_exists(tar_path)) { | ||
| RDK_LOG(RDK_LOG_DEBUG, LOG_UPLOADSTB, | ||
| "[%s:%d] Removing tar file: %s\n", | ||
| __FUNCTION__, __LINE__, tar_path); | ||
| remove_file(tar_path); | ||
| } | ||
|
|
||
| // Remove timestamps from filenames (restore original names) | ||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] Removing timestamps from filenames\n", __FUNCTION__, __LINE__); | ||
|
|
||
| int ret = remove_timestamp_from_files(ctx->prev_log_path); | ||
| if (ret != 0) { | ||
| RDK_LOG(RDK_LOG_WARN, LOG_UPLOADSTB, | ||
| "[%s:%d] Failed to remove timestamps from some files\n", | ||
| __FUNCTION__, __LINE__); | ||
| // Continue anyway | ||
| } | ||
|
|
||
| // Get permanent backup path (stored in setup phase) | ||
| const char* perm_log_path = perm_log_path_storage; | ||
|
|
||
| // Create permanent backup directory | ||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] Creating permanent backup directory: %s\n", | ||
| __FUNCTION__, __LINE__, perm_log_path); | ||
|
|
||
| if (!create_directory(perm_log_path)) { | ||
| RDK_LOG(RDK_LOG_ERROR, LOG_UPLOADSTB, | ||
| "[%s:%d] Failed to create permanent backup directory\n", | ||
| __FUNCTION__, __LINE__); | ||
| return -1; | ||
| } | ||
|
|
||
| // Move all files from PREV_LOG_PATH to permanent backup | ||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] Moving files to permanent backup\n", __FUNCTION__, __LINE__); | ||
|
|
||
| ret = move_directory_contents(ctx->prev_log_path, perm_log_path); | ||
| if (ret != 0) { | ||
| RDK_LOG(RDK_LOG_WARN, LOG_UPLOADSTB, | ||
| "[%s:%d] Failed to move some files to permanent backup\n", | ||
| __FUNCTION__, __LINE__); | ||
| } | ||
|
|
||
| // Clean PREV_LOG_PATH | ||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] Cleaning PREV_LOG_PATH\n", __FUNCTION__, __LINE__); | ||
|
|
||
| clean_directory(ctx->prev_log_path); | ||
|
|
||
| // Recreate PREV_LOG_BACKUP_PATH for next boot cycle | ||
| // Script lines 900-902: rm -rf + mkdir -p PREV_LOG_BACKUP_PATH | ||
| // PREV_LOG_BACKUP_PATH = $LOG_PATH/PreviousLogs_backup/ | ||
| char prev_log_backup_path[MAX_PATH_LENGTH]; | ||
| written = snprintf(prev_log_backup_path, sizeof(prev_log_backup_path), "%s/PreviousLogs_backup", | ||
| ctx->log_path); | ||
|
|
||
| if (written >= (int)sizeof(prev_log_backup_path)) { | ||
| RDK_LOG(RDK_LOG_ERROR, LOG_UPLOADSTB, | ||
| "[%s:%d] PREV_LOG_BACKUP_PATH too long\n", __FUNCTION__, __LINE__); | ||
| } else { | ||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] Recreating PREV_LOG_BACKUP_PATH for next boot: %s\n", | ||
| __FUNCTION__, __LINE__, prev_log_backup_path); | ||
|
|
||
| if (dir_exists(prev_log_backup_path)) { | ||
| remove_directory(prev_log_backup_path); | ||
| } | ||
|
|
||
| if (!create_directory(prev_log_backup_path)) { | ||
| RDK_LOG(RDK_LOG_WARN, LOG_UPLOADSTB, | ||
| "[%s:%d] Failed to create PREV_LOG_BACKUP_PATH\n", __FUNCTION__, __LINE__); | ||
| } | ||
| } | ||
|
|
||
| // If DCM mode with upload_on_reboot=false, add permanent path to DCM batch list | ||
| // Script line 1019: echo $PERM_LOG_PATH >> $DCM_UPLOAD_LIST | ||
| if (ctx->dcm_flag == 1 && ctx->upload_on_reboot == 0) { | ||
| char dcm_upload_list[MAX_PATH_LENGTH]; | ||
| int written = snprintf(dcm_upload_list, sizeof(dcm_upload_list), "%s/dcm_upload", ctx->log_path); | ||
|
|
||
| if (written >= (int)sizeof(dcm_upload_list)) { | ||
| RDK_LOG(RDK_LOG_ERROR, LOG_UPLOADSTB, | ||
| "[%s:%d] DCM upload list path too long\n", __FUNCTION__, __LINE__); | ||
| } else { | ||
| FILE* fp = fopen(dcm_upload_list, "a"); | ||
| if (fp) { | ||
| fprintf(fp, "%s\n", perm_log_path); | ||
| fclose(fp); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| RDK_LOG(RDK_LOG_INFO, LOG_UPLOADSTB, | ||
| "[%s:%d] REBOOT/NON_DCM: Cleanup phase complete. Logs backed up to: %s\n", | ||
| __FUNCTION__, __LINE__, perm_log_path); | ||
|
|
||
| return 0; | ||
| } |
Copilot
AI
Jan 7, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The strategies.c file (reboot strategy section) uses the flattened structure for most fields but still uses nested structure for some fields like ctx->flags.dcm_flag and ctx->flags.upload_on_reboot (lines 835, 842, 1091), and ctx->settings.include_pcap and ctx->settings.include_dri (lines 786, 916) and ctx->device.mac_address (line 924). These should be changed to ctx->dcm_flag, ctx->upload_on_reboot, ctx->include_pcap, ctx->include_dri, and ctx->mac_address respectively to be consistent with the refactoring.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 43 out of 44 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
No description provided.