File: | xlators/nfs/server/src/mount3.c |
Location: | line 654, column 25 |
Description: | Value stored to 'pfh' during its initialization is never read |
1 | /* |
2 | Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com> |
3 | This file is part of GlusterFS. |
4 | |
5 | GlusterFS is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published |
7 | by the Free Software Foundation; either version 3 of the License, |
8 | or (at your option) any later version. |
9 | |
10 | GlusterFS is distributed in the hope that it will be useful, but |
11 | WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | General Public License for more details. |
14 | |
15 | You should have received a copy of the GNU General Public License |
16 | along with this program. If not, see |
17 | <http://www.gnu.org/licenses/>. |
18 | */ |
19 | |
20 | #ifndef _CONFIG_H |
21 | #define _CONFIG_H |
22 | #include "config.h" |
23 | #endif |
24 | |
25 | #include "rpcsvc.h" |
26 | #include "dict.h" |
27 | #include "xlator.h" |
28 | #include "mount3.h" |
29 | #include "xdr-nfs3.h" |
30 | #include "msg-nfs3.h" |
31 | #include "iobuf.h" |
32 | #include "nfs-common.h" |
33 | #include "nfs3-fh.h" |
34 | #include "nfs-fops.h" |
35 | #include "nfs-inodes.h" |
36 | #include "nfs-generics.h" |
37 | #include "locking.h" |
38 | #include "iatt.h" |
39 | #include "nfs-mem-types.h" |
40 | #include "nfs.h" |
41 | #include "common-utils.h" |
42 | |
43 | |
44 | #include <errno(*__errno_location ()).h> |
45 | #include <sys/socket.h> |
46 | #include <sys/uio.h> |
47 | |
48 | typedef ssize_t (*mnt3_serializer) (struct iovec outmsg, void *args); |
49 | |
50 | extern void * |
51 | mount3udp_thread (void *argv); |
52 | |
53 | |
54 | /* Generic reply function for MOUNTv3 specific replies. */ |
55 | int |
56 | mnt3svc_submit_reply (rpcsvc_request_t *req, void *arg, mnt3_serializer sfunc) |
57 | { |
58 | struct iovec outmsg = {0, }; |
59 | struct iobuf *iob = NULL((void*)0); |
60 | struct mount3_state *ms = NULL((void*)0); |
61 | int ret = -1; |
62 | struct iobref *iobref = NULL((void*)0); |
63 | |
64 | if (!req) |
65 | return -1; |
66 | |
67 | ms = (struct mount3_state *)rpcsvc_request_program_private (req)(((rpcsvc_program_t *)((req)->prog))->private); |
68 | if (!ms) { |
69 | gf_log (GF_MNT, GF_LOG_ERROR, "mount state not found")do { do { if (0) printf ("mount state not found"); } while (0 ); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 69, GF_LOG_ERROR , "mount state not found"); } while (0); |
70 | goto ret; |
71 | } |
72 | |
73 | /* First, get the io buffer into which the reply in arg will |
74 | * be serialized. |
75 | */ |
76 | /* TODO: use 'xdrproc_t' instead of 'sfunc' to get the xdr-size */ |
77 | iob = iobuf_get (ms->iobpool); |
78 | if (!iob) { |
79 | gf_log (GF_MNT, GF_LOG_ERROR, "Failed to get iobuf")do { do { if (0) printf ("Failed to get iobuf"); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 79, GF_LOG_ERROR , "Failed to get iobuf"); } while (0); |
80 | goto ret; |
81 | } |
82 | |
83 | iobuf_to_iovec (iob, &outmsg); |
84 | /* Use the given serializer to translate the give C structure in arg |
85 | * to XDR format which will be written into the buffer in outmsg. |
86 | */ |
87 | outmsg.iov_len = sfunc (outmsg, arg); |
88 | |
89 | iobref = iobref_new (); |
90 | if (iobref == NULL((void*)0)) { |
91 | gf_log (GF_MNT, GF_LOG_ERROR, "Failed to get iobref")do { do { if (0) printf ("Failed to get iobref"); } while (0) ; _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 91, GF_LOG_ERROR , "Failed to get iobref"); } while (0); |
92 | goto ret; |
93 | } |
94 | |
95 | iobref_add (iobref, iob); |
96 | |
97 | /* Then, submit the message for transmission. */ |
98 | ret = rpcsvc_submit_message (req, &outmsg, 1, NULL((void*)0), 0, iobref); |
99 | iobuf_unref (iob); |
100 | iobref_unref (iobref); |
101 | if (ret == -1) { |
102 | gf_log (GF_MNT, GF_LOG_ERROR, "Reply submission failed")do { do { if (0) printf ("Reply submission failed"); } while ( 0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 102, GF_LOG_ERROR , "Reply submission failed"); } while (0); |
103 | goto ret; |
104 | } |
105 | |
106 | ret = 0; |
107 | ret: |
108 | return ret; |
109 | } |
110 | |
111 | |
112 | /* Generic error reply function, just pass the err status |
113 | * and it will do the rest, including transmission. |
114 | */ |
115 | int |
116 | mnt3svc_mnt_error_reply (rpcsvc_request_t *req, int mntstat) |
117 | { |
118 | mountres3 res; |
119 | |
120 | if (!req) |
121 | return -1; |
122 | |
123 | res.fhs_status = mntstat; |
124 | mnt3svc_submit_reply (req, (void *)&res, |
125 | (mnt3_serializer)xdr_serialize_mountres3); |
126 | |
127 | return 0; |
128 | } |
129 | |
130 | |
131 | mountstat3 |
132 | mnt3svc_errno_to_mnterr (int32_t errnum) |
133 | { |
134 | mountstat3 stat; |
135 | |
136 | switch (errnum) { |
137 | |
138 | case 0: |
139 | stat = MNT3_OK; |
140 | break; |
141 | case ENOENT2: |
142 | stat = MNT3ERR_NOENT; |
143 | break; |
144 | case EPERM1: |
145 | stat = MNT3ERR_PERM; |
146 | break; |
147 | case EIO5: |
148 | stat = MNT3ERR_IO; |
149 | break; |
150 | case EACCES13: |
151 | stat = MNT3ERR_ACCES; |
152 | break; |
153 | case ENOTDIR20: |
154 | stat = MNT3ERR_NOTDIR; |
155 | break; |
156 | case EINVAL22: |
157 | stat = MNT3ERR_INVAL; |
158 | break; |
159 | case ENOSYS38: |
160 | stat = MNT3ERR_NOTSUPP; |
161 | break; |
162 | case ENOMEM12: |
163 | stat = MNT3ERR_SERVERFAULT; |
164 | break; |
165 | default: |
166 | stat = MNT3ERR_SERVERFAULT; |
167 | break; |
168 | } |
169 | |
170 | return stat; |
171 | } |
172 | |
173 | |
174 | mountres3 |
175 | mnt3svc_set_mountres3 (mountstat3 stat, struct nfs3_fh *fh, int *authflavor, |
176 | u_int aflen) |
177 | { |
178 | mountres3 res = {0, }; |
179 | uint32_t fhlen = 0; |
180 | |
181 | res.fhs_status = stat; |
182 | fhlen = nfs3_fh_compute_size (fh); |
183 | res.mountres3_u.mountinfo.fhandle.fhandle3_len = fhlen; |
184 | res.mountres3_u.mountinfo.fhandle.fhandle3_val = (char *)fh; |
185 | res.mountres3_u.mountinfo.auth_flavors.auth_flavors_val = authflavor; |
186 | res.mountres3_u.mountinfo.auth_flavors.auth_flavors_len = aflen; |
187 | |
188 | return res; |
189 | } |
190 | |
191 | |
192 | int |
193 | mnt3svc_update_mountlist (struct mount3_state *ms, rpcsvc_request_t *req, |
194 | char *expname) |
195 | { |
196 | struct mountentry *me = NULL((void*)0); |
197 | int ret = -1; |
198 | char *colon = NULL((void*)0); |
199 | |
200 | if ((!ms) || (!req) || (!expname)) |
201 | return -1; |
202 | |
203 | me = (struct mountentry *)GF_CALLOC (1, sizeof (*me),__gf_calloc (1, sizeof (*me), gf_nfs_mt_mountentry) |
204 | gf_nfs_mt_mountentry)__gf_calloc (1, sizeof (*me), gf_nfs_mt_mountentry); |
205 | if (!me) |
206 | return -1; |
207 | |
208 | strcpy (me->exname, expname); |
209 | INIT_LIST_HEAD (&me->mlist)do { (&me->mlist)->next = (&me->mlist)->prev = &me->mlist; } while (0); |
210 | /* Must get the IP or hostname of the client so we |
211 | * can map it into the mount entry. |
212 | */ |
213 | ret = rpcsvc_transport_peername (req->trans, me->hostname, MNTPATHLEN1024); |
214 | if (ret == -1) |
215 | goto free_err; |
216 | |
217 | colon = strrchr (me->hostname, ':'); |
218 | if (colon) { |
219 | *colon = '\0'; |
220 | } |
221 | LOCK (&ms->mountlock)pthread_spin_lock (&ms->mountlock); |
222 | { |
223 | list_add_tail (&me->mlist, &ms->mountlist); |
224 | } |
225 | UNLOCK (&ms->mountlock)pthread_spin_unlock (&ms->mountlock); |
226 | |
227 | free_err: |
228 | if (ret == -1) |
229 | GF_FREE (me)__gf_free (me); |
230 | |
231 | return ret; |
232 | } |
233 | |
234 | |
235 | int |
236 | __mnt3_get_volume_id (struct mount3_state *ms, xlator_t *mntxl, |
237 | uuid_t volumeid) |
238 | { |
239 | int ret = -1; |
240 | struct mnt3_export *exp = NULL((void*)0); |
241 | |
242 | if ((!ms) || (!mntxl)) |
243 | return ret; |
244 | |
245 | list_for_each_entry (exp, &ms->exportlist, explist)for (exp = ((typeof(*exp) *)((char *)((&ms->exportlist )->next)-(unsigned long)(&((typeof(*exp) *)0)->explist ))); &exp->explist != (&ms->exportlist); exp = ( (typeof(*exp) *)((char *)(exp->explist.next)-(unsigned long )(&((typeof(*exp) *)0)->explist)))) { |
246 | if (exp->vol == mntxl) { |
247 | uuid_copy (volumeid, exp->volumeid); |
248 | ret = 0; |
249 | goto out; |
250 | } |
251 | } |
252 | |
253 | out: |
254 | return ret; |
255 | } |
256 | |
257 | |
258 | int32_t |
259 | mnt3svc_lookup_mount_cbk (call_frame_t *frame, void *cookie, |
260 | xlator_t *this, int32_t op_ret, int32_t op_errno, |
261 | inode_t *inode, struct iatt *buf, dict_t *xattr, |
262 | struct iatt *postparent) |
263 | { |
264 | mountres3 res = {0, }; |
265 | rpcsvc_request_t *req = NULL((void*)0); |
266 | struct nfs3_fh fh = {{0}, }; |
267 | struct mount3_state *ms = NULL((void*)0); |
268 | mountstat3 status = 0; |
269 | int autharr[10]; |
270 | int autharrlen = 0; |
271 | rpcsvc_t *svc = NULL((void*)0); |
272 | xlator_t *mntxl = NULL((void*)0); |
273 | uuid_t volumeid = {0, }; |
274 | char fhstr[1024]; |
275 | |
276 | req = (rpcsvc_request_t *)frame->local; |
277 | |
278 | if (!req) |
279 | return -1; |
280 | |
281 | mntxl = (xlator_t *)cookie; |
282 | ms = (struct mount3_state *)rpcsvc_request_program_private (req)(((rpcsvc_program_t *)((req)->prog))->private); |
283 | if (!ms) { |
284 | gf_log (GF_MNT, GF_LOG_ERROR, "mount state not found")do { do { if (0) printf ("mount state not found"); } while (0 ); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 284, GF_LOG_ERROR , "mount state not found"); } while (0); |
285 | op_ret = -1; |
286 | op_errno = EINVAL22; |
287 | } |
288 | |
289 | if (op_ret == -1) { |
290 | gf_log (GF_NFS, GF_LOG_ERROR, "error=%s", strerror (op_errno))do { do { if (0) printf ("error=%s", strerror (op_errno)); } while (0); _gf_log ("nfs", "mount3.c", __FUNCTION__, 290, GF_LOG_ERROR , "error=%s", strerror (op_errno)); } while (0); |
291 | status = mnt3svc_errno_to_mnterr (op_errno); |
292 | } |
293 | if (status != MNT3_OK) |
294 | goto xmit_res; |
295 | |
296 | mnt3svc_update_mountlist (ms, req, mntxl->name); |
297 | if (gf_nfs_dvm_off (nfs_state (ms->nfsx))(((struct nfs_state *)(ms->nfsx)->private)->dynamicvolumes == 2)) { |
298 | fh = nfs3_fh_build_indexed_root_fh (ms->nfsx->children, mntxl); |
299 | goto xmit_res; |
300 | } |
301 | |
302 | __mnt3_get_volume_id (ms, mntxl, volumeid); |
303 | fh = nfs3_fh_build_uuid_root_fh (volumeid); |
304 | |
305 | xmit_res: |
306 | nfs3_fh_to_str (&fh, fhstr); |
307 | gf_log (GF_MNT, GF_LOG_DEBUG, "MNT reply: fh %s, status: %d", fhstr,do { do { if (0) printf ("MNT reply: fh %s, status: %d", fhstr , status); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__ , 308, GF_LOG_DEBUG, "MNT reply: fh %s, status: %d", fhstr, status ); } while (0) |
308 | status)do { do { if (0) printf ("MNT reply: fh %s, status: %d", fhstr , status); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__ , 308, GF_LOG_DEBUG, "MNT reply: fh %s, status: %d", fhstr, status ); } while (0); |
309 | if (op_ret == 0) { |
310 | svc = rpcsvc_request_service (req)((req)->svc); |
311 | autharrlen = rpcsvc_auth_array (svc, mntxl->name, autharr, |
312 | 10); |
313 | } |
314 | |
315 | res = mnt3svc_set_mountres3 (status, &fh, autharr, autharrlen); |
316 | mnt3svc_submit_reply (req, (void *)&res, |
317 | (mnt3_serializer)xdr_serialize_mountres3); |
318 | |
319 | return 0; |
320 | } |
321 | |
322 | |
323 | int |
324 | mnt3_match_dirpath_export (char *expname, char *dirpath) |
325 | { |
326 | int ret = 0; |
327 | size_t dlen; |
328 | |
329 | if ((!expname) || (!dirpath)) |
330 | return 0; |
331 | |
332 | /* Some clients send a dirpath for mount that includes the slash at the |
333 | * end. String compare for searching the export will fail because our |
334 | * exports list does not include that slash. Remove the slash to |
335 | * compare. |
336 | */ |
337 | dlen = strlen (dirpath); |
338 | if (dlen && dirpath [dlen - 1] == '/') |
339 | dirpath [dlen - 1] = '\0'; |
340 | |
341 | if (dirpath[0] != '/') |
342 | expname++; |
343 | |
344 | if (strcmp (expname, dirpath) == 0) |
345 | ret = 1; |
346 | |
347 | return ret; |
348 | } |
349 | |
350 | |
351 | int |
352 | mnt3svc_mount_inode (rpcsvc_request_t *req, struct mount3_state *ms, |
353 | xlator_t * xl, inode_t *exportinode) |
354 | { |
355 | int ret = -EFAULT14; |
356 | nfs_user_t nfu = {0, }; |
357 | loc_t exportloc = {0, }; |
358 | |
359 | if ((!req) || (!xl) || (!ms) || (!exportinode)) |
360 | return ret; |
361 | |
362 | ret = nfs_inode_loc_fill (exportinode, &exportloc, NFS_RESOLVE_EXIST1); |
363 | if (ret < 0) { |
364 | gf_log (GF_MNT, GF_LOG_ERROR, "Loc fill failed for export inode"do { do { if (0) printf ("Loc fill failed for export inode" ": gfid %s, volume: %s" , uuid_utoa (exportinode->gfid), xl->name); } while (0) ; _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 366, GF_LOG_ERROR , "Loc fill failed for export inode" ": gfid %s, volume: %s", uuid_utoa (exportinode->gfid), xl->name); } while (0) |
365 | ": gfid %s, volume: %s",do { do { if (0) printf ("Loc fill failed for export inode" ": gfid %s, volume: %s" , uuid_utoa (exportinode->gfid), xl->name); } while (0) ; _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 366, GF_LOG_ERROR , "Loc fill failed for export inode" ": gfid %s, volume: %s", uuid_utoa (exportinode->gfid), xl->name); } while (0) |
366 | uuid_utoa (exportinode->gfid), xl->name)do { do { if (0) printf ("Loc fill failed for export inode" ": gfid %s, volume: %s" , uuid_utoa (exportinode->gfid), xl->name); } while (0) ; _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 366, GF_LOG_ERROR , "Loc fill failed for export inode" ": gfid %s, volume: %s", uuid_utoa (exportinode->gfid), xl->name); } while (0); |
367 | goto err; |
368 | } |
369 | |
370 | /* To service the mount request, all we need to do |
371 | * is to send a lookup fop that returns the stat |
372 | * for the root of the child volume. This is |
373 | * used to build the root fh sent to the client. |
374 | */ |
375 | nfs_request_user_init (&nfu, req); |
376 | ret = nfs_lookup (ms->nfsx, xl, &nfu, &exportloc, |
377 | mnt3svc_lookup_mount_cbk, (void *)req); |
378 | |
379 | nfs_loc_wipe (&exportloc); |
380 | err: |
381 | return ret; |
382 | } |
383 | |
384 | |
385 | /* For a volume mount request, we just have to create loc on the root inode, |
386 | * and send a lookup. In the lookup callback the mount reply is send along with |
387 | * the file handle. |
388 | */ |
389 | int |
390 | mnt3svc_volume_mount (rpcsvc_request_t *req, struct mount3_state *ms, |
391 | struct mnt3_export *exp) |
392 | { |
393 | inode_t *exportinode = NULL((void*)0); |
394 | int ret = -EFAULT14; |
395 | uuid_t rootgfid = {0, }; |
396 | |
397 | if ((!req) || (!exp) || (!ms)) |
398 | return ret; |
399 | |
400 | rootgfid[15] = 1; |
401 | exportinode = inode_find (exp->vol->itable, rootgfid); |
402 | if (!exportinode) { |
403 | gf_log (GF_MNT, GF_LOG_ERROR, "Failed to get root inode")do { do { if (0) printf ("Failed to get root inode"); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 403, GF_LOG_ERROR , "Failed to get root inode"); } while (0); |
404 | ret = -ENOENT2; |
405 | goto err; |
406 | } |
407 | |
408 | ret = mnt3svc_mount_inode (req, ms, exp->vol, exportinode); |
409 | inode_unref (exportinode); |
410 | |
411 | err: |
412 | return ret; |
413 | } |
414 | |
415 | |
416 | /* The catch with directory exports is that the first component of the export |
417 | * name will be the name of the volume. |
418 | * Any lookup that needs to be performed to build the directory's file handle |
419 | * needs to start from the directory path from the root of the volume. For that |
420 | * we need to strip out the volume name first. |
421 | */ |
422 | char * |
423 | __volume_subdir (char *dirpath, char **volname) |
424 | { |
425 | char *subdir = NULL((void*)0); |
426 | int volname_len = 0; |
427 | |
428 | if (!dirpath) |
429 | return NULL((void*)0); |
430 | |
431 | if (dirpath[0] == '/') |
432 | dirpath++; |
433 | |
434 | subdir = index (dirpath, (int)'/'); |
435 | if (!subdir) |
436 | goto out; |
437 | |
438 | if (!volname) |
439 | goto out; |
440 | |
441 | if (!*volname) |
442 | goto out; |
443 | |
444 | /* subdir points to the first / after the volume name while dirpath |
445 | * points to the first char of the volume name. |
446 | */ |
447 | volname_len = subdir - dirpath; |
448 | strncpy (*volname, dirpath, volname_len); |
449 | *(*volname + volname_len) = '\0'; |
450 | out: |
451 | return subdir; |
452 | } |
453 | |
454 | |
455 | void |
456 | mnt3_resolve_state_wipe (mnt3_resolve_t *mres) |
457 | { |
458 | if (!mres) |
459 | return; |
460 | |
461 | nfs_loc_wipe (&mres->resolveloc); |
462 | GF_FREE (mres)__gf_free (mres); |
463 | |
464 | } |
465 | |
466 | |
467 | /* Sets up the component argument to contain the next component in the path and |
468 | * sets up path as an absolute path starting from the next component. |
469 | */ |
470 | char * |
471 | __setup_next_component (char *path, char *component) |
472 | { |
473 | char *comp = NULL((void*)0); |
474 | char *nextcomp = NULL((void*)0); |
475 | |
476 | if ((!path) || (!component)) |
477 | return NULL((void*)0); |
478 | |
479 | strcpy (component, path); |
480 | comp = index (component, (int)'/'); |
481 | if (!comp) |
482 | goto err; |
483 | |
484 | comp++; |
485 | nextcomp = index (comp, (int)'/'); |
486 | if (nextcomp) { |
487 | strcpy (path, nextcomp); |
488 | *nextcomp = '\0'; |
489 | } else |
490 | path[0] = '\0'; |
491 | |
492 | err: |
493 | return comp; |
494 | } |
495 | |
496 | int32_t |
497 | mnt3_resolve_subdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, |
498 | int32_t op_ret, int32_t op_errno, inode_t *inode, |
499 | struct iatt *buf, dict_t *xattr, |
500 | struct iatt *postparent); |
501 | |
502 | /* There are multiple components in the directory export path and each one |
503 | * needs to be looked up one after the other. |
504 | */ |
505 | int |
506 | __mnt3_resolve_export_subdir_comp (mnt3_resolve_t *mres) |
507 | { |
508 | char dupsubdir[MNTPATHLEN1024]; |
509 | char *nextcomp = NULL((void*)0); |
510 | int ret = -EFAULT14; |
511 | nfs_user_t nfu = {0, }; |
512 | uuid_t gfid = {0, }; |
513 | |
514 | if (!mres) |
515 | return ret; |
516 | |
517 | nextcomp = __setup_next_component (mres->remainingdir, dupsubdir); |
518 | if (!nextcomp) |
519 | goto err; |
520 | |
521 | /* Wipe the contents of the previous component */ |
522 | uuid_copy (gfid, mres->resolveloc.inode->gfid); |
523 | nfs_loc_wipe (&mres->resolveloc); |
524 | ret = nfs_entry_loc_fill (mres->exp->vol->itable, gfid, nextcomp, |
525 | &mres->resolveloc, NFS_RESOLVE_CREATE2); |
526 | if ((ret < 0) && (ret != -2)) { |
527 | gf_log (GF_MNT, GF_LOG_ERROR, "Failed to resolve and create "do { do { if (0) printf ("Failed to resolve and create " "inode: parent gfid %s, entry %s" , uuid_utoa (mres->resolveloc.inode->gfid), nextcomp); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 529, GF_LOG_ERROR, "Failed to resolve and create " "inode: parent gfid %s, entry %s" , uuid_utoa (mres->resolveloc.inode->gfid), nextcomp); } while (0) |
528 | "inode: parent gfid %s, entry %s",do { do { if (0) printf ("Failed to resolve and create " "inode: parent gfid %s, entry %s" , uuid_utoa (mres->resolveloc.inode->gfid), nextcomp); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 529, GF_LOG_ERROR, "Failed to resolve and create " "inode: parent gfid %s, entry %s" , uuid_utoa (mres->resolveloc.inode->gfid), nextcomp); } while (0) |
529 | uuid_utoa (mres->resolveloc.inode->gfid), nextcomp)do { do { if (0) printf ("Failed to resolve and create " "inode: parent gfid %s, entry %s" , uuid_utoa (mres->resolveloc.inode->gfid), nextcomp); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 529, GF_LOG_ERROR, "Failed to resolve and create " "inode: parent gfid %s, entry %s" , uuid_utoa (mres->resolveloc.inode->gfid), nextcomp); } while (0); |
530 | ret = -EFAULT14; |
531 | goto err; |
532 | } |
533 | |
534 | nfs_request_user_init (&nfu, mres->req); |
535 | ret = nfs_lookup (mres->mstate->nfsx, mres->exp->vol, &nfu, |
536 | &mres->resolveloc, mnt3_resolve_subdir_cbk, mres); |
537 | |
538 | err: |
539 | return ret; |
540 | } |
541 | |
542 | |
543 | int32_t |
544 | mnt3_resolve_subdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, |
545 | int32_t op_ret, int32_t op_errno, inode_t *inode, |
546 | struct iatt *buf, dict_t *xattr, |
547 | struct iatt *postparent) |
548 | { |
549 | mnt3_resolve_t *mres = NULL((void*)0); |
550 | mountstat3 mntstat = MNT3ERR_SERVERFAULT; |
551 | struct nfs3_fh fh = {{0}, }; |
552 | int autharr[10]; |
553 | int autharrlen = 0; |
554 | rpcsvc_t *svc = NULL((void*)0); |
555 | mountres3 res = {0, }; |
556 | xlator_t *mntxl = NULL((void*)0); |
557 | |
558 | mres = frame->local; |
559 | mntxl = (xlator_t *)cookie; |
560 | if (op_ret == -1) { |
561 | gf_log (GF_NFS, GF_LOG_ERROR, "path=%s (%s)",do { do { if (0) printf ("path=%s (%s)", mres->resolveloc. path, strerror (op_errno)); } while (0); _gf_log ("nfs", "mount3.c" , __FUNCTION__, 562, GF_LOG_ERROR, "path=%s (%s)", mres->resolveloc .path, strerror (op_errno)); } while (0) |
562 | mres->resolveloc.path, strerror (op_errno))do { do { if (0) printf ("path=%s (%s)", mres->resolveloc. path, strerror (op_errno)); } while (0); _gf_log ("nfs", "mount3.c" , __FUNCTION__, 562, GF_LOG_ERROR, "path=%s (%s)", mres->resolveloc .path, strerror (op_errno)); } while (0); |
563 | mntstat = mnt3svc_errno_to_mnterr (op_errno); |
564 | goto err; |
565 | } |
566 | |
567 | inode_link (mres->resolveloc.inode, mres->resolveloc.parent, |
568 | mres->resolveloc.name, buf); |
569 | |
570 | nfs3_fh_build_child_fh (&mres->parentfh, buf, &fh); |
571 | if (strlen (mres->remainingdir) <= 0) { |
572 | op_ret = -1; |
573 | mntstat = MNT3_OK; |
574 | mnt3svc_update_mountlist (mres->mstate, mres->req, |
575 | mres->exp->expname); |
576 | goto err; |
577 | } |
578 | |
579 | mres->parentfh = fh; |
580 | op_ret = __mnt3_resolve_export_subdir_comp (mres); |
581 | if (op_ret < 0) |
582 | mntstat = mnt3svc_errno_to_mnterr (-op_ret); |
583 | err: |
584 | if (op_ret == -1) { |
585 | gf_log (GF_MNT, GF_LOG_DEBUG, "Mount reply status: %d",do { do { if (0) printf ("Mount reply status: %d", mntstat); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 586, GF_LOG_DEBUG, "Mount reply status: %d", mntstat); } while (0) |
586 | mntstat)do { do { if (0) printf ("Mount reply status: %d", mntstat); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 586, GF_LOG_DEBUG, "Mount reply status: %d", mntstat); } while (0); |
587 | svc = rpcsvc_request_service (mres->req)((mres->req)->svc); |
588 | autharrlen = rpcsvc_auth_array (svc, mntxl->name, autharr, |
589 | 10); |
590 | |
591 | res = mnt3svc_set_mountres3 (mntstat, &fh, autharr, autharrlen); |
592 | mnt3svc_submit_reply (mres->req, (void *)&res, |
593 | (mnt3_serializer)xdr_serialize_mountres3); |
594 | mnt3_resolve_state_wipe (mres); |
595 | } |
596 | |
597 | return 0; |
598 | } |
599 | |
600 | |
601 | |
602 | /* We will always have to perform a hard lookup on all the components of a |
603 | * directory export for a mount request because in the mount reply we need the |
604 | * file handle of the directory. Our file handle creation code is designed with |
605 | * the assumption that to build a child file/dir fh, we'll always have the |
606 | * parent dir's fh available so that we may copy the hash array of the previous |
607 | * dir levels. |
608 | * |
609 | * Since we do not store the file handles anywhere, for every mount request we |
610 | * must resolve the file handles of every component so that the parent dir file |
611 | * of the exported directory can be built. |
612 | */ |
613 | int |
614 | __mnt3_resolve_subdir (mnt3_resolve_t *mres) |
615 | { |
616 | char dupsubdir[MNTPATHLEN1024]; |
617 | char *firstcomp = NULL((void*)0); |
618 | int ret = -EFAULT14; |
619 | nfs_user_t nfu = {0, }; |
620 | uuid_t rootgfid = {0, }; |
621 | |
622 | if (!mres) |
623 | return ret; |
624 | |
625 | firstcomp = __setup_next_component (mres->remainingdir, dupsubdir); |
626 | if (!firstcomp) |
627 | goto err; |
628 | |
629 | rootgfid[15] = 1; |
630 | ret = nfs_entry_loc_fill (mres->exp->vol->itable, rootgfid, firstcomp, |
631 | &mres->resolveloc, NFS_RESOLVE_CREATE2); |
632 | if ((ret < 0) && (ret != -2)) { |
633 | gf_log (GF_MNT, GF_LOG_ERROR, "Failed to resolve and create "do { do { if (0) printf ("Failed to resolve and create " "inode for volume root: %s" , mres->exp->vol->name); } while (0); _gf_log ("nfs" "-mount", "mount3.c", __FUNCTION__, 634, GF_LOG_ERROR, "Failed to resolve and create " "inode for volume root: %s", mres->exp->vol->name); } while (0) |
634 | "inode for volume root: %s", mres->exp->vol->name)do { do { if (0) printf ("Failed to resolve and create " "inode for volume root: %s" , mres->exp->vol->name); } while (0); _gf_log ("nfs" "-mount", "mount3.c", __FUNCTION__, 634, GF_LOG_ERROR, "Failed to resolve and create " "inode for volume root: %s", mres->exp->vol->name); } while (0); |
635 | ret = -EFAULT14; |
636 | goto err; |
637 | } |
638 | |
639 | nfs_request_user_init (&nfu, mres->req); |
640 | ret = nfs_lookup (mres->mstate->nfsx, mres->exp->vol, &nfu, |
641 | &mres->resolveloc, mnt3_resolve_subdir_cbk, mres); |
642 | |
643 | err: |
644 | return ret; |
645 | } |
646 | |
647 | |
648 | int |
649 | mnt3_resolve_subdir (rpcsvc_request_t *req, struct mount3_state *ms, |
650 | struct mnt3_export *exp, char *subdir) |
651 | { |
652 | mnt3_resolve_t *mres = NULL((void*)0); |
653 | int ret = -EFAULT14; |
654 | struct nfs3_fh pfh = GF_NFS3FH_STATIC_INITIALIZER{{0},}; |
Value stored to 'pfh' during its initialization is never read | |
655 | |
656 | if ((!req) || (!ms) || (!exp) || (!subdir)) |
657 | return ret; |
658 | |
659 | mres = GF_CALLOC (1, sizeof (mnt3_resolve_t), gf_nfs_mt_mnt3_resolve)__gf_calloc (1, sizeof (mnt3_resolve_t), gf_nfs_mt_mnt3_resolve ); |
660 | if (!mres) { |
661 | gf_log (GF_MNT, GF_LOG_ERROR, "Memory allocation failed")do { do { if (0) printf ("Memory allocation failed"); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 661, GF_LOG_ERROR , "Memory allocation failed"); } while (0); |
662 | goto err; |
663 | } |
664 | |
665 | mres->exp = exp; |
666 | mres->mstate = ms; |
667 | mres->req = req; |
668 | strcpy (mres->remainingdir, subdir); |
669 | if (gf_nfs_dvm_off (nfs_state (ms->nfsx))(((struct nfs_state *)(ms->nfsx)->private)->dynamicvolumes == 2)) |
670 | pfh = nfs3_fh_build_indexed_root_fh (mres->mstate->nfsx->children, mres->exp->vol); |
671 | else |
672 | pfh = nfs3_fh_build_uuid_root_fh (exp->volumeid); |
673 | |
674 | mres->parentfh = pfh; |
675 | ret = __mnt3_resolve_subdir (mres); |
676 | if (ret < 0) { |
677 | gf_log (GF_MNT, GF_LOG_ERROR, "Failed to resolve export dir: %s"do { do { if (0) printf ("Failed to resolve export dir: %s" , mres->exp->expname); } while (0); _gf_log ("nfs""-mount" , "mount3.c", __FUNCTION__, 678, GF_LOG_ERROR, "Failed to resolve export dir: %s" , mres->exp->expname); } while (0) |
678 | , mres->exp->expname)do { do { if (0) printf ("Failed to resolve export dir: %s" , mres->exp->expname); } while (0); _gf_log ("nfs""-mount" , "mount3.c", __FUNCTION__, 678, GF_LOG_ERROR, "Failed to resolve export dir: %s" , mres->exp->expname); } while (0); |
679 | GF_FREE (mres)__gf_free (mres); |
680 | } |
681 | |
682 | err: |
683 | return ret; |
684 | } |
685 | |
686 | |
687 | int |
688 | mnt3_resolve_export_subdir (rpcsvc_request_t *req, struct mount3_state *ms, |
689 | struct mnt3_export *exp) |
690 | { |
691 | char *volume_subdir = NULL((void*)0); |
692 | int ret = -EFAULT14; |
693 | |
694 | if ((!req) || (!ms) || (!exp)) |
695 | return ret; |
696 | |
697 | volume_subdir = __volume_subdir (exp->expname, NULL((void*)0)); |
698 | if (!volume_subdir) |
699 | goto err; |
700 | |
701 | ret = mnt3_resolve_subdir (req, ms, exp, volume_subdir); |
702 | if (ret < 0) { |
703 | gf_log (GF_MNT, GF_LOG_ERROR, "Failed to resolve export dir: %s"do { do { if (0) printf ("Failed to resolve export dir: %s" , exp->expname); } while (0); _gf_log ("nfs""-mount", "mount3.c" , __FUNCTION__, 704, GF_LOG_ERROR, "Failed to resolve export dir: %s" , exp->expname); } while (0) |
704 | , exp->expname)do { do { if (0) printf ("Failed to resolve export dir: %s" , exp->expname); } while (0); _gf_log ("nfs""-mount", "mount3.c" , __FUNCTION__, 704, GF_LOG_ERROR, "Failed to resolve export dir: %s" , exp->expname); } while (0); |
705 | goto err; |
706 | } |
707 | |
708 | err: |
709 | return ret; |
710 | } |
711 | |
712 | |
713 | int |
714 | mnt3svc_mount (rpcsvc_request_t *req, struct mount3_state *ms, |
715 | struct mnt3_export *exp) |
716 | { |
717 | int ret = -EFAULT14; |
718 | |
719 | if ((!req) || (!ms) || (!exp)) |
720 | return ret; |
721 | |
722 | if (exp->exptype == MNT3_EXPTYPE_VOLUME1) |
723 | ret = mnt3svc_volume_mount (req, ms, exp); |
724 | else if (exp->exptype == MNT3_EXPTYPE_DIR2) |
725 | ret = mnt3_resolve_export_subdir (req, ms, exp); |
726 | |
727 | return ret; |
728 | } |
729 | |
730 | |
731 | /* mnt3_mntpath_to_xlator sets this to 1 if the mount is for a full |
732 | * volume or 2 for a subdir in the volume. |
733 | */ |
734 | struct mnt3_export * |
735 | mnt3_mntpath_to_export (struct mount3_state *ms, char *dirpath) |
736 | { |
737 | struct mnt3_export *exp = NULL((void*)0); |
738 | struct mnt3_export *found = NULL((void*)0); |
739 | |
740 | if ((!ms) || (!dirpath)) |
741 | return NULL((void*)0); |
742 | |
743 | list_for_each_entry (exp, &ms->exportlist, explist)for (exp = ((typeof(*exp) *)((char *)((&ms->exportlist )->next)-(unsigned long)(&((typeof(*exp) *)0)->explist ))); &exp->explist != (&ms->exportlist); exp = ( (typeof(*exp) *)((char *)(exp->explist.next)-(unsigned long )(&((typeof(*exp) *)0)->explist)))) { |
744 | |
745 | /* Search for the an exact match with the volume */ |
746 | if (mnt3_match_dirpath_export (exp->expname, dirpath)) { |
747 | found = exp; |
748 | gf_log (GF_MNT, GF_LOG_DEBUG, "Found export volume: "do { do { if (0) printf ("Found export volume: " "%s", exp-> vol->name); } while (0); _gf_log ("nfs""-mount", "mount3.c" , __FUNCTION__, 749, GF_LOG_DEBUG, "Found export volume: " "%s" , exp->vol->name); } while (0) |
749 | "%s", exp->vol->name)do { do { if (0) printf ("Found export volume: " "%s", exp-> vol->name); } while (0); _gf_log ("nfs""-mount", "mount3.c" , __FUNCTION__, 749, GF_LOG_DEBUG, "Found export volume: " "%s" , exp->vol->name); } while (0); |
750 | goto foundexp; |
751 | } |
752 | } |
753 | |
754 | gf_log (GF_MNT, GF_LOG_DEBUG, "Export not found")do { do { if (0) printf ("Export not found"); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 754, GF_LOG_DEBUG, "Export not found"); } while (0); |
755 | foundexp: |
756 | return found; |
757 | } |
758 | |
759 | |
760 | int |
761 | mnt3_check_client_net (struct mount3_state *ms, rpcsvc_request_t *req, |
762 | xlator_t *targetxl) |
763 | { |
764 | |
765 | rpcsvc_t *svc = NULL((void*)0); |
766 | rpc_transport_t *trans = NULL((void*)0); |
767 | struct sockaddr_storage sastorage = {0,}; |
768 | char peer[RPCSVC_PEER_STRLEN1024] = {0,}; |
769 | int ret = -1; |
770 | |
771 | if ((!ms) || (!req) || (!targetxl)) |
772 | return -1; |
773 | |
774 | svc = rpcsvc_request_service (req)((req)->svc); |
775 | |
776 | trans = rpcsvc_request_transport (req)((req)->trans); |
777 | ret = rpcsvc_transport_peeraddr (trans, peer, RPCSVC_PEER_STRLEN1024, |
778 | &sastorage, sizeof (sastorage)); |
779 | if (ret != 0) { |
780 | gf_log (GF_MNT, GF_LOG_WARNING, "Failed to get peer addr: %s",do { do { if (0) printf ("Failed to get peer addr: %s", gai_strerror (ret)); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__ , 781, GF_LOG_WARNING, "Failed to get peer addr: %s", gai_strerror (ret)); } while (0) |
781 | gai_strerror (ret))do { do { if (0) printf ("Failed to get peer addr: %s", gai_strerror (ret)); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__ , 781, GF_LOG_WARNING, "Failed to get peer addr: %s", gai_strerror (ret)); } while (0); |
782 | } |
783 | |
784 | ret = rpcsvc_auth_check (svc->options, targetxl->name, trans); |
785 | if (ret == RPCSVC_AUTH_REJECT2) { |
786 | gf_log (GF_MNT, GF_LOG_INFO, "Peer %s not allowed", peer)do { do { if (0) printf ("Peer %s not allowed", peer); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 786, GF_LOG_INFO , "Peer %s not allowed", peer); } while (0); |
787 | goto err; |
788 | } |
789 | |
790 | ret = rpcsvc_transport_privport_check (svc, targetxl->name, |
791 | rpcsvc_request_transport (req)((req)->trans)); |
792 | if (ret == RPCSVC_AUTH_REJECT2) { |
793 | gf_log (GF_MNT, GF_LOG_INFO, "Peer %s rejected. Unprivileged "do { do { if (0) printf ("Peer %s rejected. Unprivileged " "port not allowed" , peer); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__ , 794, GF_LOG_INFO, "Peer %s rejected. Unprivileged " "port not allowed" , peer); } while (0) |
794 | "port not allowed", peer)do { do { if (0) printf ("Peer %s rejected. Unprivileged " "port not allowed" , peer); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__ , 794, GF_LOG_INFO, "Peer %s rejected. Unprivileged " "port not allowed" , peer); } while (0); |
795 | goto err; |
796 | } |
797 | |
798 | ret = 0; |
799 | err: |
800 | return ret; |
801 | } |
802 | |
803 | |
804 | int |
805 | mnt3_parse_dir_exports (rpcsvc_request_t *req, struct mount3_state *ms, |
806 | char *subdir) |
807 | { |
808 | char volname[1024]; |
809 | struct mnt3_export *exp = NULL((void*)0); |
810 | char *volname_ptr = NULL((void*)0); |
811 | int ret = -1; |
812 | |
813 | if ((!ms) || (!subdir)) |
814 | return -1; |
815 | |
816 | volname_ptr = volname; |
817 | subdir = __volume_subdir (subdir, &volname_ptr); |
818 | if (!subdir) |
819 | goto err; |
820 | |
821 | exp = mnt3_mntpath_to_export (ms, volname); |
822 | if (!exp) |
823 | goto err; |
824 | |
825 | ret = mnt3_resolve_subdir (req, ms, exp, subdir); |
826 | if (ret < 0) { |
827 | gf_log (GF_MNT, GF_LOG_ERROR, "Failed to resolve export dir: %s"do { do { if (0) printf ("Failed to resolve export dir: %s" , subdir); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__ , 828, GF_LOG_ERROR, "Failed to resolve export dir: %s" , subdir ); } while (0) |
828 | , subdir)do { do { if (0) printf ("Failed to resolve export dir: %s" , subdir); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__ , 828, GF_LOG_ERROR, "Failed to resolve export dir: %s" , subdir ); } while (0); |
829 | goto err; |
830 | } |
831 | |
832 | err: |
833 | return ret; |
834 | } |
835 | |
836 | |
837 | int |
838 | mnt3_find_export (rpcsvc_request_t *req, char *path, struct mnt3_export **e) |
839 | { |
840 | int ret = -EFAULT14; |
841 | struct mount3_state *ms = NULL((void*)0); |
842 | struct mnt3_export *exp = NULL((void*)0); |
843 | |
844 | if ((!req) || (!path) || (!e)) |
845 | return -1; |
846 | |
847 | ms = (struct mount3_state *) rpcsvc_request_program_private (req)(((rpcsvc_program_t *)((req)->prog))->private); |
848 | if (!ms) { |
849 | gf_log (GF_MNT, GF_LOG_ERROR, "Mount state not present")do { do { if (0) printf ("Mount state not present"); } while ( 0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 849, GF_LOG_ERROR , "Mount state not present"); } while (0); |
850 | rpcsvc_request_seterr (req, SYSTEM_ERR)(req)->rpc_err = SYSTEM_ERR; |
851 | goto err; |
852 | } |
853 | |
854 | gf_log (GF_MNT, GF_LOG_DEBUG, "dirpath: %s", path)do { do { if (0) printf ("dirpath: %s", path); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 854, GF_LOG_DEBUG, "dirpath: %s", path); } while (0); |
855 | exp = mnt3_mntpath_to_export (ms, path); |
856 | if (exp) { |
857 | ret = 0; |
858 | *e = exp; |
859 | goto err; |
860 | } |
861 | |
862 | if (!gf_mnt3_export_dirs(ms)((ms)->export_dirs)) { |
863 | ret = -1; |
864 | goto err; |
865 | } |
866 | |
867 | ret = mnt3_parse_dir_exports (req, ms, path); |
868 | if (ret == 0) { |
869 | ret = -2; |
870 | goto err; |
871 | } |
872 | |
873 | err: |
874 | return ret; |
875 | } |
876 | |
877 | |
878 | int |
879 | mnt3svc_mnt (rpcsvc_request_t *req) |
880 | { |
881 | struct iovec pvec = {0, }; |
882 | char path[MNTPATHLEN1024]; |
883 | int ret = -1; |
884 | struct mount3_state *ms = NULL((void*)0); |
885 | mountstat3 mntstat = MNT3ERR_SERVERFAULT; |
886 | struct mnt3_export *exp = NULL((void*)0); |
887 | struct nfs_state *nfs = NULL((void*)0); |
888 | |
889 | if (!req) |
890 | return -1; |
891 | |
892 | pvec.iov_base = path; |
893 | pvec.iov_len = MNTPATHLEN1024; |
894 | ret = xdr_to_mountpath (pvec, req->msg[0]); |
895 | if (ret == -1) { |
896 | gf_log (GF_MNT, GF_LOG_ERROR, "Failed to decode args")do { do { if (0) printf ("Failed to decode args"); } while (0 ); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 896, GF_LOG_ERROR , "Failed to decode args"); } while (0); |
897 | rpcsvc_request_seterr (req, GARBAGE_ARGS)(req)->rpc_err = GARBAGE_ARGS; |
898 | goto rpcerr; |
899 | } |
900 | |
901 | ms = (struct mount3_state *)rpcsvc_request_program_private (req)(((rpcsvc_program_t *)((req)->prog))->private); |
902 | if (!ms) { |
903 | gf_log (GF_MNT, GF_LOG_ERROR, "Mount state not present")do { do { if (0) printf ("Mount state not present"); } while ( 0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 903, GF_LOG_ERROR , "Mount state not present"); } while (0); |
904 | rpcsvc_request_seterr (req, SYSTEM_ERR)(req)->rpc_err = SYSTEM_ERR; |
905 | ret = -1; |
906 | goto rpcerr; |
907 | } |
908 | |
909 | ret = 0; |
910 | nfs = (struct nfs_state *)ms->nfsx->private; |
911 | gf_log (GF_MNT, GF_LOG_DEBUG, "dirpath: %s", path)do { do { if (0) printf ("dirpath: %s", path); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 911, GF_LOG_DEBUG, "dirpath: %s", path); } while (0); |
912 | ret = mnt3_find_export (req, path, &exp); |
913 | if (ret == -2) { |
914 | ret = 0; |
915 | goto rpcerr; |
916 | } else if (ret < 0) { |
917 | ret = -1; |
918 | mntstat = MNT3ERR_NOENT; |
919 | goto mnterr; |
920 | } |
921 | |
922 | if (!nfs_subvolume_started (nfs, exp->vol)) { |
923 | gf_log (GF_MNT, GF_LOG_DEBUG, "Volume %s not started",do { do { if (0) printf ("Volume %s not started", exp->vol ->name); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__ , 924, GF_LOG_DEBUG, "Volume %s not started", exp->vol-> name); } while (0) |
924 | exp->vol->name)do { do { if (0) printf ("Volume %s not started", exp->vol ->name); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__ , 924, GF_LOG_DEBUG, "Volume %s not started", exp->vol-> name); } while (0); |
925 | ret = -1; |
926 | mntstat = MNT3ERR_NOENT; |
927 | goto mnterr; |
928 | } |
929 | |
930 | ret = mnt3_check_client_net (ms, req, exp->vol); |
931 | if (ret == RPCSVC_AUTH_REJECT2) { |
932 | mntstat = MNT3ERR_ACCES; |
933 | gf_log (GF_MNT, GF_LOG_DEBUG, "Client mount not allowed")do { do { if (0) printf ("Client mount not allowed"); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 933, GF_LOG_DEBUG , "Client mount not allowed"); } while (0); |
934 | ret = -1; |
935 | goto mnterr; |
936 | } |
937 | |
938 | ret = mnt3svc_mount (req, ms, exp); |
939 | if (ret < 0) |
940 | mntstat = mnt3svc_errno_to_mnterr (-ret); |
941 | mnterr: |
942 | if (ret < 0) { |
943 | mnt3svc_mnt_error_reply (req, mntstat); |
944 | ret = 0; |
945 | } |
946 | |
947 | rpcerr: |
948 | return ret; |
949 | } |
950 | |
951 | |
952 | int |
953 | mnt3svc_null (rpcsvc_request_t *req) |
954 | { |
955 | struct iovec dummyvec = {0, }; |
956 | |
957 | if (!req) { |
958 | gf_log (GF_MNT, GF_LOG_ERROR, "Got NULL request!")do { do { if (0) printf ("Got NULL request!"); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 958, GF_LOG_ERROR, "Got NULL request!"); } while (0); |
959 | return 0; |
960 | } |
961 | rpcsvc_submit_generic (req, &dummyvec, 1, NULL((void*)0), 0, NULL((void*)0)); |
962 | return 0; |
963 | } |
964 | |
965 | |
966 | mountlist |
967 | __build_mountlist (struct mount3_state *ms, int *count) |
968 | { |
969 | struct mountbody *mlist = NULL((void*)0); |
970 | struct mountbody *prev = NULL((void*)0); |
971 | struct mountbody *first = NULL((void*)0); |
972 | size_t namelen = 0; |
973 | int ret = -1; |
974 | struct mountentry *me = NULL((void*)0); |
975 | |
976 | if ((!ms) || (!count)) |
977 | return NULL((void*)0); |
978 | |
979 | *count = 0; |
980 | gf_log (GF_MNT, GF_LOG_DEBUG, "Building mount list:")do { do { if (0) printf ("Building mount list:"); } while (0) ; _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 980, GF_LOG_DEBUG , "Building mount list:"); } while (0); |
981 | list_for_each_entry (me, &ms->mountlist, mlist)for (me = ((typeof(*me) *)((char *)((&ms->mountlist)-> next)-(unsigned long)(&((typeof(*me) *)0)->mlist))); & me->mlist != (&ms->mountlist); me = ((typeof(*me) * )((char *)(me->mlist.next)-(unsigned long)(&((typeof(* me) *)0)->mlist)))) { |
982 | namelen = strlen (me->exname); |
983 | mlist = GF_CALLOC (1, sizeof (*mlist), gf_nfs_mt_mountbody)__gf_calloc (1, sizeof (*mlist), gf_nfs_mt_mountbody); |
984 | if (!mlist) { |
985 | gf_log (GF_MNT, GF_LOG_ERROR, "Memory allocation"do { do { if (0) printf ("Memory allocation" " failed"); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 986, GF_LOG_ERROR , "Memory allocation" " failed"); } while (0) |
986 | " failed")do { do { if (0) printf ("Memory allocation" " failed"); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 986, GF_LOG_ERROR , "Memory allocation" " failed"); } while (0); |
987 | goto free_list; |
988 | } |
989 | |
990 | mlist->ml_directory = GF_CALLOC (namelen + 2, sizeof (char),__gf_calloc (namelen + 2, sizeof (char), gf_nfs_mt_char) |
991 | gf_nfs_mt_char)__gf_calloc (namelen + 2, sizeof (char), gf_nfs_mt_char); |
992 | if (!mlist->ml_directory) { |
993 | gf_log (GF_MNT, GF_LOG_ERROR, "Memory allocation"do { do { if (0) printf ("Memory allocation" " failed"); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 994, GF_LOG_ERROR , "Memory allocation" " failed"); } while (0) |
994 | " failed")do { do { if (0) printf ("Memory allocation" " failed"); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 994, GF_LOG_ERROR , "Memory allocation" " failed"); } while (0); |
995 | goto free_list; |
996 | } |
997 | |
998 | strcpy (mlist->ml_directory, "/"); |
999 | strcat (mlist->ml_directory, me->exname); |
1000 | |
1001 | namelen = strlen (me->hostname); |
1002 | mlist->ml_hostname = GF_CALLOC (namelen + 2, sizeof (char),__gf_calloc (namelen + 2, sizeof (char), gf_nfs_mt_char) |
1003 | gf_nfs_mt_char)__gf_calloc (namelen + 2, sizeof (char), gf_nfs_mt_char); |
1004 | if (!mlist->ml_hostname) { |
1005 | gf_log (GF_MNT, GF_LOG_ERROR, "Memory allocation"do { do { if (0) printf ("Memory allocation" " failed"); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 1006, GF_LOG_ERROR, "Memory allocation" " failed"); } while (0) |
1006 | " failed")do { do { if (0) printf ("Memory allocation" " failed"); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 1006, GF_LOG_ERROR, "Memory allocation" " failed"); } while (0); |
1007 | goto free_list; |
1008 | } |
1009 | |
1010 | strcat (mlist->ml_hostname, me->hostname); |
1011 | |
1012 | gf_log (GF_MNT, GF_LOG_DEBUG, "mount entry: dir: %s, host: %s",do { do { if (0) printf ("mount entry: dir: %s, host: %s", mlist ->ml_directory, mlist->ml_hostname); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 1013, GF_LOG_DEBUG , "mount entry: dir: %s, host: %s", mlist->ml_directory, mlist ->ml_hostname); } while (0) |
1013 | mlist->ml_directory, mlist->ml_hostname)do { do { if (0) printf ("mount entry: dir: %s, host: %s", mlist ->ml_directory, mlist->ml_hostname); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 1013, GF_LOG_DEBUG , "mount entry: dir: %s, host: %s", mlist->ml_directory, mlist ->ml_hostname); } while (0); |
1014 | if (prev) { |
1015 | prev->ml_next = mlist; |
1016 | prev = mlist; |
1017 | } else |
1018 | prev = mlist; |
1019 | |
1020 | if (!first) |
1021 | first = mlist; |
1022 | |
1023 | (*count)++; |
1024 | } |
1025 | |
1026 | ret = 0; |
1027 | |
1028 | free_list: |
1029 | if (ret == -1) { |
1030 | xdr_free_mountlist (first); |
1031 | first = NULL((void*)0); |
1032 | } |
1033 | |
1034 | return first; |
1035 | } |
1036 | |
1037 | |
1038 | mountlist |
1039 | mnt3svc_build_mountlist (struct mount3_state *ms, int *count) |
1040 | { |
1041 | struct mountbody *first = NULL((void*)0); |
1042 | |
1043 | LOCK (&ms->mountlock)pthread_spin_lock (&ms->mountlock); |
1044 | { |
1045 | first = __build_mountlist (ms, count); |
1046 | } |
1047 | UNLOCK (&ms->mountlock)pthread_spin_unlock (&ms->mountlock); |
1048 | |
1049 | return first; |
1050 | } |
1051 | |
1052 | |
1053 | int |
1054 | mnt3svc_dump (rpcsvc_request_t *req) |
1055 | { |
1056 | int ret = -1; |
1057 | struct mount3_state *ms = NULL((void*)0); |
1058 | mountlist mlist; |
1059 | mountstat3 mstat = 0; |
1060 | mnt3_serializer sfunc = NULL((void*)0); |
1061 | void *arg = NULL((void*)0); |
1062 | |
1063 | |
1064 | if (!req) |
1065 | return -1; |
1066 | |
1067 | ms = (struct mount3_state *)rpcsvc_request_program_private (req)(((rpcsvc_program_t *)((req)->prog))->private); |
1068 | if (!ms) { |
1069 | rpcsvc_request_seterr (req, SYSTEM_ERR)(req)->rpc_err = SYSTEM_ERR; |
1070 | goto rpcerr; |
1071 | } |
1072 | |
1073 | sfunc = (mnt3_serializer)xdr_serialize_mountlist; |
1074 | mlist = mnt3svc_build_mountlist (ms, &ret); |
1075 | arg = &mlist; |
1076 | |
1077 | if (!mlist) { |
1078 | if (ret != 0) { |
1079 | rpcsvc_request_seterr (req, SYSTEM_ERR)(req)->rpc_err = SYSTEM_ERR; |
1080 | ret = -1; |
1081 | goto rpcerr; |
1082 | } else { |
1083 | arg = &mstat; |
1084 | sfunc = (mnt3_serializer)xdr_serialize_mountstat3; |
1085 | } |
1086 | } |
1087 | |
1088 | mnt3svc_submit_reply (req, arg, sfunc); |
1089 | |
1090 | xdr_free_mountlist (mlist); |
1091 | ret = 0; |
1092 | |
1093 | rpcerr: |
1094 | return ret; |
1095 | } |
1096 | |
1097 | |
1098 | int |
1099 | __mnt3svc_umount (struct mount3_state *ms, char *dirpath, char *hostname) |
1100 | { |
1101 | struct mountentry *me = NULL((void*)0); |
1102 | char *exname = NULL((void*)0); |
1103 | int ret = -1; |
1104 | |
1105 | if ((!ms) || (!dirpath) || (!hostname)) |
1106 | return -1; |
1107 | |
1108 | if (list_empty (&ms->mountlist)) |
1109 | return 0; |
1110 | |
1111 | if (dirpath[0] == '/') |
1112 | exname = dirpath+1; |
1113 | else |
1114 | exname = dirpath; |
1115 | |
1116 | list_for_each_entry (me, &ms->mountlist, mlist)for (me = ((typeof(*me) *)((char *)((&ms->mountlist)-> next)-(unsigned long)(&((typeof(*me) *)0)->mlist))); & me->mlist != (&ms->mountlist); me = ((typeof(*me) * )((char *)(me->mlist.next)-(unsigned long)(&((typeof(* me) *)0)->mlist)))) { |
1117 | if ((strcmp (me->exname, exname) == 0) && |
1118 | (strcmp (me->hostname, hostname) == 0)) { |
1119 | ret = 0; |
1120 | break; |
1121 | } |
1122 | } |
1123 | |
1124 | /* Need this check here because at the end of the search me might still |
1125 | * be pointing to the last entry, which may not be the one we're |
1126 | * looking for. |
1127 | */ |
1128 | if (ret == -1) {/* Not found in list. */ |
1129 | gf_log (GF_MNT, GF_LOG_DEBUG, "Export not found")do { do { if (0) printf ("Export not found"); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 1129, GF_LOG_DEBUG , "Export not found"); } while (0); |
1130 | goto ret; |
1131 | } |
1132 | |
1133 | if (!me) |
1134 | goto ret; |
1135 | |
1136 | gf_log (GF_MNT, GF_LOG_DEBUG, "Unmounting: dir %s, host: %s",do { do { if (0) printf ("Unmounting: dir %s, host: %s", me-> exname, me->hostname); } while (0); _gf_log ("nfs""-mount" , "mount3.c", __FUNCTION__, 1137, GF_LOG_DEBUG, "Unmounting: dir %s, host: %s" , me->exname, me->hostname); } while (0) |
1137 | me->exname, me->hostname)do { do { if (0) printf ("Unmounting: dir %s, host: %s", me-> exname, me->hostname); } while (0); _gf_log ("nfs""-mount" , "mount3.c", __FUNCTION__, 1137, GF_LOG_DEBUG, "Unmounting: dir %s, host: %s" , me->exname, me->hostname); } while (0); |
1138 | list_del (&me->mlist); |
1139 | GF_FREE (me)__gf_free (me); |
1140 | ret = 0; |
1141 | ret: |
1142 | return ret; |
1143 | } |
1144 | |
1145 | |
1146 | |
1147 | int |
1148 | mnt3svc_umount (struct mount3_state *ms, char *dirpath, char *hostname) |
1149 | { |
1150 | int ret = -1; |
1151 | if ((!ms) || (!dirpath) || (!hostname)) |
1152 | return -1; |
1153 | |
1154 | LOCK (&ms->mountlock)pthread_spin_lock (&ms->mountlock); |
1155 | { |
1156 | ret = __mnt3svc_umount (ms, dirpath, hostname); |
1157 | } |
1158 | UNLOCK (&ms->mountlock)pthread_spin_unlock (&ms->mountlock); |
1159 | |
1160 | return ret; |
1161 | } |
1162 | |
1163 | |
1164 | int |
1165 | mnt3svc_umnt (rpcsvc_request_t *req) |
1166 | { |
1167 | char hostname[MNTPATHLEN1024]; |
1168 | char dirpath[MNTPATHLEN1024]; |
1169 | struct iovec pvec = {0, }; |
1170 | int ret = -1; |
1171 | struct mount3_state *ms = NULL((void*)0); |
1172 | mountstat3 mstat = MNT3_OK; |
1173 | char *colon = NULL((void*)0); |
1174 | |
1175 | if (!req) |
1176 | return -1; |
1177 | |
1178 | /* Remove the mount point from the exports list. */ |
1179 | pvec.iov_base = dirpath; |
1180 | pvec.iov_len = MNTPATHLEN1024; |
1181 | ret = xdr_to_mountpath (pvec, req->msg[0]); |
1182 | if (ret == -1) { |
1183 | gf_log (GF_MNT, GF_LOG_ERROR, "Failed decode args")do { do { if (0) printf ("Failed decode args"); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 1183, GF_LOG_ERROR , "Failed decode args"); } while (0); |
1184 | rpcsvc_request_seterr (req, GARBAGE_ARGS)(req)->rpc_err = GARBAGE_ARGS; |
1185 | goto rpcerr; |
1186 | } |
1187 | |
1188 | ms = (struct mount3_state *)rpcsvc_request_program_private (req)(((rpcsvc_program_t *)((req)->prog))->private); |
1189 | if (!ms) { |
1190 | gf_log (GF_MNT, GF_LOG_ERROR, "Mount state not present")do { do { if (0) printf ("Mount state not present"); } while ( 0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 1190, GF_LOG_ERROR , "Mount state not present"); } while (0); |
1191 | rpcsvc_request_seterr (req, SYSTEM_ERR)(req)->rpc_err = SYSTEM_ERR; |
1192 | ret = -1; |
1193 | goto rpcerr; |
1194 | } |
1195 | |
1196 | ret = rpcsvc_transport_peername (req->trans, hostname, MNTPATHLEN1024); |
1197 | if (ret != 0) { |
1198 | gf_log (GF_MNT, GF_LOG_ERROR, "Failed to get remote name: %s",do { do { if (0) printf ("Failed to get remote name: %s", gai_strerror (ret)); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__ , 1199, GF_LOG_ERROR, "Failed to get remote name: %s", gai_strerror (ret)); } while (0) |
1199 | gai_strerror (ret))do { do { if (0) printf ("Failed to get remote name: %s", gai_strerror (ret)); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__ , 1199, GF_LOG_ERROR, "Failed to get remote name: %s", gai_strerror (ret)); } while (0); |
1200 | goto rpcerr; |
1201 | } |
1202 | |
1203 | colon = strrchr (hostname, ':'); |
1204 | if (colon) { |
1205 | *colon= '\0'; |
1206 | } |
1207 | gf_log (GF_MNT, GF_LOG_DEBUG, "dirpath: %s, hostname: %s", dirpath,do { do { if (0) printf ("dirpath: %s, hostname: %s", dirpath , hostname); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 1208, GF_LOG_DEBUG, "dirpath: %s, hostname: %s" , dirpath, hostname); } while (0) |
1208 | hostname)do { do { if (0) printf ("dirpath: %s, hostname: %s", dirpath , hostname); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 1208, GF_LOG_DEBUG, "dirpath: %s, hostname: %s" , dirpath, hostname); } while (0); |
1209 | ret = mnt3svc_umount (ms, dirpath, hostname); |
1210 | |
1211 | if (ret == -1) { |
1212 | ret = 0; |
1213 | mstat = MNT3ERR_NOENT; |
1214 | } |
1215 | /* FIXME: also take care of the corner case where the |
1216 | * client was resolvable at mount but not at the umount - vice-versa. |
1217 | */ |
1218 | mnt3svc_submit_reply (req, &mstat, |
1219 | (mnt3_serializer)xdr_serialize_mountstat3); |
1220 | |
1221 | rpcerr: |
1222 | return ret; |
1223 | } |
1224 | |
1225 | |
1226 | int |
1227 | __mnt3svc_umountall (struct mount3_state *ms) |
1228 | { |
1229 | struct mountentry *me = NULL((void*)0); |
1230 | struct mountentry *tmp = NULL((void*)0); |
1231 | |
1232 | if (!ms) |
1233 | return -1; |
1234 | |
1235 | if (list_empty (&ms->mountlist)) |
1236 | return 0; |
1237 | |
1238 | list_for_each_entry_safe (me, tmp, &ms->mountlist, mlist)for (me = ((typeof(*me) *)((char *)((&ms->mountlist)-> next)-(unsigned long)(&((typeof(*me) *)0)->mlist))), tmp = ((typeof(*me) *)((char *)(me->mlist.next)-(unsigned long )(&((typeof(*me) *)0)->mlist))); &me->mlist != ( &ms->mountlist); me = tmp, tmp = ((typeof(*tmp) *)((char *)(tmp->mlist.next)-(unsigned long)(&((typeof(*tmp) * )0)->mlist)))) { |
1239 | list_del (&me->mlist); |
1240 | GF_FREE (me)__gf_free (me); |
1241 | } |
1242 | |
1243 | return 0; |
1244 | } |
1245 | |
1246 | |
1247 | int |
1248 | mnt3svc_umountall (struct mount3_state *ms) |
1249 | { |
1250 | int ret = -1; |
1251 | if (!ms) |
1252 | return -1; |
1253 | |
1254 | LOCK (&ms->mountlock)pthread_spin_lock (&ms->mountlock); |
1255 | { |
1256 | ret = __mnt3svc_umountall (ms); |
1257 | } |
1258 | UNLOCK (&ms->mountlock)pthread_spin_unlock (&ms->mountlock); |
1259 | |
1260 | return ret; |
1261 | } |
1262 | |
1263 | |
1264 | int |
1265 | mnt3svc_umntall (rpcsvc_request_t *req) |
1266 | { |
1267 | int ret = RPCSVC_ACTOR_ERROR(-1); |
1268 | struct mount3_state *ms = NULL((void*)0); |
1269 | mountstat3 mstat = MNT3_OK; |
1270 | |
1271 | if (!req) |
1272 | return ret; |
1273 | |
1274 | ms = (struct mount3_state *)rpcsvc_request_program_private (req)(((rpcsvc_program_t *)((req)->prog))->private); |
1275 | if (!ms) { |
1276 | gf_log (GF_MNT, GF_LOG_ERROR, "Mount state not present")do { do { if (0) printf ("Mount state not present"); } while ( 0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 1276, GF_LOG_ERROR , "Mount state not present"); } while (0); |
1277 | rpcsvc_request_seterr (req, SYSTEM_ERR)(req)->rpc_err = SYSTEM_ERR; |
1278 | goto rpcerr; |
1279 | } |
1280 | |
1281 | mnt3svc_umountall (ms); |
1282 | mnt3svc_submit_reply (req, &mstat, |
1283 | (mnt3_serializer)xdr_serialize_mountstat3); |
1284 | |
1285 | ret = RPCSVC_ACTOR_SUCCESS0; |
1286 | rpcerr: |
1287 | return ret; |
1288 | } |
1289 | |
1290 | |
1291 | exports |
1292 | mnt3_xlchildren_to_exports (rpcsvc_t *svc, struct mount3_state *ms) |
1293 | { |
1294 | struct exportnode *elist = NULL((void*)0); |
1295 | struct exportnode *prev = NULL((void*)0); |
1296 | struct exportnode *first = NULL((void*)0); |
1297 | size_t namelen = 0; |
1298 | int ret = -1; |
1299 | char *addrstr = NULL((void*)0); |
1300 | struct mnt3_export *ent = NULL((void*)0); |
1301 | struct nfs_state *nfs = NULL((void*)0); |
1302 | |
1303 | if ((!ms) || (!svc)) |
1304 | return NULL((void*)0); |
1305 | |
1306 | nfs = (struct nfs_state *)ms->nfsx->private; |
1307 | list_for_each_entry(ent, &ms->exportlist, explist)for (ent = ((typeof(*ent) *)((char *)((&ms->exportlist )->next)-(unsigned long)(&((typeof(*ent) *)0)->explist ))); &ent->explist != (&ms->exportlist); ent = ( (typeof(*ent) *)((char *)(ent->explist.next)-(unsigned long )(&((typeof(*ent) *)0)->explist)))) { |
1308 | |
1309 | /* If volume is not started yet, do not list it for tools like |
1310 | * showmount. |
1311 | */ |
1312 | if (!nfs_subvolume_started (nfs, ent->vol)) |
1313 | continue; |
1314 | |
1315 | namelen = strlen (ent->expname) + 1; |
1316 | elist = GF_CALLOC (1, sizeof (*elist), gf_nfs_mt_exportnode)__gf_calloc (1, sizeof (*elist), gf_nfs_mt_exportnode); |
1317 | if (!elist) { |
1318 | gf_log (GF_MNT, GF_LOG_ERROR, "Memory allocation"do { do { if (0) printf ("Memory allocation" " failed"); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 1319, GF_LOG_ERROR, "Memory allocation" " failed"); } while (0) |
1319 | " failed")do { do { if (0) printf ("Memory allocation" " failed"); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 1319, GF_LOG_ERROR, "Memory allocation" " failed"); } while (0); |
1320 | goto free_list; |
1321 | } |
1322 | |
1323 | elist->ex_dir = GF_CALLOC (namelen + 2, sizeof (char),__gf_calloc (namelen + 2, sizeof (char), gf_nfs_mt_char) |
1324 | gf_nfs_mt_char)__gf_calloc (namelen + 2, sizeof (char), gf_nfs_mt_char); |
1325 | if (!elist->ex_dir) { |
1326 | gf_log (GF_MNT, GF_LOG_ERROR, "Memory allocation"do { do { if (0) printf ("Memory allocation" " failed"); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 1327, GF_LOG_ERROR, "Memory allocation" " failed"); } while (0) |
1327 | " failed")do { do { if (0) printf ("Memory allocation" " failed"); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 1327, GF_LOG_ERROR, "Memory allocation" " failed"); } while (0); |
1328 | goto free_list; |
1329 | } |
1330 | |
1331 | strcpy (elist->ex_dir, ent->expname); |
1332 | |
1333 | addrstr = rpcsvc_volume_allowed (svc->options, |
1334 | ent->vol->name); |
1335 | if (addrstr) |
1336 | addrstr = gf_strdup (addrstr); |
1337 | else |
1338 | addrstr = gf_strdup ("No Access"); |
1339 | |
1340 | elist->ex_groups = GF_CALLOC (1, sizeof (struct groupnode),__gf_calloc (1, sizeof (struct groupnode), gf_nfs_mt_groupnode ) |
1341 | gf_nfs_mt_groupnode)__gf_calloc (1, sizeof (struct groupnode), gf_nfs_mt_groupnode ); |
1342 | if (!elist->ex_groups) { |
1343 | gf_log (GF_MNT, GF_LOG_ERROR, "Memory allocation"do { do { if (0) printf ("Memory allocation" " failed"); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 1344, GF_LOG_ERROR, "Memory allocation" " failed"); } while (0) |
1344 | " failed")do { do { if (0) printf ("Memory allocation" " failed"); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 1344, GF_LOG_ERROR, "Memory allocation" " failed"); } while (0); |
1345 | goto free_list; |
1346 | } |
1347 | |
1348 | elist->ex_groups->gr_name = addrstr; |
1349 | if (prev) { |
1350 | prev->ex_next = elist; |
1351 | prev = elist; |
1352 | } else |
1353 | prev = elist; |
1354 | |
1355 | if (!first) |
1356 | first = elist; |
1357 | } |
1358 | |
1359 | ret = 0; |
1360 | |
1361 | free_list: |
1362 | if (ret == -1) { |
1363 | xdr_free_exports_list (first); |
1364 | first = NULL((void*)0); |
1365 | } |
1366 | |
1367 | return first; |
1368 | } |
1369 | |
1370 | |
1371 | int |
1372 | mnt3svc_export (rpcsvc_request_t *req) |
1373 | { |
1374 | struct mount3_state *ms = NULL((void*)0); |
1375 | exports elist = NULL((void*)0); |
1376 | int ret = -1; |
1377 | |
1378 | if (!req) |
1379 | return -1; |
1380 | |
1381 | ms = (struct mount3_state *)rpcsvc_request_program_private (req)(((rpcsvc_program_t *)((req)->prog))->private); |
1382 | if (!ms) { |
1383 | gf_log (GF_MNT, GF_LOG_ERROR, "mount state not found")do { do { if (0) printf ("mount state not found"); } while (0 ); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 1383, GF_LOG_ERROR , "mount state not found"); } while (0); |
1384 | rpcsvc_request_seterr (req, SYSTEM_ERR)(req)->rpc_err = SYSTEM_ERR; |
1385 | goto err; |
1386 | } |
1387 | |
1388 | /* Using the children translator names, build the export list */ |
1389 | elist = mnt3_xlchildren_to_exports (rpcsvc_request_service (req)((req)->svc), |
1390 | ms); |
1391 | /* Do not return error when exports list is empty. An exports list can |
1392 | * be empty when no subvolumes have come up. No point returning error |
1393 | * and confusing the user. |
1394 | if (!elist) { |
1395 | gf_log (GF_MNT, GF_LOG_ERROR, "Failed to build exports list"); |
1396 | nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); |
1397 | goto err; |
1398 | } |
1399 | */ |
1400 | |
1401 | /* Note how the serializer is passed to the generic reply function. */ |
1402 | mnt3svc_submit_reply (req, &elist, |
1403 | (mnt3_serializer)xdr_serialize_exports); |
1404 | |
1405 | xdr_free_exports_list (elist); |
1406 | ret = 0; |
1407 | err: |
1408 | return ret; |
1409 | } |
1410 | |
1411 | /* just declaring, definition is way down below */ |
1412 | rpcsvc_program_t mnt3prog; |
1413 | |
1414 | /* nfs3_rootfh used by mount3udp thread needs to access mount3prog.private |
1415 | * directly as we don't have nfs xlator pointer to dereference it. But thats OK |
1416 | */ |
1417 | |
1418 | struct nfs3_fh * |
1419 | nfs3_rootfh (char* path) |
1420 | { |
1421 | struct mount3_state *ms = NULL((void*)0); |
1422 | struct nfs3_fh *fh = NULL((void*)0); |
1423 | struct mnt3_export *exp = NULL((void*)0); |
1424 | inode_t *inode = NULL((void*)0); |
1425 | char *tmp = NULL((void*)0); |
1426 | |
1427 | ms = mnt3prog.private; |
1428 | exp = mnt3_mntpath_to_export (ms, path); |
1429 | if (exp == NULL((void*)0)) |
1430 | goto err; |
1431 | |
1432 | tmp = (char *)path; |
1433 | tmp = strchr (tmp, '/'); |
1434 | if (tmp == NULL((void*)0)) |
1435 | tmp = "/"; |
1436 | |
1437 | inode = inode_from_path (exp->vol->itable, tmp); |
1438 | if (inode == NULL((void*)0)) |
1439 | goto err; |
1440 | |
1441 | fh = GF_CALLOC (1, sizeof(*fh), gf_nfs_mt_nfs3_fh)__gf_calloc (1, sizeof(*fh), gf_nfs_mt_nfs3_fh); |
1442 | if (fh == NULL((void*)0)) |
1443 | goto err; |
1444 | nfs3_build_fh (inode, exp->volumeid, fh); |
1445 | |
1446 | err: |
1447 | if (inode) |
1448 | inode_unref (inode); |
1449 | return fh; |
1450 | } |
1451 | |
1452 | int |
1453 | mount3udp_add_mountlist (char *host, dirpath *expname) |
1454 | { |
1455 | struct mountentry *me = NULL((void*)0); |
1456 | struct mount3_state *ms = NULL((void*)0); |
1457 | char *export = NULL((void*)0); |
1458 | |
1459 | ms = mnt3prog.private; |
1460 | me = GF_CALLOC (1, sizeof (*me), gf_nfs_mt_mountentry)__gf_calloc (1, sizeof (*me), gf_nfs_mt_mountentry); |
1461 | if (!me) |
1462 | return -1; |
1463 | export = (char *)expname; |
1464 | while (*export == '/') |
1465 | export++; |
1466 | |
1467 | strcpy (me->exname, export); |
1468 | strcpy (me->hostname, host); |
1469 | INIT_LIST_HEAD (&me->mlist)do { (&me->mlist)->next = (&me->mlist)->prev = &me->mlist; } while (0); |
1470 | LOCK (&ms->mountlock)pthread_spin_lock (&ms->mountlock); |
1471 | { |
1472 | list_add_tail (&me->mlist, &ms->mountlist); |
1473 | } |
1474 | UNLOCK (&ms->mountlock)pthread_spin_unlock (&ms->mountlock); |
1475 | return 0; |
1476 | } |
1477 | |
1478 | int |
1479 | mount3udp_delete_mountlist (char *hostname, dirpath *expname) |
1480 | { |
1481 | struct mount3_state *ms = NULL((void*)0); |
1482 | char *export = NULL((void*)0); |
1483 | |
1484 | ms = mnt3prog.private; |
1485 | export = (char *)expname; |
1486 | while (*export == '/') |
1487 | export++; |
1488 | __mnt3svc_umount (ms, export, hostname); |
1489 | return 0; |
1490 | } |
1491 | |
1492 | |
1493 | struct mnt3_export * |
1494 | mnt3_init_export_ent (struct mount3_state *ms, xlator_t *xl, char *exportpath, |
1495 | uuid_t volumeid) |
1496 | { |
1497 | struct mnt3_export *exp = NULL((void*)0); |
1498 | int alloclen = 0; |
1499 | int ret = -1; |
1500 | |
1501 | if ((!ms) || (!xl)) |
1502 | return NULL((void*)0); |
1503 | |
1504 | exp = GF_CALLOC (1, sizeof (*exp), gf_nfs_mt_mnt3_export)__gf_calloc (1, sizeof (*exp), gf_nfs_mt_mnt3_export); |
1505 | if (!exp) { |
1506 | gf_log (GF_MNT, GF_LOG_ERROR, "Memory allocation failed")do { do { if (0) printf ("Memory allocation failed"); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 1506, GF_LOG_ERROR, "Memory allocation failed"); } while (0); |
1507 | return NULL((void*)0); |
1508 | } |
1509 | |
1510 | INIT_LIST_HEAD (&exp->explist)do { (&exp->explist)->next = (&exp->explist) ->prev = &exp->explist; } while (0); |
1511 | if (exportpath) |
1512 | alloclen = strlen (xl->name) + 2 + strlen (exportpath); |
1513 | else |
1514 | alloclen = strlen (xl->name) + 2; |
1515 | |
1516 | exp->expname = GF_CALLOC (alloclen, sizeof (char), gf_nfs_mt_char)__gf_calloc (alloclen, sizeof (char), gf_nfs_mt_char); |
1517 | if (!exp->expname) { |
1518 | gf_log (GF_MNT, GF_LOG_ERROR, "Memory allocation failed")do { do { if (0) printf ("Memory allocation failed"); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 1518, GF_LOG_ERROR, "Memory allocation failed"); } while (0); |
1519 | GF_FREE (exp)__gf_free (exp); |
1520 | exp = NULL((void*)0); |
1521 | goto err; |
1522 | } |
1523 | |
1524 | if (exportpath) { |
1525 | gf_log (GF_MNT, GF_LOG_TRACE, "Initing dir export: %s:%s",do { do { if (0) printf ("Initing dir export: %s:%s", xl-> name, exportpath); } while (0); _gf_log ("nfs""-mount", "mount3.c" , __FUNCTION__, 1526, GF_LOG_TRACE, "Initing dir export: %s:%s" , xl->name, exportpath); } while (0) |
1526 | xl->name, exportpath)do { do { if (0) printf ("Initing dir export: %s:%s", xl-> name, exportpath); } while (0); _gf_log ("nfs""-mount", "mount3.c" , __FUNCTION__, 1526, GF_LOG_TRACE, "Initing dir export: %s:%s" , xl->name, exportpath); } while (0); |
1527 | exp->exptype = MNT3_EXPTYPE_DIR2; |
1528 | ret = snprintf (exp->expname, alloclen, "/%s%s", xl->name, |
1529 | exportpath); |
1530 | } else { |
1531 | gf_log (GF_MNT, GF_LOG_TRACE, "Initing volume export: %s",do { do { if (0) printf ("Initing volume export: %s", xl-> name); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__ , 1532, GF_LOG_TRACE, "Initing volume export: %s", xl->name ); } while (0) |
1532 | xl->name)do { do { if (0) printf ("Initing volume export: %s", xl-> name); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__ , 1532, GF_LOG_TRACE, "Initing volume export: %s", xl->name ); } while (0); |
1533 | exp->exptype = MNT3_EXPTYPE_VOLUME1; |
1534 | ret = snprintf (exp->expname, alloclen, "/%s", xl->name); |
1535 | } |
1536 | if (ret < 0) { |
1537 | gf_log (xl->name, GF_LOG_WARNING,do { do { if (0) printf ("failed to get the export name"); } while (0); _gf_log (xl->name, "mount3.c", __FUNCTION__, 1538, GF_LOG_WARNING , "failed to get the export name"); } while (0) |
1538 | "failed to get the export name")do { do { if (0) printf ("failed to get the export name"); } while (0); _gf_log (xl->name, "mount3.c", __FUNCTION__, 1538, GF_LOG_WARNING , "failed to get the export name"); } while (0); |
1539 | } |
1540 | /* Just copy without discrimination, we'll determine whether to |
1541 | * actually use it when a mount request comes in and a file handle |
1542 | * needs to be built. |
1543 | */ |
1544 | uuid_copy (exp->volumeid, volumeid); |
1545 | exp->vol = xl; |
1546 | err: |
1547 | return exp; |
1548 | } |
1549 | |
1550 | |
1551 | int |
1552 | __mnt3_init_volume_direxports (struct mount3_state *ms, xlator_t *xlator, |
1553 | char *optstr, uuid_t volumeid) |
1554 | { |
1555 | struct mnt3_export *newexp = NULL((void*)0); |
1556 | int ret = -1; |
1557 | char *savptr = NULL((void*)0); |
1558 | char *dupopt = NULL((void*)0); |
1559 | char *token = NULL((void*)0); |
1560 | |
1561 | if ((!ms) || (!xlator) || (!optstr)) |
1562 | return -1; |
1563 | |
1564 | dupopt = gf_strdup (optstr); |
1565 | if (!dupopt) { |
1566 | gf_log (GF_MNT, GF_LOG_ERROR, "gf_strdup failed")do { do { if (0) printf ("gf_strdup failed"); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 1566, GF_LOG_ERROR , "gf_strdup failed"); } while (0); |
1567 | goto err; |
1568 | } |
1569 | |
1570 | token = strtok_r (dupopt, ",", &savptr); |
1571 | while (token) { |
1572 | newexp = mnt3_init_export_ent (ms, xlator, token, volumeid); |
1573 | if (!newexp) { |
1574 | gf_log (GF_MNT, GF_LOG_ERROR, "Failed to init dir "do { do { if (0) printf ("Failed to init dir " "export: %s", token ); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__ , 1575, GF_LOG_ERROR, "Failed to init dir " "export: %s", token ); } while (0) |
1575 | "export: %s", token)do { do { if (0) printf ("Failed to init dir " "export: %s", token ); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__ , 1575, GF_LOG_ERROR, "Failed to init dir " "export: %s", token ); } while (0); |
1576 | ret = -1; |
1577 | goto err; |
1578 | } |
1579 | |
1580 | list_add_tail (&newexp->explist, &ms->exportlist); |
1581 | token = strtok_r (NULL((void*)0), ",", &savptr); |
1582 | } |
1583 | |
1584 | ret = 0; |
1585 | err: |
1586 | GF_FREE (dupopt)__gf_free (dupopt); |
1587 | |
1588 | return ret; |
1589 | } |
1590 | |
1591 | |
1592 | int |
1593 | __mnt3_init_volume (struct mount3_state *ms, dict_t *opts, xlator_t *xlator) |
1594 | { |
1595 | struct mnt3_export *newexp = NULL((void*)0); |
1596 | int ret = -1; |
1597 | char searchstr[1024]; |
1598 | char *optstr = NULL((void*)0); |
1599 | uuid_t volumeid = {0, }; |
1600 | |
1601 | if ((!ms) || (!xlator) || (!opts)) |
1602 | return -1; |
1603 | |
1604 | uuid_clear (volumeid); |
1605 | if (gf_nfs_dvm_off (nfs_state (ms->nfsx))(((struct nfs_state *)(ms->nfsx)->private)->dynamicvolumes == 2)) |
1606 | goto no_dvm; |
1607 | |
1608 | ret = snprintf (searchstr, 1024, "nfs3.%s.volume-id", xlator->name); |
1609 | if (ret < 0) { |
1610 | gf_log (GF_MNT, GF_LOG_ERROR, "snprintf failed")do { do { if (0) printf ("snprintf failed"); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 1610, GF_LOG_ERROR , "snprintf failed"); } while (0); |
1611 | ret = -1; |
1612 | goto err; |
1613 | } |
1614 | |
1615 | if (dict_get (opts, searchstr)) { |
1616 | ret = dict_get_str (opts, searchstr, &optstr); |
1617 | if (ret < 0) { |
1618 | gf_log (GF_MNT, GF_LOG_ERROR, "Failed to read option"do { do { if (0) printf ("Failed to read option" ": %s", searchstr ); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__ , 1619, GF_LOG_ERROR, "Failed to read option" ": %s", searchstr ); } while (0) |
1619 | ": %s", searchstr)do { do { if (0) printf ("Failed to read option" ": %s", searchstr ); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__ , 1619, GF_LOG_ERROR, "Failed to read option" ": %s", searchstr ); } while (0); |
1620 | ret = -1; |
1621 | goto err; |
1622 | } |
1623 | } else { |
1624 | gf_log (GF_MNT, GF_LOG_ERROR, "DVM is on but volume-id not "do { do { if (0) printf ("DVM is on but volume-id not " "given for volume: %s" , xlator->name); } while (0); _gf_log ("nfs""-mount", "mount3.c" , __FUNCTION__, 1625, GF_LOG_ERROR, "DVM is on but volume-id not " "given for volume: %s", xlator->name); } while (0) |
1625 | "given for volume: %s", xlator->name)do { do { if (0) printf ("DVM is on but volume-id not " "given for volume: %s" , xlator->name); } while (0); _gf_log ("nfs""-mount", "mount3.c" , __FUNCTION__, 1625, GF_LOG_ERROR, "DVM is on but volume-id not " "given for volume: %s", xlator->name); } while (0); |
1626 | ret = -1; |
1627 | goto err; |
1628 | } |
1629 | |
1630 | if (optstr) { |
1631 | ret = uuid_parse (optstr, volumeid); |
1632 | if (ret < 0) { |
1633 | gf_log (GF_MNT, GF_LOG_ERROR, "Failed to parse volume "do { do { if (0) printf ("Failed to parse volume " "UUID"); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 1634, GF_LOG_ERROR, "Failed to parse volume " "UUID"); } while (0) |
1634 | "UUID")do { do { if (0) printf ("Failed to parse volume " "UUID"); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 1634, GF_LOG_ERROR, "Failed to parse volume " "UUID"); } while (0); |
1635 | ret = -1; |
1636 | goto err; |
1637 | } |
1638 | } |
1639 | |
1640 | no_dvm: |
1641 | ret = snprintf (searchstr, 1024, "nfs3.%s.export-dir", xlator->name); |
1642 | if (ret < 0) { |
1643 | gf_log (GF_MNT, GF_LOG_ERROR, "snprintf failed")do { do { if (0) printf ("snprintf failed"); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 1643, GF_LOG_ERROR , "snprintf failed"); } while (0); |
1644 | ret = -1; |
1645 | goto err; |
1646 | } |
1647 | |
1648 | if (dict_get (opts, searchstr)) { |
1649 | ret = dict_get_str (opts, searchstr, &optstr); |
1650 | if (ret < 0) { |
1651 | gf_log (GF_MNT, GF_LOG_ERROR, "Failed to read option: "do { do { if (0) printf ("Failed to read option: " "%s", searchstr ); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__ , 1652, GF_LOG_ERROR, "Failed to read option: " "%s", searchstr ); } while (0) |
1652 | "%s", searchstr)do { do { if (0) printf ("Failed to read option: " "%s", searchstr ); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__ , 1652, GF_LOG_ERROR, "Failed to read option: " "%s", searchstr ); } while (0); |
1653 | ret = -1; |
1654 | goto err; |
1655 | } |
1656 | |
1657 | ret = __mnt3_init_volume_direxports (ms, xlator, optstr, |
1658 | volumeid); |
1659 | if (ret == -1) { |
1660 | gf_log (GF_MNT, GF_LOG_ERROR, "Dir export setup failed"do { do { if (0) printf ("Dir export setup failed" " for volume: %s" , xlator->name); } while (0); _gf_log ("nfs""-mount", "mount3.c" , __FUNCTION__, 1661, GF_LOG_ERROR, "Dir export setup failed" " for volume: %s", xlator->name); } while (0) |
1661 | " for volume: %s", xlator->name)do { do { if (0) printf ("Dir export setup failed" " for volume: %s" , xlator->name); } while (0); _gf_log ("nfs""-mount", "mount3.c" , __FUNCTION__, 1661, GF_LOG_ERROR, "Dir export setup failed" " for volume: %s", xlator->name); } while (0); |
1662 | goto err; |
1663 | } |
1664 | } |
1665 | |
1666 | if (ms->export_volumes) { |
1667 | newexp = mnt3_init_export_ent (ms, xlator, NULL((void*)0), volumeid); |
1668 | if (!newexp) { |
1669 | ret = -1; |
1670 | goto err; |
1671 | } |
1672 | |
1673 | list_add_tail (&newexp->explist, &ms->exportlist); |
1674 | } |
1675 | ret = 0; |
1676 | |
1677 | |
1678 | err: |
1679 | return ret; |
1680 | } |
1681 | |
1682 | |
1683 | int |
1684 | __mnt3_init_volume_export (struct mount3_state *ms, dict_t *opts) |
1685 | { |
1686 | int ret = -1; |
1687 | char *optstr = NULL((void*)0); |
1688 | /* On by default. */ |
1689 | gf_boolean_t boolt = _gf_true; |
1690 | |
1691 | if ((!ms) || (!opts)) |
1692 | return -1; |
1693 | |
1694 | if (!dict_get (opts, "nfs3.export-volumes")) { |
1695 | ret = 0; |
1696 | goto err; |
1697 | } |
1698 | |
1699 | ret = dict_get_str (opts, "nfs3.export-volumes", &optstr); |
1700 | if (ret < 0) { |
1701 | gf_log (GF_MNT, GF_LOG_ERROR, "Failed to read option: "do { do { if (0) printf ("Failed to read option: " "nfs3.export-volumes" ); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__ , 1702, GF_LOG_ERROR, "Failed to read option: " "nfs3.export-volumes" ); } while (0) |
1702 | "nfs3.export-volumes")do { do { if (0) printf ("Failed to read option: " "nfs3.export-volumes" ); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__ , 1702, GF_LOG_ERROR, "Failed to read option: " "nfs3.export-volumes" ); } while (0); |
1703 | ret = -1; |
1704 | goto err; |
1705 | } |
1706 | |
1707 | gf_string2boolean (optstr, &boolt); |
1708 | ret = 0; |
1709 | |
1710 | err: |
1711 | if (boolt == _gf_false) { |
1712 | gf_log (GF_MNT, GF_LOG_TRACE, "Volume exports disabled")do { do { if (0) printf ("Volume exports disabled"); } while ( 0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 1712, GF_LOG_TRACE , "Volume exports disabled"); } while (0); |
1713 | ms->export_volumes = 0; |
1714 | } else { |
1715 | gf_log (GF_MNT, GF_LOG_TRACE, "Volume exports enabled")do { do { if (0) printf ("Volume exports enabled"); } while ( 0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 1715, GF_LOG_TRACE , "Volume exports enabled"); } while (0); |
1716 | ms->export_volumes = 1; |
1717 | } |
1718 | |
1719 | return ret; |
1720 | } |
1721 | |
1722 | |
1723 | int |
1724 | __mnt3_init_dir_export (struct mount3_state *ms, dict_t *opts) |
1725 | { |
1726 | int ret = -1; |
1727 | char *optstr = NULL((void*)0); |
1728 | /* On by default. */ |
1729 | gf_boolean_t boolt = _gf_true; |
1730 | |
1731 | if ((!ms) || (!opts)) |
1732 | return -1; |
1733 | |
1734 | if (!dict_get (opts, "nfs3.export-dirs")) { |
1735 | ret = 0; |
1736 | goto err; |
1737 | } |
1738 | |
1739 | ret = dict_get_str (opts, "nfs3.export-dirs", &optstr); |
1740 | if (ret < 0) { |
1741 | gf_log (GF_MNT, GF_LOG_ERROR, "Failed to read option: "do { do { if (0) printf ("Failed to read option: " "nfs3.export-dirs" ); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__ , 1742, GF_LOG_ERROR, "Failed to read option: " "nfs3.export-dirs" ); } while (0) |
1742 | "nfs3.export-dirs")do { do { if (0) printf ("Failed to read option: " "nfs3.export-dirs" ); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__ , 1742, GF_LOG_ERROR, "Failed to read option: " "nfs3.export-dirs" ); } while (0); |
1743 | ret = -1; |
1744 | goto err; |
1745 | } |
1746 | |
1747 | gf_string2boolean (optstr, &boolt); |
1748 | ret = 0; |
1749 | |
1750 | err: |
1751 | if (boolt == _gf_false) { |
1752 | gf_log (GF_MNT, GF_LOG_TRACE, "Dir exports disabled")do { do { if (0) printf ("Dir exports disabled"); } while (0) ; _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 1752, GF_LOG_TRACE , "Dir exports disabled"); } while (0); |
1753 | ms->export_dirs = 0; |
1754 | } else { |
1755 | gf_log (GF_MNT, GF_LOG_TRACE, "Dir exports enabled")do { do { if (0) printf ("Dir exports enabled"); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 1755, GF_LOG_TRACE , "Dir exports enabled"); } while (0); |
1756 | ms->export_dirs = 1; |
1757 | } |
1758 | |
1759 | return ret; |
1760 | } |
1761 | |
1762 | |
1763 | int |
1764 | mnt3_init_options (struct mount3_state *ms, dict_t *options) |
1765 | { |
1766 | xlator_list_t *volentry = NULL((void*)0); |
1767 | int ret = -1; |
1768 | |
1769 | if ((!ms) || (!options)) |
1770 | return -1; |
1771 | |
1772 | __mnt3_init_volume_export (ms, options); |
1773 | __mnt3_init_dir_export (ms, options); |
1774 | volentry = ms->nfsx->children; |
1775 | while (volentry) { |
1776 | gf_log (GF_MNT, GF_LOG_TRACE, "Initing options for: %s",do { do { if (0) printf ("Initing options for: %s", volentry-> xlator->name); } while (0); _gf_log ("nfs""-mount", "mount3.c" , __FUNCTION__, 1777, GF_LOG_TRACE, "Initing options for: %s" , volentry->xlator->name); } while (0) |
1777 | volentry->xlator->name)do { do { if (0) printf ("Initing options for: %s", volentry-> xlator->name); } while (0); _gf_log ("nfs""-mount", "mount3.c" , __FUNCTION__, 1777, GF_LOG_TRACE, "Initing options for: %s" , volentry->xlator->name); } while (0); |
1778 | ret = __mnt3_init_volume (ms, options, volentry->xlator); |
1779 | if (ret < 0) { |
1780 | gf_log (GF_MNT, GF_LOG_ERROR, "Volume init failed")do { do { if (0) printf ("Volume init failed"); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 1780, GF_LOG_ERROR , "Volume init failed"); } while (0); |
1781 | goto err; |
1782 | } |
1783 | |
1784 | volentry = volentry->next; |
1785 | } |
1786 | |
1787 | ret = 0; |
1788 | err: |
1789 | return ret; |
1790 | } |
1791 | |
1792 | |
1793 | struct mount3_state * |
1794 | mnt3_init_state (xlator_t *nfsx) |
1795 | { |
1796 | struct mount3_state *ms = NULL((void*)0); |
1797 | int ret = -1; |
1798 | |
1799 | if (!nfsx) |
1800 | return NULL((void*)0); |
1801 | |
1802 | ms = GF_CALLOC (1, sizeof (*ms), gf_nfs_mt_mount3_state)__gf_calloc (1, sizeof (*ms), gf_nfs_mt_mount3_state); |
1803 | if (!ms) { |
1804 | gf_log (GF_MNT, GF_LOG_ERROR, "Memory allocation failed")do { do { if (0) printf ("Memory allocation failed"); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 1804, GF_LOG_ERROR, "Memory allocation failed"); } while (0); |
1805 | return NULL((void*)0); |
1806 | } |
1807 | |
1808 | ms->iobpool = nfsx->ctx->iobuf_pool; |
1809 | ms->nfsx = nfsx; |
1810 | INIT_LIST_HEAD (&ms->exportlist)do { (&ms->exportlist)->next = (&ms->exportlist )->prev = &ms->exportlist; } while (0); |
1811 | ret = mnt3_init_options (ms, nfsx->options); |
1812 | if (ret < 0) { |
1813 | gf_log (GF_MNT, GF_LOG_ERROR, "Options init failed")do { do { if (0) printf ("Options init failed"); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 1813, GF_LOG_ERROR , "Options init failed"); } while (0); |
1814 | return NULL((void*)0); |
1815 | } |
1816 | |
1817 | INIT_LIST_HEAD (&ms->mountlist)do { (&ms->mountlist)->next = (&ms->mountlist )->prev = &ms->mountlist; } while (0); |
1818 | LOCK_INIT (&ms->mountlock)pthread_spin_init (&ms->mountlock, 0); |
1819 | |
1820 | return ms; |
1821 | } |
1822 | |
1823 | int |
1824 | mount_init_state (xlator_t *nfsx) |
1825 | { |
1826 | int ret = -1; |
1827 | struct nfs_state *nfs = NULL((void*)0); |
1828 | |
1829 | if (!nfsx) |
1830 | goto out; |
1831 | |
1832 | nfs = (struct nfs_state *)nfs_state (nfsx)(nfsx)->private; |
1833 | /*Maintaining global state for MOUNT1 and MOUNT3*/ |
1834 | nfs->mstate = mnt3_init_state (nfsx); |
1835 | if (!nfs->mstate) { |
1836 | gf_log (GF_NFS, GF_LOG_ERROR, "Failed to allocate"do { do { if (0) printf ("Failed to allocate" "mount state"); } while (0); _gf_log ("nfs", "mount3.c", __FUNCTION__, 1837, GF_LOG_ERROR, "Failed to allocate" "mount state"); } while ( 0) |
1837 | "mount state")do { do { if (0) printf ("Failed to allocate" "mount state"); } while (0); _gf_log ("nfs", "mount3.c", __FUNCTION__, 1837, GF_LOG_ERROR, "Failed to allocate" "mount state"); } while ( 0); |
1838 | goto out; |
1839 | } |
1840 | ret = 0; |
1841 | out: |
1842 | return ret; |
1843 | } |
1844 | |
1845 | rpcsvc_actor_t mnt3svc_actors[MOUNT3_PROC_COUNT6] = { |
1846 | {"NULL", MOUNT3_NULL0, mnt3svc_null, NULL((void*)0), 0}, |
1847 | {"MNT", MOUNT3_MNT1, mnt3svc_mnt, NULL((void*)0), 0}, |
1848 | {"DUMP", MOUNT3_DUMP2, mnt3svc_dump, NULL((void*)0), 0}, |
1849 | {"UMNT", MOUNT3_UMNT3, mnt3svc_umnt, NULL((void*)0), 0}, |
1850 | {"UMNTALL", MOUNT3_UMNTALL4, mnt3svc_umntall, NULL((void*)0), 0}, |
1851 | {"EXPORT", MOUNT3_EXPORT5, mnt3svc_export, NULL((void*)0), 0} |
1852 | }; |
1853 | |
1854 | |
1855 | |
1856 | /* Static init parts are assigned here, dynamic ones are done in |
1857 | * mnt3svc_init and mnt3_init_state. |
1858 | * Making MOUNT3 a synctask so that the blocking DNS calls during rpc auth |
1859 | * gets offloaded to syncenv, keeping the main/poll thread unblocked |
1860 | */ |
1861 | rpcsvc_program_t mnt3prog = { |
1862 | .progname = "MOUNT3", |
1863 | .prognum = MOUNT_PROGRAM100005, |
1864 | .progver = MOUNT_V33, |
1865 | .progport = GF_MOUNTV3_PORT38465, |
1866 | .actors = mnt3svc_actors, |
1867 | .numactors = MOUNT3_PROC_COUNT6, |
1868 | .min_auth = AUTH_NULL0, |
1869 | .synctask = _gf_true, |
1870 | }; |
1871 | |
1872 | |
1873 | |
1874 | rpcsvc_program_t * |
1875 | mnt3svc_init (xlator_t *nfsx) |
1876 | { |
1877 | struct mount3_state *mstate = NULL((void*)0); |
1878 | struct nfs_state *nfs = NULL((void*)0); |
1879 | dict_t *options = NULL((void*)0); |
1880 | char *portstr = NULL((void*)0); |
1881 | int ret = -1; |
1882 | pthread_t udp_thread; |
1883 | |
1884 | if (!nfsx || !nfsx->private) |
1885 | return NULL((void*)0); |
1886 | |
1887 | nfs = (struct nfs_state *)nfsx->private; |
1888 | |
1889 | gf_log (GF_MNT, GF_LOG_DEBUG, "Initing Mount v3 state")do { do { if (0) printf ("Initing Mount v3 state"); } while ( 0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 1889, GF_LOG_DEBUG , "Initing Mount v3 state"); } while (0); |
1890 | mstate = (struct mount3_state *)nfs->mstate; |
1891 | if (!mstate) { |
1892 | gf_log (GF_MNT, GF_LOG_ERROR, "Mount v3 state init failed")do { do { if (0) printf ("Mount v3 state init failed"); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 1892, GF_LOG_ERROR, "Mount v3 state init failed"); } while (0); |
1893 | goto err; |
1894 | } |
1895 | |
1896 | mnt3prog.private = mstate; |
1897 | options = dict_new (); |
1898 | |
1899 | ret = gf_asprintf (&portstr, "%d", GF_MOUNTV3_PORT38465); |
1900 | if (ret == -1) |
1901 | goto err; |
1902 | |
1903 | ret = dict_set_dynstr (options, "transport.socket.listen-port", portstr); |
1904 | if (ret == -1) |
1905 | goto err; |
1906 | ret = dict_set_str (options, "transport-type", "socket"); |
1907 | if (ret == -1) { |
1908 | gf_log (GF_NFS, GF_LOG_ERROR, "dict_set_str error")do { do { if (0) printf ("dict_set_str error"); } while (0); _gf_log ("nfs", "mount3.c", __FUNCTION__, 1908, GF_LOG_ERROR, "dict_set_str error" ); } while (0); |
1909 | goto err; |
1910 | } |
1911 | |
1912 | if (nfs->allow_insecure) { |
1913 | ret = dict_set_str (options, "rpc-auth-allow-insecure", "on"); |
1914 | if (ret == -1) { |
1915 | gf_log (GF_NFS, GF_LOG_ERROR, "dict_set_str error")do { do { if (0) printf ("dict_set_str error"); } while (0); _gf_log ("nfs", "mount3.c", __FUNCTION__, 1915, GF_LOG_ERROR, "dict_set_str error" ); } while (0); |
1916 | goto err; |
1917 | } |
1918 | ret = dict_set_str (options, "rpc-auth.ports.insecure", "on"); |
1919 | if (ret == -1) { |
1920 | gf_log (GF_NFS, GF_LOG_ERROR, "dict_set_str error")do { do { if (0) printf ("dict_set_str error"); } while (0); _gf_log ("nfs", "mount3.c", __FUNCTION__, 1920, GF_LOG_ERROR, "dict_set_str error" ); } while (0); |
1921 | goto err; |
1922 | } |
1923 | } |
1924 | |
1925 | rpcsvc_create_listeners (nfs->rpcsvc, options, nfsx->name); |
1926 | if (ret == -1) { |
1927 | gf_log (GF_NFS, GF_LOG_ERROR, "Unable to create listeners")do { do { if (0) printf ("Unable to create listeners"); } while (0); _gf_log ("nfs", "mount3.c", __FUNCTION__, 1927, GF_LOG_ERROR , "Unable to create listeners"); } while (0); |
1928 | dict_unref (options); |
1929 | goto err; |
1930 | } |
1931 | |
1932 | if (nfs->mount_udp) { |
1933 | pthread_create (&udp_thread, NULL((void*)0), mount3udp_thread, NULL((void*)0)); |
1934 | } |
1935 | return &mnt3prog; |
1936 | err: |
1937 | return NULL((void*)0); |
1938 | } |
1939 | |
1940 | |
1941 | rpcsvc_actor_t mnt1svc_actors[MOUNT1_PROC_COUNT6] = { |
1942 | {"NULL", MOUNT1_NULL0, mnt3svc_null, NULL((void*)0), 0}, |
1943 | {{0, 0}, }, |
1944 | {"DUMP", MOUNT1_DUMP2, mnt3svc_dump, NULL((void*)0), 0}, |
1945 | {"UMNT", MOUNT1_UMNT3, mnt3svc_umnt, NULL((void*)0), 0}, |
1946 | {{0, 0}, }, |
1947 | {"EXPORT", MOUNT1_EXPORT5, mnt3svc_export, NULL((void*)0), 0} |
1948 | }; |
1949 | |
1950 | rpcsvc_program_t mnt1prog = { |
1951 | .progname = "MOUNT1", |
1952 | .prognum = MOUNT_PROGRAM100005, |
1953 | .progver = MOUNT_V11, |
1954 | .progport = GF_MOUNTV1_PORT38466, |
1955 | .actors = mnt1svc_actors, |
1956 | .numactors = MOUNT1_PROC_COUNT6, |
1957 | .min_auth = AUTH_NULL0, |
1958 | .synctask = _gf_true, |
1959 | }; |
1960 | |
1961 | |
1962 | rpcsvc_program_t * |
1963 | mnt1svc_init (xlator_t *nfsx) |
1964 | { |
1965 | struct mount3_state *mstate = NULL((void*)0); |
1966 | struct nfs_state *nfs = NULL((void*)0); |
1967 | dict_t *options = NULL((void*)0); |
1968 | char *portstr = NULL((void*)0); |
1969 | int ret = -1; |
1970 | |
1971 | if (!nfsx || !nfsx->private) |
1972 | return NULL((void*)0); |
1973 | |
1974 | nfs = (struct nfs_state *)nfsx->private; |
1975 | |
1976 | gf_log (GF_MNT, GF_LOG_DEBUG, "Initing Mount v1 state")do { do { if (0) printf ("Initing Mount v1 state"); } while ( 0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 1976, GF_LOG_DEBUG , "Initing Mount v1 state"); } while (0); |
1977 | mstate = (struct mount3_state *)nfs->mstate; |
1978 | if (!mstate) { |
1979 | gf_log (GF_MNT, GF_LOG_ERROR, "Mount v3 state init failed")do { do { if (0) printf ("Mount v3 state init failed"); } while (0); _gf_log ("nfs""-mount", "mount3.c", __FUNCTION__, 1979, GF_LOG_ERROR, "Mount v3 state init failed"); } while (0); |
1980 | goto err; |
1981 | } |
1982 | |
1983 | mnt1prog.private = mstate; |
1984 | |
1985 | options = dict_new (); |
1986 | |
1987 | ret = gf_asprintf (&portstr, "%d", GF_MOUNTV1_PORT38466); |
1988 | if (ret == -1) |
1989 | goto err; |
1990 | |
1991 | ret = dict_set_dynstr (options, "transport.socket.listen-port", portstr); |
1992 | if (ret == -1) |
1993 | goto err; |
1994 | ret = dict_set_str (options, "transport-type", "socket"); |
1995 | if (ret == -1) { |
1996 | gf_log (GF_NFS, GF_LOG_ERROR, "dict_set_str error")do { do { if (0) printf ("dict_set_str error"); } while (0); _gf_log ("nfs", "mount3.c", __FUNCTION__, 1996, GF_LOG_ERROR, "dict_set_str error" ); } while (0); |
1997 | goto err; |
1998 | } |
1999 | |
2000 | if (nfs->allow_insecure) { |
2001 | ret = dict_set_str (options, "rpc-auth-allow-insecure", "on"); |
2002 | if (ret == -1) { |
2003 | gf_log (GF_NFS, GF_LOG_ERROR, "dict_set_str error")do { do { if (0) printf ("dict_set_str error"); } while (0); _gf_log ("nfs", "mount3.c", __FUNCTION__, 2003, GF_LOG_ERROR, "dict_set_str error" ); } while (0); |
2004 | goto err; |
2005 | } |
2006 | ret = dict_set_str (options, "rpc-auth.ports.insecure", "on"); |
2007 | if (ret == -1) { |
2008 | gf_log (GF_NFS, GF_LOG_ERROR, "dict_set_str error")do { do { if (0) printf ("dict_set_str error"); } while (0); _gf_log ("nfs", "mount3.c", __FUNCTION__, 2008, GF_LOG_ERROR, "dict_set_str error" ); } while (0); |
2009 | goto err; |
2010 | } |
2011 | } |
2012 | |
2013 | rpcsvc_create_listeners (nfs->rpcsvc, options, nfsx->name); |
2014 | if (ret == -1) { |
2015 | gf_log (GF_NFS, GF_LOG_ERROR, "Unable to create listeners")do { do { if (0) printf ("Unable to create listeners"); } while (0); _gf_log ("nfs", "mount3.c", __FUNCTION__, 2015, GF_LOG_ERROR , "Unable to create listeners"); } while (0); |
2016 | dict_unref (options); |
2017 | goto err; |
2018 | } |
2019 | |
2020 | return &mnt1prog; |
2021 | err: |
2022 | return NULL((void*)0); |
2023 | } |