luo_kexec_simple.c 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2025, Google LLC.
  4. * Pasha Tatashin <pasha.tatashin@soleen.com>
  5. *
  6. * A simple selftest to validate the end-to-end lifecycle of a LUO session
  7. * across a single kexec reboot.
  8. */
  9. #include "luo_test_utils.h"
  10. #define TEST_SESSION_NAME "test-session"
  11. #define TEST_MEMFD_TOKEN 0x1A
  12. #define TEST_MEMFD_DATA "hello kexec world"
  13. /* Constants for the state-tracking mechanism, specific to this test file. */
  14. #define STATE_SESSION_NAME "kexec_simple_state"
  15. #define STATE_MEMFD_TOKEN 999
  16. /* Stage 1: Executed before the kexec reboot. */
  17. static void run_stage_1(int luo_fd)
  18. {
  19. int session_fd;
  20. ksft_print_msg("[STAGE 1] Starting pre-kexec setup...\n");
  21. ksft_print_msg("[STAGE 1] Creating state file for next stage (2)...\n");
  22. create_state_file(luo_fd, STATE_SESSION_NAME, STATE_MEMFD_TOKEN, 2);
  23. ksft_print_msg("[STAGE 1] Creating session '%s' and preserving memfd...\n",
  24. TEST_SESSION_NAME);
  25. session_fd = luo_create_session(luo_fd, TEST_SESSION_NAME);
  26. if (session_fd < 0)
  27. fail_exit("luo_create_session for '%s'", TEST_SESSION_NAME);
  28. if (create_and_preserve_memfd(session_fd, TEST_MEMFD_TOKEN,
  29. TEST_MEMFD_DATA) < 0) {
  30. fail_exit("create_and_preserve_memfd for token %#x",
  31. TEST_MEMFD_TOKEN);
  32. }
  33. close(luo_fd);
  34. daemonize_and_wait();
  35. }
  36. /* Stage 2: Executed after the kexec reboot. */
  37. static void run_stage_2(int luo_fd, int state_session_fd)
  38. {
  39. int session_fd, mfd, stage;
  40. ksft_print_msg("[STAGE 2] Starting post-kexec verification...\n");
  41. restore_and_read_stage(state_session_fd, STATE_MEMFD_TOKEN, &stage);
  42. if (stage != 2)
  43. fail_exit("Expected stage 2, but state file contains %d", stage);
  44. ksft_print_msg("[STAGE 2] Retrieving session '%s'...\n", TEST_SESSION_NAME);
  45. session_fd = luo_retrieve_session(luo_fd, TEST_SESSION_NAME);
  46. if (session_fd < 0)
  47. fail_exit("luo_retrieve_session for '%s'", TEST_SESSION_NAME);
  48. ksft_print_msg("[STAGE 2] Restoring and verifying memfd (token %#x)...\n",
  49. TEST_MEMFD_TOKEN);
  50. mfd = restore_and_verify_memfd(session_fd, TEST_MEMFD_TOKEN,
  51. TEST_MEMFD_DATA);
  52. if (mfd < 0)
  53. fail_exit("restore_and_verify_memfd for token %#x", TEST_MEMFD_TOKEN);
  54. close(mfd);
  55. ksft_print_msg("[STAGE 2] Test data verified successfully.\n");
  56. ksft_print_msg("[STAGE 2] Finalizing test session...\n");
  57. if (luo_session_finish(session_fd) < 0)
  58. fail_exit("luo_session_finish for test session");
  59. close(session_fd);
  60. ksft_print_msg("[STAGE 2] Finalizing state session...\n");
  61. if (luo_session_finish(state_session_fd) < 0)
  62. fail_exit("luo_session_finish for state session");
  63. close(state_session_fd);
  64. ksft_print_msg("\n--- SIMPLE KEXEC TEST PASSED ---\n");
  65. }
  66. int main(int argc, char *argv[])
  67. {
  68. return luo_test(argc, argv, STATE_SESSION_NAME,
  69. run_stage_1, run_stage_2);
  70. }