From: Kirill Tkhai <ktk...@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 <ava...@openvz.org> Signed-off-by: Kirill Tkhai <ktk...@odin.com> Signed-off-by: Dmitry Safonov <dsafo...@virtuozzo.com> Signed-off-by: Stanislav Kinsburskiy <skinsbur...@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 <khore...@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 <ptikhomi...@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 _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel