[kernel] r13199 - in dists/lenny/linux-2.6/debian: . patches/features/all/openvz patches/series

Maximilian Attems maks at alioth.debian.org
Sun Mar 22 21:12:53 UTC 2009


Author: maks
Date: Sun Mar 22 21:12:49 2009
New Revision: 13199

Log:
openvz add several stable proposed patches

this fourth serie are selected ABI breaker from 0014-0029
Reported-by: Kir Kolyshkin <kir at openvz.org>
Tested-by: Ola Lundqvist <ola at inguza.com>

Added:
   dists/lenny/linux-2.6/debian/patches/features/all/openvz/0016-nfs-fix-nfs-clinet-in-VE-finally.patch
   dists/lenny/linux-2.6/debian/patches/features/all/openvz/0017-cpt-bump-image-version-to-VERSION_26.patch
   dists/lenny/linux-2.6/debian/patches/features/all/openvz/0018-nfs-add-missed-ve_nfs.h-file.patch
   dists/lenny/linux-2.6/debian/patches/features/all/openvz/0020-autofs4-pidns-friendly-oz_mode.patch
   dists/lenny/linux-2.6/debian/patches/features/all/openvz/0025-conntrack-Allocate-free-ve_nf_conntrack_l3proto_ipv.patch
   dists/lenny/linux-2.6/debian/patches/features/all/openvz/0026-ct-Move-_nf_conntrack_l3proto_ipv6-to-net-namespace.patch
   dists/lenny/linux-2.6/debian/patches/features/all/openvz/0028-conntrack-fix-oops-in-nf_ct_frag6_gather.patch
Modified:
   dists/lenny/linux-2.6/debian/changelog
   dists/lenny/linux-2.6/debian/patches/series/14-extra

Modified: dists/lenny/linux-2.6/debian/changelog
==============================================================================
--- dists/lenny/linux-2.6/debian/changelog	(original)
+++ dists/lenny/linux-2.6/debian/changelog	Sun Mar 22 21:12:49 2009
@@ -85,6 +85,13 @@
   * [openvz] 09686c1 Free skb->nf_bridge in veth_xmit() and venet_xmit().
   * [openvz] 397500c autofs4: fix ia32 compat mode.
   * [openvz] 0328e3d pidns: update leader_pid at pidns attach.
+  * [openvz] 66ec7f7 nfs: fix nfs clinet in VE (finally).
+  * [openvz] 4fc3a18 cpt: bump image version to VERSION_26.
+  * [openvz] 2a08380 nfs: add missed ve_nfs.h file.
+  * [openvz] 4c9010e autofs4: pidns friendly oz_mode.
+  * [openvz] 2c1b2f7 conntrack: Allocate/free ve_nf_conntrack_l3proto_ipv6.
+  * [openvz] e29a555 ct: Move _nf_conntrack_l3proto_ipv6 to net namespace.
+  * [openvz] 4355344 conntrack: fix oops in nf_ct_frag6_gather.
 
  -- dann frazier <dannf at debian.org>  Sun, 22 Mar 2009 14:09:23 -0600
 

Added: dists/lenny/linux-2.6/debian/patches/features/all/openvz/0016-nfs-fix-nfs-clinet-in-VE-finally.patch
==============================================================================
--- (empty file)
+++ dists/lenny/linux-2.6/debian/patches/features/all/openvz/0016-nfs-fix-nfs-clinet-in-VE-finally.patch	Sun Mar 22 21:12:49 2009
@@ -0,0 +1,1279 @@
+From 66ec7f7f493fb98e8baa6591e9225086ae640fb8 Mon Sep 17 00:00:00 2001
+From: Denis Lunev <den at openvz.org>
+Date: Tue, 9 Sep 2008 18:32:50 +0400
+Subject: [PATCH] nfs: fix nfs clinet in VE (finally)
+
+Ah! Thanks to our Den we now have an NFS client back!
+
+It turned out, that while going the 2.6.18->2.6.20->...->2.6.26
+NFS changed too much and we didn't test it properly (nobody
+required it badly) in the intermediate states, lost many hunks
+and that's why the patch is *that* big.
+
+Signed-off-by: Denis Lunev <den at openvz.org>
+Signed-off-by: Pavel Emelyanov <xemul at openvz.org>
+---
+ fs/lockd/clntproc.c         |    4 ++
+ fs/lockd/host.c             |   52 +++++++++++++++++++
+ fs/lockd/svc.c              |   54 ++++++++++++++++----
+ fs/lockd/svcsubs.c          |    3 +
+ fs/nfs/client.c             |   11 ++++
+ fs/nfs/super.c              |   70 +++++++++++++++++++++++++-
+ fs/super.c                  |    2 +
+ include/linux/lockd/lockd.h |    8 ++-
+ include/linux/nfs_fs_sb.h   |    1 +
+ include/linux/sunrpc/clnt.h |    2 +
+ include/linux/sunrpc/xprt.h |    9 +++
+ include/linux/ve.h          |   12 ++++
+ include/linux/vzcalluser.h  |    1 +
+ include/net/sock.h          |    7 +++
+ net/socket.c                |    2 +-
+ net/sunrpc/clnt.c           |  117 +++++++++++++++++++++++++++++++++++++++++-
+ net/sunrpc/rpc_pipe.c       |    1 +
+ net/sunrpc/sched.c          |   10 +++-
+ net/sunrpc/sunrpc_syms.c    |    5 ++
+ net/sunrpc/svcsock.c        |   21 ++------
+ net/sunrpc/xprt.c           |    8 +++
+ net/sunrpc/xprtsock.c       |   61 ++++++++++++++++++++--
+ 22 files changed, 417 insertions(+), 44 deletions(-)
+
+diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c
+index 5df517b..d05fcba 100644
+--- a/fs/lockd/clntproc.c
++++ b/fs/lockd/clntproc.c
+@@ -156,12 +156,15 @@ int nlmclnt_proc(struct nlm_host *host, int cmd, struct file_lock *fl)
+ {
+ 	struct nlm_rqst		*call;
+ 	int			status;
++	struct ve_struct *ve;
+ 
+ 	nlm_get_host(host);
+ 	call = nlm_alloc_call(host);
+ 	if (call == NULL)
+ 		return -ENOMEM;
+ 
++	ve = set_exec_env(host->owner_env);
++
+ 	nlmclnt_locks_init_private(fl, host);
+ 	/* Set up the argument struct */
+ 	nlmclnt_setlockargs(call, fl);
+@@ -181,6 +184,7 @@ int nlmclnt_proc(struct nlm_host *host, int cmd, struct file_lock *fl)
+ 	fl->fl_ops = NULL;
+ 
+ 	dprintk("lockd: clnt proc returns %d\n", status);
++	(void)set_exec_env(ve);
+ 	return status;
+ }
+ EXPORT_SYMBOL_GPL(nlmclnt_proc);
+diff --git a/fs/lockd/host.c b/fs/lockd/host.c
+index a17664c..cfa0cf3 100644
+--- a/fs/lockd/host.c
++++ b/fs/lockd/host.c
+@@ -53,6 +53,7 @@ static struct nlm_host *nlm_lookup_host(int server,
+ 	struct nlm_host	*host;
+ 	struct nsm_handle *nsm = NULL;
+ 	int		hash;
++	struct ve_struct *ve;
+ 
+ 	dprintk("lockd: nlm_lookup_host("NIPQUAD_FMT"->"NIPQUAD_FMT
+ 			", p=%d, v=%u, my role=%s, name=%.*s)\n",
+@@ -78,10 +79,14 @@ static struct nlm_host *nlm_lookup_host(int server,
+ 	 * different NLM rpc_clients into one single nlm_host object.
+ 	 * This would allow us to have one nlm_host per address.
+ 	 */
++
++	ve = get_exec_env();
+ 	chain = &nlm_hosts[hash];
+ 	hlist_for_each_entry(host, pos, chain, h_hash) {
+ 		if (!nlm_cmp_addr(&host->h_addr, sin))
+ 			continue;
++		if (!ve_accessible_strict(host->owner_env, ve))
++			continue;
+ 
+ 		/* See if we have an NSM handle for this client */
+ 		if (!nsm)
+@@ -141,6 +146,7 @@ static struct nlm_host *nlm_lookup_host(int server,
+ 	spin_lock_init(&host->h_lock);
+ 	INIT_LIST_HEAD(&host->h_granted);
+ 	INIT_LIST_HEAD(&host->h_reclaim);
++	host->owner_env    = ve;
+ 
+ 	nrhosts++;
+ out:
+@@ -454,6 +460,52 @@ nlm_gc_hosts(void)
+ 	next_gc = jiffies + NLM_HOST_COLLECT;
+ }
+ 
++#ifdef CONFIG_VE
++void ve_nlm_shutdown_hosts(struct ve_struct *ve)
++{
++	envid_t veid = ve->veid;
++	int  i;
++
++	dprintk("lockd: shutting down host module for ve %d\n", veid);
++	mutex_lock(&nlm_host_mutex);
++
++	/* Perform a garbage collection pass */
++	for (i = 0; i < NLM_HOST_NRHASH; i++) {
++		struct nlm_host	*host;
++		struct hlist_node *pos;
++
++		hlist_for_each_entry(host, pos, &nlm_hosts[i], h_hash) {
++			struct rpc_clnt	*clnt;
++
++			if (ve != host->owner_env)
++				continue;
++
++			hlist_del(&host->h_hash);
++			if (host->h_nsmhandle)
++				host->h_nsmhandle->sm_monitored = 0;
++			dprintk("lockd: delete host %s ve %d\n", host->h_name,
++				veid);
++			if ((clnt = host->h_rpcclnt) != NULL) {
++				if (!list_empty(&clnt->cl_tasks)) {
++					struct rpc_xprt *xprt;
++
++					printk(KERN_WARNING
++						"lockd: active RPC handle\n");
++					rpc_killall_tasks(clnt);
++					xprt = clnt->cl_xprt;
++					xprt_disconnect_done(xprt);
++					xprt->ops->close(xprt);
++				} else
++					rpc_shutdown_client(clnt);
++			}
++			kfree(host);
++			nrhosts--;
++		}
++	}
++
++	mutex_unlock(&nlm_host_mutex);
++}
++#endif
+ 
+ /*
+  * Manage NSM handles
+diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
+index 2169af4..f9f02fc 100644
+--- a/fs/lockd/svc.c
++++ b/fs/lockd/svc.c
+@@ -27,6 +27,7 @@
+ #include <linux/mutex.h>
+ #include <linux/kthread.h>
+ #include <linux/freezer.h>
++#include <linux/ve_proto.h>
+ 
+ #include <linux/sunrpc/types.h>
+ #include <linux/sunrpc/stats.h>
+@@ -48,11 +49,13 @@ struct nlmsvc_binding *		nlmsvc_ops;
+ EXPORT_SYMBOL(nlmsvc_ops);
+ 
+ static DEFINE_MUTEX(nlmsvc_mutex);
+-static unsigned int		nlmsvc_users;
+-static struct task_struct	*nlmsvc_task;
+-static struct svc_serv		*nlmsvc_serv;
+-int				nlmsvc_grace_period;
+-unsigned long			nlmsvc_timeout;
++#ifndef CONFIG_VE
++static unsigned int		_nlmsvc_users;
++static struct task_struct	*_nlmsvc_task;
++int				_nlmsvc_grace_period;
++unsigned long			_nlmsvc_timeout;
++static struct svc_serv		*_nlmsvc_serv;
++#endif
+ 
+ /*
+  * These can be set at insmod time (useful for NFS as root filesystem),
+@@ -175,6 +178,10 @@ lockd(void *vrqstp)
+ 		 */
+ 		err = svc_recv(rqstp, timeout);
+ 		if (err == -EAGAIN || err == -EINTR) {
++#ifdef CONFIG_VE
++			if (!get_exec_env()->is_running)
++				break;
++#endif
+ 			preverr = err;
+ 			continue;
+ 		}
+@@ -338,12 +345,12 @@ lockd_down(void)
+ 	} else {
+ 		printk(KERN_ERR "lockd_down: no users! task=%p\n",
+ 			nlmsvc_task);
+-		BUG();
++		goto out;
+ 	}
+ 
+ 	if (!nlmsvc_task) {
+ 		printk(KERN_ERR "lockd_down: no lockd running.\n");
+-		BUG();
++		goto out;
+ 	}
+ 	kthread_stop(nlmsvc_task);
+ out:
+@@ -485,6 +492,29 @@ static int lockd_authenticate(struct svc_rqst *rqstp)
+ 	return SVC_DENIED;
+ }
+ 
++#ifdef CONFIG_VE
++extern void ve_nlm_shutdown_hosts(struct ve_struct *ve);
++
++static int ve_lockd_start(void *data)
++{
++	return 0;
++}
++
++static void ve_lockd_stop(void *data)
++{
++	struct ve_struct *ve = (struct ve_struct *)data;
++
++	ve_nlm_shutdown_hosts(ve);
++	flush_scheduled_work();
++}
++
++static struct ve_hook lockd_hook = {
++	.init	  = ve_lockd_start,
++	.fini	  = ve_lockd_stop,
++	.owner	  = THIS_MODULE,
++	.priority = HOOK_PRIO_FS,
++};
++#endif
+ 
+ param_set_min_max(port, int, simple_strtol, 0, 65535)
+ param_set_min_max(grace_period, unsigned long, simple_strtoul,
+@@ -512,16 +542,20 @@ module_param(nsm_use_hostnames, bool, 0644);
+ 
+ static int __init init_nlm(void)
+ {
++	ve_hook_register(VE_SS_CHAIN, &lockd_hook);
+ #ifdef CONFIG_SYSCTL
+ 	nlm_sysctl_table = register_sysctl_table(nlm_sysctl_root);
+-	return nlm_sysctl_table ? 0 : -ENOMEM;
+-#else
+-	return 0;
++	if (nlm_sysctl_table == NULL) {
++		ve_hook_unregister(&lockd_hook);
++		return -ENOMEM;
++	}
+ #endif
++	return 0;
+ }
+ 
+ static void __exit exit_nlm(void)
+ {
++	ve_hook_unregister(&lockd_hook);
+ 	/* FIXME: delete all NLM clients */
+ 	nlm_shutdown_hosts();
+ #ifdef CONFIG_SYSCTL
+diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c
+index d1c48b5..c226c9d 100644
+--- a/fs/lockd/svcsubs.c
++++ b/fs/lockd/svcsubs.c
+@@ -335,6 +335,9 @@ nlmsvc_is_client(void *data, struct nlm_host *dummy)
+ {
+ 	struct nlm_host *host = data;
+ 
++	if (!ve_accessible_strict(host->owner_env, get_exec_env()))
++		return 0;
++
+ 	if (host->h_server) {
+ 		/* we are destroying locks even though the client
+ 		 * hasn't asked us too, so don't unmonitor the
+diff --git a/fs/nfs/client.c b/fs/nfs/client.c
+index f2a092c..3366257 100644
+--- a/fs/nfs/client.c
++++ b/fs/nfs/client.c
+@@ -127,6 +127,7 @@ static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_
+ 
+ 	atomic_set(&clp->cl_count, 1);
+ 	clp->cl_cons_state = NFS_CS_INITING;
++	clp->owner_env = get_exec_env();
+ 
+ 	memcpy(&clp->cl_addr, cl_init->addr, cl_init->addrlen);
+ 	clp->cl_addrlen = cl_init->addrlen;
+@@ -257,6 +258,7 @@ static int nfs_sockaddr_match_ipaddr(const struct sockaddr *sa1,
+ struct nfs_client *nfs_find_client(const struct sockaddr *addr, u32 nfsversion)
+ {
+ 	struct nfs_client *clp;
++	struct ve_struct *ve = get_exec_env();
+ 
+ 	spin_lock(&nfs_client_lock);
+ 	list_for_each_entry(clp, &nfs_client_list, cl_share_link) {
+@@ -272,6 +274,9 @@ struct nfs_client *nfs_find_client(const struct sockaddr *addr, u32 nfsversion)
+ 
+ 		if (addr->sa_family != clap->sa_family)
+ 			continue;
++		if (!ve_accessible_strict(clp->owner_env, ve))
++			continue;
++
+ 		/* Match only the IP address, not the port number */
+ 		if (!nfs_sockaddr_match_ipaddr(addr, clap))
+ 			continue;
+@@ -292,6 +297,7 @@ struct nfs_client *nfs_find_client_next(struct nfs_client *clp)
+ {
+ 	struct sockaddr *sap = (struct sockaddr *)&clp->cl_addr;
+ 	u32 nfsvers = clp->rpc_ops->version;
++	struct ve_struct *ve = get_exec_env();
+ 
+ 	spin_lock(&nfs_client_lock);
+ 	list_for_each_entry_continue(clp, &nfs_client_list, cl_share_link) {
+@@ -307,6 +313,9 @@ struct nfs_client *nfs_find_client_next(struct nfs_client *clp)
+ 
+ 		if (sap->sa_family != clap->sa_family)
+ 			continue;
++		if (!ve_accessible_strict(clp->owner_env, ve))
++			continue;
++
+ 		/* Match only the IP address, not the port number */
+ 		if (!nfs_sockaddr_match_ipaddr(sap, clap))
+ 			continue;
+@@ -326,7 +335,9 @@ struct nfs_client *nfs_find_client_next(struct nfs_client *clp)
+ static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *data)
+ {
+ 	struct nfs_client *clp;
++	struct ve_struct *ve;
+ 
++	ve = get_exec_env();
+ 	list_for_each_entry(clp, &nfs_client_list, cl_share_link) {
+ 		/* Don't match clients that failed to initialise properly */
+ 		if (clp->cl_cons_state < 0)
+diff --git a/fs/nfs/super.c b/fs/nfs/super.c
+index 614efee..cb4e28a 100644
+--- a/fs/nfs/super.c
++++ b/fs/nfs/super.c
+@@ -50,6 +50,9 @@
+ #include <linux/nfs_xdr.h>
+ #include <linux/magic.h>
+ #include <linux/parser.h>
++#include <linux/ve_proto.h>
++#include <linux/vzcalluser.h>
++#include <linux/ve_nfs.h>
+ 
+ #include <asm/system.h>
+ #include <asm/uaccess.h>
+@@ -213,7 +216,8 @@ static struct file_system_type nfs_fs_type = {
+ 	.name		= "nfs",
+ 	.get_sb		= nfs_get_sb,
+ 	.kill_sb	= nfs_kill_super,
+-	.fs_flags	= FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
++	.fs_flags	= FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|
++			  FS_BINARY_MOUNTDATA|FS_VIRTUALIZED,
+ };
+ 
+ struct file_system_type nfs_xdev_fs_type = {
+@@ -221,7 +225,8 @@ struct file_system_type nfs_xdev_fs_type = {
+ 	.name		= "nfs",
+ 	.get_sb		= nfs_xdev_get_sb,
+ 	.kill_sb	= nfs_kill_super,
+-	.fs_flags	= FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
++	.fs_flags	= FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|
++			  FS_BINARY_MOUNTDATA|FS_VIRTUALIZED,
+ };
+ 
+ static const struct super_operations nfs_sops = {
+@@ -286,6 +291,55 @@ static struct shrinker acl_shrinker = {
+ 	.seeks		= DEFAULT_SEEKS,
+ };
+ 
++#ifdef CONFIG_VE
++static int ve_nfs_start(void *data)
++{
++	return 0;
++}
++
++static void ve_nfs_stop(void *data)
++{
++	struct ve_struct *ve;
++	struct super_block *sb;
++
++	flush_scheduled_work();
++
++	ve = (struct ve_struct *)data;
++	/* Basically, on a valid stop we can be here iff NFS was mounted
++	   read-only. In such a case client force-stop is not a problem.
++	   If we are here and NFS is read-write, we are in a FORCE stop, so
++	   force the client to stop.
++	   Lock daemon is already dead.
++	   Only superblock client remains. Den */
++	spin_lock(&sb_lock);
++	list_for_each_entry(sb, &super_blocks, s_list) {
++		struct rpc_clnt *clnt;
++		struct rpc_xprt *xprt;
++		if (sb->s_type != &nfs_fs_type)
++			continue;
++		clnt = NFS_SB(sb)->client;
++		if (!ve_accessible_strict(clnt->cl_xprt->owner_env, ve))
++			continue;
++		clnt->cl_broken = 1;
++		rpc_killall_tasks(clnt);
++
++		xprt = clnt->cl_xprt;
++		xprt_disconnect_done(xprt);
++		xprt->ops->close(xprt);
++	}
++	spin_unlock(&sb_lock);
++
++	flush_scheduled_work();
++}
++
++static struct ve_hook nfs_hook = {
++	.init	  = ve_nfs_start,
++	.fini	  = ve_nfs_stop,
++	.owner	  = THIS_MODULE,
++	.priority = HOOK_PRIO_NET_POST,
++};
++#endif
++
+ /*
+  * Register the NFS filesystems
+  */
+@@ -306,6 +360,7 @@ int __init register_nfs_fs(void)
+ 		goto error_2;
+ #endif
+ 	register_shrinker(&acl_shrinker);
++	ve_hook_register(VE_SS_CHAIN, &nfs_hook);
+ 	return 0;
+ 
+ #ifdef CONFIG_NFS_V4
+@@ -324,6 +379,7 @@ error_0:
+ void __exit unregister_nfs_fs(void)
+ {
+ 	unregister_shrinker(&acl_shrinker);
++	ve_hook_unregister(&nfs_hook);
+ #ifdef CONFIG_NFS_V4
+ 	unregister_filesystem(&nfs4_fs_type);
+ #endif
+@@ -1591,6 +1647,11 @@ static int nfs_get_sb(struct file_system_type *fs_type,
+ 		.mntflags = flags,
+ 	};
+ 	int error = -ENOMEM;
++	struct ve_struct *ve;
++
++	ve = get_exec_env();
++	if (!ve_is_super(ve) && !(ve->features & VE_FEATURE_NFS))
++		return -ENODEV;
+ 
+ 	data = kzalloc(sizeof(*data), GFP_KERNEL);
+ 	mntfh = kzalloc(sizeof(*mntfh), GFP_KERNEL);
+@@ -1700,6 +1761,11 @@ static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags,
+ 		.mntflags = flags,
+ 	};
+ 	int error;
++	struct ve_struct *ve;
++
++	ve = get_exec_env();
++	if (!ve_is_super(ve) && !(ve->features & VE_FEATURE_NFS))
++		return -ENODEV;
+ 
+ 	dprintk("--> nfs_xdev_get_sb()\n");
+ 
+diff --git a/fs/super.c b/fs/super.c
+index 55ce500..960317f 100644
+--- a/fs/super.c
++++ b/fs/super.c
+@@ -44,7 +44,9 @@
+ 
+ 
+ LIST_HEAD(super_blocks);
++EXPORT_SYMBOL_GPL(super_blocks);
+ DEFINE_SPINLOCK(sb_lock);
++EXPORT_SYMBOL_GPL(sb_lock);
+ 
+ /**
+  *	alloc_super	-	create new superblock
+diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
+index 102d928..7ef434d 100644
+--- a/include/linux/lockd/lockd.h
++++ b/include/linux/lockd/lockd.h
+@@ -61,6 +61,7 @@ struct nlm_host {
+ 	struct list_head	h_granted;	/* Locks in GRANTED state */
+ 	struct list_head	h_reclaim;	/* Locks in RECLAIM state */
+ 	struct nsm_handle *	h_nsmhandle;	/* NSM status handle */
++	struct ve_struct *	owner_env;	/* VE owning the host */
+ };
+ 
+ struct nsm_handle {
+@@ -152,8 +153,11 @@ extern struct svc_procedure	nlmsvc_procedures[];
+ #ifdef CONFIG_LOCKD_V4
+ extern struct svc_procedure	nlmsvc_procedures4[];
+ #endif
+-extern int			nlmsvc_grace_period;
+-extern unsigned long		nlmsvc_timeout;
++
++#include <linux/ve_nfs.h>
++extern int			_nlmsvc_grace_period;
++extern unsigned long		_nlmsvc_timeout;
++
+ extern int			nsm_use_hostnames;
+ 
+ /*
+diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
+index c9beacd..cb87ca2 100644
+--- a/include/linux/nfs_fs_sb.h
++++ b/include/linux/nfs_fs_sb.h
+@@ -70,6 +70,7 @@ struct nfs_client {
+ 	char			cl_ipaddr[48];
+ 	unsigned char		cl_id_uniquifier;
+ #endif
++	struct ve_struct	*owner_env;
+ };
+ 
+ /*
+diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
+index 6fff7f8..7b4d4cf 100644
+--- a/include/linux/sunrpc/clnt.h
++++ b/include/linux/sunrpc/clnt.h
+@@ -43,6 +43,7 @@ struct rpc_clnt {
+ 	unsigned int		cl_softrtry : 1,/* soft timeouts */
+ 				cl_discrtry : 1,/* disconnect before retry */
+ 				cl_autobind : 1;/* use getport() */
++	unsigned int		cl_broken   : 1;/* no responce for too long */
+ 
+ 	struct rpc_rtt *	cl_rtt;		/* RTO estimator data */
+ 	const struct rpc_timeout *cl_timeout;	/* Timeout strategy */
+@@ -56,6 +57,7 @@ struct rpc_clnt {
+ 	struct rpc_rtt		cl_rtt_default;
+ 	struct rpc_timeout	cl_timeout_default;
+ 	struct rpc_program *	cl_program;
++	unsigned long		cl_pr_time;
+ 	char			cl_inline_name[32];
+ };
+ 
+diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
+index 4d80a11..ceee9a3 100644
+--- a/include/linux/sunrpc/xprt.h
++++ b/include/linux/sunrpc/xprt.h
+@@ -24,6 +24,14 @@
+ #define RPC_MAX_SLOT_TABLE	(128U)
+ 
+ /*
++ * Grand abort timeout (stop the client if occures)
++ */
++extern int xprt_abort_timeout;
++
++#define RPC_MIN_ABORT_TIMEOUT	300
++#define RPC_MAX_ABORT_TIMEOUT	INT_MAX
++
++/*
+  * This describes a timeout strategy
+  */
+ struct rpc_timeout {
+@@ -123,6 +131,7 @@ struct rpc_xprt_ops {
+ struct rpc_xprt {
+ 	struct kref		kref;		/* Reference count */
+ 	struct rpc_xprt_ops *	ops;		/* transport methods */
++	struct ve_struct *	owner_env;	/* VE owner of mount */
+ 
+ 	const struct rpc_timeout *timeout;	/* timeout parms */
+ 	struct sockaddr_storage	addr;		/* server address */
+diff --git a/include/linux/ve.h b/include/linux/ve.h
+index 7025716..970aadc 100644
+--- a/include/linux/ve.h
++++ b/include/linux/ve.h
+@@ -139,6 +139,7 @@ struct ve_cpu_stats {
+ 
+ struct ve_ipt_recent;
+ struct ve_xt_hashlimit;
++struct svc_serv;
+ 
+ struct cgroup;
+ struct css_set;
+@@ -183,6 +184,8 @@ struct ve_struct {
+ 	struct devpts_config	*devpts_config;
+ #endif
+ 
++	struct ve_nfs_context	*nfs_context;
++
+ 	struct file_system_type *shmem_fstype;
+ 	struct vfsmount		*shmem_mnt;
+ #ifdef CONFIG_SYSFS
+@@ -274,6 +277,15 @@ struct ve_struct {
+ 	struct proc_dir_entry	*monitor_proc;
+ 	unsigned long		meminfo_val;
+ 
++#if defined(CONFIG_NFS_FS) || defined(CONFIG_NFS_FS_MODULE) \
++	|| defined(CONFIG_NFSD) || defined(CONFIG_NFSD_MODULE)
++	unsigned int		_nlmsvc_users;
++	struct task_struct*	_nlmsvc_task;
++	int			_nlmsvc_grace_period;
++	unsigned long		_nlmsvc_timeout;
++	struct svc_serv*	_nlmsvc_serv;
++#endif
++
+ 	struct nsproxy		*ve_ns;
+ 	struct net		*ve_netns;
+ 	struct cgroup		*ve_cgroup;
+diff --git a/include/linux/vzcalluser.h b/include/linux/vzcalluser.h
+index 9736479..a62b84c 100644
+--- a/include/linux/vzcalluser.h
++++ b/include/linux/vzcalluser.h
+@@ -102,6 +102,7 @@ struct env_create_param3 {
+ };
+ 
+ #define VE_FEATURE_SYSFS	(1ULL << 0)
++#define VE_FEATURE_NFS		(1ULL << 1)
+ #define VE_FEATURE_DEF_PERMS	(1ULL << 2)
+ 
+ #define VE_FEATURES_OLD		(VE_FEATURE_SYSFS)
+diff --git a/include/net/sock.h b/include/net/sock.h
+index 873caf6..718e410 100644
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -1334,6 +1334,13 @@ static inline void sk_change_net(struct sock *sk, struct net *net)
+ 	sock_net_set(sk, hold_net(net));
+ }
+ 
++static inline void sk_change_net_get(struct sock *sk, struct net *net)
++{
++	struct net *old_net = sock_net(sk);
++	sock_net_set(sk, get_net(net));
++	put_net(old_net);
++}
++
+ extern void sock_enable_timestamp(struct sock *sk);
+ extern int sock_get_timestamp(struct sock *, struct timeval __user *);
+ extern int sock_get_timestampns(struct sock *, struct timespec __user *);
+diff --git a/net/socket.c b/net/socket.c
+index 09d8fc5..799f3c9 100644
+--- a/net/socket.c
++++ b/net/socket.c
+@@ -2363,7 +2363,7 @@ int kernel_sock_ioctl(struct socket *sock, int cmd, unsigned long arg)
+ 	struct ve_struct *old_env;
+ 
+ 	set_fs(KERNEL_DS);
+-	old_env = set_exec_env(get_ve0());
++	old_env = set_exec_env(sock->sk->owner_env);
+ 	err = sock->ops->ioctl(sock, cmd, arg);
+ 	(void)set_exec_env(old_env);
+ 	set_fs(oldfs);
+diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
+index 8945307..f303e1d 100644
+--- a/net/sunrpc/clnt.c
++++ b/net/sunrpc/clnt.c
+@@ -31,6 +31,7 @@
+ #include <linux/utsname.h>
+ #include <linux/workqueue.h>
+ #include <linux/in6.h>
++#include <linux/ve_proto.h>
+ 
+ #include <linux/sunrpc/clnt.h>
+ #include <linux/sunrpc/rpc_pipe_fs.h>
+@@ -89,6 +90,35 @@ static void rpc_unregister_client(struct rpc_clnt *clnt)
+ 	spin_unlock(&rpc_client_lock);
+ }
+ 
++/*
++ * Grand abort timeout (stop the client if occures)
++ */
++int xprt_abort_timeout = RPC_MAX_ABORT_TIMEOUT;
++
++static int rpc_abort_hard(struct rpc_task *task)
++{
++	struct rpc_clnt *clnt;
++	clnt = task->tk_client;
++
++	if (clnt->cl_pr_time == 0) {
++		clnt->cl_pr_time = jiffies;
++		return 0;
++	}
++	if (xprt_abort_timeout == RPC_MAX_ABORT_TIMEOUT)
++		return 0;
++	if (time_before(jiffies, clnt->cl_pr_time + xprt_abort_timeout * HZ))
++		return 0;
++
++	clnt->cl_broken = 1;
++	rpc_killall_tasks(clnt);
++	return -ETIMEDOUT;
++}
++
++static void rpc_abort_clear(struct rpc_task *task)
++{
++	task->tk_client->cl_pr_time = 0;
++}
++
+ static int
+ rpc_setup_pipedir(struct rpc_clnt *clnt, char *dir_name)
+ {
+@@ -178,6 +208,7 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, stru
+ 	clnt->cl_vers     = version->number;
+ 	clnt->cl_stats    = program->stats;
+ 	clnt->cl_metrics  = rpc_alloc_iostats(clnt);
++	clnt->cl_broken = 0;
+ 	err = -ENOMEM;
+ 	if (clnt->cl_metrics == NULL)
+ 		goto out_no_stats;
+@@ -293,6 +324,7 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args)
+ 	xprt = xprt_create_transport(&xprtargs);
+ 	if (IS_ERR(xprt))
+ 		return (struct rpc_clnt *)xprt;
++	xprt->owner_env = get_ve(get_exec_env());
+ 
+ 	/*
+ 	 * By default, kernel RPC client connects from a reserved port.
+@@ -305,13 +337,16 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args)
+ 		xprt->resvport = 0;
+ 
+ 	clnt = rpc_new_client(args, xprt);
+-	if (IS_ERR(clnt))
++	if (IS_ERR(clnt)) {
++		put_ve(xprt->owner_env);
+ 		return clnt;
++	}
+ 
+ 	if (!(args->flags & RPC_CLNT_CREATE_NOPING)) {
+ 		int err = rpc_ping(clnt, RPC_TASK_SOFT);
+ 		if (err != 0) {
+ 			rpc_shutdown_client(clnt);
++			put_ve(xprt->owner_env);
+ 			return ERR_PTR(err);
+ 		}
+ 	}
+@@ -517,6 +552,9 @@ struct rpc_task *rpc_run_task(const struct rpc_task_setup *task_setup_data)
+ {
+ 	struct rpc_task *task, *ret;
+ 
++	if (task_setup_data->rpc_client->cl_broken)
++		return ERR_PTR(-EIO);
++
+ 	task = rpc_new_task(task_setup_data);
+ 	if (task == NULL) {
+ 		rpc_release_calldata(task_setup_data->callback_ops,
+@@ -923,6 +961,7 @@ call_bind_status(struct rpc_task *task)
+ 
+ 	if (task->tk_status >= 0) {
+ 		dprint_status(task);
++		rpc_abort_clear(task);
+ 		task->tk_status = 0;
+ 		task->tk_action = call_connect;
+ 		return;
+@@ -948,6 +987,10 @@ call_bind_status(struct rpc_task *task)
+ 	case -ETIMEDOUT:
+ 		dprintk("RPC: %5u rpcbind request timed out\n",
+ 				task->tk_pid);
++		if (rpc_abort_hard(task)) {
++			status = -EIO;
++			break;
++		}
+ 		goto retry_timeout;
+ 	case -EPFNOSUPPORT:
+ 		/* server doesn't support any rpcbind version we know of */
+@@ -1013,6 +1056,8 @@ call_connect_status(struct rpc_task *task)
+ 
+ 	/* Something failed: remote service port may have changed */
+ 	rpc_force_rebind(clnt);
++	if (rpc_abort_hard(task))
++		goto exit;
+ 
+ 	switch (status) {
+ 	case -ENOTCONN:
+@@ -1025,6 +1070,7 @@ call_connect_status(struct rpc_task *task)
+ 		task->tk_action = call_timeout;
+ 		return;
+ 	}
++exit:
+ 	rpc_exit(task, -EIO);
+ }
+ 
+@@ -1156,7 +1202,7 @@ call_timeout(struct rpc_task *task)
+ 	dprintk("RPC: %5u call_timeout (major)\n", task->tk_pid);
+ 	task->tk_timeouts++;
+ 
+-	if (RPC_IS_SOFT(task)) {
++	if (RPC_IS_SOFT(task) || rpc_abort_hard(task)) {
+ 		printk(KERN_NOTICE "%s: server %s not responding, timed out\n",
+ 				clnt->cl_protname, clnt->cl_server);
+ 		rpc_exit(task, -EIO);
+@@ -1201,6 +1247,7 @@ call_decode(struct rpc_task *task)
+ 		task->tk_flags &= ~RPC_CALL_MAJORSEEN;
+ 	}
+ 
++	rpc_abort_clear(task);
+ 	/*
+ 	 * Ensure that we see all writes made by xprt_complete_rqst()
+ 	 * before it changed req->rq_received.
+@@ -1213,7 +1260,7 @@ call_decode(struct rpc_task *task)
+ 				sizeof(req->rq_rcv_buf)) != 0);
+ 
+ 	if (req->rq_rcv_buf.len < 12) {
+-		if (!RPC_IS_SOFT(task)) {
++		if (!RPC_IS_SOFT(task) && !rpc_abort_hard(task)) {
+ 			task->tk_action = call_bind;
+ 			clnt->cl_stats->rpcretrans++;
+ 			goto out_retry;
+@@ -1558,3 +1605,67 @@ out:
+ 	spin_unlock(&rpc_client_lock);
+ }
+ #endif
++
++#ifdef CONFIG_VE
++static int ve_sunrpc_start(void *data)
++{
++	return 0;
++}
++
++void ve_sunrpc_stop(void *data)
++{
++	struct ve_struct *ve = (struct ve_struct *)data;
++	struct rpc_clnt *clnt;
++	struct rpc_task	*rovr;
++
++	dprintk("RPC:       killing all tasks for VE %d\n", ve->veid);
++
++	spin_lock(&rpc_client_lock);
++	list_for_each_entry(clnt, &all_clients, cl_clients) {
++		if (clnt->cl_xprt->owner_env != ve)
++			continue;
++
++		spin_lock(&clnt->cl_lock);
++		list_for_each_entry(rovr, &clnt->cl_tasks, tk_task) {
++			if (!RPC_IS_ACTIVATED(rovr))
++				continue;
++			printk(KERN_WARNING "RPC: Killing task %d client %p\n",
++			       rovr->tk_pid, clnt);
++
++			rovr->tk_flags |= RPC_TASK_KILLED;
++			rpc_exit(rovr, -EIO);
++			rpc_wake_up_queued_task(rovr->tk_waitqueue, rovr);
++		}
++		schedule_work(&clnt->cl_xprt->task_cleanup);
++		spin_unlock(&clnt->cl_lock);
++	}
++	spin_unlock(&rpc_client_lock);
++
++	flush_scheduled_work();
++}
++
++static struct ve_hook sunrpc_hook = {
++	.init	  = ve_sunrpc_start,
++	.fini	  = ve_sunrpc_stop,
++	.owner	  = THIS_MODULE,
++	.priority = HOOK_PRIO_NET_PRE,
++};
++
++void ve_sunrpc_hook_register(void)
++{
++	ve_hook_register(VE_SS_CHAIN, &sunrpc_hook);
++}
++
++void ve_sunrpc_hook_unregister(void)
++{
++	ve_hook_unregister(&sunrpc_hook);
++}
++#else
++void ve_sunrpc_hook_register(void)
++{
++}
++
++void ve_sunrpc_hook_unregister(void)
++{
++}
++#endif
+diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
+index 5a9b0e7..ab6bf80 100644
+--- a/net/sunrpc/rpc_pipe.c
++++ b/net/sunrpc/rpc_pipe.c
+@@ -894,6 +894,7 @@ static struct file_system_type rpc_pipe_fs_type = {
+ 	.name		= "rpc_pipefs",
+ 	.get_sb		= rpc_get_sb,
+ 	.kill_sb	= kill_litter_super,
++	.fs_flags	= FS_VIRTUALIZED,	
+ };
+ 
+ static void
+diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
+index 4fba93a..265296d 100644
+--- a/net/sunrpc/sched.c
++++ b/net/sunrpc/sched.c
+@@ -617,7 +617,7 @@ static void __rpc_execute(struct rpc_task *task)
+ 	int		status = 0;
+ 	struct ve_struct *env;
+ 
+-	env = set_exec_env(get_ve0());
++	env = set_exec_env(task->tk_client->cl_xprt->owner_env);
+ 	dprintk("RPC: %5u __rpc_execute flags=0x%x\n",
+ 			task->tk_pid, task->tk_flags);
+ 
+@@ -663,10 +663,14 @@ static void __rpc_execute(struct rpc_task *task)
+ 		rpc_clear_running(task);
+ 		if (RPC_IS_ASYNC(task)) {
+ 			/* Careful! we may have raced... */
+-			if (RPC_IS_QUEUED(task))
++			if (RPC_IS_QUEUED(task)) {
++				(void)set_exec_env(env);
+ 				return;
+-			if (rpc_test_and_set_running(task))
++			}
++			if (rpc_test_and_set_running(task)) {
++				(void)set_exec_env(env);
+ 				return;
++			}
+ 			continue;
+ 		}
+ 
+diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
+index 843629f..94c3fb0 100644
+--- a/net/sunrpc/sunrpc_syms.c
++++ b/net/sunrpc/sunrpc_syms.c
+@@ -24,6 +24,9 @@
+ 
+ extern struct cache_detail ip_map_cache, unix_gid_cache;
+ 
++extern void ve_sunrpc_hook_register(void);
++extern void ve_sunrpc_hook_unregister(void);
++
+ static int __init
+ init_sunrpc(void)
+ {
+@@ -46,6 +49,7 @@ init_sunrpc(void)
+ 	svc_init_xprt_sock();	/* svc sock transport */
+ 	init_socket_xprt();	/* clnt sock transport */
+ 	rpcauth_init_module();
++	ve_sunrpc_hook_register();
+ out:
+ 	return err;
+ }
+@@ -53,6 +57,7 @@ out:
+ static void __exit
+ cleanup_sunrpc(void)
+ {
++	ve_sunrpc_hook_unregister();
+ 	rpcauth_remove_module();
+ 	cleanup_socket_xprt();
+ 	svc_cleanup_xprt_sock();
+diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
+index 029c673..0d49dfc 100644
+--- a/net/sunrpc/svcsock.c
++++ b/net/sunrpc/svcsock.c
+@@ -180,7 +180,7 @@ static int svc_sendto(struct svc_rqst *rqstp, struct xdr_buf *xdr)
+ 	RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]);
+ 	struct ve_struct *old_env;
+ 
+-	old_env = set_exec_env(get_ve0());
++	old_env = set_exec_env(sock->sk->owner_env);
+ 
+ 	slen = xdr->len;
+ 
+@@ -321,14 +321,11 @@ static int svc_recvfrom(struct svc_rqst *rqstp, struct kvec *iov, int nr,
+ 		.msg_flags	= MSG_DONTWAIT,
+ 	};
+ 	int len;
+-	struct ve_struct *old_env;
+ 
+ 	rqstp->rq_xprt_hlen = 0;
+ 
+-	old_env = set_exec_env(get_ve0());
+ 	len = kernel_recvmsg(svsk->sk_sock, &msg, iov, nr, buflen,
+ 				msg.msg_flags);
+-	(void)set_exec_env(get_ve0());
+ 
+ 	dprintk("svc: socket %p recvfrom(%p, %Zu) = %d\n",
+ 		svsk, iov[0].iov_base, iov[0].iov_len, len);
+@@ -727,13 +724,11 @@ static struct svc_xprt *svc_tcp_accept(struct svc_xprt *xprt)
+ 	struct svc_sock	*newsvsk;
+ 	int		err, slen;
+ 	RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]);
+-	struct ve_struct *old_env;
+ 
+ 	dprintk("svc: tcp_accept %p sock %p\n", svsk, sock);
+ 	if (!sock)
+ 		return NULL;
+ 
+-	old_env = set_exec_env(get_ve0());
+ 	clear_bit(XPT_CONN, &svsk->sk_xprt.xpt_flags);
+ 	err = kernel_accept(sock, &newsock, O_NONBLOCK);
+ 	if (err < 0) {
+@@ -743,7 +738,7 @@ static struct svc_xprt *svc_tcp_accept(struct svc_xprt *xprt)
+ 		else if (err != -EAGAIN && net_ratelimit())
+ 			printk(KERN_WARNING "%s: accept failed (err %d)!\n",
+ 				   serv->sv_name, -err);
+-		goto restore;
++		return NULL;
+ 	}
+ 	set_bit(XPT_CONN, &svsk->sk_xprt.xpt_flags);
+ 
+@@ -784,8 +779,6 @@ static struct svc_xprt *svc_tcp_accept(struct svc_xprt *xprt)
+ 	}
+ 	svc_xprt_set_local(&newsvsk->sk_xprt, sin, slen);
+ 
+-	(void)set_exec_env(old_env);
+-
+ 	if (serv->sv_stats)
+ 		serv->sv_stats->nettcpconn++;
+ 
+@@ -793,8 +786,6 @@ static struct svc_xprt *svc_tcp_accept(struct svc_xprt *xprt)
+ 
+ failed:
+ 	sock_release(newsock);
+-restore:
+-	(void)set_exec_env(old_env);
+ 	return NULL;
+ }
+ 
+@@ -1225,7 +1216,6 @@ static struct svc_xprt *svc_create_socket(struct svc_serv *serv,
+ 	struct sockaddr *newsin = (struct sockaddr *)&addr;
+ 	int		newlen;
+ 	RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]);
+-	struct ve_struct *old_env;
+ 
+ 	dprintk("svc: svc_create_socket(%s, %d, %s)\n",
+ 			serv->sv_program->pg_name, protocol,
+@@ -1238,11 +1228,11 @@ static struct svc_xprt *svc_create_socket(struct svc_serv *serv,
+ 	}
+ 	type = (protocol == IPPROTO_UDP)? SOCK_DGRAM : SOCK_STREAM;
+ 
+-	old_env = set_exec_env(get_ve0());
+ 	error = sock_create_kern(sin->sa_family, type, protocol, &sock);
+ 	if (error < 0)
+-		goto restore;
++		return ERR_PTR(-ENOMEM);
+ 
++	sk_change_net_get(sock->sk, get_exec_env()->ve_netns);
+ 	svc_reclassify_socket(sock);
+ 
+ 	if (type == SOCK_STREAM)
+@@ -1263,15 +1253,12 @@ static struct svc_xprt *svc_create_socket(struct svc_serv *serv,
+ 
+ 	if ((svsk = svc_setup_socket(serv, sock, &error, flags)) != NULL) {
+ 		svc_xprt_set_local(&svsk->sk_xprt, newsin, newlen);
+-		(void)set_exec_env(old_env);
+ 		return (struct svc_xprt *)svsk;
+ 	}
+ 
+ bummer:
+ 	dprintk("svc: svc_create_socket error = %d\n", -error);
+ 	sock_release(sock);
+-restore:
+-	(void)set_exec_env(old_env);
+ 	return ERR_PTR(error);
+ }
+ 
+diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
+index e1770f7..831ad1b 100644
+--- a/net/sunrpc/xprt.c
++++ b/net/sunrpc/xprt.c
+@@ -568,10 +568,13 @@ static void xprt_autoclose(struct work_struct *work)
+ {
+ 	struct rpc_xprt *xprt =
+ 		container_of(work, struct rpc_xprt, task_cleanup);
++	struct ve_struct *ve;
+ 
++	ve = set_exec_env(xprt->owner_env);
+ 	xprt->ops->close(xprt);
+ 	clear_bit(XPRT_CLOSE_WAIT, &xprt->state);
+ 	xprt_release_write(xprt, NULL);
++	(void)set_exec_env(ve);
+ }
+ 
+ /**
+@@ -638,7 +641,9 @@ static void
+ xprt_init_autodisconnect(unsigned long data)
+ {
+ 	struct rpc_xprt *xprt = (struct rpc_xprt *)data;
++	struct ve_struct *ve;
+ 
++	ve = set_exec_env(xprt->owner_env);
+ 	spin_lock(&xprt->transport_lock);
+ 	if (!list_empty(&xprt->recv) || xprt->shutdown)
+ 		goto out_abort;
+@@ -649,9 +654,11 @@ xprt_init_autodisconnect(unsigned long data)
+ 		xprt_release_write(xprt, NULL);
+ 	else
+ 		queue_work(rpciod_workqueue, &xprt->task_cleanup);
++	(void)set_exec_env(ve);
+ 	return;
+ out_abort:
+ 	spin_unlock(&xprt->transport_lock);
++	(void)set_exec_env(ve);
+ }
+ 
+ /**
+@@ -1049,6 +1056,7 @@ found:
+ 	xprt->last_used = jiffies;
+ 	xprt->cwnd = RPC_INITCWND;
+ 	xprt->bind_index = 0;
++	xprt->owner_env = get_exec_env();
+ 
+ 	rpc_init_wait_queue(&xprt->binding, "xprt_binding");
+ 	rpc_init_wait_queue(&xprt->pending, "xprt_pending");
+diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
+index ddbe981..7ade3e3 100644
+--- a/net/sunrpc/xprtsock.c
++++ b/net/sunrpc/xprtsock.c
+@@ -64,6 +64,8 @@ static unsigned int min_slot_table_size = RPC_MIN_SLOT_TABLE;
+ static unsigned int max_slot_table_size = RPC_MAX_SLOT_TABLE;
+ static unsigned int xprt_min_resvport_limit = RPC_MIN_RESVPORT;
+ static unsigned int xprt_max_resvport_limit = RPC_MAX_RESVPORT;
++static int xprt_min_abort_timeout = RPC_MIN_ABORT_TIMEOUT;
++static int xprt_max_abort_timeout = RPC_MAX_ABORT_TIMEOUT;
+ 
+ static struct ctl_table_header *sunrpc_table_header;
+ 
+@@ -117,6 +119,16 @@ static ctl_table xs_tunables_table[] = {
+ 		.extra2		= &xprt_max_resvport_limit
+ 	},
+ 	{
++		.procname	= "abort_timeout",
++		.data		= &xprt_abort_timeout,
++		.maxlen		= sizeof(unsigned int),
++		.mode		= 0644,
++		.proc_handler	= &proc_dointvec_minmax,
++		.strategy	= &sysctl_intvec,
++		.extra1		= &xprt_min_abort_timeout,
++		.extra2		= &xprt_max_abort_timeout
++	},
++	{
+ 		.ctl_name = 0,
+ 	},
+ };
+@@ -754,18 +766,23 @@ out_release:
+ static void xs_close(struct rpc_xprt *xprt)
+ {
+ 	struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
+-	struct socket *sock = transport->sock;
+-	struct sock *sk = transport->inet;
+-
+-	if (!sk)
+-		goto clear_close_wait;
++	struct socket *sock;
++	struct sock *sk;
+ 
+ 	dprintk("RPC:       xs_close xprt %p\n", xprt);
+ 
+-	write_lock_bh(&sk->sk_callback_lock);
++	spin_lock_bh(&xprt->transport_lock);
++	if (transport->sock == NULL) {
++		spin_unlock_bh(&xprt->transport_lock);
++		goto clear_close_wait;
++	}
++	sock = transport->sock;
++	sk = transport->inet;
+ 	transport->inet = NULL;
+ 	transport->sock = NULL;
++	spin_unlock_bh(&xprt->transport_lock);
+ 
++	write_lock_bh(&sk->sk_callback_lock);
+ 	sk->sk_user_data = NULL;
+ 	sk->sk_data_ready = transport->old_data_ready;
+ 	sk->sk_state_change = transport->old_state_change;
+@@ -1489,7 +1506,12 @@ static void xs_udp_connect_worker4(struct work_struct *work)
+ 	struct rpc_xprt *xprt = &transport->xprt;
+ 	struct socket *sock = transport->sock;
+ 	int err, status = -EIO;
++	struct ve_struct *ve;
+ 
++	ve = set_exec_env(xprt->owner_env);
++	down_read(&xprt->owner_env->op_sem);
++	if (!xprt->owner_env->is_running)
++		goto out;
+ 	if (xprt->shutdown || !xprt_bound(xprt))
+ 		goto out;
+ 
+@@ -1500,6 +1522,7 @@ static void xs_udp_connect_worker4(struct work_struct *work)
+ 		dprintk("RPC:       can't create UDP transport socket (%d).\n", -err);
+ 		goto out;
+ 	}
++	sk_change_net_get(sock->sk, xprt->owner_env->ve_netns);
+ 	xs_reclassify_socket4(sock);
+ 
+ 	if (xs_bind4(transport, sock)) {
+@@ -1515,6 +1538,8 @@ static void xs_udp_connect_worker4(struct work_struct *work)
+ out:
+ 	xprt_wake_pending_tasks(xprt, status);
+ 	xprt_clear_connecting(xprt);
++	up_read(&xprt->owner_env->op_sem);
++	(void)set_exec_env(ve);
+ }
+ 
+ /**
+@@ -1530,7 +1555,12 @@ static void xs_udp_connect_worker6(struct work_struct *work)
+ 	struct rpc_xprt *xprt = &transport->xprt;
+ 	struct socket *sock = transport->sock;
+ 	int err, status = -EIO;
++	struct ve_struct *ve;
+ 
++	ve = set_exec_env(xprt->owner_env);
++	down_read(&xprt->owner_env->op_sem);
++	if (!xprt->owner_env->is_running)
++		goto out;
+ 	if (xprt->shutdown || !xprt_bound(xprt))
+ 		goto out;
+ 
+@@ -1541,6 +1571,7 @@ static void xs_udp_connect_worker6(struct work_struct *work)
+ 		dprintk("RPC:       can't create UDP transport socket (%d).\n", -err);
+ 		goto out;
+ 	}
++	sk_change_net_get(sock->sk, xprt->owner_env->ve_netns);
+ 	xs_reclassify_socket6(sock);
+ 
+ 	if (xs_bind6(transport, sock) < 0) {
+@@ -1556,6 +1587,8 @@ static void xs_udp_connect_worker6(struct work_struct *work)
+ out:
+ 	xprt_wake_pending_tasks(xprt, status);
+ 	xprt_clear_connecting(xprt);
++	up_read(&xprt->owner_env->op_sem);
++	(void)set_exec_env(ve);
+ }
+ 
+ /*
+@@ -1634,7 +1667,12 @@ static void xs_tcp_connect_worker4(struct work_struct *work)
+ 	struct rpc_xprt *xprt = &transport->xprt;
+ 	struct socket *sock = transport->sock;
+ 	int err, status = -EIO;
++	struct ve_struct *ve;
+ 
++	ve = set_exec_env(xprt->owner_env);
++	down_read(&xprt->owner_env->op_sem);
++	if (!xprt->owner_env->is_running)
++		goto out;
+ 	if (xprt->shutdown || !xprt_bound(xprt))
+ 		goto out;
+ 
+@@ -1644,6 +1682,7 @@ static void xs_tcp_connect_worker4(struct work_struct *work)
+ 			dprintk("RPC:       can't create TCP transport socket (%d).\n", -err);
+ 			goto out;
+ 		}
++		sk_change_net_get(sock->sk, xprt->owner_env->ve_netns);
+ 		xs_reclassify_socket4(sock);
+ 
+ 		if (xs_bind4(transport, sock) < 0) {
+@@ -1679,6 +1718,8 @@ out:
+ 	xprt_wake_pending_tasks(xprt, status);
+ out_clear:
+ 	xprt_clear_connecting(xprt);
++	up_read(&xprt->owner_env->op_sem);
++	(void)set_exec_env(ve);
+ }
+ 
+ /**
+@@ -1694,7 +1735,12 @@ static void xs_tcp_connect_worker6(struct work_struct *work)
+ 	struct rpc_xprt *xprt = &transport->xprt;
+ 	struct socket *sock = transport->sock;
+ 	int err, status = -EIO;
++	struct ve_struct *ve;
+ 
++	ve = set_exec_env(xprt->owner_env);
++	down_read(&xprt->owner_env->op_sem);
++	if (!xprt->owner_env->is_running)
++		goto out;
+ 	if (xprt->shutdown || !xprt_bound(xprt))
+ 		goto out;
+ 
+@@ -1704,6 +1750,7 @@ static void xs_tcp_connect_worker6(struct work_struct *work)
+ 			dprintk("RPC:       can't create TCP transport socket (%d).\n", -err);
+ 			goto out;
+ 		}
++		sk_change_net_get(sock->sk, xprt->owner_env->ve_netns);
+ 		xs_reclassify_socket6(sock);
+ 
+ 		if (xs_bind6(transport, sock) < 0) {
+@@ -1738,6 +1785,8 @@ out:
+ 	xprt_wake_pending_tasks(xprt, status);
+ out_clear:
+ 	xprt_clear_connecting(xprt);
++	up_read(&xprt->owner_env->op_sem);
++	(void)set_exec_env(ve);
+ }
+ 
+ /**
+-- 
+1.6.0.6
+

Added: dists/lenny/linux-2.6/debian/patches/features/all/openvz/0017-cpt-bump-image-version-to-VERSION_26.patch
==============================================================================
--- (empty file)
+++ dists/lenny/linux-2.6/debian/patches/features/all/openvz/0017-cpt-bump-image-version-to-VERSION_26.patch	Sun Mar 22 21:12:49 2009
@@ -0,0 +1,42 @@
+From 4fc3a18ab7c46e4bc375fa3ce59b7fb1b173f35b Mon Sep 17 00:00:00 2001
+From: Pavel Emelyanov <xemul at openvz.org>
+Date: Tue, 9 Sep 2008 19:25:00 +0400
+Subject: [PATCH] cpt: bump image version to VERSION_26
+
+Images from older kernels will most likely not get restored...
+
+Signed-off-by: Pavel Emelyanov <xemul at openvz.org>
+---
+ kernel/cpt/cpt_context.c |    2 +-
+ kernel/cpt/rst_context.c |    2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/kernel/cpt/cpt_context.c b/kernel/cpt/cpt_context.c
+index 58a8069..e3f3f9f 100644
+--- a/kernel/cpt/cpt_context.c
++++ b/kernel/cpt/cpt_context.c
+@@ -122,7 +122,7 @@ int cpt_major_hdr_out(struct cpt_context *ctx)
+ 	hdr.cpt_signature[2] = CPT_SIGNATURE2;
+ 	hdr.cpt_signature[3] = CPT_SIGNATURE3;
+ 	hdr.cpt_hdrlen = sizeof(hdr);
+-	hdr.cpt_image_version = CPT_VERSION_20;
++	hdr.cpt_image_version = CPT_VERSION_26;
+ #ifdef CONFIG_X86_64
+ 	hdr.cpt_os_arch = CPT_OS_ARCH_EMT64;
+ #elif defined(CONFIG_X86_32)
+diff --git a/kernel/cpt/rst_context.c b/kernel/cpt/rst_context.c
+index 47e4f35..cc381fe 100644
+--- a/kernel/cpt/rst_context.c
++++ b/kernel/cpt/rst_context.c
+@@ -178,7 +178,7 @@ int rst_open_dumpfile(struct cpt_context *ctx)
+ 	ctx->start_time.tv_nsec = h.cpt_start_nsec;
+ 	ctx->kernel_config_flags = h.cpt_kernel_config[0];
+ 	ctx->iptables_mask = h.cpt_iptables_mask;
+-	if (h.cpt_image_version > CPT_VERSION_20 ||
++	if (h.cpt_image_version > CPT_VERSION_26 ||
+ 			CPT_VERSION_MINOR(h.cpt_image_version) > 1) {
+ 		eprintk_ctx("Unknown image version: %x. Can't restore.\n",
+ 				h.cpt_image_version);
+-- 
+1.6.0.6
+

Added: dists/lenny/linux-2.6/debian/patches/features/all/openvz/0018-nfs-add-missed-ve_nfs.h-file.patch
==============================================================================
--- (empty file)
+++ dists/lenny/linux-2.6/debian/patches/features/all/openvz/0018-nfs-add-missed-ve_nfs.h-file.patch	Sun Mar 22 21:12:49 2009
@@ -0,0 +1,53 @@
+From 2a083801fe1655bf9e403469c494b83a72186f56 Mon Sep 17 00:00:00 2001
+From: Denis Lunev <den at openvz.org>
+Date: Wed, 10 Sep 2008 12:02:33 +0400
+Subject: [PATCH] nfs: add missed ve_nfs.h file
+
+Lost when committing 66ec7f7f493fb98e8baa6591e9225086ae640fb8
+
+Signed-off-by: Denis Lunev <den at openvz.org>
+Signed-off-by: Pavel Emelyanov <xemul at openvz.org>
+---
+ include/linux/ve_nfs.h |   30 ++++++++++++++++++++++++++++++
+ 1 files changed, 30 insertions(+), 0 deletions(-)
+ create mode 100644 include/linux/ve_nfs.h
+
+diff --git a/include/linux/ve_nfs.h b/include/linux/ve_nfs.h
+new file mode 100644
+index 0000000..4ed5105
+--- /dev/null
++++ b/include/linux/ve_nfs.h
+@@ -0,0 +1,30 @@
++/*
++ * linux/include/ve_nfs.h
++ *
++ * VE context for NFS
++ *
++ * Copyright (C) 2007 SWsoft
++ */
++
++#ifndef __VE_NFS_H__
++#define __VE_NFS_H__
++
++#ifdef CONFIG_VE
++
++#include <linux/ve.h>
++
++#define NFS_CTX_FIELD(arg)  (get_exec_env()->_##arg)
++
++#else /* CONFIG_VE */
++
++#define NFS_CTX_FIELD(arg)	_##arg
++
++#endif /* CONFIG_VE */
++
++#define nlmsvc_grace_period	NFS_CTX_FIELD(nlmsvc_grace_period)
++#define nlmsvc_timeout		NFS_CTX_FIELD(nlmsvc_timeout)
++#define nlmsvc_users		NFS_CTX_FIELD(nlmsvc_users)
++#define nlmsvc_task		NFS_CTX_FIELD(nlmsvc_task)
++#define nlmsvc_serv		NFS_CTX_FIELD(nlmsvc_serv)
++
++#endif
+-- 
+1.6.0.6
+

Added: dists/lenny/linux-2.6/debian/patches/features/all/openvz/0020-autofs4-pidns-friendly-oz_mode.patch
==============================================================================
--- (empty file)
+++ dists/lenny/linux-2.6/debian/patches/features/all/openvz/0020-autofs4-pidns-friendly-oz_mode.patch	Sun Mar 22 21:12:49 2009
@@ -0,0 +1,132 @@
+From 4c9010eff11d97bf013f53601a76990b017e45b7 Mon Sep 17 00:00:00 2001
+From: Konstantin Khlebnikov <khlebnikov at openvz.org>
+Date: Mon, 22 Sep 2008 13:20:00 +0400
+Subject: [PATCH] autofs4: pidns friendly oz_mode
+
+Fix oz_mode detect to prevent autofs daemon hang inside CT.
+
+Switch from pid_t to struct pid of oz mode process group.
+The same changes as in mainstream commit fa0334f1 for autofs.
+
+http://bugzilla.openvz.org/show_bug.cgi?id=959
+
+Signed-off-by: Konstantin Khlebnikov <khlebnikov at openvz.org>
+Signed-off-by: Pavel Emelyanov <xemul at openvz.org>
+---
+ fs/autofs4/autofs_i.h |    4 ++--
+ fs/autofs4/inode.c    |   24 ++++++++++++++++++------
+ 2 files changed, 20 insertions(+), 8 deletions(-)
+
+diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h
+index c3d352d..4c8d035 100644
+--- a/fs/autofs4/autofs_i.h
++++ b/fs/autofs4/autofs_i.h
+@@ -98,7 +98,7 @@ struct autofs_sb_info {
+ 	u32 magic;
+ 	int pipefd;
+ 	struct file *pipe;
+-	pid_t oz_pgrp;
++	struct pid *oz_pgrp;
+ 	int catatonic;
+ 	int version;
+ 	int sub_version;
+@@ -131,7 +131,7 @@ static inline struct autofs_info *autofs4_dentry_ino(struct dentry *dentry)
+    filesystem without "magic".) */
+ 
+ static inline int autofs4_oz_mode(struct autofs_sb_info *sbi) {
+-	return sbi->catatonic || task_pgrp_nr(current) == sbi->oz_pgrp;
++	return sbi->catatonic || task_pgrp(current) == sbi->oz_pgrp;
+ }
+ 
+ /* Does a dentry have some pending activity? */
+diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c
+index 2fdcf5e..2d8dcb2 100644
+--- a/fs/autofs4/inode.c
++++ b/fs/autofs4/inode.c
+@@ -165,6 +165,8 @@ void autofs4_kill_sb(struct super_block *sb)
+ 	/* Clean up and release dangling references */
+ 	autofs4_force_release(sbi);
+ 
++	put_pid(sbi->oz_pgrp);
++
+ 	sb->s_fs_info = NULL;
+ 	kfree(sbi);
+ 
+@@ -186,7 +188,7 @@ static int autofs4_show_options(struct seq_file *m, struct vfsmount *mnt)
+ 		seq_printf(m, ",uid=%u", root_inode->i_uid);
+ 	if (root_inode->i_gid != 0)
+ 		seq_printf(m, ",gid=%u", root_inode->i_gid);
+-	seq_printf(m, ",pgrp=%d", sbi->oz_pgrp);
++	seq_printf(m, ",pgrp=%d", pid_vnr(sbi->oz_pgrp));
+ 	seq_printf(m, ",timeout=%lu", sbi->exp_timeout/HZ);
+ 	seq_printf(m, ",minproto=%d", sbi->min_proto);
+ 	seq_printf(m, ",maxproto=%d", sbi->max_proto);
+@@ -231,7 +233,7 @@ static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid,
+ 
+ 	*uid = current->uid;
+ 	*gid = current->gid;
+-	*pgrp = task_pgrp_nr(current);
++	*pgrp = task_pgrp_vnr(current);
+ 
+ 	*minproto = AUTOFS_MIN_PROTO_VERSION;
+ 	*maxproto = AUTOFS_MAX_PROTO_VERSION;
+@@ -316,6 +318,7 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)
+ 	int pipefd;
+ 	struct autofs_sb_info *sbi;
+ 	struct autofs_info *ino;
++	pid_t pgrp;
+ 
+ 	sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
+ 	if (!sbi)
+@@ -328,7 +331,6 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)
+ 	sbi->pipe = NULL;
+ 	sbi->catatonic = 1;
+ 	sbi->exp_timeout = 0;
+-	sbi->oz_pgrp = task_pgrp_nr(current);
+ 	sbi->sb = s;
+ 	sbi->version = 0;
+ 	sbi->sub_version = 0;
+@@ -366,7 +368,7 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)
+ 
+ 	/* Can this call block? */
+ 	if (parse_options(data, &pipefd, &root_inode->i_uid, &root_inode->i_gid,
+-				&sbi->oz_pgrp, &sbi->type, &sbi->min_proto,
++				&pgrp, &sbi->type, &sbi->min_proto,
+ 				&sbi->max_proto)) {
+ 		printk("autofs: called with bogus options\n");
+ 		goto fail_dput;
+@@ -394,12 +396,20 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)
+ 		sbi->version = sbi->max_proto;
+ 	sbi->sub_version = AUTOFS_PROTO_SUBVERSION;
+ 
+-	DPRINTK("pipe fd = %d, pgrp = %u", pipefd, sbi->oz_pgrp);
++	DPRINTK("pipe fd = %d, pgrp = %u", pipefd, pgrp);
++
++	sbi->oz_pgrp = find_get_pid(pgrp);
++
++	if (!sbi->oz_pgrp) {
++		printk("autofs: could not find process group %d\n", pgrp);
++		goto fail_dput;
++	}
++
+ 	pipe = fget(pipefd);
+ 	
+ 	if (!pipe) {
+ 		printk("autofs: could not open pipe file descriptor\n");
+-		goto fail_dput;
++		goto fail_put_pid;
+ 	}
+ 	if (!pipe->f_op || !pipe->f_op->write)
+ 		goto fail_fput;
+@@ -420,6 +430,8 @@ fail_fput:
+ 	printk("autofs: pipe file descriptor does not contain proper ops\n");
+ 	fput(pipe);
+ 	/* fall through */
++fail_put_pid:
++	put_pid(sbi->oz_pgrp);
+ fail_dput:
+ 	dput(root);
+ 	goto fail_free;
+-- 
+1.6.0.6
+

Added: dists/lenny/linux-2.6/debian/patches/features/all/openvz/0025-conntrack-Allocate-free-ve_nf_conntrack_l3proto_ipv.patch
==============================================================================
--- (empty file)
+++ dists/lenny/linux-2.6/debian/patches/features/all/openvz/0025-conntrack-Allocate-free-ve_nf_conntrack_l3proto_ipv.patch	Sun Mar 22 21:12:49 2009
@@ -0,0 +1,150 @@
+From 2c1b2f728e1ae136ec1713bfec9892cf7cd656b6 Mon Sep 17 00:00:00 2001
+From: Vitaliy Gusev <vgusev at openvz.org>
+Date: Wed, 24 Sep 2008 14:51:32 +0400
+Subject: [PATCH] conntrack: Allocate/free ve_nf_conntrack_l3proto_ipv6
+
+Virtualize nf_ct_ipv6_sysctl_table and allocate/free ve_nf_conntrack_l3proto_ipv6.
+
+Per VE nf_ct_ipv6_sysctl_table sysctl registration looks like:
+
+	nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto)
+		nf_ct_l3proto_register_sysctl(proto);
+			nf_ct_register_sysctl(&l3proto->ctl_table_header,
+						l3proto->ctl_table_path,
+						l3proto->ctl_table, NULL);
+
+So ve_nf_conntrack_l3proto_ipv6 is allocated per VE as l3proto sysctl
+registration changes l3proto->ctl_table_header.
+
+Signed-off-by: Vitaliy Gusev <vgusev at openvz.org>
+Signed-off-by: Pavel Emelyanov <xemul at openvz.org>
+---
+ net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c |   34 +++++++++++++++++++++++-
+ net/ipv6/netfilter/nf_conntrack_reasm.c        |   25 +++++++++++++++++-
+ 2 files changed, 57 insertions(+), 2 deletions(-)
+
+diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+index 71b15ab..8623b7c 100644
+--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
++++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+@@ -360,6 +360,33 @@ MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET6));
+ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR("Yasuyuki KOZAKAI @USAGI <yasuyuki.kozakai at toshiba.co.jp>");
+ 
++static int nf_ct_proto_ipv6_init_net(struct net *net)
++{
++	struct nf_conntrack_l3proto *ipv6;
++
++	ipv6 = &nf_conntrack_l3proto_ipv6;
++	if (net != &init_net) {
++		ipv6 = kmemdup(ipv6,
++			       sizeof(struct nf_conntrack_l3proto), GFP_KERNEL);
++		if (!ipv6)
++			return -ENOMEM;
++	}
++
++	ve_nf_conntrack_l3proto_ipv6 = ipv6;
++	return 0;
++}
++
++static void nf_ct_proto_ipv6_exit_net(struct net *net)
++{
++	if (net != &init_net)
++		kfree(ve_nf_conntrack_l3proto_ipv6);
++}
++
++static struct pernet_operations nf_ct_ipv6_ops = {
++	.init = nf_ct_proto_ipv6_init_net,
++	.exit = nf_ct_proto_ipv6_exit_net,
++};
++
+ int init_nf_ct_l3proto_ipv6(void)
+ {
+ 	int ret = -ENOMEM;
+@@ -435,10 +462,12 @@ static int __init nf_conntrack_l3proto_ipv6_init(void)
+ 
+ 	need_conntrack();
+ 
++	register_pernet_subsys(&nf_ct_ipv6_ops);
++
+ 	ret = nf_ct_frag6_init();
+ 	if (ret < 0) {
+ 		printk("nf_conntrack_ipv6: can't initialize frag6.\n");
+-		return ret;
++		goto unreg_subsys;
+ 	}
+ 
+ 	ret = init_nf_ct_l3proto_ipv6();
+@@ -461,6 +490,8 @@ static int __init nf_conntrack_l3proto_ipv6_init(void)
+ 
+ cleanup_frag6:
+ 	nf_ct_frag6_cleanup();
++unreg_subsys:
++	unregister_pernet_subsys(&nf_ct_ipv6_ops);
+ 	return ret;
+ }
+ 
+@@ -473,6 +504,7 @@ static void __exit nf_conntrack_l3proto_ipv6_fini(void)
+ 	nf_unregister_hooks(ipv6_conntrack_ops, ARRAY_SIZE(ipv6_conntrack_ops));
+ 	fini_nf_ct_l3proto_ipv6();
+ 	nf_ct_frag6_cleanup();
++	unregister_pernet_subsys(&nf_ct_ipv6_ops);
+ }
+ 
+ module_init(nf_conntrack_l3proto_ipv6_init);
+diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
+index 9faaa59..e8e4112 100644
+--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
++++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
+@@ -40,6 +40,7 @@
+ #include <net/ndisc.h>
+ #include <net/addrconf.h>
+ #include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
++#include <net/netfilter/nf_conntrack_l3proto.h>
+ #include <linux/sysctl.h>
+ #include <linux/netfilter.h>
+ #include <linux/netfilter_ipv6.h>
+@@ -696,17 +697,39 @@ static int nf_ct_frag6_init_net(struct net *net)
+ {
+ 	struct netns_frags *frags = &net->ipv6.ct_frags;
+ 
++#ifdef CONFIG_SYSCTL
++	if (net != &init_net) {
++		struct nf_conntrack_l3proto *ipv6 =
++			ve_nf_conntrack_l3proto_ipv6;
++
++		ipv6->ctl_table = kmemdup(nf_ct_ipv6_sysctl_table,
++					  sizeof(nf_ct_ipv6_sysctl_table),
++					  GFP_KERNEL);
++		if (!ipv6->ctl_table)
++			return -ENOMEM;
++
++		ipv6->ctl_table_header = NULL;
++		ipv6->ctl_table_path = nf_net_netfilter_sysctl_path;
++
++		ipv6->ctl_table[0].data = &frags->timeout;
++		ipv6->ctl_table[1].data = &frags->low_thresh;
++		ipv6->ctl_table[2].data = &frags->high_thresh;
++	}
++#endif
+ 	frags->timeout = IPV6_FRAG_TIMEOUT;
+ 	frags->high_thresh = 256 * 1024;
+ 	frags->low_thresh = 192 * 1024;
+ 	inet_frags_init_net(frags);
+ 
+-	return 0; /* FIXME : sysctls */
++	return 0;
+ }
+ 
+ static void nf_ct_frag6_exit_net(struct net *net)
+ {
+ 	inet_frags_exit_net(&net->ipv6.ct_frags, &nf_frags);
++	if (net != &init_net)
++		kfree(ve_nf_conntrack_l3proto_ipv6->ctl_table);
++
+ }
+ 
+ static struct pernet_operations nf_ct_frag6_ops = {
+-- 
+1.6.0.6
+

Added: dists/lenny/linux-2.6/debian/patches/features/all/openvz/0026-ct-Move-_nf_conntrack_l3proto_ipv6-to-net-namespace.patch
==============================================================================
--- (empty file)
+++ dists/lenny/linux-2.6/debian/patches/features/all/openvz/0026-ct-Move-_nf_conntrack_l3proto_ipv6-to-net-namespace.patch	Sun Mar 22 21:12:49 2009
@@ -0,0 +1,173 @@
+From e29a555d7d8f88dbfcaed541e340a4e3977c76aa Mon Sep 17 00:00:00 2001
+From: Vitaliy Gusev <vgusev at openvz.org>
+Date: Wed, 24 Sep 2008 14:52:08 +0400
+Subject: [PATCH] ct: Move _nf_conntrack_l3proto_ipv6 to net namespace
+
+Move _nf_conntrack_l3proto_ipv6 from ve_nf_conntrack to net namespace.
+
+The patch [4/5] "conntrack: Allocate/free ve_nf_conntrack_l3proto_ipv6"
+has lines:
+
++static int nf_ct_proto_ipv6_init_net(struct net *net)
+...
++	ve_nf_conntrack_l3proto_ipv6 = ipv6;
++	return 0;
+
+ve_nf_conntrack_l3proto_ipv6 points to not allocated memory, as this function
+is called during net initialization (conntrack isn't initialized yet).
+
+So move ve_nf_conntrack_l3proto_ipv6 to net namespace
+
+Signed-off-by: Vitaliy Gusev <vgusev at openvz.org>
+Signed-off-by: Pavel Emelyanov <xemul at openvz.org>
+---
+ include/linux/ve.h                             |    1 -
+ include/net/netfilter/nf_conntrack_l3proto.h   |    2 --
+ include/net/netns/ipv6.h                       |    4 ++++
+ net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c |   12 ++++++++----
+ net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c |    3 ++-
+ net/ipv6/netfilter/nf_conntrack_reasm.c        |    4 ++--
+ 6 files changed, 16 insertions(+), 10 deletions(-)
+
+diff --git a/include/linux/ve.h b/include/linux/ve.h
+index 970aadc..2180c1f 100644
+--- a/include/linux/ve.h
++++ b/include/linux/ve.h
+@@ -107,7 +107,6 @@ struct ve_nf_conntrack {
+ 	struct nf_conntrack_l4proto	**_nf_ct_protos[PF_MAX];
+ 	/* l3 protocols sysctl tables: */
+ 	struct nf_conntrack_l3proto	*_nf_conntrack_l3proto_ipv4;
+-	struct nf_conntrack_l3proto	*_nf_conntrack_l3proto_ipv6;
+ 	struct nf_conntrack_l3proto	*_nf_ct_l3protos[AF_MAX];
+ 	/* sysctl standalone stuff: */
+ 	struct ctl_table_header		*_nf_ct_sysctl_header;
+diff --git a/include/net/netfilter/nf_conntrack_l3proto.h b/include/net/netfilter/nf_conntrack_l3proto.h
+index 6b1f720..ac81973 100644
+--- a/include/net/netfilter/nf_conntrack_l3proto.h
++++ b/include/net/netfilter/nf_conntrack_l3proto.h
+@@ -79,14 +79,12 @@ struct nf_conntrack_l3proto
+ #if defined(CONFIG_VE_IPTABLES) && defined(CONFIG_SYSCTL)
+ #define ve_nf_ct_l3protos		ve_nf_ct3->_nf_ct_l3protos
+ #define ve_nf_conntrack_l3proto_ipv4	(ve_nf_ct3->_nf_conntrack_l3proto_ipv4)
+-#define	ve_nf_conntrack_l3proto_ipv6	(ve_nf_ct3->_nf_conntrack_l3proto_ipv6)
+ #define ve_nf_conntrack_max		(ve_nf_ct3->_nf_conntrack_max)
+ #define ve_nf_conntrack_count		(ve_nf_ct3->_nf_conntrack_count)
+ #define ve_nf_conntrack_checksum	(ve_nf_ct3->_nf_conntrack_checksum)
+ #else /* !CONFIG_VE_IPTABLES || !CONFIG_SYSCTL: */
+ #define ve_nf_ct_l3protos		nf_ct_l3protos
+ #define ve_nf_conntrack_l3proto_ipv4	&nf_conntrack_l3proto_ipv4
+-#define ve_nf_conntrack_l3proto_ipv6	&nf_conntrack_l3proto_ipv6
+ #define ve_nf_conntrack_max		nf_conntrack_max
+ #define ve_nf_conntrack_count		nf_conntrack_count
+ #define ve_nf_conntrack_checksum	nf_conntrack_checksum
+diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h
+index c368713..11c8cc8 100644
+--- a/include/net/netns/ipv6.h
++++ b/include/net/netns/ipv6.h
+@@ -33,6 +33,10 @@ struct netns_ipv6 {
+ 	struct ipv6_devconf	*devconf_dflt;
+ 	struct netns_frags	frags;
+ 	struct netns_frags	ct_frags;
++
++#ifdef CONFIG_SYSCTL
++	struct nf_conntrack_l3proto *nf_conntrack_l3proto_ipv6;
++#endif
+ #ifdef CONFIG_NETFILTER
+ 	struct xt_table		*ip6table_filter;
+ 	struct xt_table		*ip6table_mangle;
+diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+index 8623b7c..8288efc 100644
+--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
++++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+@@ -372,14 +372,14 @@ static int nf_ct_proto_ipv6_init_net(struct net *net)
+ 			return -ENOMEM;
+ 	}
+ 
+-	ve_nf_conntrack_l3proto_ipv6 = ipv6;
++	net->ipv6.nf_conntrack_l3proto_ipv6 = ipv6;
+ 	return 0;
+ }
+ 
+ static void nf_ct_proto_ipv6_exit_net(struct net *net)
+ {
+ 	if (net != &init_net)
+-		kfree(ve_nf_conntrack_l3proto_ipv6);
++		kfree(net->ipv6.nf_conntrack_l3proto_ipv6);
+ }
+ 
+ static struct pernet_operations nf_ct_ipv6_ops = {
+@@ -389,6 +389,8 @@ static struct pernet_operations nf_ct_ipv6_ops = {
+ 
+ int init_nf_ct_l3proto_ipv6(void)
+ {
++	struct net *net = get_exec_env()->ve_netns;
++
+ 	int ret = -ENOMEM;
+ 
+ #ifdef CONFIG_VE_IPTABLES
+@@ -417,7 +419,7 @@ int init_nf_ct_l3proto_ipv6(void)
+ 		goto unreg_udp;
+ 	}
+ 
+-	ret = nf_conntrack_l3proto_register(ve_nf_conntrack_l3proto_ipv6);
++	ret = nf_conntrack_l3proto_register(net->ipv6.nf_conntrack_l3proto_ipv6);
+ 	if (ret < 0) {
+ 		printk("nf_conntrack_ipv6: can't register ipv6\n");
+ 		goto unreg_icmpv6;
+@@ -443,7 +445,9 @@ EXPORT_SYMBOL(init_nf_ct_l3proto_ipv6);
+ 
+ void fini_nf_ct_l3proto_ipv6(void)
+ {
+-	nf_conntrack_l3proto_unregister(ve_nf_conntrack_l3proto_ipv6);
++	struct net *net = get_exec_env()->ve_netns;
++
++	nf_conntrack_l3proto_unregister(net->ipv6.nf_conntrack_l3proto_ipv6);
+ 	nf_conntrack_l4proto_unregister(ve_nf_conntrack_l4proto_icmpv6);
+ 	nf_conntrack_l4proto_unregister(ve_nf_conntrack_l4proto_udp6);
+ 	nf_conntrack_l4proto_unregister(ve_nf_conntrack_l4proto_tcp6);
+diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
+index cae064f..20e8750 100644
+--- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
++++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
+@@ -132,6 +132,7 @@ icmpv6_error_message(struct sk_buff *skb,
+ 	struct nf_conntrack_tuple intuple, origtuple;
+ 	const struct nf_conntrack_tuple_hash *h;
+ 	const struct nf_conntrack_l4proto *inproto;
++	struct net *net = get_exec_env()->ve_netns;
+ 
+ 	NF_CT_ASSERT(skb->nfct == NULL);
+ 
+@@ -151,7 +152,7 @@ icmpv6_error_message(struct sk_buff *skb,
+ 	/* Ordinarily, we'd expect the inverted tupleproto, but it's
+ 	   been preserved inside the ICMP. */
+ 	if (!nf_ct_invert_tuple(&intuple, &origtuple,
+-				ve_nf_conntrack_l3proto_ipv6, inproto)) {
++				net->ipv6.nf_conntrack_l3proto_ipv6, inproto)) {
+ 		pr_debug("icmpv6_error: Can't invert tuple\n");
+ 		return -NF_ACCEPT;
+ 	}
+diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
+index e8e4112..c2236df 100644
+--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
++++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
+@@ -700,7 +700,7 @@ static int nf_ct_frag6_init_net(struct net *net)
+ #ifdef CONFIG_SYSCTL
+ 	if (net != &init_net) {
+ 		struct nf_conntrack_l3proto *ipv6 =
+-			ve_nf_conntrack_l3proto_ipv6;
++			net->ipv6.nf_conntrack_l3proto_ipv6;
+ 
+ 		ipv6->ctl_table = kmemdup(nf_ct_ipv6_sysctl_table,
+ 					  sizeof(nf_ct_ipv6_sysctl_table),
+@@ -728,7 +728,7 @@ static void nf_ct_frag6_exit_net(struct net *net)
+ {
+ 	inet_frags_exit_net(&net->ipv6.ct_frags, &nf_frags);
+ 	if (net != &init_net)
+-		kfree(ve_nf_conntrack_l3proto_ipv6->ctl_table);
++		kfree(net->ipv6.nf_conntrack_l3proto_ipv6->ctl_table);
+ 
+ }
+ 
+-- 
+1.6.0.6
+

Added: dists/lenny/linux-2.6/debian/patches/features/all/openvz/0028-conntrack-fix-oops-in-nf_ct_frag6_gather.patch
==============================================================================
--- (empty file)
+++ dists/lenny/linux-2.6/debian/patches/features/all/openvz/0028-conntrack-fix-oops-in-nf_ct_frag6_gather.patch	Sun Mar 22 21:12:49 2009
@@ -0,0 +1,78 @@
+From 43553442d9467e2cdca7be044ff0cd497abe987f Mon Sep 17 00:00:00 2001
+From: Vitaliy Gusev <vgusev at openvz.org>
+Date: Thu, 25 Sep 2008 13:06:13 +0400
+Subject: [PATCH] conntrack: fix oops in nf_ct_frag6_gather
+
+skb->dev == NULL in NF_LOCAL_OUT hook level. So dev_inet(skb->dev)
+in nf_ct_frag6_gather() function causes OOPS.
+Pass directly net namespace to nf_ct_frag6_gather() as parameter
+to avoid this issue.
+
+(#122210)
+
+Signed-off-by: Vitaliy Gusev <vgusev at openvz.org>
+Signed-off-by: Pavel Emelyanov <xemul at openvz.org>
+---
+ include/net/netfilter/ipv6/nf_conntrack_ipv6.h |    3 ++-
+ net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c |    3 ++-
+ net/ipv6/netfilter/nf_conntrack_reasm.c        |    4 ++--
+ 3 files changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/include/net/netfilter/ipv6/nf_conntrack_ipv6.h b/include/net/netfilter/ipv6/nf_conntrack_ipv6.h
+index abc55ad..9cc2036 100644
+--- a/include/net/netfilter/ipv6/nf_conntrack_ipv6.h
++++ b/include/net/netfilter/ipv6/nf_conntrack_ipv6.h
+@@ -9,7 +9,8 @@ extern struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6;
+ 
+ extern int nf_ct_frag6_init(void);
+ extern void nf_ct_frag6_cleanup(void);
+-extern struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb);
++extern struct sk_buff *nf_ct_frag6_gather(struct net *net,
++					  struct sk_buff *skb);
+ extern void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb,
+ 			       struct net_device *in,
+ 			       struct net_device *out,
+diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+index 8288efc..5ff46a2 100644
+--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
++++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+@@ -191,12 +191,13 @@ static unsigned int ipv6_defrag(unsigned int hooknum,
+ 				int (*okfn)(struct sk_buff *))
+ {
+ 	struct sk_buff *reasm;
++	struct net *net = out ? dev_net(out) : dev_net(in);
+ 
+ 	/* Previously seen (loopback)?  */
+ 	if (skb->nfct)
+ 		return NF_ACCEPT;
+ 
+-	reasm = nf_ct_frag6_gather(skb);
++	reasm = nf_ct_frag6_gather(net, skb);
+ 
+ 	/* queued */
+ 	if (reasm == NULL)
+diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
+index c2236df..7036eba 100644
+--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
++++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
+@@ -593,7 +593,8 @@ find_prev_fhdr(struct sk_buff *skb, u8 *prevhdrp, int *prevhoff, int *fhoff)
+ 	return 0;
+ }
+ 
+-struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb)
++struct sk_buff *nf_ct_frag6_gather(struct net *net,
++				   struct sk_buff *skb)
+ {
+ 	struct sk_buff *clone;
+ 	struct net_device *dev = skb->dev;
+@@ -603,7 +604,6 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb)
+ 	int fhoff, nhoff;
+ 	u8 prevhdr;
+ 	struct sk_buff *ret_skb = NULL;
+-	struct net *net = dev_net(dev);
+ 
+ 	/* Jumbo payload inhibits frag. header */
+ 	if (ipv6_hdr(skb)->payload_len == 0) {
+-- 
+1.6.0.6
+

Modified: dists/lenny/linux-2.6/debian/patches/series/14-extra
==============================================================================
--- dists/lenny/linux-2.6/debian/patches/series/14-extra	(original)
+++ dists/lenny/linux-2.6/debian/patches/series/14-extra	Sun Mar 22 21:12:49 2009
@@ -22,3 +22,10 @@
 + features/all/openvz/0066-Free-skb-nf_bridge-in-veth_xmit-and-venet_xmit.patch featureset=openvz
 + features/all/openvz/0067-autofs4-fix-ia32-compat-mode.patch featureset=openvz
 + features/all/openvz/0070-pidns-update-leader_pid-at-pidns-attach.patch featureset=openvz
++ features/all/openvz/0016-nfs-fix-nfs-clinet-in-VE-finally.patch featureset=openvz
++ features/all/openvz/0017-cpt-bump-image-version-to-VERSION_26.patch featureset=openvz
++ features/all/openvz/0018-nfs-add-missed-ve_nfs.h-file.patch featureset=openvz
++ features/all/openvz/0020-autofs4-pidns-friendly-oz_mode.patch featureset=openvz
++ features/all/openvz/0025-conntrack-Allocate-free-ve_nf_conntrack_l3proto_ipv.patch featureset=openvz
++ features/all/openvz/0026-ct-Move-_nf_conntrack_l3proto_ipv6-to-net-namespace.patch featureset=openvz
++ features/all/openvz/0028-conntrack-fix-oops-in-nf_ct_frag6_gather.patch featureset=openvz



More information about the Kernel-svn-changes mailing list