From mboxrd@z Thu Jan 1 00:00:00 1970 From: Vladimir Riabchun Date: Wed, 19 Aug 2026 09:07:45 +0000 Subject: [Devel] [PATCH VZ10 v6 8/9] selftests/ve: Add more helpers In-Reply-To: References: Message-ID: <543732c5c384fa1a5817c4bff4ed0b80eba22082.1787129389.git.vladimir.riabchun@virtuozzo.com> List-Id: Some more read/write helpers may be useful. Also, add a helper to execute functions in child process with switched namespaces and cgroup. https://virtuozzo.atlassian.net/browse/VSTOR-135520 Feature: per-ve failcounters Signed-off-by: Vladimir Riabchun --- tools/testing/selftests/ve/ve_selftest.h | 81 ++++++++++++++++++++++-- 1 file changed, 75 insertions(+), 6 deletions(-) diff --git a/tools/testing/selftests/ve/ve_selftest.h b/tools/testing/selftests/ve/ve_selftest.h index 69c0a52dd7ef..48bb7d1871bd 100644 --- a/tools/testing/selftests/ve/ve_selftest.h +++ b/tools/testing/selftests/ve/ve_selftest.h @@ -43,6 +43,14 @@ static inline int write_file_at(int dirfd, const char *path, const char *val) return (ret == (int)len) ? 0 : -1; } +static inline int write_u64_at(int dirfd, const char *path, unsigned long long val) +{ + char s[20]; + + snprintf(s, sizeof(s), "%llu", val); + return write_file_at(dirfd, path, s); +} + static inline int read_file_at(int dirfd, const char *path, char *buf, size_t buflen) { @@ -73,19 +81,31 @@ static inline int read_u64_at(int dirfd, const char *path, unsigned long long *out) { char buf[32] = {0}, *end; - int fd, ret; + int ret; - fd = openat(dirfd, path, O_RDONLY); - if (fd < 0) + ret = read_file_at(dirfd, path, buf, sizeof(buf)); + if (ret <= 0) return -1; - ret = read(fd, buf, sizeof(buf) - 1); - close(fd); + errno = 0; + *out = strtoull(buf, &end, 10); + if (errno || end == buf) + return -1; + return 0; +} + +static inline int read_s32_at(int dirfd, const char *path, + int *out) +{ + char buf[32] = {0}, *end; + int ret; + + ret = read_file_at(dirfd, path, buf, sizeof(buf)); if (ret <= 0) return -1; errno = 0; - *out = strtoull(buf, &end, 10); + *out = strtol(buf, &end, 10); if (errno || end == buf) return -1; return 0; @@ -134,6 +154,55 @@ static inline int enter_cgroup(int cgv2_fd, int ctid) return ret; } +/* + * Run function in VE cgroup and new namespaces. + * + * Namespaces are provided via unshare_flags. + * CLONE_NEWVE flag is set by this function. + * Return values: + * - 0 if function returns zero + * - -1 if function returns negative value + * - 1 if setup fails or function returns positive value + */ +static inline int run_in_ve(int cgv2_fd, int ctid, int unshare_flags, + int (*fn)(void *), void *arg) +{ + int status; + pid_t pid; + + unshare_flags |= CLONE_NEWVE; + pid = fork(); + if (pid < 0) { + fprintf(stderr, "%s: fork failed\n", __func__); + return 1; + } + if (pid == 0) { + int ret; + + if (enter_cgroup(cgv2_fd, ctid) < 0) { + fprintf(stderr, "%s: enter_cgroup failed\n", __func__); + _exit(255); + } + if (unshare(unshare_flags) < 0) { + fprintf(stderr, "%s: unshare(%d) failed\n", + __func__, unshare_flags); + _exit(255); + } + ret = fn(arg); + if (ret < 0) + ret = 1; + else if (ret > 0) + ret = 255; + _exit(ret); + } + if (waitpid(pid, &status, 0) < 0 || !WIFEXITED(status) || WEXITSTATUS(status) == 255) + return 1; + if (WEXITSTATUS(status)) + return -1; + return 0; + +} + /* * Create a fresh VE cgroup at the first free id at or after @from and unhide * its ve.* control files. Return the new id, or -1. -- 2.47.1