Merge nfs containerization work from Trond's tree
The nfs containerization work is a prerequisite for Jeff Layton's reboot recovery rework.
This commit is contained in:
119
fs/lockd/svc.c
119
fs/lockd/svc.c
@@ -35,6 +35,8 @@
|
||||
#include <linux/lockd/lockd.h>
|
||||
#include <linux/nfs.h>
|
||||
|
||||
#include "netns.h"
|
||||
|
||||
#define NLMDBG_FACILITY NLMDBG_SVC
|
||||
#define LOCKD_BUFSIZE (1024 + NLMSVC_XDRSIZE)
|
||||
#define ALLOWED_SIGS (sigmask(SIGKILL))
|
||||
@@ -50,6 +52,8 @@ static struct task_struct *nlmsvc_task;
|
||||
static struct svc_rqst *nlmsvc_rqst;
|
||||
unsigned long nlmsvc_timeout;
|
||||
|
||||
int lockd_net_id;
|
||||
|
||||
/*
|
||||
* These can be set at insmod time (useful for NFS as root filesystem),
|
||||
* and also changed through the sysctl interface. -- Jamie Lokier, Aug 2003
|
||||
@@ -189,27 +193,29 @@ lockd(void *vrqstp)
|
||||
}
|
||||
|
||||
static int create_lockd_listener(struct svc_serv *serv, const char *name,
|
||||
const int family, const unsigned short port)
|
||||
struct net *net, const int family,
|
||||
const unsigned short port)
|
||||
{
|
||||
struct svc_xprt *xprt;
|
||||
|
||||
xprt = svc_find_xprt(serv, name, family, 0);
|
||||
xprt = svc_find_xprt(serv, name, net, family, 0);
|
||||
if (xprt == NULL)
|
||||
return svc_create_xprt(serv, name, &init_net, family, port,
|
||||
return svc_create_xprt(serv, name, net, family, port,
|
||||
SVC_SOCK_DEFAULTS);
|
||||
svc_xprt_put(xprt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int create_lockd_family(struct svc_serv *serv, const int family)
|
||||
static int create_lockd_family(struct svc_serv *serv, struct net *net,
|
||||
const int family)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = create_lockd_listener(serv, "udp", family, nlm_udpport);
|
||||
err = create_lockd_listener(serv, "udp", net, family, nlm_udpport);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
return create_lockd_listener(serv, "tcp", family, nlm_tcpport);
|
||||
return create_lockd_listener(serv, "tcp", net, family, nlm_tcpport);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -222,16 +228,16 @@ static int create_lockd_family(struct svc_serv *serv, const int family)
|
||||
* Returns zero if all listeners are available; otherwise a
|
||||
* negative errno value is returned.
|
||||
*/
|
||||
static int make_socks(struct svc_serv *serv)
|
||||
static int make_socks(struct svc_serv *serv, struct net *net)
|
||||
{
|
||||
static int warned;
|
||||
int err;
|
||||
|
||||
err = create_lockd_family(serv, PF_INET);
|
||||
err = create_lockd_family(serv, net, PF_INET);
|
||||
if (err < 0)
|
||||
goto out_err;
|
||||
|
||||
err = create_lockd_family(serv, PF_INET6);
|
||||
err = create_lockd_family(serv, net, PF_INET6);
|
||||
if (err < 0 && err != -EAFNOSUPPORT)
|
||||
goto out_err;
|
||||
|
||||
@@ -245,6 +251,47 @@ out_err:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int lockd_up_net(struct net *net)
|
||||
{
|
||||
struct lockd_net *ln = net_generic(net, lockd_net_id);
|
||||
struct svc_serv *serv = nlmsvc_rqst->rq_server;
|
||||
int error;
|
||||
|
||||
if (ln->nlmsvc_users)
|
||||
return 0;
|
||||
|
||||
error = svc_rpcb_setup(serv, net);
|
||||
if (error)
|
||||
goto err_rpcb;
|
||||
|
||||
error = make_socks(serv, net);
|
||||
if (error < 0)
|
||||
goto err_socks;
|
||||
return 0;
|
||||
|
||||
err_socks:
|
||||
svc_rpcb_cleanup(serv, net);
|
||||
err_rpcb:
|
||||
return error;
|
||||
}
|
||||
|
||||
static void lockd_down_net(struct net *net)
|
||||
{
|
||||
struct lockd_net *ln = net_generic(net, lockd_net_id);
|
||||
struct svc_serv *serv = nlmsvc_rqst->rq_server;
|
||||
|
||||
if (ln->nlmsvc_users) {
|
||||
if (--ln->nlmsvc_users == 0) {
|
||||
nlm_shutdown_hosts_net(net);
|
||||
svc_shutdown_net(serv, net);
|
||||
}
|
||||
} else {
|
||||
printk(KERN_ERR "lockd_down_net: no users! task=%p, net=%p\n",
|
||||
nlmsvc_task, net);
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Bring up the lockd process if it's not already up.
|
||||
*/
|
||||
@@ -252,13 +299,16 @@ int lockd_up(void)
|
||||
{
|
||||
struct svc_serv *serv;
|
||||
int error = 0;
|
||||
struct net *net = current->nsproxy->net_ns;
|
||||
|
||||
mutex_lock(&nlmsvc_mutex);
|
||||
/*
|
||||
* Check whether we're already up and running.
|
||||
*/
|
||||
if (nlmsvc_rqst)
|
||||
if (nlmsvc_rqst) {
|
||||
error = lockd_up_net(net);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sanity check: if there's no pid,
|
||||
@@ -275,7 +325,7 @@ int lockd_up(void)
|
||||
goto out;
|
||||
}
|
||||
|
||||
error = make_socks(serv);
|
||||
error = make_socks(serv, net);
|
||||
if (error < 0)
|
||||
goto destroy_and_out;
|
||||
|
||||
@@ -313,8 +363,12 @@ int lockd_up(void)
|
||||
destroy_and_out:
|
||||
svc_destroy(serv);
|
||||
out:
|
||||
if (!error)
|
||||
if (!error) {
|
||||
struct lockd_net *ln = net_generic(net, lockd_net_id);
|
||||
|
||||
ln->nlmsvc_users++;
|
||||
nlmsvc_users++;
|
||||
}
|
||||
mutex_unlock(&nlmsvc_mutex);
|
||||
return error;
|
||||
}
|
||||
@@ -328,8 +382,10 @@ lockd_down(void)
|
||||
{
|
||||
mutex_lock(&nlmsvc_mutex);
|
||||
if (nlmsvc_users) {
|
||||
if (--nlmsvc_users)
|
||||
if (--nlmsvc_users) {
|
||||
lockd_down_net(current->nsproxy->net_ns);
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
printk(KERN_ERR "lockd_down: no users! task=%p\n",
|
||||
nlmsvc_task);
|
||||
@@ -497,24 +553,55 @@ module_param_call(nlm_tcpport, param_set_port, param_get_int,
|
||||
module_param(nsm_use_hostnames, bool, 0644);
|
||||
module_param(nlm_max_connections, uint, 0644);
|
||||
|
||||
static int lockd_init_net(struct net *net)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void lockd_exit_net(struct net *net)
|
||||
{
|
||||
}
|
||||
|
||||
static struct pernet_operations lockd_net_ops = {
|
||||
.init = lockd_init_net,
|
||||
.exit = lockd_exit_net,
|
||||
.id = &lockd_net_id,
|
||||
.size = sizeof(struct lockd_net),
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Initialising and terminating the module.
|
||||
*/
|
||||
|
||||
static int __init init_nlm(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
err = -ENOMEM;
|
||||
nlm_sysctl_table = register_sysctl_table(nlm_sysctl_root);
|
||||
return nlm_sysctl_table ? 0 : -ENOMEM;
|
||||
#else
|
||||
return 0;
|
||||
if (nlm_sysctl_table == NULL)
|
||||
goto err_sysctl;
|
||||
#endif
|
||||
err = register_pernet_subsys(&lockd_net_ops);
|
||||
if (err)
|
||||
goto err_pernet;
|
||||
return 0;
|
||||
|
||||
err_pernet:
|
||||
#ifdef CONFIG_SYSCTL
|
||||
unregister_sysctl_table(nlm_sysctl_table);
|
||||
#endif
|
||||
err_sysctl:
|
||||
return err;
|
||||
}
|
||||
|
||||
static void __exit exit_nlm(void)
|
||||
{
|
||||
/* FIXME: delete all NLM clients */
|
||||
nlm_shutdown_hosts();
|
||||
unregister_pernet_subsys(&lockd_net_ops);
|
||||
#ifdef CONFIG_SYSCTL
|
||||
unregister_sysctl_table(nlm_sysctl_table);
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user