Provide luo_session_freeze() in the liveupdate test library and add unit tests in liveupdate.c covering the LIVEUPDATE_SESSION_FREEZE ioctl. The tests verify that an outgoing session with preserved files can be frozen early, that freezing an already frozen session returns -EBUSY, and that attempting to preserve an additional file descriptor into a frozen session fails with -EBUSY.
Also freeze the test session early in luo_kexec_simple.c to exercise LIVEUPDATE_SESSION_FREEZE across a kexec reboot. Signed-off-by: Pasha Tatashin <[email protected]> --- .../liveupdate/lib/include/libliveupdate.h | 1 + .../selftests/liveupdate/lib/lu_utils.c | 10 +++++ .../testing/selftests/liveupdate/liveupdate.c | 40 +++++++++++++++++++ .../selftests/liveupdate/luo_kexec_simple.c | 5 +++ 4 files changed, 56 insertions(+) diff --git a/tools/testing/selftests/liveupdate/lib/include/libliveupdate.h b/tools/testing/selftests/liveupdate/lib/include/libliveupdate.h index fa07fed083646..15a7db3a6b3e8 100644 --- a/tools/testing/selftests/liveupdate/lib/include/libliveupdate.h +++ b/tools/testing/selftests/liveupdate/lib/include/libliveupdate.h @@ -26,6 +26,7 @@ int luo_create_session(int luo_fd, const char *name); int luo_retrieve_session(int luo_fd, const char *name); int luo_session_finish(int session_fd); int luo_get_session_name(int session_fd, char *name, size_t name_len); +int luo_session_freeze(int session_fd); int luo_ensure_nofile_limit(long min_limit); int luo_session_preserve_fd(int session_fd, int fd, __u64 token); diff --git a/tools/testing/selftests/liveupdate/lib/lu_utils.c b/tools/testing/selftests/liveupdate/lib/lu_utils.c index 74d41115c2815..6315746ff08f8 100644 --- a/tools/testing/selftests/liveupdate/lib/lu_utils.c +++ b/tools/testing/selftests/liveupdate/lib/lu_utils.c @@ -198,6 +198,16 @@ int luo_session_finish(int session_fd) return 0; } +int luo_session_freeze(int session_fd) +{ + struct liveupdate_session_freeze arg = { .size = sizeof(arg) }; + + if (ioctl(session_fd, LIVEUPDATE_SESSION_FREEZE, &arg) < 0) + return -errno; + + return 0; +} + void create_state_file(int luo_fd, const char *session_name, int token, int next_stage) { diff --git a/tools/testing/selftests/liveupdate/liveupdate.c b/tools/testing/selftests/liveupdate/liveupdate.c index 2dedd5fc2534f..9de068f31c3ec 100644 --- a/tools/testing/selftests/liveupdate/liveupdate.c +++ b/tools/testing/selftests/liveupdate/liveupdate.c @@ -530,4 +530,44 @@ TEST_F(liveupdate_device, preserve_many_files) ASSERT_EQ(close(session_fd), 0); } +/* + * Test Case: Session Freeze + * + * Verifies that an outgoing session can be frozen early via + * LIVEUPDATE_SESSION_FREEZE, that subsequent freeze attempts return -EBUSY, + * and that attempting to preserve an additional file descriptor into a frozen + * session fails with -EBUSY. + */ +TEST_F(liveupdate_device, session_freeze) +{ + int session_fd, mem_fd1, mem_fd2; + + self->fd1 = open(LIVEUPDATE_DEV, O_RDWR); + if (self->fd1 < 0 && errno == ENOENT) + SKIP(return, "%s does not exist", LIVEUPDATE_DEV); + ASSERT_GE(self->fd1, 0); + + session_fd = luo_create_session(self->fd1, "session-freeze-test"); + ASSERT_GE(session_fd, 0); + + mem_fd1 = memfd_create("freeze-memfd-1", 0); + ASSERT_GE(mem_fd1, 0); + ASSERT_EQ(luo_session_preserve_fd(session_fd, mem_fd1, 0x1111), 0); + + /* Freeze the session early */ + ASSERT_EQ(luo_session_freeze(session_fd), 0); + + /* Subsequent freeze attempt on an already frozen session must fail with -EBUSY */ + EXPECT_EQ(luo_session_freeze(session_fd), -EBUSY); + + /* Preserving a file after freeze must fail with -EBUSY */ + mem_fd2 = memfd_create("freeze-memfd-2", 0); + ASSERT_GE(mem_fd2, 0); + EXPECT_EQ(luo_session_preserve_fd(session_fd, mem_fd2, 0x2222), -EBUSY); + + ASSERT_EQ(close(session_fd), 0); + ASSERT_EQ(close(mem_fd1), 0); + ASSERT_EQ(close(mem_fd2), 0); +} + TEST_HARNESS_MAIN diff --git a/tools/testing/selftests/liveupdate/luo_kexec_simple.c b/tools/testing/selftests/liveupdate/luo_kexec_simple.c index 786ac93b9ae38..ab108c7f1d855 100644 --- a/tools/testing/selftests/liveupdate/luo_kexec_simple.c +++ b/tools/testing/selftests/liveupdate/luo_kexec_simple.c @@ -40,6 +40,11 @@ static void run_stage_1(int luo_fd) TEST_MEMFD_TOKEN); } + ksft_print_msg("[STAGE 1] Freezing session '%s' early...\n", + TEST_SESSION_NAME); + if (luo_session_freeze(session_fd) < 0) + fail_exit("luo_session_freeze for '%s'", TEST_SESSION_NAME); + close(luo_fd); daemonize_and_wait(); } -- 2.56.0.385.gd3acb90ef8-goog

