This change unifies mount limit handling with other VE limits. This will simplify refactoring later and allow more precise limits control from one place.
https://virtuozzo.atlassian.net/browse/VSTOR-135520 Feature: per-ve failcounters Signed-off-by: Vladimir Riabchun <[email protected]> --- include/linux/ve.h | 7 ++++ kernel/ve/ve.c | 34 ++++++++++++++++++- kernel/ve/veowner.c | 19 ----------- tools/testing/selftests/ve/ve_ns_owner_test.c | 6 +++- 4 files changed, 45 insertions(+), 21 deletions(-) diff --git a/include/linux/ve.h b/include/linux/ve.h index b2b3d4c12e39..5a5413107eef 100644 --- a/include/linux/ve.h +++ b/include/linux/ve.h @@ -87,7 +87,13 @@ struct ve_struct { atomic_t nd_neigh_nr; unsigned long meminfo_val; + /* + * Operations with a big amount of mount points can require a lot of time. + * These operations take the global lock namespace_sem, so they can affect + * other containers. + */ atomic_t mnt_avail_nr; /* number of present VE mounts */ + int mnt_max_nr; #ifdef CONFIG_COREDUMP char core_pattern[CORENAME_MAX_SIZE]; @@ -134,6 +140,7 @@ extern int nr_ve; #define NETNS_MAX_NR_DEFAULT 256 /* number of net-namespaces per-VE */ #define NETIF_MAX_NR_DEFAULT 256 /* number of net-interfaces per-VE */ #define BPF_PROG_MAX_NR_DEFAULT 256 /* number of loaded BPF progs per-VE */ +#define MNT_MAX_NR_DEFAULT 4096 /* number of mounts per-VE */ extern unsigned int sysctl_ve_mount_nr; diff --git a/kernel/ve/ve.c b/kernel/ve/ve.c index 0fb5a2c1f63a..e92bc25c8933 100644 --- a/kernel/ve/ve.c +++ b/kernel/ve/ve.c @@ -79,6 +79,7 @@ struct ve_struct ve0 = { .arp_neigh_nr = ATOMIC_INIT(0), .nd_neigh_nr = ATOMIC_INIT(0), .mnt_avail_nr = ATOMIC_INIT(INT_MAX), + .mnt_max_nr = INT_MAX, .meminfo_val = VE_MEMINFO_SYSTEM, .umh_running_helpers = ATOMIC_INIT(0), .umh_helpers_waitq = __WAIT_QUEUE_HEAD_INITIALIZER(ve0.umh_helpers_waitq), @@ -774,7 +775,8 @@ static struct cgroup_subsys_state *ve_create(struct cgroup_subsys_state *parent_ atomic_set(&ve->arp_neigh_nr, 0); atomic_set(&ve->nd_neigh_nr, 0); - atomic_set(&ve->mnt_avail_nr, sysctl_ve_mount_nr); + ve->mnt_max_nr = MNT_MAX_NR_DEFAULT; + atomic_set(&ve->mnt_avail_nr, MNT_MAX_NR_DEFAULT); #ifdef CONFIG_COREDUMP strcpy(ve->core_pattern, "core"); @@ -1053,6 +1055,30 @@ static s64 ve_mnt_avail_nr_read(struct cgroup_subsys_state *css, struct cftype * return atomic_read(&css_to_ve(css)->mnt_avail_nr); } +static u64 ve_mnt_max_nr_read(struct cgroup_subsys_state *css, struct cftype *cft) +{ + return css_to_ve(css)->mnt_max_nr; +} + +static int ve_mnt_max_nr_write(struct cgroup_subsys_state *css, struct cftype *cft, u64 val) +{ + struct ve_struct *ve = css_to_ve(css); + int delta; + + if (!ve_is_super(get_exec_env())) + return -EPERM; + + if (val > INT_MAX) + return -EOVERFLOW; + + down_write(&ve->op_sem); + delta = val - ve->mnt_max_nr; + ve->mnt_max_nr = val; + atomic_add(delta, &ve->mnt_avail_nr); + up_write(&ve->op_sem); + return 0; +} + static u64 ve_netif_max_nr_read(struct cgroup_subsys_state *css, struct cftype *cft) { return css_to_ve(css)->netif_max_nr; @@ -1613,6 +1639,12 @@ static struct cftype ve_cftypes[] = { .name = "mnt_avail_nr", .read_s64 = ve_mnt_avail_nr_read, }, + { + .name = "mnt_max_nr", + .flags = CFTYPE_NOT_ON_ROOT, + .read_u64 = ve_mnt_max_nr_read, + .write_u64 = ve_mnt_max_nr_write, + }, { .name = "netif_max_nr", .flags = CFTYPE_NOT_ON_ROOT, diff --git a/kernel/ve/veowner.c b/kernel/ve/veowner.c index 1e631baf0de9..c77735f8c035 100644 --- a/kernel/ve/veowner.c +++ b/kernel/ve/veowner.c @@ -48,26 +48,7 @@ static void prepare_proc(void) * ------------------------------------------------------------------------ */ -/* - * Operations with a big amount of mount points can require a lot of time. - * These operations take the global lock namespace_sem, so they can affect - * other containers. Let us allow no more than sysctl_ve_mount_nr mount - * points for a VE. - */ -unsigned int sysctl_ve_mount_nr = 4096; -static int ve_mount_nr_min = 0; -static int ve_mount_nr_max = INT_MAX; - static struct ctl_table vz_fs_table[] = { - { - .procname = "ve-mount-nr", - .data = &sysctl_ve_mount_nr, - .maxlen = sizeof(sysctl_ve_mount_nr), - .mode = 0644, - .proc_handler = proc_dointvec_minmax, - .extra1 = &ve_mount_nr_min, - .extra2 = &ve_mount_nr_max, - }, { .procname = "fsync-enable", .data = &ve0.fsync_enable, diff --git a/tools/testing/selftests/ve/ve_ns_owner_test.c b/tools/testing/selftests/ve/ve_ns_owner_test.c index 3b5979fa63f6..3b62f87babbf 100644 --- a/tools/testing/selftests/ve/ve_ns_owner_test.c +++ b/tools/testing/selftests/ve/ve_ns_owner_test.c @@ -56,7 +56,7 @@ * any spurious accounting against the parent ve would overflow it. */ #define VE_NETNS_MAX 3 -#define VE_MOUNTS_MAX 4096 +#define VE_MOUNTS_MAX 32 static int write_file_at(int dirfd, const char *path, const char *val) { @@ -267,6 +267,10 @@ FIXTURE_SETUP(ve_ns_owner) snprintf(val, sizeof(val), "%d", VE_NETNS_MAX); ASSERT_EQ(write_file_at(self->cgv2_fd, path, val), 0); + snprintf(path, sizeof(path), "%d/ve.mnt_max_nr", self->ctid); + snprintf(val, sizeof(val), "%d", VE_MOUNTS_MAX); + ASSERT_EQ(write_file_at(self->cgv2_fd, path, val), 0); + /* * The new ve cgroup has not been entered by anything yet, so its * mnt_avail_nr counter be VE_MOUNTS_MAX. Each test below verifies that -- 2.47.1 _______________________________________________ Devel mailing list [email protected] https://lists.openvz.org/mailman/listinfo/devel
