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