Print this page
Clean up merge problems with illumos#11083 (nfs-zone)
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/uts/common/fs/nfs/nfs_sys.c
+++ new/usr/src/uts/common/fs/nfs/nfs_sys.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
↓ open down ↓ |
14 lines elided |
↑ open up ↑ |
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 - * Copyright 2017 Joyent, Inc.
26 - *
27 25 */
28 26
29 27 /*
30 28 * Copyright (c) 1983,1984,1985,1986,1987,1988,1989 AT&T.
31 29 * All rights reserved.
32 30 */
33 31
34 32 /*
33 + * Copyright 2017 Joyent, Inc.
35 34 * Copyright 2018 Nexenta Systems, Inc.
36 35 */
37 36
38 37 #include <sys/types.h>
39 38 #include <rpc/types.h>
40 39 #include <sys/systm.h>
41 40 #include <sys/vfs.h>
42 41 #include <sys/errno.h>
43 42 #include <sys/cred.h>
44 43 #include <sys/policy.h>
45 44 #include <sys/siginfo.h>
46 45 #include <sys/proc.h> /* for exit() declaration */
47 46 #include <sys/kmem.h>
48 47 #include <nfs/nfs4.h>
49 48 #include <nfs/nfssys.h>
50 49 #include <sys/thread.h>
51 50 #include <rpc/auth.h>
52 51 #include <rpc/rpcsys.h>
53 52 #include <rpc/svc.h>
54 53
55 54 /*
56 55 * This is filled in with an appropriate address for the
57 56 * function that will traverse the rfs4_client_t table
58 57 * and mark any matching IP Address as "forced_expire".
59 58 *
60 59 * It is the server init() function that plops the
61 60 * function pointer.
62 61 */
63 62 void (*rfs4_client_clrst)(struct nfs4clrst_args *) = NULL;
64 63
65 64 /* This filled in by nfssrv:_init() */
66 65 void (*nfs_srv_quiesce_func)(void) = NULL;
67 66
68 67 extern void nfscmd_args(uint_t);
69 68
70 69 /*
71 70 * These will be reset by klmmod:lm_svc(), when lockd starts NLM service,
72 71 * based on values read by lockd from /etc/default/nfs. Since nfssrv depends on
73 72 * klmmod, the declarations need to be here (in nfs, on which both depend) so
74 73 * that nfssrv can see the klmmod changes.
75 74 * When the dependency of NFSv4 on NLM/lockd is removed, this will need to
76 75 * be adjusted.
77 76 */
78 77 #define RFS4_LEASETIME 90 /* seconds */
79 78 time_t rfs4_lease_time = RFS4_LEASETIME;
80 79 time_t rfs4_grace_period = RFS4_LEASETIME;
81 80
82 81 /* DSS: distributed stable storage */
83 82 size_t nfs4_dss_buflen = 0;
84 83 /* This filled in by nfssrv:_init() */
85 84 int (*nfs_srv_dss_func)(char *, size_t) = NULL;
86 85
87 86 int
88 87 nfs_export(void *arg)
89 88 {
90 89 STRUCT_DECL(exportfs_args, ea);
91 90
92 91 STRUCT_INIT(ea, get_udatamodel());
93 92 if (copyin(arg, STRUCT_BUF(ea), STRUCT_SIZE(ea)))
94 93 return (set_errno(EFAULT));
95 94
96 95 return (exportfs(STRUCT_BUF(ea), get_udatamodel(), CRED()));
97 96 }
98 97
99 98 int
100 99 nfssys(enum nfssys_op opcode, void *arg)
101 100 {
102 101 int error = 0;
103 102
104 103 if (!(opcode == NFS_REVAUTH || opcode == NFS4_SVC) &&
105 104 secpolicy_nfs(CRED()) != 0)
106 105 return (set_errno(EPERM));
107 106
108 107 switch (opcode) {
109 108 case NFS4_CLR_STATE: { /* Clear NFS4 client state */
110 109 struct nfs4clrst_args clr;
111 110 STRUCT_DECL(nfs4clrst_args, u_clr);
112 111
113 112 /*
114 113 * If the server is not loaded then no point in
115 114 * clearing nothing :-)
116 115 */
117 116 if (rfs4_client_clrst == NULL) {
118 117 break;
119 118 }
120 119
121 120 STRUCT_INIT(u_clr, get_udatamodel());
122 121
123 122 if (copyin(arg, STRUCT_BUF(u_clr), STRUCT_SIZE(u_clr)))
124 123 return (set_errno(EFAULT));
125 124
126 125 clr.vers = STRUCT_FGET(u_clr, vers);
127 126
128 127 if (clr.vers != NFS4_CLRST_VERSION)
129 128 return (set_errno(EINVAL));
130 129
131 130 clr.addr_type = STRUCT_FGET(u_clr, addr_type);
132 131 clr.ap = STRUCT_FGETP(u_clr, ap);
133 132 rfs4_client_clrst(&clr);
134 133 break;
135 134 }
136 135
137 136 case SVCPOOL_CREATE: { /* setup an RPC server thread pool */
138 137 struct svcpool_args p;
139 138
140 139 if (copyin(arg, &p, sizeof (p)))
141 140 return (set_errno(EFAULT));
142 141
143 142 error = svc_pool_create(&p);
144 143 break;
145 144 }
146 145
147 146 case SVCPOOL_WAIT: { /* wait in kernel for threads to be needed */
148 147 int id;
149 148
150 149 if (copyin(arg, &id, sizeof (id)))
151 150 return (set_errno(EFAULT));
152 151
153 152 error = svc_wait(id);
154 153 break;
155 154 }
156 155
157 156 case SVCPOOL_RUN: { /* give work to a runnable thread */
158 157 int id;
159 158
160 159 if (copyin(arg, &id, sizeof (id)))
161 160 return (set_errno(EFAULT));
162 161
163 162 error = svc_do_run(id);
164 163 break;
165 164 }
166 165
167 166 case RDMA_SVC_INIT: {
168 167 struct rdma_svc_args rsa;
169 168 char netstore[20] = "tcp";
170 169
171 170 if (get_udatamodel() != DATAMODEL_NATIVE) {
172 171 STRUCT_DECL(rdma_svc_args, ursa);
173 172
174 173 STRUCT_INIT(ursa, get_udatamodel());
175 174 if (copyin(arg, STRUCT_BUF(ursa), STRUCT_SIZE(ursa)))
176 175 return (set_errno(EFAULT));
177 176
178 177 rsa.poolid = STRUCT_FGET(ursa, poolid);
179 178 rsa.nfs_versmin = STRUCT_FGET(ursa, nfs_versmin);
180 179 rsa.nfs_versmax = STRUCT_FGET(ursa, nfs_versmax);
181 180 rsa.delegation = STRUCT_FGET(ursa, delegation);
182 181 } else {
183 182 if (copyin(arg, &rsa, sizeof (rsa)))
184 183 return (set_errno(EFAULT));
185 184 }
186 185 rsa.netid = netstore;
187 186
188 187 error = rdma_start(&rsa);
189 188 break;
190 189 }
191 190
192 191 case NFS_SVC: { /* NFS server daemon */
193 192 STRUCT_DECL(nfs_svc_args, nsa);
194 193 STRUCT_INIT(nsa, get_udatamodel());
195 194
196 195 if (copyin(arg, STRUCT_BUF(nsa), STRUCT_SIZE(nsa)))
197 196 return (set_errno(EFAULT));
198 197
199 198 error = nfs_svc(STRUCT_BUF(nsa), get_udatamodel());
200 199 break;
201 200 }
202 201
203 202 case EXPORTFS: { /* export a file system */
204 203 error = nfs_export(arg);
205 204 break;
206 205 }
207 206
208 207 case NFS_GETFH: { /* get a file handle */
209 208 STRUCT_DECL(nfs_getfh_args, nga);
210 209
211 210 STRUCT_INIT(nga, get_udatamodel());
212 211 if (copyin(arg, STRUCT_BUF(nga), STRUCT_SIZE(nga)))
213 212 return (set_errno(EFAULT));
214 213
215 214 error = nfs_getfh(STRUCT_BUF(nga), get_udatamodel(), CRED());
216 215 break;
217 216 }
218 217
219 218 case NFS_REVAUTH: { /* revoke the cached credentials for the uid */
220 219 STRUCT_DECL(nfs_revauth_args, nra);
221 220
222 221 STRUCT_INIT(nra, get_udatamodel());
223 222 if (copyin(arg, STRUCT_BUF(nra), STRUCT_SIZE(nra)))
224 223 return (set_errno(EFAULT));
225 224
226 225 /* This call performs its own privilege checking */
227 226 error = sec_clnt_revoke(STRUCT_FGET(nra, authtype),
228 227 STRUCT_FGET(nra, uid), CRED(), NULL, get_udatamodel());
229 228 break;
230 229 }
231 230
232 231 case LM_SVC: { /* LM server daemon */
233 232 struct lm_svc_args lsa;
234 233
235 234 if (get_udatamodel() != DATAMODEL_NATIVE) {
236 235 STRUCT_DECL(lm_svc_args, ulsa);
237 236
238 237 STRUCT_INIT(ulsa, get_udatamodel());
239 238 if (copyin(arg, STRUCT_BUF(ulsa), STRUCT_SIZE(ulsa)))
240 239 return (set_errno(EFAULT));
241 240
242 241 lsa.version = STRUCT_FGET(ulsa, version);
243 242 lsa.fd = STRUCT_FGET(ulsa, fd);
244 243 lsa.n_fmly = STRUCT_FGET(ulsa, n_fmly);
245 244 lsa.n_proto = STRUCT_FGET(ulsa, n_proto);
246 245 lsa.n_rdev = expldev(STRUCT_FGET(ulsa, n_rdev));
247 246 lsa.n_v4_only = STRUCT_FGET(ulsa, n_v4_only);
248 247 lsa.timout = STRUCT_FGET(ulsa, timout);
249 248 lsa.grace = STRUCT_FGET(ulsa, grace);
250 249 lsa.retransmittimeout = STRUCT_FGET(ulsa,
251 250 retransmittimeout);
252 251 } else {
253 252 if (copyin(arg, &lsa, sizeof (lsa)))
254 253 return (set_errno(EFAULT));
255 254 }
256 255
257 256 error = lm_svc(&lsa);
258 257 break;
259 258 }
260 259
261 260 case KILL_LOCKMGR: {
262 261 error = lm_shutdown();
263 262 break;
264 263 }
265 264
266 265 case LOG_FLUSH: { /* Flush log buffer and possibly rename */
267 266 STRUCT_DECL(nfsl_flush_args, nfa);
268 267
269 268 STRUCT_INIT(nfa, get_udatamodel());
270 269 if (copyin(arg, STRUCT_BUF(nfa), STRUCT_SIZE(nfa)))
271 270 return (set_errno(EFAULT));
272 271
273 272 error = nfsl_flush(STRUCT_BUF(nfa), get_udatamodel());
274 273 break;
275 274 }
276 275
277 276 case NFS4_SVC: { /* NFS client callback daemon */
278 277
279 278 STRUCT_DECL(nfs4_svc_args, nsa);
280 279
281 280 STRUCT_INIT(nsa, get_udatamodel());
282 281
283 282 if (copyin(arg, STRUCT_BUF(nsa), STRUCT_SIZE(nsa)))
284 283 return (set_errno(EFAULT));
285 284
286 285 error = nfs4_svc(STRUCT_BUF(nsa), get_udatamodel());
287 286 break;
288 287 }
289 288
290 289 /* Request that NFSv4 server quiesce on next shutdown */
291 290 case NFS4_SVC_REQUEST_QUIESCE: {
292 291 int id;
293 292
294 293 /* check that nfssrv module is loaded */
295 294 if (nfs_srv_quiesce_func == NULL)
296 295 return (set_errno(ENOTSUP));
297 296
298 297 if (copyin(arg, &id, sizeof (id)))
299 298 return (set_errno(EFAULT));
300 299
301 300 error = svc_pool_control(id, SVCPSET_SHUTDOWN_PROC,
302 301 (void *)nfs_srv_quiesce_func);
303 302 break;
304 303 }
305 304
306 305 case NFS_IDMAP: {
307 306 struct nfsidmap_args idm;
308 307
309 308 if (copyin(arg, &idm, sizeof (idm)))
310 309 return (set_errno(EFAULT));
311 310
312 311 nfs_idmap_args(&idm);
313 312 error = 0;
314 313 break;
315 314 }
316 315
317 316 case NFS4_DSS_SETPATHS_SIZE: {
318 317 /* crosses ILP32/LP64 boundary */
319 318 uint32_t nfs4_dss_bufsize = 0;
320 319
321 320 if (copyin(arg, &nfs4_dss_bufsize, sizeof (nfs4_dss_bufsize)))
322 321 return (set_errno(EFAULT));
323 322 nfs4_dss_buflen = (long)nfs4_dss_bufsize;
324 323 error = 0;
325 324 break;
326 325 }
327 326
328 327 case NFS4_DSS_SETPATHS: {
329 328 char *nfs4_dss_bufp;
330 329
331 330 /* check that nfssrv module is loaded */
332 331 if (nfs_srv_dss_func == NULL)
333 332 return (set_errno(ENOTSUP));
334 333
335 334 /*
336 335 * NFS4_DSS_SETPATHS_SIZE must be called before
337 336 * NFS4_DSS_SETPATHS, to tell us how big a buffer we need
338 337 * to allocate.
339 338 */
340 339 if (nfs4_dss_buflen == 0)
341 340 return (set_errno(EINVAL));
342 341 nfs4_dss_bufp = kmem_alloc(nfs4_dss_buflen, KM_SLEEP);
343 342 if (nfs4_dss_bufp == NULL)
344 343 return (set_errno(ENOMEM));
345 344
346 345 if (copyin(arg, nfs4_dss_bufp, nfs4_dss_buflen)) {
347 346 kmem_free(nfs4_dss_bufp, nfs4_dss_buflen);
348 347 return (set_errno(EFAULT));
349 348 }
350 349
351 350 /* unpack the buffer and extract the pathnames */
352 351 error = nfs_srv_dss_func(nfs4_dss_bufp, nfs4_dss_buflen);
353 352 kmem_free(nfs4_dss_bufp, nfs4_dss_buflen);
354 353
355 354 break;
356 355 }
357 356
358 357 case NFS4_EPHEMERAL_MOUNT_TO: {
359 358 uint_t mount_to;
360 359
361 360 /*
362 361 * Not a very complicated call.
363 362 */
364 363 if (copyin(arg, &mount_to, sizeof (mount_to)))
365 364 return (set_errno(EFAULT));
366 365 nfs4_ephemeral_set_mount_to(mount_to);
367 366 error = 0;
368 367 break;
369 368 }
370 369
371 370 case MOUNTD_ARGS: {
372 371 uint_t did;
373 372
374 373 /*
375 374 * For now, only passing down the door fd; if we
376 375 * ever need to pass down more info, we can use
377 376 * a (properly aligned) struct.
378 377 */
379 378 if (copyin(arg, &did, sizeof (did)))
380 379 return (set_errno(EFAULT));
381 380 mountd_args(did);
382 381 error = 0;
383 382 break;
384 383 }
385 384
386 385 case NFSCMD_ARGS: {
387 386 uint_t did;
388 387
389 388 /*
390 389 * For now, only passing down the door fd; if we
391 390 * ever need to pass down more info, we can use
392 391 * a (properly aligned) struct.
393 392 */
394 393 if (copyin(arg, &did, sizeof (did)))
395 394 return (set_errno(EFAULT));
396 395 nfscmd_args(did);
397 396 error = 0;
398 397 break;
399 398 }
400 399
401 400 default:
402 401 error = EINVAL;
403 402 break;
404 403 }
405 404
406 405 return ((error != 0) ? set_errno(error) : 0);
407 406 }
|
↓ open down ↓ |
363 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX