xref: /linux/tools/testing/selftests/liveupdate/luo_stress_files.c (revision 46429a15a6dfe522880d5085f1f6999357758872)
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