selftests/liveupdate: Test session and file limit removal

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>
This commit is contained in:
Pasha Tatashin
2026-06-03 15:44:00 +00:00
committed by Mike Rapoport (Microsoft)
parent 1d1153097f
commit 5ba3f30643
3 changed files with 101 additions and 0 deletions

View 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

View 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) };

View 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);