File: | xlators/nfs/server/src/mount3.c |
Location: | line 922, column 42 |
Description: | Access to field 'vol' results in a dereference of a null pointer (loaded from variable 'exp') |
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},}; | |||
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 | } |