1 // SPDX-License-Identifier: GPL-2.0-only
5 * This is the central lockd service.
7 * FIXME: Separate the lockd NFS server functionality from the lockd NFS
8 * client functionality. Oh why didn't Sun create two separate
9 * services in the first place?
11 * Authors: Olaf Kirch (okir@monad.swb.de)
13 * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
16 #include <linux/module.h>
17 #include <linux/init.h>
18 #include <linux/sysctl.h>
19 #include <linux/moduleparam.h>
21 #include <linux/sched/signal.h>
22 #include <linux/errno.h>
24 #include <linux/uio.h>
25 #include <linux/smp.h>
26 #include <linux/mutex.h>
27 #include <linux/freezer.h>
28 #include <linux/inetdevice.h>
30 #include <linux/sunrpc/types.h>
31 #include <linux/sunrpc/stats.h>
32 #include <linux/sunrpc/clnt.h>
33 #include <linux/sunrpc/svc.h>
34 #include <linux/sunrpc/svcsock.h>
35 #include <linux/sunrpc/svc_xprt.h>
37 #include <net/addrconf.h>
39 #include <linux/lockd/lockd.h>
40 #include <linux/nfs.h>
45 #define NLMDBG_FACILITY NLMDBG_SVC
46 #define LOCKD_BUFSIZE (1024 + NLMSVC_XDRSIZE)
48 static struct svc_program nlmsvc_program
;
50 const struct nlmsvc_binding
*nlmsvc_ops
;
51 EXPORT_SYMBOL_GPL(nlmsvc_ops
);
53 static DEFINE_MUTEX(nlmsvc_mutex
);
54 static unsigned int nlmsvc_users
;
55 static struct svc_serv
*nlmsvc_serv
;
57 static void nlmsvc_request_retry(struct timer_list
*tl
)
59 svc_wake_up(nlmsvc_serv
);
61 DEFINE_TIMER(nlmsvc_retry
, nlmsvc_request_retry
);
63 unsigned int lockd_net_id
;
66 * These can be set at insmod time (useful for NFS as root filesystem),
67 * and also changed through the sysctl interface. -- Jamie Lokier, Aug 2003
69 static unsigned long nlm_grace_period
;
70 unsigned long nlm_timeout
= LOCKD_DFLT_TIMEO
;
71 static int nlm_udpport
, nlm_tcpport
;
73 /* RLIM_NOFILE defaults to 1024. That seems like a reasonable default here. */
74 static unsigned int nlm_max_connections
= 1024;
77 * Constants needed for the sysctl interface.
79 static const unsigned long nlm_grace_period_min
= 0;
80 static const unsigned long nlm_grace_period_max
= 240;
81 static const unsigned long nlm_timeout_min
= 3;
82 static const unsigned long nlm_timeout_max
= 20;
85 static const int nlm_port_min
= 0, nlm_port_max
= 65535;
86 static struct ctl_table_header
* nlm_sysctl_table
;
89 static unsigned long get_lockd_grace_period(void)
91 /* Note: nlm_timeout should always be nonzero */
93 return roundup(nlm_grace_period
, nlm_timeout
) * HZ
;
95 return nlm_timeout
* 5 * HZ
;
98 static void grace_ender(struct work_struct
*grace
)
100 struct delayed_work
*dwork
= to_delayed_work(grace
);
101 struct lockd_net
*ln
= container_of(dwork
, struct lockd_net
,
104 locks_end_grace(&ln
->lockd_manager
);
107 static void set_grace_period(struct net
*net
)
109 unsigned long grace_period
= get_lockd_grace_period();
110 struct lockd_net
*ln
= net_generic(net
, lockd_net_id
);
112 locks_start_grace(net
, &ln
->lockd_manager
);
113 cancel_delayed_work_sync(&ln
->grace_period_end
);
114 schedule_delayed_work(&ln
->grace_period_end
, grace_period
);
118 * This is the lockd kernel thread
123 struct svc_rqst
*rqstp
= vrqstp
;
124 struct net
*net
= &init_net
;
125 struct lockd_net
*ln
= net_generic(net
, lockd_net_id
);
127 svc_thread_init_status(rqstp
, 0);
129 /* try_to_freeze() is called from svc_recv() */
132 dprintk("NFS locking service started (ver " LOCKD_VERSION
").\n");
135 * The main request loop. We don't terminate until the last
136 * NFS mount or NFS daemon has gone away.
138 while (!svc_thread_should_stop(rqstp
)) {
139 /* update sv_maxconn if it has changed */
140 rqstp
->rq_server
->sv_maxconn
= nlm_max_connections
;
142 nlmsvc_retry_blocked(rqstp
);
146 nlmsvc_invalidate_all();
147 nlm_shutdown_hosts();
148 cancel_delayed_work_sync(&ln
->grace_period_end
);
149 locks_end_grace(&ln
->lockd_manager
);
151 dprintk("lockd_down: service stopped\n");
153 svc_exit_thread(rqstp
);
157 static int create_lockd_listener(struct svc_serv
*serv
, const char *name
,
158 struct net
*net
, const int family
,
159 const unsigned short port
,
160 const struct cred
*cred
)
162 struct svc_xprt
*xprt
;
164 xprt
= svc_find_xprt(serv
, name
, net
, family
, 0);
166 return svc_xprt_create(serv
, name
, net
, family
, port
,
167 SVC_SOCK_DEFAULTS
, cred
);
172 static int create_lockd_family(struct svc_serv
*serv
, struct net
*net
,
173 const int family
, const struct cred
*cred
)
177 err
= create_lockd_listener(serv
, "udp", net
, family
, nlm_udpport
,
182 return create_lockd_listener(serv
, "tcp", net
, family
, nlm_tcpport
,
187 * Ensure there are active UDP and TCP listeners for lockd.
189 * Even if we have only TCP NFS mounts and/or TCP NFSDs, some
190 * local services (such as rpc.statd) still require UDP, and
191 * some NFS servers do not yet support NLM over TCP.
193 * Returns zero if all listeners are available; otherwise a
194 * negative errno value is returned.
196 static int make_socks(struct svc_serv
*serv
, struct net
*net
,
197 const struct cred
*cred
)
202 err
= create_lockd_family(serv
, net
, PF_INET
, cred
);
206 err
= create_lockd_family(serv
, net
, PF_INET6
, cred
);
207 if (err
< 0 && err
!= -EAFNOSUPPORT
)
216 "lockd_up: makesock failed, error=%d\n", err
);
217 svc_xprt_destroy_all(serv
, net
);
218 svc_rpcb_cleanup(serv
, net
);
222 static int lockd_up_net(struct svc_serv
*serv
, struct net
*net
,
223 const struct cred
*cred
)
225 struct lockd_net
*ln
= net_generic(net
, lockd_net_id
);
228 if (ln
->nlmsvc_users
++)
231 error
= svc_bind(serv
, net
);
235 error
= make_socks(serv
, net
, cred
);
238 set_grace_period(net
);
239 dprintk("%s: per-net data created; net=%x\n", __func__
, net
->ns
.inum
);
247 static void lockd_down_net(struct svc_serv
*serv
, struct net
*net
)
249 struct lockd_net
*ln
= net_generic(net
, lockd_net_id
);
251 if (ln
->nlmsvc_users
) {
252 if (--ln
->nlmsvc_users
== 0) {
253 nlm_shutdown_hosts_net(net
);
254 cancel_delayed_work_sync(&ln
->grace_period_end
);
255 locks_end_grace(&ln
->lockd_manager
);
256 svc_xprt_destroy_all(serv
, net
);
257 svc_rpcb_cleanup(serv
, net
);
260 pr_err("%s: no users! net=%x\n",
261 __func__
, net
->ns
.inum
);
266 static int lockd_inetaddr_event(struct notifier_block
*this,
267 unsigned long event
, void *ptr
)
269 struct in_ifaddr
*ifa
= (struct in_ifaddr
*)ptr
;
270 struct sockaddr_in sin
;
272 if (event
!= NETDEV_DOWN
)
276 dprintk("lockd_inetaddr_event: removed %pI4\n",
278 sin
.sin_family
= AF_INET
;
279 sin
.sin_addr
.s_addr
= ifa
->ifa_local
;
280 svc_age_temp_xprts_now(nlmsvc_serv
, (struct sockaddr
*)&sin
);
287 static struct notifier_block lockd_inetaddr_notifier
= {
288 .notifier_call
= lockd_inetaddr_event
,
291 #if IS_ENABLED(CONFIG_IPV6)
292 static int lockd_inet6addr_event(struct notifier_block
*this,
293 unsigned long event
, void *ptr
)
295 struct inet6_ifaddr
*ifa
= (struct inet6_ifaddr
*)ptr
;
296 struct sockaddr_in6 sin6
;
298 if (event
!= NETDEV_DOWN
)
302 dprintk("lockd_inet6addr_event: removed %pI6\n", &ifa
->addr
);
303 sin6
.sin6_family
= AF_INET6
;
304 sin6
.sin6_addr
= ifa
->addr
;
305 if (ipv6_addr_type(&sin6
.sin6_addr
) & IPV6_ADDR_LINKLOCAL
)
306 sin6
.sin6_scope_id
= ifa
->idev
->dev
->ifindex
;
307 svc_age_temp_xprts_now(nlmsvc_serv
, (struct sockaddr
*)&sin6
);
314 static struct notifier_block lockd_inet6addr_notifier
= {
315 .notifier_call
= lockd_inet6addr_event
,
319 static int lockd_get(void)
321 struct svc_serv
*serv
;
330 * Sanity check: if there's no pid,
331 * we should be the first user ...
335 "lockd_up: no pid, %d users??\n", nlmsvc_users
);
337 serv
= svc_create(&nlmsvc_program
, LOCKD_BUFSIZE
, lockd
);
339 printk(KERN_WARNING
"lockd_up: create service failed\n");
343 serv
->sv_maxconn
= nlm_max_connections
;
344 error
= svc_set_num_threads(serv
, NULL
, 1);
351 register_inetaddr_notifier(&lockd_inetaddr_notifier
);
352 #if IS_ENABLED(CONFIG_IPV6)
353 register_inet6addr_notifier(&lockd_inet6addr_notifier
);
355 dprintk("lockd_up: service created\n");
360 static void lockd_put(void)
362 if (WARN(nlmsvc_users
<= 0, "lockd_down: no users!\n"))
367 unregister_inetaddr_notifier(&lockd_inetaddr_notifier
);
368 #if IS_ENABLED(CONFIG_IPV6)
369 unregister_inet6addr_notifier(&lockd_inet6addr_notifier
);
372 svc_set_num_threads(nlmsvc_serv
, NULL
, 0);
373 timer_delete_sync(&nlmsvc_retry
);
374 svc_destroy(&nlmsvc_serv
);
375 dprintk("lockd_down: service destroyed\n");
379 * Bring up the lockd process if it's not already up.
381 int lockd_up(struct net
*net
, const struct cred
*cred
)
385 mutex_lock(&nlmsvc_mutex
);
391 error
= lockd_up_net(nlmsvc_serv
, net
, cred
);
398 mutex_unlock(&nlmsvc_mutex
);
401 EXPORT_SYMBOL_GPL(lockd_up
);
404 * Decrement the user count and bring down lockd if we're the last.
407 lockd_down(struct net
*net
)
409 mutex_lock(&nlmsvc_mutex
);
410 lockd_down_net(nlmsvc_serv
, net
);
412 mutex_unlock(&nlmsvc_mutex
);
414 EXPORT_SYMBOL_GPL(lockd_down
);
419 * Sysctl parameters (same as module parameters, different interface).
422 static struct ctl_table nlm_sysctls
[] = {
424 .procname
= "nlm_grace_period",
425 .data
= &nlm_grace_period
,
426 .maxlen
= sizeof(unsigned long),
428 .proc_handler
= proc_doulongvec_minmax
,
429 .extra1
= (unsigned long *) &nlm_grace_period_min
,
430 .extra2
= (unsigned long *) &nlm_grace_period_max
,
433 .procname
= "nlm_timeout",
434 .data
= &nlm_timeout
,
435 .maxlen
= sizeof(unsigned long),
437 .proc_handler
= proc_doulongvec_minmax
,
438 .extra1
= (unsigned long *) &nlm_timeout_min
,
439 .extra2
= (unsigned long *) &nlm_timeout_max
,
442 .procname
= "nlm_udpport",
443 .data
= &nlm_udpport
,
444 .maxlen
= sizeof(int),
446 .proc_handler
= proc_dointvec_minmax
,
447 .extra1
= (int *) &nlm_port_min
,
448 .extra2
= (int *) &nlm_port_max
,
451 .procname
= "nlm_tcpport",
452 .data
= &nlm_tcpport
,
453 .maxlen
= sizeof(int),
455 .proc_handler
= proc_dointvec_minmax
,
456 .extra1
= (int *) &nlm_port_min
,
457 .extra2
= (int *) &nlm_port_max
,
460 .procname
= "nsm_use_hostnames",
461 .data
= &nsm_use_hostnames
,
462 .maxlen
= sizeof(bool),
464 .proc_handler
= proc_dobool
,
467 .procname
= "nsm_local_state",
468 .data
= &nsm_local_state
,
469 .maxlen
= sizeof(int),
471 .proc_handler
= proc_dointvec
,
475 #endif /* CONFIG_SYSCTL */
478 * Module (and sysfs) parameters.
481 #define param_set_min_max(name, type, which_strtol, min, max) \
482 static int param_set_##name(const char *val, const struct kernel_param *kp) \
485 __typeof__(type) num = which_strtol(val, &endp, 0); \
486 if (endp == val || *endp || num < (min) || num > (max)) \
488 *((type *) kp->arg) = num; \
492 static inline int is_callback(u32 proc
)
494 return proc
== NLMPROC_GRANTED
495 || proc
== NLMPROC_GRANTED_MSG
496 || proc
== NLMPROC_TEST_RES
497 || proc
== NLMPROC_LOCK_RES
498 || proc
== NLMPROC_CANCEL_RES
499 || proc
== NLMPROC_UNLOCK_RES
500 || proc
== NLMPROC_NSM_NOTIFY
;
504 static enum svc_auth_status
lockd_authenticate(struct svc_rqst
*rqstp
)
506 rqstp
->rq_client
= NULL
;
507 switch (rqstp
->rq_authop
->flavour
) {
510 rqstp
->rq_auth_stat
= rpc_auth_ok
;
511 if (rqstp
->rq_proc
== 0)
513 if (is_callback(rqstp
->rq_proc
)) {
514 /* Leave it to individual procedures to
515 * call nlmsvc_lookup_host(rqstp)
519 return svc_set_client(rqstp
);
521 rqstp
->rq_auth_stat
= rpc_autherr_badcred
;
526 param_set_min_max(port
, int, simple_strtol
, 0, 65535)
527 param_set_min_max(grace_period
, unsigned long, simple_strtoul
,
528 nlm_grace_period_min
, nlm_grace_period_max
)
529 param_set_min_max(timeout
, unsigned long, simple_strtoul
,
530 nlm_timeout_min
, nlm_timeout_max
)
532 MODULE_AUTHOR("Olaf Kirch <okir@monad.swb.de>");
533 MODULE_DESCRIPTION("NFS file locking service version " LOCKD_VERSION
".");
534 MODULE_LICENSE("GPL");
536 module_param_call(nlm_grace_period
, param_set_grace_period
, param_get_ulong
,
537 &nlm_grace_period
, 0644);
538 module_param_call(nlm_timeout
, param_set_timeout
, param_get_ulong
,
540 module_param_call(nlm_udpport
, param_set_port
, param_get_int
,
542 module_param_call(nlm_tcpport
, param_set_port
, param_get_int
,
544 module_param(nsm_use_hostnames
, bool, 0644);
545 module_param(nlm_max_connections
, uint
, 0644);
547 static int lockd_init_net(struct net
*net
)
549 struct lockd_net
*ln
= net_generic(net
, lockd_net_id
);
551 INIT_DELAYED_WORK(&ln
->grace_period_end
, grace_ender
);
552 INIT_LIST_HEAD(&ln
->lockd_manager
.list
);
553 ln
->lockd_manager
.block_opens
= false;
554 INIT_LIST_HEAD(&ln
->nsm_handles
);
558 static void lockd_exit_net(struct net
*net
)
560 struct lockd_net
*ln
= net_generic(net
, lockd_net_id
);
562 WARN_ONCE(!list_empty(&ln
->lockd_manager
.list
),
563 "net %x %s: lockd_manager.list is not empty\n",
564 net
->ns
.inum
, __func__
);
565 WARN_ONCE(!list_empty(&ln
->nsm_handles
),
566 "net %x %s: nsm_handles list is not empty\n",
567 net
->ns
.inum
, __func__
);
568 WARN_ONCE(delayed_work_pending(&ln
->grace_period_end
),
569 "net %x %s: grace_period_end was not cancelled\n",
570 net
->ns
.inum
, __func__
);
573 static struct pernet_operations lockd_net_ops
= {
574 .init
= lockd_init_net
,
575 .exit
= lockd_exit_net
,
577 .size
= sizeof(struct lockd_net
),
582 * Initialising and terminating the module.
585 static int __init
init_nlm(void)
591 nlm_sysctl_table
= register_sysctl("fs/nfs", nlm_sysctls
);
592 if (nlm_sysctl_table
== NULL
)
595 err
= register_pernet_subsys(&lockd_net_ops
);
599 err
= lockd_create_procfs();
606 unregister_pernet_subsys(&lockd_net_ops
);
609 unregister_sysctl_table(nlm_sysctl_table
);
615 static void __exit
exit_nlm(void)
617 /* FIXME: delete all NLM clients */
618 nlm_shutdown_hosts();
619 lockd_remove_procfs();
620 unregister_pernet_subsys(&lockd_net_ops
);
622 unregister_sysctl_table(nlm_sysctl_table
);
626 module_init(init_nlm
);
627 module_exit(exit_nlm
);
630 * nlmsvc_dispatch - Process an NLM Request
631 * @rqstp: incoming request
634 * %0: Processing complete; do not send a Reply
635 * %1: Processing complete; send Reply in rqstp->rq_res
637 static int nlmsvc_dispatch(struct svc_rqst
*rqstp
)
639 const struct svc_procedure
*procp
= rqstp
->rq_procinfo
;
640 __be32
*statp
= rqstp
->rq_accept_statp
;
642 if (!procp
->pc_decode(rqstp
, &rqstp
->rq_arg_stream
))
645 *statp
= procp
->pc_func(rqstp
);
646 if (*statp
== rpc_drop_reply
)
648 if (*statp
!= rpc_success
)
651 if (!procp
->pc_encode(rqstp
, &rqstp
->rq_res_stream
))
657 *statp
= rpc_garbage_args
;
661 *statp
= rpc_system_err
;
666 * Define NLM program and procedures
668 static DEFINE_PER_CPU_ALIGNED(unsigned long, nlmsvc_version1_count
[17]);
669 static const struct svc_version nlmsvc_version1
= {
672 .vs_proc
= nlmsvc_procedures
,
673 .vs_count
= nlmsvc_version1_count
,
674 .vs_dispatch
= nlmsvc_dispatch
,
675 .vs_xdrsize
= NLMSVC_XDRSIZE
,
678 static DEFINE_PER_CPU_ALIGNED(unsigned long,
679 nlmsvc_version3_count
[ARRAY_SIZE(nlmsvc_procedures
)]);
680 static const struct svc_version nlmsvc_version3
= {
682 .vs_nproc
= ARRAY_SIZE(nlmsvc_procedures
),
683 .vs_proc
= nlmsvc_procedures
,
684 .vs_count
= nlmsvc_version3_count
,
685 .vs_dispatch
= nlmsvc_dispatch
,
686 .vs_xdrsize
= NLMSVC_XDRSIZE
,
689 #ifdef CONFIG_LOCKD_V4
690 static DEFINE_PER_CPU_ALIGNED(unsigned long,
691 nlmsvc_version4_count
[ARRAY_SIZE(nlmsvc_procedures4
)]);
692 static const struct svc_version nlmsvc_version4
= {
694 .vs_nproc
= ARRAY_SIZE(nlmsvc_procedures4
),
695 .vs_proc
= nlmsvc_procedures4
,
696 .vs_count
= nlmsvc_version4_count
,
697 .vs_dispatch
= nlmsvc_dispatch
,
698 .vs_xdrsize
= NLMSVC_XDRSIZE
,
702 static const struct svc_version
*nlmsvc_version
[] = {
703 [1] = &nlmsvc_version1
,
704 [3] = &nlmsvc_version3
,
705 #ifdef CONFIG_LOCKD_V4
706 [4] = &nlmsvc_version4
,
710 #define NLM_NRVERS ARRAY_SIZE(nlmsvc_version)
711 static struct svc_program nlmsvc_program
= {
712 .pg_prog
= NLM_PROGRAM
, /* program number */
713 .pg_nvers
= NLM_NRVERS
, /* number of entries in nlmsvc_version */
714 .pg_vers
= nlmsvc_version
, /* version table */
715 .pg_name
= "lockd", /* service name */
716 .pg_class
= "nfsd", /* share authentication with nfsd */
717 .pg_authenticate
= &lockd_authenticate
, /* export authentication */
718 .pg_init_request
= svc_generic_init_request
,
719 .pg_rpcbind_set
= svc_generic_rpcbind_set
,