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