* [Devel] [PATCH VZ10 v4 0/3] Improvements for ve selftests
@ 2026-09-25 12:47 Konstantin Khorenko
2026-09-25 12:47 ` [Devel] [PATCH VZ10 v4 1/3] ve_namespace: Allow entering non-running VE namespace Konstantin Khorenko
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Konstantin Khorenko @ 2026-09-25 12:47 UTC (permalink / raw)
To: Vladimir Riabchun, Vasileios Almpanis; +Cc: devel
This change adds helpers for creating and preserving various
namespaces and running functions inside them.
This appeared useful while implementing ve mount accounting
selftests - it required keeping mount namespace alive and
doing different things at different moments of time.
To make setns work with CLONE_NEWVE without starting VE,
the first patch changes the -EINVAL return to a warning message.
https://virtuozzo.atlassian.net/browse/VSTOR-144504
Feature: ve selftests
Changes in v4:
- Moved the ve_namespace patch to the front, before the selftest
helpers that rely on it.
- ve_namespace: the warning follows the "CT: %s:" format of other
ve.c messages and prints the VE state and the offender's comm/pid;
the commit message now explains why the warning is kept.
- namespace management helpers: prepare_namespaces() leaves ctx
empty on any failure (mask zeroed on entry, saved fds closed on
error), so unconditional cleanup in callers is safe; fixed a
comment typo.
- more helpers: dropped a stray blank line in run_in_ve().
- Collected Reviewed-by tags.
- Link to v3: http://lore.virtuozzo.com/20260909-ve-selftest-improv-v3-0-4b41980d9a45@virtuozzo.com
Changes in v3:
- Patch 1: wrap flag -> (flag) in macros, undef them after use.
- Patch 2: Fix comments in run_in_ve function.
- Link to v2: http://lore.virtuozzo.com/20260909-ve-selftest-improv-v2-0-aad0a25d6569@virtuozzo.com
Changes in v2:
- Patch 1: fixed JOIN_NS order in enter_namespaces, added proper
cleanup in prepare_namespaces.
- Patch 2: increased buf size in write_u64_at, added range check in
read_s32_at, separated setup failures in run_in_ve from fn setup
failures.
- Patch 3: Removed kselftests mention.
- Link to v1: http://lore.virtuozzo.com/20260907-ve-selftest-improv-v1-0-a17847abbd48@virtuozzo.com
Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com>
---
Vladimir Riabchun (3):
ve_namespace: Allow entering non-running VE namespace
selftests/ve: Add namespace management helpers
selftests/ve: Add more helpers
kernel/ve/ve_namespace.c | 4 +-
tools/testing/selftests/ve/ve_selftest.h | 214 ++++++++++++++++++++++++++++++-
2 files changed, 210 insertions(+), 8 deletions(-)
---
base-commit: f7ba712715849bef1a54e1f13fab79b094ccc0df
change-id: 20260907-ve-selftest-improv-2d043d021cae
Best regards,
--
Konstantin Khorenko <khorenko@virtuozzo.com>
_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel
^ permalink raw reply [flat|nested] 5+ messages in thread
* [Devel] [PATCH VZ10 v4 1/3] ve_namespace: Allow entering non-running VE namespace
2026-09-25 12:47 [Devel] [PATCH VZ10 v4 0/3] Improvements for ve selftests Konstantin Khorenko
@ 2026-09-25 12:47 ` Konstantin Khorenko
2026-09-25 12:47 ` [Devel] [PATCH VZ10 v4 2/3] selftests/ve: Add namespace management helpers Konstantin Khorenko
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Konstantin Khorenko @ 2026-09-25 12:47 UTC (permalink / raw)
To: Vladimir Riabchun, Vasileios Almpanis; +Cc: devel
From: Vladimir Riabchun <vladimir.riabchun@virtuozzo.com>
The restriction doesn't bring a lot of value and makes tests more
complex: to enter a VE namespace, the VE has to be actually started.
In vzctl we have locking to prevent parallel creations.
If someone decides to skip locks and start one CT
in parallel - big mistake, but not ours.
Still, entering a non-running CT is a strange thing to do. Our
selftests do it on purpose, but if some of our userspace does the
same on a production node, that is a bug we want to know about and
fix, so leave a warning in place of the check.
https://virtuozzo.atlassian.net/browse/VSTOR-144504
Feature: ve selftests
Signed-off-by: Vladimir Riabchun <vladimir.riabchun@virtuozzo.com>
Reviewed-by: Vasileios Almpanis <vasileios.almpanis@virtuozzo.com>
Reviewed-by: Konstantin Khorenko <khorenko@virtuozzo.com>
---
kernel/ve/ve_namespace.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/kernel/ve/ve_namespace.c b/kernel/ve/ve_namespace.c
index 3dbe0dde2645d..6b12bcd605ea4 100644
--- a/kernel/ve/ve_namespace.c
+++ b/kernel/ve/ve_namespace.c
@@ -227,7 +227,9 @@ static int ve_ns_install(struct nsset *nsset, struct ns_common *new)
return -EPERM;
if (!VE_IS_RUNNING(ve_ns->ve))
- return -EINVAL;
+ pr_warn_once("CT: %s: setns to the VE namespace of a non-running CT (state %d) by %s (%d)\n",
+ ve_name(ve_ns->ve), ve_ns->ve->state,
+ current->comm, task_pid_nr(current));
/*
* Don't need to put_ve_ns(nsset->ve_ns) here,
--
2.43.0
_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel
^ permalink raw reply [flat|nested] 5+ messages in thread
* [Devel] [PATCH VZ10 v4 2/3] selftests/ve: Add namespace management helpers
2026-09-25 12:47 [Devel] [PATCH VZ10 v4 0/3] Improvements for ve selftests Konstantin Khorenko
2026-09-25 12:47 ` [Devel] [PATCH VZ10 v4 1/3] ve_namespace: Allow entering non-running VE namespace Konstantin Khorenko
@ 2026-09-25 12:47 ` Konstantin Khorenko
2026-09-25 12:47 ` [Devel] [PATCH VZ10 v4 3/3] selftests/ve: Add more helpers Konstantin Khorenko
2026-09-25 13:37 ` [Devel] [PATCH VZ10 v4 0/3] Improvements for ve selftests Konstantin Khorenko
3 siblings, 0 replies; 5+ messages in thread
From: Konstantin Khorenko @ 2026-09-25 12:47 UTC (permalink / raw)
To: Vladimir Riabchun, Vasileios Almpanis; +Cc: devel
From: Vladimir Riabchun <vladimir.riabchun@virtuozzo.com>
When mount namespace is created in a child, it is destroyed
when the child dies. We may need to keep it for a while to check
how VE handles resources.
Instead of keeping a thread which lives in a new ve+mnt namespaces,
let's store open namespace file descriptors to enter them later
without keeping children alive.
https://virtuozzo.atlassian.net/browse/VSTOR-144504
Feature: ve selftests
Signed-off-by: Vladimir Riabchun <vladimir.riabchun@virtuozzo.com>
Reviewed-by: Vasileios Almpanis <vasileios.almpanis@virtuozzo.com>
Reviewed-by: Konstantin Khorenko <khorenko@virtuozzo.com>
---
tools/testing/selftests/ve/ve_selftest.h | 130 +++++++++++++++++++++++++++++++
1 file changed, 130 insertions(+)
diff --git a/tools/testing/selftests/ve/ve_selftest.h b/tools/testing/selftests/ve/ve_selftest.h
index c53bf7900d208..bc9dc28a8d074 100644
--- a/tools/testing/selftests/ve/ve_selftest.h
+++ b/tools/testing/selftests/ve/ve_selftest.h
@@ -31,6 +31,136 @@
#define VE_CONTROLLERS \
"+cpuset +cpu +cpuacct +io +memory +hugetlb +pids +rdma +misc +ve"
+struct namespace_ctx {
+ int ns_save_mask; /* Mask of stored CLONE_NEW* namespaces. */
+ /* Namespace file descriptors. Name should match /proc/PID/ns/NAME */
+ int ve_fd;
+ int mnt_fd;
+};
+
+static inline void close_namespace_fds(struct namespace_ctx *ctx)
+{
+ if (ctx->ns_save_mask & CLONE_NEWVE)
+ close(ctx->ve_fd);
+ if (ctx->ns_save_mask & CLONE_NEWNS)
+ close(ctx->mnt_fd);
+
+ ctx->ns_save_mask = 0;
+}
+
+static inline int save_namespace_fds(struct namespace_ctx *ctx, int flags)
+{
+#define OPEN_NS(name, flag) \
+do { \
+ if (flags & (flag)) { \
+ ctx->name##_fd = open("/proc/self/ns/" #name, O_RDONLY); \
+ if (ctx->name##_fd < 0) { \
+ fprintf(stderr, "%s: could not open fd %s: %s\n", \
+ __func__, #name, strerror(errno)); \
+ goto err; \
+ } \
+ ctx->ns_save_mask |= (flag); \
+ } \
+} while (0)
+
+ ctx->ns_save_mask = 0;
+
+ OPEN_NS(ve, CLONE_NEWVE);
+ OPEN_NS(mnt, CLONE_NEWNS);
+
+#undef OPEN_NS
+ return 0;
+
+err:
+ close_namespace_fds(ctx);
+ return -1;
+}
+
+static inline int enter_namespaces(struct namespace_ctx *ctx, int flags)
+{
+#define JOIN_NS(name, flag) \
+do { \
+ if (flags & (flag)) { \
+ if (!(ctx->ns_save_mask & (flag))) { \
+ fprintf(stderr, "%s: could not switch ns %s:" \
+ " no fd in context.\n", __func__, #name); \
+ return -1; \
+ } \
+ if (setns(ctx->name##_fd, (flag))) { \
+ fprintf(stderr, "%s: could not switch ns %s: %s\n", \
+ __func__, #name, strerror(errno)); \
+ return -1; \
+ } \
+ } \
+} while (0)
+
+ JOIN_NS(ve, CLONE_NEWVE);
+ JOIN_NS(mnt, CLONE_NEWNS);
+
+#undef JOIN_NS
+ return 0;
+}
+
+static inline int enter_cgroup(int cgv2_fd, int ctid);
+
+/*
+ * Create new namespaces and store them in ctx.
+ * CLONE_NEWVE is treated specially - before unshare corresponding
+ * CT cgroup is entered, after it root cgroup is entered (not the original one).
+ */
+static inline int prepare_namespaces(struct namespace_ctx *ctx, int flags,
+ int cgv2_fd, int ctid)
+{
+ struct namespace_ctx tmp_ctx;
+ int ret = 0;
+
+ ctx->ns_save_mask = 0;
+
+ if (save_namespace_fds(&tmp_ctx, flags) < 0)
+ return -1;
+
+ if (flags & CLONE_NEWVE) {
+ if (enter_cgroup(cgv2_fd, ctid) < 0) {
+ fprintf(stderr, "%s: failed to enter CT cgroup\n", __func__);
+ ret = -1;
+ goto restore_ns;
+ }
+ }
+
+ if (unshare(flags) < 0) {
+ fprintf(stderr, "%s: failed to unshare, flags %x: %s\n",
+ __func__, flags, strerror(errno));
+ ret = -1;
+ goto restore_cg;
+ }
+
+ if (save_namespace_fds(ctx, flags)) {
+ fprintf(stderr, "%s: failed to save new namespaces, flags %x\n",
+ __func__, flags);
+ ret = -1;
+ }
+
+restore_cg:
+ if (flags & CLONE_NEWVE) {
+ if (enter_cgroup(cgv2_fd, 0) < 0) {
+ fprintf(stderr, "%s: failed to restore root cgroup\n", __func__);
+ ret = -1;
+ }
+ }
+
+restore_ns:
+ if (enter_namespaces(&tmp_ctx, flags) < 0) {
+ fprintf(stderr, "%s: failed to restore old namespaces, flags %x\n",
+ __func__, flags);
+ ret = -1;
+ }
+
+ close_namespace_fds(&tmp_ctx);
+ if (ret < 0)
+ close_namespace_fds(ctx);
+ return ret;
+}
+
static inline int write_file_at(int dirfd, const char *path, const char *val)
{
int fd, ret;
--
2.43.0
_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel
^ permalink raw reply [flat|nested] 5+ messages in thread
* [Devel] [PATCH VZ10 v4 3/3] selftests/ve: Add more helpers
2026-09-25 12:47 [Devel] [PATCH VZ10 v4 0/3] Improvements for ve selftests Konstantin Khorenko
2026-09-25 12:47 ` [Devel] [PATCH VZ10 v4 1/3] ve_namespace: Allow entering non-running VE namespace Konstantin Khorenko
2026-09-25 12:47 ` [Devel] [PATCH VZ10 v4 2/3] selftests/ve: Add namespace management helpers Konstantin Khorenko
@ 2026-09-25 12:47 ` Konstantin Khorenko
2026-09-25 13:37 ` [Devel] [PATCH VZ10 v4 0/3] Improvements for ve selftests Konstantin Khorenko
3 siblings, 0 replies; 5+ messages in thread
From: Konstantin Khorenko @ 2026-09-25 12:47 UTC (permalink / raw)
To: Vladimir Riabchun, Vasileios Almpanis; +Cc: devel
From: Vladimir Riabchun <vladimir.riabchun@virtuozzo.com>
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-144504
Feature: ve selftests
Signed-off-by: Vladimir Riabchun <vladimir.riabchun@virtuozzo.com>
Reviewed-by: Vasileios Almpanis <vasileios.almpanis@virtuozzo.com>
Reviewed-by: Konstantin Khorenko <khorenko@virtuozzo.com>
---
tools/testing/selftests/ve/ve_selftest.h | 84 +++++++++++++++++++++++++++++---
1 file changed, 77 insertions(+), 7 deletions(-)
diff --git a/tools/testing/selftests/ve/ve_selftest.h b/tools/testing/selftests/ve/ve_selftest.h
index bc9dc28a8d074..7b45f91c1d561 100644
--- a/tools/testing/selftests/ve/ve_selftest.h
+++ b/tools/testing/selftests/ve/ve_selftest.h
@@ -175,6 +175,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[32];
+
+ 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)
{
@@ -205,14 +213,9 @@ static inline int read_u64_at(int dirfd, const char *path,
unsigned long long *out)
{
char buf[32] = {0}, *end;
- int fd, ret;
-
- fd = openat(dirfd, path, O_RDONLY);
- if (fd < 0)
- return -1;
+ int ret;
- ret = read(fd, buf, sizeof(buf) - 1);
- close(fd);
+ ret = read_file_at(dirfd, path, buf, sizeof(buf));
if (ret <= 0)
return -1;
@@ -223,6 +226,25 @@ static inline int read_u64_at(int dirfd, const char *path,
return 0;
}
+static inline int read_s32_at(int dirfd, const char *path,
+ int *out)
+{
+ char buf[32] = {0}, *end;
+ long tmp;
+ int ret;
+
+ ret = read_file_at(dirfd, path, buf, sizeof(buf));
+ if (ret <= 0)
+ return -1;
+
+ errno = 0;
+ tmp = strtol(buf, &end, 10);
+ if (errno || end == buf || tmp < INT_MIN || tmp > INT_MAX)
+ return -1;
+ *out = tmp;
+ return 0;
+}
+
/* A fresh, private cgroup2 mount, returned as an fd to use with *at() calls. */
static inline int mount_cg2_fd(void)
{
@@ -266,6 +288,54 @@ static inline int enter_cgroup(int cgv2_fd, int ctid)
return ret;
}
+/*
+ * Run function in VE cgroup and given namespaces.
+ *
+ * Namespaces are provided via namespace_ctx and entered based on flags mask.
+ *
+ * Return values:
+ * - 0 if function returns zero
+ * - -1 if function returns negative value
+ * - 1 if function returns positive value
+ * - 2 if setup fails
+ */
+static inline int run_in_ve(int cgv2_fd, int ctid, struct namespace_ctx *ctx,
+ int flags, int (*fn)(void *), void *arg)
+{
+ int status;
+ pid_t pid;
+
+ pid = fork();
+ if (pid < 0) {
+ fprintf(stderr, "%s: fork failed\n", __func__);
+ return 2;
+ }
+ if (pid == 0) {
+ int ret;
+
+ if (enter_cgroup(cgv2_fd, ctid) < 0) {
+ fprintf(stderr, "%s: enter_cgroup failed\n", __func__);
+ _exit(254);
+ }
+ if (enter_namespaces(ctx, flags) < 0)
+ _exit(254);
+
+ 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) == 254)
+ return 2;
+ if (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.43.0
_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Devel] [PATCH VZ10 v4 0/3] Improvements for ve selftests
2026-09-25 12:47 [Devel] [PATCH VZ10 v4 0/3] Improvements for ve selftests Konstantin Khorenko
` (2 preceding siblings ...)
2026-09-25 12:47 ` [Devel] [PATCH VZ10 v4 3/3] selftests/ve: Add more helpers Konstantin Khorenko
@ 2026-09-25 13:37 ` Konstantin Khorenko
3 siblings, 0 replies; 5+ messages in thread
From: Konstantin Khorenko @ 2026-09-25 13:37 UTC (permalink / raw)
To: Vladimir Riabchun, Vasileios Almpanis, Konstantin Khorenko; +Cc: devel
On Fri, 25 Sep 2026 14:47:01 +0200, Konstantin Khorenko wrote:
> Improvements for ve selftests
>
> This change adds helpers for creating and preserving various
> namespaces and running functions inside them.
> This appeared useful while implementing ve mount accounting
> selftests - it required keeping mount namespace alive and
> doing different things at different moments of time.
>
> [...]
Applied to branch-rh10-6.12.0-211.52.1.22.x.vz10-ovz, will be released in rh10-6.12.0-211.52.1.22.4.vz10, thanks!
[1/3] ve_namespace: Allow entering non-running VE namespace
https://bitbucket.org/virtuozzocore/vzkernel.vzs/commits/9c6f7ef26780
[2/3] selftests/ve: Add namespace management helpers
https://bitbucket.org/virtuozzocore/vzkernel.vzs/commits/c941a3e9e564
[3/3] selftests/ve: Add more helpers
https://bitbucket.org/virtuozzocore/vzkernel.vzs/commits/e5808fb271c3
--
Konstantin Khorenko <khorenko@virtuozzo.com>
_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-09-25 13:38 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-25 12:47 [Devel] [PATCH VZ10 v4 0/3] Improvements for ve selftests Konstantin Khorenko
2026-09-25 12:47 ` [Devel] [PATCH VZ10 v4 1/3] ve_namespace: Allow entering non-running VE namespace Konstantin Khorenko
2026-09-25 12:47 ` [Devel] [PATCH VZ10 v4 2/3] selftests/ve: Add namespace management helpers Konstantin Khorenko
2026-09-25 12:47 ` [Devel] [PATCH VZ10 v4 3/3] selftests/ve: Add more helpers Konstantin Khorenko
2026-09-25 13:37 ` [Devel] [PATCH VZ10 v4 0/3] Improvements for ve selftests Konstantin Khorenko
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox