]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
selftests/liveupdate: Test session and file limit removal
authorPasha Tatashin <pasha.tatashin@soleen.com>
Wed, 3 Jun 2026 15:44:00 +0000 (15:44 +0000)
committerMike Rapoport (Microsoft) <rppt@kernel.org>
Wed, 3 Jun 2026 18:15:46 +0000 (21:15 +0300)
With the removal of static limits on the number of sessions and files per
session, the orchestrator now uses dynamic allocation.

Add new test cases to verify that the system can handle a large number of
sessions and files. These tests ensure that the dynamic block allocation
and reuse logic for session metadata and outgoing files work correctly
beyond the previous static limits.

Acked-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Reviewed-by: Pratyush Yadav (Google) <pratyush@kernel.org>
Signed-off-by: Pasha Tatashin <pasha.tatashin@soleen.com>
Link: https://patch.msgid.link/20260603154402.468928-12-pasha.tatashin@soleen.com
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
tools/testing/selftests/liveupdate/liveupdate.c
tools/testing/selftests/liveupdate/luo_test_utils.c
tools/testing/selftests/liveupdate/luo_test_utils.h

index c7d94b9181e120eae053077750c5fa4ef1d3017b..502fb3567e38d84652229edf79a74c8eb8c2081e 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <linux/liveupdate.h>
 
+#include "luo_test_utils.h"
 #include "../kselftest.h"
 #include "../kselftest_harness.h"
 
@@ -499,4 +500,78 @@ TEST_F(liveupdate_device, get_session_name_max_length)
        ASSERT_EQ(close(session_fd), 0);
 }
 
+/*
+ * Test Case: Manage Many Sessions
+ *
+ * Verifies that a large number of sessions can be created and then
+ * destroyed during normal system operation. This specifically tests the
+ * dynamic block allocation and reuse logic for session metadata management
+ * without preserving any files.
+ */
+TEST_F(liveupdate_device, preserve_many_sessions)
+{
+#define MANY_SESSIONS 2000
+       int session_fds[MANY_SESSIONS];
+       int ret, i;
+
+       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);
+
+       ret = luo_ensure_nofile_limit(MANY_SESSIONS);
+       if (ret == -EPERM)
+               SKIP(return, "Insufficient privileges to set RLIMIT_NOFILE");
+       ASSERT_EQ(ret, 0);
+
+       for (i = 0; i < MANY_SESSIONS; i++) {
+               char name[64];
+
+               snprintf(name, sizeof(name), "many-session-%d", i);
+               session_fds[i] = create_session(self->fd1, name);
+               ASSERT_GE(session_fds[i], 0);
+       }
+
+       for (i = 0; i < MANY_SESSIONS; i++)
+               ASSERT_EQ(close(session_fds[i]), 0);
+}
+
+/*
+ * Test Case: Preserve Many Files
+ *
+ * Verifies that a large number of files can be preserved in a single session
+ * and then destroyed during normal system operation. This tests the dynamic
+ * block allocation and management for outgoing files.
+ */
+TEST_F(liveupdate_device, preserve_many_files)
+{
+#define MANY_FILES 500
+       int mem_fds[MANY_FILES];
+       int session_fd, ret, i;
+
+       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 = create_session(self->fd1, "many-files-test");
+       ASSERT_GE(session_fd, 0);
+
+       ret = luo_ensure_nofile_limit(MANY_FILES + 10);
+       if (ret == -EPERM)
+               SKIP(return, "Insufficient privileges to set RLIMIT_NOFILE");
+       ASSERT_EQ(ret, 0);
+
+       for (i = 0; i < MANY_FILES; i++) {
+               mem_fds[i] = memfd_create("test-memfd", 0);
+               ASSERT_GE(mem_fds[i], 0);
+               ASSERT_EQ(preserve_fd(session_fd, mem_fds[i], i), 0);
+       }
+
+       for (i = 0; i < MANY_FILES; i++)
+               ASSERT_EQ(close(mem_fds[i]), 0);
+
+       ASSERT_EQ(close(session_fd), 0);
+}
+
 TEST_HARNESS_MAIN
index 3c8721c505df88a9371fa37cbab46d860f7396a9..333a3530051b4e4ac0de89b3a8c50145d8539364 100644 (file)
@@ -17,6 +17,7 @@
 #include <sys/syscall.h>
 #include <sys/mman.h>
 #include <sys/types.h>
+#include <sys/resource.h>
 #include <sys/stat.h>
 #include <errno.h>
 #include <stdarg.h>
@@ -28,6 +29,29 @@ int luo_open_device(void)
        return open(LUO_DEVICE, O_RDWR);
 }
 
+int luo_ensure_nofile_limit(long min_limit)
+{
+       struct rlimit hl;
+
+       /* Allow to extra files to be used by test itself */
+       min_limit += 32;
+
+       if (getrlimit(RLIMIT_NOFILE, &hl) < 0)
+               return -errno;
+
+       if (hl.rlim_cur >= min_limit)
+               return 0;
+
+       hl.rlim_cur = min_limit;
+       if (hl.rlim_cur > hl.rlim_max)
+               hl.rlim_max = hl.rlim_cur;
+
+       if (setrlimit(RLIMIT_NOFILE, &hl) < 0)
+               return -errno;
+
+       return 0;
+}
+
 int luo_create_session(int luo_fd, const char *name)
 {
        struct liveupdate_ioctl_create_session arg = { .size = sizeof(arg) };
index 90099bf49577ce482248951667fc15bfe7690fa5..6a0d85386613e1c4611679dbe83f3b27b9159ac7 100644 (file)
@@ -26,6 +26,8 @@ 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_ensure_nofile_limit(long min_limit);
+
 int create_and_preserve_memfd(int session_fd, int token, const char *data);
 int restore_and_verify_memfd(int session_fd, int token, const char *expected_data);