lockd.c revision 1.5 1 1.5 bouyer /* $NetBSD: lockd.c,v 1.5 2000/06/07 14:34:40 bouyer Exp $ */
2 1.1 scottr
3 1.1 scottr /*
4 1.1 scottr * Copyright (c) 1995
5 1.1 scottr * A.R. Gordon (andrew.gordon (at) net-tel.co.uk). All rights reserved.
6 1.1 scottr *
7 1.1 scottr * Redistribution and use in source and binary forms, with or without
8 1.1 scottr * modification, are permitted provided that the following conditions
9 1.1 scottr * are met:
10 1.1 scottr * 1. Redistributions of source code must retain the above copyright
11 1.1 scottr * notice, this list of conditions and the following disclaimer.
12 1.1 scottr * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 scottr * notice, this list of conditions and the following disclaimer in the
14 1.1 scottr * documentation and/or other materials provided with the distribution.
15 1.1 scottr * 3. All advertising materials mentioning features or use of this software
16 1.1 scottr * must display the following acknowledgement:
17 1.1 scottr * This product includes software developed for the FreeBSD project
18 1.1 scottr * 4. Neither the name of the author nor the names of any co-contributors
19 1.1 scottr * may be used to endorse or promote products derived from this software
20 1.1 scottr * without specific prior written permission.
21 1.1 scottr *
22 1.1 scottr * THIS SOFTWARE IS PROVIDED BY ANDREW GORDON AND CONTRIBUTORS ``AS IS'' AND
23 1.1 scottr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 1.1 scottr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 1.1 scottr * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26 1.1 scottr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 1.1 scottr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 1.1 scottr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 1.1 scottr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 1.1 scottr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 1.1 scottr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 1.1 scottr * SUCH DAMAGE.
33 1.1 scottr *
34 1.1 scottr */
35 1.1 scottr
36 1.2 lukem #include <sys/cdefs.h>
37 1.2 lukem #ifndef lint
38 1.5 bouyer __RCSID("$NetBSD: lockd.c,v 1.5 2000/06/07 14:34:40 bouyer Exp $");
39 1.2 lukem #endif
40 1.1 scottr
41 1.1 scottr /*
42 1.1 scottr * main() function for NFS lock daemon. Most of the code in this
43 1.1 scottr * file was generated by running rpcgen /usr/include/rpcsvc/nlm_prot.x.
44 1.1 scottr *
45 1.5 bouyer * The actual program logic is in the file lock_proc.c
46 1.1 scottr */
47 1.1 scottr
48 1.2 lukem #include <err.h>
49 1.1 scottr #include <stdio.h>
50 1.2 lukem #include <stdlib.h>
51 1.5 bouyer #include <errno.h>
52 1.1 scottr #include <syslog.h>
53 1.5 bouyer #include <signal.h>
54 1.5 bouyer #include <string.h>
55 1.2 lukem #include <unistd.h>
56 1.3 thorpej #include <util.h>
57 1.1 scottr
58 1.1 scottr #include <rpc/rpc.h>
59 1.1 scottr #include <rpcsvc/sm_inter.h>
60 1.1 scottr
61 1.1 scottr #include "lockd.h"
62 1.1 scottr #include "nlm_prot.h"
63 1.1 scottr
64 1.1 scottr int debug_level = 0; /* 0 = no debugging syslog() calls */
65 1.1 scottr int _rpcsvcdirty = 0;
66 1.1 scottr
67 1.5 bouyer int grace_expired;
68 1.5 bouyer
69 1.2 lukem int main __P((int, char **));
70 1.5 bouyer void nlm_prog_0 __P((struct svc_req *, SVCXPRT *));
71 1.1 scottr void nlm_prog_1 __P((struct svc_req *, SVCXPRT *));
72 1.1 scottr void nlm_prog_3 __P((struct svc_req *, SVCXPRT *));
73 1.4 bouyer void nlm_prog_4 __P((struct svc_req *, SVCXPRT *));
74 1.5 bouyer void usage __P((void));
75 1.5 bouyer
76 1.5 bouyer void sigalarm_handler __P((int));
77 1.1 scottr
78 1.2 lukem int
79 1.1 scottr main(argc, argv)
80 1.1 scottr int argc;
81 1.1 scottr char **argv;
82 1.1 scottr {
83 1.1 scottr SVCXPRT *transp;
84 1.1 scottr int ch;
85 1.5 bouyer struct sigaction sigchild, sigalarm;
86 1.5 bouyer int grace_period = 30;
87 1.1 scottr
88 1.5 bouyer while ((ch = getopt(argc, argv, "d:g:")) != (-1)) {
89 1.1 scottr switch (ch) {
90 1.1 scottr case 'd':
91 1.1 scottr debug_level = atoi(optarg);
92 1.1 scottr if (!debug_level) {
93 1.5 bouyer usage();
94 1.5 bouyer /* NOTREACHED */
95 1.5 bouyer }
96 1.5 bouyer break;
97 1.5 bouyer case 'g':
98 1.5 bouyer grace_period = atoi(optarg);
99 1.5 bouyer if (!grace_period) {
100 1.5 bouyer usage();
101 1.1 scottr /* NOTREACHED */
102 1.1 scottr }
103 1.1 scottr break;
104 1.1 scottr default:
105 1.1 scottr case '?':
106 1.5 bouyer usage();
107 1.1 scottr /* NOTREACHED */
108 1.1 scottr }
109 1.1 scottr }
110 1.1 scottr
111 1.5 bouyer (void)pmap_unset(NLM_PROG, NLM_SM);
112 1.1 scottr (void)pmap_unset(NLM_PROG, NLM_VERS);
113 1.1 scottr (void)pmap_unset(NLM_PROG, NLM_VERSX);
114 1.4 bouyer (void)pmap_unset(NLM_PROG, NLM_VERS4);
115 1.1 scottr
116 1.1 scottr transp = svcudp_create(RPC_ANYSOCK);
117 1.1 scottr if (transp == NULL) {
118 1.1 scottr errx(1, "cannot create udp service.");
119 1.1 scottr /* NOTREACHED */
120 1.1 scottr }
121 1.5 bouyer if (!svc_register(transp, NLM_PROG, NLM_SM,
122 1.5 bouyer nlm_prog_0, IPPROTO_UDP)) {
123 1.5 bouyer errx(1, "unable to register (NLM_PROG, NLM_SM, udp).");
124 1.5 bouyer /* NOTREACHED */
125 1.5 bouyer }
126 1.1 scottr if (!svc_register(transp, NLM_PROG, NLM_VERS,
127 1.1 scottr nlm_prog_1, IPPROTO_UDP)) {
128 1.1 scottr errx(1, "unable to register (NLM_PROG, NLM_VERS, udp).");
129 1.1 scottr /* NOTREACHED */
130 1.1 scottr }
131 1.1 scottr if (!svc_register(transp, NLM_PROG, NLM_VERSX,
132 1.1 scottr nlm_prog_3, IPPROTO_UDP)) {
133 1.1 scottr errx(1, "unable to register (NLM_PROG, NLM_VERSX, udp).");
134 1.1 scottr /* NOTREACHED */
135 1.1 scottr }
136 1.4 bouyer if (!svc_register(transp, NLM_PROG, NLM_VERS4,
137 1.4 bouyer nlm_prog_4, IPPROTO_UDP)) {
138 1.4 bouyer errx(1, "unable to register (NLM_PROG, NLM_VERS4, udp).");
139 1.4 bouyer /* NOTREACHED */
140 1.4 bouyer }
141 1.1 scottr transp = svctcp_create(RPC_ANYSOCK, 0, 0);
142 1.1 scottr if (transp == NULL) {
143 1.1 scottr errx(1, "cannot create tcp service.");
144 1.1 scottr /* NOTREACHED */
145 1.1 scottr }
146 1.1 scottr if (!svc_register(transp, NLM_PROG, NLM_VERS,
147 1.1 scottr nlm_prog_1, IPPROTO_TCP)) {
148 1.1 scottr errx(1, "unable to register (NLM_PROG, NLM_VERS, tcp).");
149 1.1 scottr /* NOTREACHED */
150 1.1 scottr }
151 1.1 scottr if (!svc_register(transp, NLM_PROG, NLM_VERSX,
152 1.1 scottr nlm_prog_3, IPPROTO_TCP)) {
153 1.1 scottr errx(1, "unable to register (NLM_PROG, NLM_VERSX, tcp).");
154 1.4 bouyer /* NOTREACHED */
155 1.4 bouyer }
156 1.4 bouyer if (!svc_register(transp, NLM_PROG, NLM_VERS4,
157 1.4 bouyer nlm_prog_4, IPPROTO_TCP)) {
158 1.4 bouyer errx(1, "unable to register (NLM_PROG, NLM_VERS4, tcp).");
159 1.1 scottr /* NOTREACHED */
160 1.1 scottr }
161 1.1 scottr
162 1.1 scottr /*
163 1.1 scottr * Note that it is NOT sensible to run this program from inetd - the
164 1.1 scottr * protocol assumes that it will run immediately at boot time.
165 1.1 scottr */
166 1.1 scottr if (daemon(0, 0)) {
167 1.1 scottr err(1, "cannot fork");
168 1.1 scottr /* NOTREACHED */
169 1.1 scottr }
170 1.3 thorpej pidfile(NULL);
171 1.1 scottr
172 1.1 scottr openlog("rpc.lockd", 0, LOG_DAEMON);
173 1.1 scottr if (debug_level)
174 1.1 scottr syslog(LOG_INFO, "Starting, debug level %d", debug_level);
175 1.1 scottr else
176 1.1 scottr syslog(LOG_INFO, "Starting");
177 1.1 scottr
178 1.5 bouyer sigchild.sa_handler = sigchild_handler;
179 1.5 bouyer sigemptyset(&sigchild.sa_mask);
180 1.5 bouyer sigchild.sa_flags = SA_RESTART;
181 1.5 bouyer if (sigaction(SIGCHLD, &sigchild, NULL) != 0) {
182 1.5 bouyer syslog(LOG_WARNING, "sigaction(SIGCHLD) failed: %s",
183 1.5 bouyer strerror(errno));
184 1.5 bouyer exit(1);
185 1.5 bouyer }
186 1.5 bouyer sigalarm.sa_handler = sigalarm_handler;
187 1.5 bouyer sigemptyset(&sigalarm.sa_mask);
188 1.5 bouyer sigalarm.sa_flags = SA_RESETHAND; /* should only happen once */
189 1.5 bouyer sigalarm.sa_flags |= SA_RESTART;
190 1.5 bouyer if (sigaction(SIGALRM, &sigalarm, NULL) != 0) {
191 1.5 bouyer syslog(LOG_WARNING, "sigaction(SIGALRM) failed: %s",
192 1.5 bouyer strerror(errno));
193 1.5 bouyer exit(1);
194 1.5 bouyer }
195 1.5 bouyer grace_expired = 0;
196 1.5 bouyer if (alarm(10) < 0) {
197 1.5 bouyer syslog(LOG_WARNING, "alarm failed: %s",
198 1.5 bouyer strerror(errno));
199 1.5 bouyer exit(1);
200 1.5 bouyer }
201 1.5 bouyer
202 1.1 scottr svc_run(); /* Should never return */
203 1.1 scottr exit(1);
204 1.5 bouyer }
205 1.5 bouyer
206 1.5 bouyer void
207 1.5 bouyer sigalarm_handler(s)
208 1.5 bouyer int s;
209 1.5 bouyer {
210 1.5 bouyer grace_expired = 1;
211 1.5 bouyer }
212 1.5 bouyer
213 1.5 bouyer void
214 1.5 bouyer usage()
215 1.5 bouyer {
216 1.5 bouyer errx(1, "usage: rpc.lockd [-d <debuglevel>] [-g <grace period>]");
217 1.1 scottr }
218