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


Reply via email to