1 // SPDX-License-Identifier: GPL-2.0-only 2 3 /* 4 * Copyright (c) 2026, Google LLC. 5 * Pasha Tatashin <pasha.tatashin@soleen.com> 6 * 7 * Validate that LUO can handle a large number of files per session across 8 * a kexec reboot. 9 */ 10 11 #include <stdio.h> 12 #include <unistd.h> 13 #include "luo_test_utils.h" 14 15 #define NUM_FILES 500 16 #define STATE_SESSION_NAME "kexec_many_files_state" 17 #define STATE_MEMFD_TOKEN 9999 18 #define TEST_SESSION_NAME "many_files_session" 19 20 /* Stage 1: Executed before the kexec reboot. */ 21 static void run_stage_1(int luo_fd) 22 { 23 int session_fd, i; 24 25 ksft_print_msg("[STAGE 1] Creating state file for next stage (2)...\n"); 26 create_state_file(luo_fd, STATE_SESSION_NAME, STATE_MEMFD_TOKEN, 2); 27 28 ksft_print_msg("[STAGE 1] Creating test session '%s'...\n", TEST_SESSION_NAME); 29 session_fd = luo_create_session(luo_fd, TEST_SESSION_NAME); 30 if (session_fd < 0) 31 fail_exit("luo_create_session"); 32 33 ksft_print_msg("[STAGE 1] Preserving %d files...\n", NUM_FILES); 34 for (i = 0; i < NUM_FILES; i++) { 35 char data[64]; 36 37 snprintf(data, sizeof(data), "file-data-%d", i); 38 if (create_and_preserve_memfd(session_fd, i, data) < 0) 39 fail_exit("create_and_preserve_memfd for index %d", i); 40 } 41 42 ksft_print_msg("[STAGE 1] Successfully preserved %d files.\n", NUM_FILES); 43 44 close(luo_fd); 45 daemonize_and_wait(); 46 } 47 48 /* Stage 2: Executed after the kexec reboot. */ 49 static void run_stage_2(int luo_fd, int state_session_fd) 50 { 51 int session_fd; 52 int i, stage; 53 54 ksft_print_msg("[STAGE 2] Starting post-kexec verification...\n"); 55 56 restore_and_read_stage(state_session_fd, STATE_MEMFD_TOKEN, &stage); 57 if (stage != 2) { 58 fail_exit("Expected stage 2, but state file contains %d", 59 stage); 60 } 61 62 ksft_print_msg("[STAGE 2] Retrieving test session '%s'...\n", TEST_SESSION_NAME); 63 session_fd = luo_retrieve_session(luo_fd, TEST_SESSION_NAME); 64 if (session_fd < 0) 65 fail_exit("luo_retrieve_session"); 66 67 ksft_print_msg("[STAGE 2] Verifying %d files...\n", NUM_FILES); 68 for (i = 0; i < NUM_FILES; i++) { 69 char data[64]; 70 int fd; 71 72 snprintf(data, sizeof(data), "file-data-%d", i); 73 fd = restore_and_verify_memfd(session_fd, i, data); 74 if (fd < 0) 75 fail_exit("restore_and_verify_memfd for index %d", i); 76 close(fd); 77 } 78 79 ksft_print_msg("[STAGE 2] Finishing test session...\n"); 80 if (luo_session_finish(session_fd) < 0) 81 fail_exit("luo_session_finish for test session"); 82 close(session_fd); 83 84 ksft_print_msg("[STAGE 2] Finalizing state session...\n"); 85 if (luo_session_finish(state_session_fd) < 0) 86 fail_exit("luo_session_finish for state session"); 87 close(state_session_fd); 88 89 ksft_print_msg("\n--- MANY-FILES KEXEC TEST PASSED (%d files) ---\n", 90 NUM_FILES); 91 } 92 93 int main(int argc, char *argv[]) 94 { 95 return luo_test(argc, argv, STATE_SESSION_NAME, 96 run_stage_1, run_stage_2); 97 } 98