^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * linux/fs/lockd/svc.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * This is the central lockd service.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * FIXME: Separate the lockd NFS server functionality from the lockd NFS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * client functionality. Oh why didn't Sun create two separate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * services in the first place?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Authors: Olaf Kirch (okir@monad.swb.de)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/sysctl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/moduleparam.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/sched/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/in.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/uio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/smp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/kthread.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/freezer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/inetdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/sunrpc/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/sunrpc/stats.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/sunrpc/clnt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/sunrpc/svc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/sunrpc/svcsock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/sunrpc/svc_xprt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <net/ip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <net/addrconf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <net/ipv6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/lockd/lockd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/nfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include "netns.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include "procfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define NLMDBG_FACILITY NLMDBG_SVC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define LOCKD_BUFSIZE (1024 + NLMSVC_XDRSIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define ALLOWED_SIGS (sigmask(SIGKILL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) static struct svc_program nlmsvc_program;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) const struct nlmsvc_binding *nlmsvc_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) EXPORT_SYMBOL_GPL(nlmsvc_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) static DEFINE_MUTEX(nlmsvc_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) static unsigned int nlmsvc_users;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) static struct task_struct *nlmsvc_task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) static struct svc_rqst *nlmsvc_rqst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) unsigned long nlmsvc_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static atomic_t nlm_ntf_refcnt = ATOMIC_INIT(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) static DECLARE_WAIT_QUEUE_HEAD(nlm_ntf_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) unsigned int lockd_net_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * These can be set at insmod time (useful for NFS as root filesystem),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * and also changed through the sysctl interface. -- Jamie Lokier, Aug 2003
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) static unsigned long nlm_grace_period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) static unsigned long nlm_timeout = LOCKD_DFLT_TIMEO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static int nlm_udpport, nlm_tcpport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) /* RLIM_NOFILE defaults to 1024. That seems like a reasonable default here. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) static unsigned int nlm_max_connections = 1024;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * Constants needed for the sysctl interface.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) static const unsigned long nlm_grace_period_min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) static const unsigned long nlm_grace_period_max = 240;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) static const unsigned long nlm_timeout_min = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) static const unsigned long nlm_timeout_max = 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) static const int nlm_port_min = 0, nlm_port_max = 65535;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #ifdef CONFIG_SYSCTL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) static struct ctl_table_header * nlm_sysctl_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) static unsigned long get_lockd_grace_period(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) /* Note: nlm_timeout should always be nonzero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) if (nlm_grace_period)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) return roundup(nlm_grace_period, nlm_timeout) * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) return nlm_timeout * 5 * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) static void grace_ender(struct work_struct *grace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct delayed_work *dwork = to_delayed_work(grace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct lockd_net *ln = container_of(dwork, struct lockd_net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) grace_period_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) locks_end_grace(&ln->lockd_manager);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static void set_grace_period(struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) unsigned long grace_period = get_lockd_grace_period();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct lockd_net *ln = net_generic(net, lockd_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) locks_start_grace(net, &ln->lockd_manager);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) cancel_delayed_work_sync(&ln->grace_period_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) schedule_delayed_work(&ln->grace_period_end, grace_period);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) static void restart_grace(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) if (nlmsvc_ops) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) struct net *net = &init_net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct lockd_net *ln = net_generic(net, lockd_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) cancel_delayed_work_sync(&ln->grace_period_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) locks_end_grace(&ln->lockd_manager);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) nlmsvc_invalidate_all();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) set_grace_period(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * This is the lockd kernel thread
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) lockd(void *vrqstp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) struct svc_rqst *rqstp = vrqstp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) struct net *net = &init_net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) struct lockd_net *ln = net_generic(net, lockd_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) /* try_to_freeze() is called from svc_recv() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) set_freezable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) /* Allow SIGKILL to tell lockd to drop all of its locks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) allow_signal(SIGKILL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) dprintk("NFS locking service started (ver " LOCKD_VERSION ").\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * The main request loop. We don't terminate until the last
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * NFS mount or NFS daemon has gone away.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) while (!kthread_should_stop()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) long timeout = MAX_SCHEDULE_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) /* update sv_maxconn if it has changed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) rqstp->rq_server->sv_maxconn = nlm_max_connections;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) if (signalled()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) flush_signals(current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) restart_grace();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) timeout = nlmsvc_retry_blocked();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) * Find a socket with data available and call its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * recvfrom routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) err = svc_recv(rqstp, timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) if (err == -EAGAIN || err == -EINTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) dprintk("lockd: request from %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) svc_print_addr(rqstp, buf, sizeof(buf)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) svc_process(rqstp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) flush_signals(current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if (nlmsvc_ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) nlmsvc_invalidate_all();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) nlm_shutdown_hosts();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) cancel_delayed_work_sync(&ln->grace_period_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) locks_end_grace(&ln->lockd_manager);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) static int create_lockd_listener(struct svc_serv *serv, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) struct net *net, const int family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) const unsigned short port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) const struct cred *cred)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) struct svc_xprt *xprt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) xprt = svc_find_xprt(serv, name, net, family, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) if (xprt == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) return svc_create_xprt(serv, name, net, family, port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) SVC_SOCK_DEFAULTS, cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) svc_xprt_put(xprt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) static int create_lockd_family(struct svc_serv *serv, struct net *net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) const int family, const struct cred *cred)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) err = create_lockd_listener(serv, "udp", net, family, nlm_udpport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) return create_lockd_listener(serv, "tcp", net, family, nlm_tcpport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) * Ensure there are active UDP and TCP listeners for lockd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) * Even if we have only TCP NFS mounts and/or TCP NFSDs, some
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) * local services (such as rpc.statd) still require UDP, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) * some NFS servers do not yet support NLM over TCP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * Returns zero if all listeners are available; otherwise a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) * negative errno value is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) static int make_socks(struct svc_serv *serv, struct net *net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) const struct cred *cred)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) static int warned;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) err = create_lockd_family(serv, net, PF_INET, cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) err = create_lockd_family(serv, net, PF_INET6, cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) if (err < 0 && err != -EAFNOSUPPORT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) warned = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) if (warned++ == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) "lockd_up: makesock failed, error=%d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) svc_shutdown_net(serv, net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) static int lockd_up_net(struct svc_serv *serv, struct net *net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) const struct cred *cred)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) struct lockd_net *ln = net_generic(net, lockd_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) if (ln->nlmsvc_users++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) error = svc_bind(serv, net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) goto err_bind;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) error = make_socks(serv, net, cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) goto err_bind;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) set_grace_period(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) dprintk("%s: per-net data created; net=%x\n", __func__, net->ns.inum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) err_bind:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) ln->nlmsvc_users--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) static void lockd_down_net(struct svc_serv *serv, struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) struct lockd_net *ln = net_generic(net, lockd_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) if (ln->nlmsvc_users) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) if (--ln->nlmsvc_users == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) nlm_shutdown_hosts_net(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) cancel_delayed_work_sync(&ln->grace_period_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) locks_end_grace(&ln->lockd_manager);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) svc_shutdown_net(serv, net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) dprintk("%s: per-net data destroyed; net=%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) __func__, net->ns.inum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) pr_err("%s: no users! task=%p, net=%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) __func__, nlmsvc_task, net->ns.inum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) static int lockd_inetaddr_event(struct notifier_block *this,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) unsigned long event, void *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) struct sockaddr_in sin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if ((event != NETDEV_DOWN) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) !atomic_inc_not_zero(&nlm_ntf_refcnt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) if (nlmsvc_rqst) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) dprintk("lockd_inetaddr_event: removed %pI4\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) &ifa->ifa_local);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) sin.sin_family = AF_INET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) sin.sin_addr.s_addr = ifa->ifa_local;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) svc_age_temp_xprts_now(nlmsvc_rqst->rq_server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) (struct sockaddr *)&sin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) atomic_dec(&nlm_ntf_refcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) wake_up(&nlm_ntf_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) static struct notifier_block lockd_inetaddr_notifier = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) .notifier_call = lockd_inetaddr_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) static int lockd_inet6addr_event(struct notifier_block *this,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) unsigned long event, void *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) struct sockaddr_in6 sin6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) if ((event != NETDEV_DOWN) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) !atomic_inc_not_zero(&nlm_ntf_refcnt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (nlmsvc_rqst) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) dprintk("lockd_inet6addr_event: removed %pI6\n", &ifa->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) sin6.sin6_family = AF_INET6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) sin6.sin6_addr = ifa->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (ipv6_addr_type(&sin6.sin6_addr) & IPV6_ADDR_LINKLOCAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) sin6.sin6_scope_id = ifa->idev->dev->ifindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) svc_age_temp_xprts_now(nlmsvc_rqst->rq_server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) (struct sockaddr *)&sin6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) atomic_dec(&nlm_ntf_refcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) wake_up(&nlm_ntf_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) static struct notifier_block lockd_inet6addr_notifier = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) .notifier_call = lockd_inet6addr_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) static void lockd_unregister_notifiers(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) unregister_inetaddr_notifier(&lockd_inetaddr_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) unregister_inet6addr_notifier(&lockd_inet6addr_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) wait_event(nlm_ntf_wq, atomic_read(&nlm_ntf_refcnt) == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) static void lockd_svc_exit_thread(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) atomic_dec(&nlm_ntf_refcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) lockd_unregister_notifiers();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) svc_exit_thread(nlmsvc_rqst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) static int lockd_start_svc(struct svc_serv *serv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if (nlmsvc_rqst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) * Create the kernel thread and wait for it to start.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) nlmsvc_rqst = svc_prepare_thread(serv, &serv->sv_pools[0], NUMA_NO_NODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) if (IS_ERR(nlmsvc_rqst)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) error = PTR_ERR(nlmsvc_rqst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) "lockd_up: svc_rqst allocation failed, error=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) lockd_unregister_notifiers();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) goto out_rqst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) atomic_inc(&nlm_ntf_refcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) svc_sock_update_bufs(serv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) serv->sv_maxconn = nlm_max_connections;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) nlmsvc_task = kthread_create(lockd, nlmsvc_rqst, "%s", serv->sv_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) if (IS_ERR(nlmsvc_task)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) error = PTR_ERR(nlmsvc_task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) "lockd_up: kthread_run failed, error=%d\n", error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) goto out_task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) nlmsvc_rqst->rq_task = nlmsvc_task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) wake_up_process(nlmsvc_task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) dprintk("lockd_up: service started\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) out_task:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) lockd_svc_exit_thread();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) nlmsvc_task = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) out_rqst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) nlmsvc_rqst = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) static const struct svc_serv_ops lockd_sv_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) .svo_shutdown = svc_rpcb_cleanup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) .svo_enqueue_xprt = svc_xprt_do_enqueue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) static struct svc_serv *lockd_create_svc(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) struct svc_serv *serv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) * Check whether we're already up and running.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) if (nlmsvc_rqst) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) * Note: increase service usage, because later in case of error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) * svc_destroy() will be called.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) svc_get(nlmsvc_rqst->rq_server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) return nlmsvc_rqst->rq_server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) * Sanity check: if there's no pid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) * we should be the first user ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) if (nlmsvc_users)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) "lockd_up: no pid, %d users??\n", nlmsvc_users);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) if (!nlm_timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) nlm_timeout = LOCKD_DFLT_TIMEO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) nlmsvc_timeout = nlm_timeout * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE, &lockd_sv_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) if (!serv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) printk(KERN_WARNING "lockd_up: create service failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) register_inetaddr_notifier(&lockd_inetaddr_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) register_inet6addr_notifier(&lockd_inet6addr_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) dprintk("lockd_up: service created\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) return serv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) * Bring up the lockd process if it's not already up.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) int lockd_up(struct net *net, const struct cred *cred)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) struct svc_serv *serv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) mutex_lock(&nlmsvc_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) serv = lockd_create_svc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) if (IS_ERR(serv)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) error = PTR_ERR(serv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) goto err_create;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) error = lockd_up_net(serv, net, cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) if (error < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) lockd_unregister_notifiers();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) goto err_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) error = lockd_start_svc(serv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) if (error < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) lockd_down_net(serv, net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) goto err_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) nlmsvc_users++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) * Note: svc_serv structures have an initial use count of 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) * so we exit through here on both success and failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) err_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) svc_destroy(serv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) err_create:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) mutex_unlock(&nlmsvc_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) EXPORT_SYMBOL_GPL(lockd_up);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) * Decrement the user count and bring down lockd if we're the last.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) lockd_down(struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) mutex_lock(&nlmsvc_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) lockd_down_net(nlmsvc_rqst->rq_server, net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) if (nlmsvc_users) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) if (--nlmsvc_users)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) printk(KERN_ERR "lockd_down: no users! task=%p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) nlmsvc_task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) if (!nlmsvc_task) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) printk(KERN_ERR "lockd_down: no lockd running.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) kthread_stop(nlmsvc_task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) dprintk("lockd_down: service stopped\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) lockd_svc_exit_thread();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) dprintk("lockd_down: service destroyed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) nlmsvc_task = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) nlmsvc_rqst = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) mutex_unlock(&nlmsvc_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) EXPORT_SYMBOL_GPL(lockd_down);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) #ifdef CONFIG_SYSCTL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) * Sysctl parameters (same as module parameters, different interface).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) static struct ctl_table nlm_sysctls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) .procname = "nlm_grace_period",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) .data = &nlm_grace_period,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) .maxlen = sizeof(unsigned long),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) .mode = 0644,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) .proc_handler = proc_doulongvec_minmax,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) .extra1 = (unsigned long *) &nlm_grace_period_min,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) .extra2 = (unsigned long *) &nlm_grace_period_max,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) .procname = "nlm_timeout",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) .data = &nlm_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) .maxlen = sizeof(unsigned long),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) .mode = 0644,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) .proc_handler = proc_doulongvec_minmax,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) .extra1 = (unsigned long *) &nlm_timeout_min,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) .extra2 = (unsigned long *) &nlm_timeout_max,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) .procname = "nlm_udpport",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) .data = &nlm_udpport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) .maxlen = sizeof(int),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) .mode = 0644,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) .proc_handler = proc_dointvec_minmax,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) .extra1 = (int *) &nlm_port_min,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) .extra2 = (int *) &nlm_port_max,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) .procname = "nlm_tcpport",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) .data = &nlm_tcpport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) .maxlen = sizeof(int),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) .mode = 0644,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) .proc_handler = proc_dointvec_minmax,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) .extra1 = (int *) &nlm_port_min,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) .extra2 = (int *) &nlm_port_max,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) .procname = "nsm_use_hostnames",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) .data = &nsm_use_hostnames,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) .maxlen = sizeof(int),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) .mode = 0644,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) .proc_handler = proc_dointvec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) .procname = "nsm_local_state",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) .data = &nsm_local_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) .maxlen = sizeof(int),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) .mode = 0644,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) .proc_handler = proc_dointvec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) static struct ctl_table nlm_sysctl_dir[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) .procname = "nfs",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) .mode = 0555,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) .child = nlm_sysctls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) static struct ctl_table nlm_sysctl_root[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) .procname = "fs",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) .mode = 0555,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) .child = nlm_sysctl_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) #endif /* CONFIG_SYSCTL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) * Module (and sysfs) parameters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) #define param_set_min_max(name, type, which_strtol, min, max) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) static int param_set_##name(const char *val, const struct kernel_param *kp) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) char *endp; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) __typeof__(type) num = which_strtol(val, &endp, 0); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) if (endp == val || *endp || num < (min) || num > (max)) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) return -EINVAL; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) *((type *) kp->arg) = num; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) return 0; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) static inline int is_callback(u32 proc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) return proc == NLMPROC_GRANTED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) || proc == NLMPROC_GRANTED_MSG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) || proc == NLMPROC_TEST_RES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) || proc == NLMPROC_LOCK_RES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) || proc == NLMPROC_CANCEL_RES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) || proc == NLMPROC_UNLOCK_RES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) || proc == NLMPROC_NSM_NOTIFY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) static int lockd_authenticate(struct svc_rqst *rqstp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) rqstp->rq_client = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) switch (rqstp->rq_authop->flavour) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) case RPC_AUTH_NULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) case RPC_AUTH_UNIX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) if (rqstp->rq_proc == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) return SVC_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) if (is_callback(rqstp->rq_proc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) /* Leave it to individual procedures to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) * call nlmsvc_lookup_host(rqstp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) return SVC_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) return svc_set_client(rqstp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) return SVC_DENIED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) param_set_min_max(port, int, simple_strtol, 0, 65535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) param_set_min_max(grace_period, unsigned long, simple_strtoul,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) nlm_grace_period_min, nlm_grace_period_max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) param_set_min_max(timeout, unsigned long, simple_strtoul,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) nlm_timeout_min, nlm_timeout_max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) MODULE_AUTHOR("Olaf Kirch <okir@monad.swb.de>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) MODULE_DESCRIPTION("NFS file locking service version " LOCKD_VERSION ".");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) module_param_call(nlm_grace_period, param_set_grace_period, param_get_ulong,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) &nlm_grace_period, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) module_param_call(nlm_timeout, param_set_timeout, param_get_ulong,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) &nlm_timeout, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) module_param_call(nlm_udpport, param_set_port, param_get_int,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) &nlm_udpport, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) module_param_call(nlm_tcpport, param_set_port, param_get_int,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) &nlm_tcpport, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) module_param(nsm_use_hostnames, bool, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) module_param(nlm_max_connections, uint, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) static int lockd_init_net(struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) struct lockd_net *ln = net_generic(net, lockd_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) INIT_DELAYED_WORK(&ln->grace_period_end, grace_ender);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) INIT_LIST_HEAD(&ln->lockd_manager.list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) ln->lockd_manager.block_opens = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) INIT_LIST_HEAD(&ln->nsm_handles);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) static void lockd_exit_net(struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) struct lockd_net *ln = net_generic(net, lockd_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) WARN_ONCE(!list_empty(&ln->lockd_manager.list),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) "net %x %s: lockd_manager.list is not empty\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) net->ns.inum, __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) WARN_ONCE(!list_empty(&ln->nsm_handles),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) "net %x %s: nsm_handles list is not empty\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) net->ns.inum, __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) WARN_ONCE(delayed_work_pending(&ln->grace_period_end),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) "net %x %s: grace_period_end was not cancelled\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) net->ns.inum, __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) static struct pernet_operations lockd_net_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) .init = lockd_init_net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) .exit = lockd_exit_net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) .id = &lockd_net_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) .size = sizeof(struct lockd_net),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) * Initialising and terminating the module.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) static int __init init_nlm(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) #ifdef CONFIG_SYSCTL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) nlm_sysctl_table = register_sysctl_table(nlm_sysctl_root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) if (nlm_sysctl_table == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) goto err_sysctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) err = register_pernet_subsys(&lockd_net_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) goto err_pernet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) err = lockd_create_procfs();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) goto err_procfs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) err_procfs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) unregister_pernet_subsys(&lockd_net_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) err_pernet:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) #ifdef CONFIG_SYSCTL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) unregister_sysctl_table(nlm_sysctl_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) err_sysctl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) static void __exit exit_nlm(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) /* FIXME: delete all NLM clients */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) nlm_shutdown_hosts();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) lockd_remove_procfs();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) unregister_pernet_subsys(&lockd_net_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) #ifdef CONFIG_SYSCTL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) unregister_sysctl_table(nlm_sysctl_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) module_init(init_nlm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) module_exit(exit_nlm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) * Define NLM program and procedures
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) static unsigned int nlmsvc_version1_count[17];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) static const struct svc_version nlmsvc_version1 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) .vs_vers = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) .vs_nproc = 17,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) .vs_proc = nlmsvc_procedures,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) .vs_count = nlmsvc_version1_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) .vs_xdrsize = NLMSVC_XDRSIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) static unsigned int nlmsvc_version3_count[24];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) static const struct svc_version nlmsvc_version3 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) .vs_vers = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) .vs_nproc = 24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) .vs_proc = nlmsvc_procedures,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) .vs_count = nlmsvc_version3_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) .vs_xdrsize = NLMSVC_XDRSIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) #ifdef CONFIG_LOCKD_V4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) static unsigned int nlmsvc_version4_count[24];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) static const struct svc_version nlmsvc_version4 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) .vs_vers = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) .vs_nproc = 24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) .vs_proc = nlmsvc_procedures4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) .vs_count = nlmsvc_version4_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) .vs_xdrsize = NLMSVC_XDRSIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) static const struct svc_version *nlmsvc_version[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) [1] = &nlmsvc_version1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) [3] = &nlmsvc_version3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) #ifdef CONFIG_LOCKD_V4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) [4] = &nlmsvc_version4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) static struct svc_stat nlmsvc_stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) #define NLM_NRVERS ARRAY_SIZE(nlmsvc_version)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) static struct svc_program nlmsvc_program = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) .pg_prog = NLM_PROGRAM, /* program number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) .pg_nvers = NLM_NRVERS, /* number of entries in nlmsvc_version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) .pg_vers = nlmsvc_version, /* version table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) .pg_name = "lockd", /* service name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) .pg_class = "nfsd", /* share authentication with nfsd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) .pg_stats = &nlmsvc_stats, /* stats table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) .pg_authenticate = &lockd_authenticate, /* export authentication */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) .pg_init_request = svc_generic_init_request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) .pg_rpcbind_set = svc_generic_rpcbind_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) };