All Virtuozzo development lists (kernel + QEMU)
 help / color / mirror / Atom feed
* [Devel] [PATCH VZ10 v2 0/3] Improvements for ve selftests
@ 2026-09-09 12:14 Vladimir Riabchun
  2026-09-09 12:14 ` [Devel] [PATCH VZ10 v2 1/3] selftests/ve: Add namespace management helpers Vladimir Riabchun
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Vladimir Riabchun @ 2026-09-09 12:14 UTC (permalink / raw)
  To: Konstantin Khorenko; +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 last patch changes -EINVAL return to warning message.

https://virtuozzo.atlassian.net/browse/VSTOR-144504

Feature: ve selftests
Signed-off-by: Vladimir Riabchun <vladimir.riabchun@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.
- Sashiko review: https://sashiko.vzint.dev/#/patchset/sashiko-inject-1788867622-560139540%40sashiko.local
- Link to v1: http://lore.virtuozzo.com/20260907-ve-selftest-improv-v1-0-a17847abbd48@virtuozzo.com

---
Vladimir Riabchun (3):
      selftests/ve: Add namespace management helpers
      selftests/ve: Add more helpers
      ve_namespace: Allow entering non-running VE namespace

 kernel/ve/ve_namespace.c                 |   3 +-
 tools/testing/selftests/ve/ve_selftest.h | 208 +++++++++++++++++++++++++++++--
 2 files changed, 203 insertions(+), 8 deletions(-)
---
base-commit: 04cfdce5ceb48a93de722643c2afe8065ca8fc10
change-id: 20260907-ve-selftest-improv-2d043d021cae

Best regards,
--  
Vladimir Riabchun <vladimir.riabchun@virtuozzo.com>

_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Devel] [PATCH VZ10 v2 1/3] selftests/ve: Add namespace management helpers
  2026-09-09 12:14 [Devel] [PATCH VZ10 v2 0/3] Improvements for ve selftests Vladimir Riabchun
@ 2026-09-09 12:14 ` Vladimir Riabchun
  2026-09-09 14:33   ` Vasileios Almpanis
  2026-09-09 12:14 ` [Devel] [PATCH VZ10 v2 2/3] selftests/ve: Add more helpers Vladimir Riabchun
  2026-09-09 12:14 ` [Devel] [PATCH VZ10 v2 3/3] ve_namespace: Allow entering non-running VE namespace Vladimir Riabchun
  2 siblings, 1 reply; 8+ messages in thread
From: Vladimir Riabchun @ 2026-09-09 12:14 UTC (permalink / raw)
  To: Konstantin Khorenko; +Cc: devel

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>
---
 tools/testing/selftests/ve/ve_selftest.h | 123 +++++++++++++++++++++++++++++++
 1 file changed, 123 insertions(+)

diff --git a/tools/testing/selftests/ve/ve_selftest.h b/tools/testing/selftests/ve/ve_selftest.h
index c53bf7900d20..ee960f7db0b4 100644
--- a/tools/testing/selftests/ve/ve_selftest.h
+++ b/tools/testing/selftests/ve/ve_selftest.h
@@ -31,6 +31,129 @@
 #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);
+
+	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);
+	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 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;
+
+	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);
+	return ret;
+}
+
 static inline int write_file_at(int dirfd, const char *path, const char *val)
 {
 	int fd, ret;

-- 
2.47.1

_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Devel] [PATCH VZ10 v2 2/3] selftests/ve: Add more helpers
  2026-09-09 12:14 [Devel] [PATCH VZ10 v2 0/3] Improvements for ve selftests Vladimir Riabchun
  2026-09-09 12:14 ` [Devel] [PATCH VZ10 v2 1/3] selftests/ve: Add namespace management helpers Vladimir Riabchun
@ 2026-09-09 12:14 ` Vladimir Riabchun
  2026-09-09 14:33   ` Vasileios Almpanis
  2026-09-09 12:14 ` [Devel] [PATCH VZ10 v2 3/3] ve_namespace: Allow entering non-running VE namespace Vladimir Riabchun
  2 siblings, 1 reply; 8+ messages in thread
From: Vladimir Riabchun @ 2026-09-09 12:14 UTC (permalink / raw)
  To: Konstantin Khorenko; +Cc: devel

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>
---
 tools/testing/selftests/ve/ve_selftest.h | 85 +++++++++++++++++++++++++++++---
 1 file changed, 78 insertions(+), 7 deletions(-)

diff --git a/tools/testing/selftests/ve/ve_selftest.h b/tools/testing/selftests/ve/ve_selftest.h
index ee960f7db0b4..e88293a39d34 100644
--- a/tools/testing/selftests/ve/ve_selftest.h
+++ b/tools/testing/selftests/ve/ve_selftest.h
@@ -168,6 +168,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)
 {
@@ -198,14 +206,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;
 
@@ -216,6 +219,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)
 {
@@ -259,6 +281,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 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.47.1

_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Devel] [PATCH VZ10 v2 3/3] ve_namespace: Allow entering non-running VE namespace
  2026-09-09 12:14 [Devel] [PATCH VZ10 v2 0/3] Improvements for ve selftests Vladimir Riabchun
  2026-09-09 12:14 ` [Devel] [PATCH VZ10 v2 1/3] selftests/ve: Add namespace management helpers Vladimir Riabchun
  2026-09-09 12:14 ` [Devel] [PATCH VZ10 v2 2/3] selftests/ve: Add more helpers Vladimir Riabchun
@ 2026-09-09 12:14 ` Vladimir Riabchun
  2026-09-09 14:33   ` Vasileios Almpanis
  2 siblings, 1 reply; 8+ messages in thread
From: Vladimir Riabchun @ 2026-09-09 12:14 UTC (permalink / raw)
  To: Konstantin Khorenko; +Cc: devel

This doesn't bring a lot of value and makes tests more complex.
To enter VE namespace we need to actually start VE.

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.

https://virtuozzo.atlassian.net/browse/VSTOR-144504

Feature: ve selftests
Signed-off-by: Vladimir Riabchun <vladimir.riabchun@virtuozzo.com>
---
 kernel/ve/ve_namespace.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/kernel/ve/ve_namespace.c b/kernel/ve/ve_namespace.c
index 3dbe0dde2645..879a7863e33f 100644
--- a/kernel/ve/ve_namespace.c
+++ b/kernel/ve/ve_namespace.c
@@ -227,7 +227,8 @@ 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("Switching to a non-running ve %s.\n",
+			ve_name(ve_ns->ve));
 
 	/*
 	 * Don't need to put_ve_ns(nsset->ve_ns) here,

-- 
2.47.1

_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Devel] [PATCH VZ10 v2 2/3] selftests/ve: Add more helpers
  2026-09-09 12:14 ` [Devel] [PATCH VZ10 v2 2/3] selftests/ve: Add more helpers Vladimir Riabchun
@ 2026-09-09 14:33   ` Vasileios Almpanis
  0 siblings, 0 replies; 8+ messages in thread
From: Vasileios Almpanis @ 2026-09-09 14:33 UTC (permalink / raw)
  To: Vladimir Riabchun; +Cc: devel

> 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>
>
> diff --git a/tools/testing/selftests/ve/ve_selftest.h b/tools/testing/selftests/ve/ve_selftest.h
> index ee960f7db0b4..e88293a39d34 100644
> --- a/tools/testing/selftests/ve/ve_selftest.h
> +++ b/tools/testing/selftests/ve/ve_selftest.h
> @@ -168,6 +168,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)
>  {
> @@ -198,14 +206,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;
>  
> @@ -216,6 +219,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)
>  {
> @@ -259,6 +281,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.

The documentation here is a bit weird. There is no unshare_flags
just flags and they are not passed to unshare but to enter_namespaces.

-- 
Vasileios Almpanis <vasileios.almpanis@virtuozzo.com>
_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Devel] [PATCH VZ10 v2 1/3] selftests/ve: Add namespace management helpers
  2026-09-09 12:14 ` [Devel] [PATCH VZ10 v2 1/3] selftests/ve: Add namespace management helpers Vladimir Riabchun
@ 2026-09-09 14:33   ` Vasileios Almpanis
  0 siblings, 0 replies; 8+ messages in thread
From: Vasileios Almpanis @ 2026-09-09 14:33 UTC (permalink / raw)
  To: Vladimir Riabchun; +Cc: devel

> 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>
>
> diff --git a/tools/testing/selftests/ve/ve_selftest.h b/tools/testing/selftests/ve/ve_selftest.h
> index c53bf7900d20..ee960f7db0b4 100644
> --- a/tools/testing/selftests/ve/ve_selftest.h
> +++ b/tools/testing/selftests/ve/ve_selftest.h
> @@ -31,6 +31,129 @@
>  #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) {                                                \

Parenthesise the macro argument, checkpatch complaints about it
	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);

Add #undef OPEN_NS after the last call to not leak to all includers and
the same for JOIN_NS.

-- 
Vasileios Almpanis <vasileios.almpanis@virtuozzo.com>
_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Devel] [PATCH VZ10 v2 3/3] ve_namespace: Allow entering non-running VE namespace
  2026-09-09 12:14 ` [Devel] [PATCH VZ10 v2 3/3] ve_namespace: Allow entering non-running VE namespace Vladimir Riabchun
@ 2026-09-09 14:33   ` Vasileios Almpanis
  2026-09-09 18:56     ` Vladimir Riabchun
  0 siblings, 1 reply; 8+ messages in thread
From: Vasileios Almpanis @ 2026-09-09 14:33 UTC (permalink / raw)
  To: Vladimir Riabchun; +Cc: devel

> This doesn't bring a lot of value and makes tests more complex.
> To enter VE namespace we need to actually start VE.
> 
> 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.
> 
> https://virtuozzo.atlassian.net/browse/VSTOR-144504
> 
> Feature: ve selftests
> Signed-off-by: Vladimir Riabchun <vladimir.riabchun@virtuozzo.com>
>
> diff --git a/kernel/ve/ve_namespace.c b/kernel/ve/ve_namespace.c
> index 3dbe0dde2645..879a7863e33f 100644
> --- a/kernel/ve/ve_namespace.c
> +++ b/kernel/ve/ve_namespace.c
> @@ -227,7 +227,8 @@ 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("Switching to a non-running ve %s.\n",

Maybe better print ve->veid instead of ve_name(). ve_offline() sets
ve->ve_name to NULL when the ve cgroup is removed, so we will see 
"ve (null)" in that case.

> +			ve_name(ve_ns->ve));

This change means that now a host task can enter the CT before the CT
has been started. A task can enter into the VE by two ways either
copy_ve_ns or by switch_ve_namespace both of which call ve_setup_task.
This function sets whether the task can be ptraced, core dumped etc
which will be skipped because ve_setup_task checks if ve is running
which it will not be. So here we break the invariant that tasks that
enter into the ve from host cannot be ptraced etc. I suggest to add
a flag to ve_setup_task entered which will be 1 for switch_ve_namespace
and 0 for copy_ve_ns

-- 
Vasileios Almpanis <vasileios.almpanis@virtuozzo.com>
_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Devel] [PATCH VZ10 v2 3/3] ve_namespace: Allow entering non-running VE namespace
  2026-09-09 14:33   ` Vasileios Almpanis
@ 2026-09-09 18:56     ` Vladimir Riabchun
  0 siblings, 0 replies; 8+ messages in thread
From: Vladimir Riabchun @ 2026-09-09 18:56 UTC (permalink / raw)
  To: Vasileios Almpanis; +Cc: devel



On 9/9/26 16:33, Vasileios Almpanis wrote:
>> This doesn't bring a lot of value and makes tests more complex.
>> To enter VE namespace we need to actually start VE.
>>
>> 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.
>>
>> https://virtuozzo.atlassian.net/browse/VSTOR-144504
>>
>> Feature: ve selftests
>> Signed-off-by: Vladimir Riabchun <vladimir.riabchun@virtuozzo.com>
>>
>> diff --git a/kernel/ve/ve_namespace.c b/kernel/ve/ve_namespace.c
>> index 3dbe0dde2645..879a7863e33f 100644
>> --- a/kernel/ve/ve_namespace.c
>> +++ b/kernel/ve/ve_namespace.c
>> @@ -227,7 +227,8 @@ 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("Switching to a non-running ve %s.\n",
> 
> Maybe better print ve->veid instead of ve_name(). ve_offline() sets
> ve->ve_name to NULL when the ve cgroup is removed, so we will see
> "ve (null)" in that case.

We don't initialize this value in tests, it is 0.
Actually, can we have this situation? Reaching ve_ns_install means
we grabbed a ve_ns reference in validate_nsset. How can we do ->css_offline
at the same time?

> 
>> +			ve_name(ve_ns->ve));
> 
> This change means that now a host task can enter the CT before the CT
> has been started. A task can enter into the VE by two ways either
> copy_ve_ns or by switch_ve_namespace both of which call ve_setup_task.
> This function sets whether the task can be ptraced, core dumped etc
> which will be skipped because ve_setup_task checks if ve is running
> which it will not be. So here we break the invariant that tasks that
> enter into the ve from host cannot be ptraced etc. I suggest to add
> a flag to ve_setup_task entered which will be 1 for switch_ve_namespace
> and 0 for copy_ve_ns> 

Good point. I'm not sure how real it is though. It should be someone
really nasty on the host trying to poison CT, but if this nasty person
is switching VE ns - it has CAP_SYS_ADMIN already.

It can protect us from bugs in vzctl though, so I think it is not completely
useless.
What if we drop VE_IS_RUNNING(ve) in ve_setup_task?

-- 
Best regards, Riabchun Vladimir
Linux Kernel Developer, Virtuozzo

_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2026-09-09 18:57 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-09 12:14 [Devel] [PATCH VZ10 v2 0/3] Improvements for ve selftests Vladimir Riabchun
2026-09-09 12:14 ` [Devel] [PATCH VZ10 v2 1/3] selftests/ve: Add namespace management helpers Vladimir Riabchun
2026-09-09 14:33   ` Vasileios Almpanis
2026-09-09 12:14 ` [Devel] [PATCH VZ10 v2 2/3] selftests/ve: Add more helpers Vladimir Riabchun
2026-09-09 14:33   ` Vasileios Almpanis
2026-09-09 12:14 ` [Devel] [PATCH VZ10 v2 3/3] ve_namespace: Allow entering non-running VE namespace Vladimir Riabchun
2026-09-09 14:33   ` Vasileios Almpanis
2026-09-09 18:56     ` Vladimir Riabchun

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.