[RHEL7,COMMIT] ve/net: hide handler for netlink NETLINK_REPAIR command unless CRIU restore

Submitted by Konstantin Khorenko on May 11, 2018, 9:20 a.m.

Details

Message ID 201805110920.w4B9KWME032157@finist_ce7.work
State New
Series "ve/net: hide handler for netlink NETLINK_REPAIR command unless CRIU restore"
Headers show

Commit Message

Konstantin Khorenko May 11, 2018, 9:20 a.m.
The commit is pushed to "branch-rh7-3.10.0-693.21.1.vz7.46.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-693.21.1.vz7.46.7
------>
commit 5b275363cdeeb68c2cf38bc57f71aa68454d740d
Author: Konstantin Khorenko <khorenko@virtuozzo.com>
Date:   Fri May 11 12:20:32 2018 +0300

    ve/net: hide handler for netlink NETLINK_REPAIR command unless CRIU restore
    
    The following patch to be applied to old kernels.
    It makes updated "ip" working and does not break online migration even if CRIU
    package has not been updated.
    
    Idea of the patch is taken from:
    08dc16449a39 ("net: Change number of netlink repair")
    
       Mainstream has NETLINK_EXT_ACK 11, which is used by fresh
       iproute utils. We don't want these utils switch the socket
       in repair mode.
    
       https://jira.sw.ru/browse/PSBM-83415
    
       Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
    
    Distributives (for example Ubuntu 18.04, RHEL7) include now those
    "fresh" version of "ip" utility which hangs on unpatched kernel.
    
    Idea of the patch: we handle netlink command number 11
    (NETLINK_REPAIR in VZ kernel / NETLINK_EXT_ACK in mainstream)
    only in case we detect CRIU restore stage, otherwise we claim
    kernel does not support it and "ip" is happy with that.
    
    https://jira.sw.ru/browse/PSBM-84191
    
    Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com>
---
 include/uapi/linux/netlink.h | 3 +++
 net/netlink/af_netlink.c     | 8 ++++++++
 2 files changed, 11 insertions(+)

Patch hide | download patch | download mbox

diff --git a/include/uapi/linux/netlink.h b/include/uapi/linux/netlink.h
index 56ddadf14e0e..a5e6e5c4c238 100644
--- a/include/uapi/linux/netlink.h
+++ b/include/uapi/linux/netlink.h
@@ -111,7 +111,10 @@  struct nlmsgerr {
 #define NETLINK_LISTEN_ALL_NSID		8
 #define NETLINK_LIST_MEMBERSHIPS	9
 #define NETLINK_CAP_ACK			10
+
+/* intersects with mainstream NETLINK_EXT_ACK */
 #define NETLINK_REPAIR			11
+#define NETLINK_REPAIR2			127
 
 struct nl_pktinfo {
 	__u32	group;
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 513597d267eb..4fd2438dcfba 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -2193,6 +2193,14 @@  static int netlink_setsockopt(struct socket *sock, int level, int optname,
 
 	switch (optname) {
 	case NETLINK_REPAIR:
+		/* Hide the command handler unless "criu" process
+		 * resumes a Container
+		 */
+		if (likely(!get_exec_env()->is_pseudosuper ||
+			   strcmp(current->comm, "criu")))
+			return -ENOPROTOOPT;
+		/* fall through */
+	case NETLINK_REPAIR2:
 		if (val)
 			nlk->flags |= NETLINK_F_REPAIR;
 		else