[Devel] [PATCH RHEL7 COMMIT] vznetstat: Port diff-vznetstat-fix-ip_vznetstat-module-load

Konstantin Khorenko khorenko at virtuozzo.com
Wed Jun 24 03:41:49 PDT 2015


The commit is pushed to "branch-rh7-3.10.0-123.1.2-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-123.1.2.vz7.5.17
------>
commit b8636962176388de0a9cda16309a55f391846206
Author: Vladimir Davydov <vdavydov at parallels.com>
Date:   Wed Jun 24 14:41:49 2015 +0400

    vznetstat: Port diff-vznetstat-fix-ip_vznetstat-module-load
    
    Author: Dmitry Guryanov
    Email: dguryanov at parallels.com
    Subject: NET: fix ip_vznetstat module load
    Date: Fri, 17 May 2013 15:03:11 +0400
    
    If we start some containers, then load module ip_vznetstat -
    ve_struct->stat pointer will not be initialized and we will
    get kernel panic with first incoming packet.
    
    So initialize all pointers, not only in ve0.
    
    BUG https://jira.sw.ru/browse/PCLIN-31771
    
    Signed-off-by: Dmitry Guryanov <dguryanov at parallels.com>
    
    Acked-by: Andrey Vagin <avagin at openvz.org>
    
    changes in v2:
            ve_hook_register(VE_SS_CHAIN, &venet_acct_hook);
            moved before stat pointers initialization, because in previous
            version contaiers, created after mutex_unlock and before
            ve_hook_register wouldn't be initialized.
    
    changes in v3:
            remove module_get/put on ct start/stop, so that we can
            unload module.
    
    changes in v4:
    	unregister vz hooks before freeing venet_stat structures
    
     net/ipv4/netfilter/ip_vznetstat.c |   50 ++++++++++++++++++++++++------------
     1 files changed, 33 insertions(+), 17 deletions(-)
    =============================================================================
    
    Author: Vasily Averin
    Email: vvs at parallels.com
    Subject: ip_venetstat_init: access to ve_list without proper locking
    Date: Fri, 12 Sep 2014 14:02:12 +0400
    
    ip_venetstat_init() on error path uses for_each_ve() without proper locking.
    Access to ve_llust head should be protected by ve_list_lock.
    
    Signed-off-by: Vasily Averin <vvs at parallels.com>
    =============================================================================
    
    Related to https://jira.sw.ru/browse/PSBM-33650
    
    Signed-off-by: Vladimir Davydov <vdavydov at parallels.com>
---
 kernel/ve/vznetstat/ip_vznetstat.c | 47 ++++++++++++++++++++++++--------------
 1 file changed, 30 insertions(+), 17 deletions(-)

diff --git a/kernel/ve/vznetstat/ip_vznetstat.c b/kernel/ve/vznetstat/ip_vznetstat.c
index ff33dc5..1eb637b 100644
--- a/kernel/ve/vznetstat/ip_vznetstat.c
+++ b/kernel/ve/vznetstat/ip_vznetstat.c
@@ -146,8 +146,6 @@ int init_venet_acct_ip_stat(struct ve_struct *env, struct venet_stat *stat)
 	env->stat = stat;
 	venet_acct_get_stat(stat);
 
-	__module_get(THIS_MODULE);
-
 	return 0;
 }
 EXPORT_SYMBOL(init_venet_acct_ip_stat);
@@ -157,7 +155,6 @@ void fini_venet_acct_ip_stat(struct ve_struct *env)
 	if (env->stat) {
 		venet_acct_put_stat(env->stat);
 		env->stat = NULL;
-		module_put(THIS_MODULE);
 	}
 }
 EXPORT_SYMBOL(fini_venet_acct_ip_stat);
@@ -203,30 +200,46 @@ EXPORT_SYMBOL(ip_vznetstat_touch);
 
 int __init ip_venetstat_init(void)
 {
-	struct ve_struct *env = get_ve0();
-	int ret;
-
-	env->stat = venet_acct_find_create_stat(env->veid);
-	if (env->stat == NULL)
-		return -ENOMEM;
+	struct ve_struct *ve;
+	int ret = -ENOMEM;
+
+	mutex_lock(&ve_list_lock);
+	for_each_ve(ve) {
+		BUG_ON(ve->stat);
+		ve->stat = venet_acct_find_create_stat(ve->veid);
+		if (!ve->stat)
+			goto err_locked;
+	}
+	mutex_unlock(&ve_list_lock);
 
 	ret = venet_acct_register_ip_hooks();
-	if (ret < 0) {
-		venet_acct_put_stat(env->stat);
-		env->stat = NULL;
-		return ret;
-	}
+	if (ret < 0)
+		goto err;
 
 	return 0;
+err:
+	mutex_lock(&ve_list_lock);
+err_locked:
+	for_each_ve(ve) {
+		venet_acct_put_stat(ve->stat);
+		ve->stat = NULL;
+	}
+	mutex_unlock(&ve_list_lock);
+	return ret;
 }
 
 void __exit ip_venetstat_exit(void)
 {
-	struct ve_struct *env = get_ve0();
+	struct ve_struct *ve;
 
 	venet_acct_unregister_ip_hooks();
-	venet_acct_put_stat(env->stat);
-	env->stat = NULL;
+
+	mutex_lock(&ve_list_lock);
+	for_each_ve(ve) {
+		venet_acct_put_stat(ve->stat);
+		ve->stat = NULL;
+	}
+	mutex_unlock(&ve_list_lock);
 }
 
 #if defined(MODULE) && defined(VZ_AUDIT)



More information about the Devel mailing list