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