[Devel] [PATCH RH9 5/7] ve/net: allow to rename devices in non-ve namespaces
Pavel Tikhomirov
ptikhomirov at virtuozzo.com
Tue Oct 5 15:55:51 MSK 2021
From: Kirill Tkhai <ktkhai at odin.com>
Porting patch diff-ve-net-allow-to-rename-devices-in-non-ve-namespaces
from 2.6.32.
https://jira.sw.ru/browse/PSBM-29810
https://jira.sw.ru/browse/PSBM-33645
Signed-off-by: Andrew Vagin <avagin at openvz.org>
Signed-off-by: Kirill Tkhai <ktkhai at odin.com>
Signed-off-by: Dmitry Safonov <dsafonov at virtuozzo.com>
Signed-off-by: Stanislav Kinsburskiy <skinsbursky at virtuozzo.com>
+++
ve/net: don't use RCU read lock in ve_dev_can_rename()
rcu_read_lock()/unlock won't help here anyway:
"can" value can change right after rcu lock is dropped.
mFixes: 13bed5e31b7c ("ve/net: allow to rename devices in non-ve
namespaces")
https://jira.sw.ru/browse/PSBM-93640
Signed-off-by: Konstantin Khorenko <khorenko at virtuozzo.com>
vz9 changes:
- fix crash by checking ve->ve_ns is not zero and is not freed under us,
meaning that we still need RCU here, let's add ve_get_net_ns helper to access
ve netns right
- add proper CONFIG_VE ifdefs
(cherry picked from vz8 commit 0460650a21fa865b072bd672ff8f829921d30e54)
Signed-off-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
---
include/linux/ve.h | 2 ++
kernel/ve/ve.c | 15 +++++++++++++++
net/core/dev.c | 22 ++++++++++++++++++++++
3 files changed, 39 insertions(+)
diff --git a/include/linux/ve.h b/include/linux/ve.h
index 6e3975ed2cf6..c2bdadb487f1 100644
--- a/include/linux/ve.h
+++ b/include/linux/ve.h
@@ -189,6 +189,8 @@ extern int vz_security_protocol_check(struct net *net, int protocol);
int ve_net_hide_sysctl(struct net *net);
+extern struct net *ve_get_net_ns(struct ve_struct* ve);
+
#else /* CONFIG_VE */
#define get_ve(ve) (NULL)
#define put_ve(ve) do { } while (0)
diff --git a/kernel/ve/ve.c b/kernel/ve/ve.c
index 21eec9973a9a..1adb875dffc9 100644
--- a/kernel/ve/ve.c
+++ b/kernel/ve/ve.c
@@ -25,6 +25,7 @@
#include <linux/nsproxy.h>
#include <linux/fs_struct.h>
#include <linux/time_namespace.h>
+#include <net/net_namespace.h>
#include <linux/genhd.h>
#include <uapi/linux/vzcalluser.h>
@@ -243,6 +244,20 @@ int ve_net_hide_sysctl(struct net *net)
}
EXPORT_SYMBOL(ve_net_hide_sysctl);
+struct net *ve_get_net_ns(struct ve_struct* ve)
+{
+ struct nsproxy *ve_ns;
+ struct net *net_ns;
+
+ rcu_read_lock();
+ ve_ns = rcu_dereference(ve->ve_ns);
+ net_ns = ve_ns ? get_net(ve_ns->net_ns) : NULL;
+ rcu_read_unlock();
+
+ return net_ns;
+}
+EXPORT_SYMBOL(ve_get_net_ns);
+
int nr_threads_ve(struct ve_struct *ve)
{
return cgroup_task_count(ve->css.cgroup);
diff --git a/net/core/dev.c b/net/core/dev.c
index e66ccebe190a..d257a67adb88 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1324,6 +1324,20 @@ static int dev_get_valid_name(struct net *net, struct net_device *dev,
return 0;
}
+#ifdef CONFIG_VE
+static bool ve_dev_can_rename(struct net_device *dev)
+{
+ struct net *net;
+ bool can;
+
+ net = ve_get_net_ns(dev_net(dev)->owner_ve);
+ can = !net || net == dev_net(dev);
+ if (net)
+ put_net(net);
+ return can;
+}
+#endif
+
/**
* dev_change_name - change name of a device
* @dev: device
@@ -1383,6 +1397,11 @@ int dev_change_name(struct net_device *dev, const char *newname)
dev->name_assign_type = NET_NAME_RENAMED;
rollback:
+#ifdef CONFIG_VE
+ if (!ve_dev_can_rename(dev))
+ goto skip_rename;
+#endif
+
ret = device_rename(&dev->dev, dev->name);
if (ret) {
memcpy(dev->name, oldname, IFNAMSIZ);
@@ -1391,6 +1410,9 @@ int dev_change_name(struct net_device *dev, const char *newname)
return ret;
}
+#ifdef CONFIG_VE
+skip_rename:
+#endif
up_write(&devnet_rename_sem);
netdev_adjacent_rename_links(dev, oldname);
--
2.31.1
More information about the Devel
mailing list