iPXE
nfs_open.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2013 Marin Hannache <ipxe@mareo.fr>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  */
19 
20 FILE_SECBOOT ( FORBIDDEN );
21 
22 #include <stdint.h>
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <assert.h>
27 #include <errno.h>
28 #include <libgen.h>
29 #include <byteswap.h>
30 #include <ipxe/time.h>
31 #include <ipxe/socket.h>
32 #include <ipxe/tcpip.h>
33 #include <ipxe/in.h>
34 #include <ipxe/iobuf.h>
35 #include <ipxe/xfer.h>
36 #include <ipxe/open.h>
37 #include <ipxe/uri.h>
38 #include <ipxe/features.h>
39 #include <ipxe/nfs.h>
40 #include <ipxe/nfs_open.h>
41 #include <ipxe/oncrpc.h>
42 #include <ipxe/oncrpc_iob.h>
43 #include <ipxe/portmap.h>
44 #include <ipxe/mount.h>
45 #include <ipxe/nfs_uri.h>
46 
47 /** @file
48  *
49  * Network File System protocol
50  *
51  */
52 
54 
55 #define NFS_RSIZE 100000
56 
62 };
63 
69 };
70 
71 enum nfs_state {
72  NFS_NONE = 0,
80 };
81 
82 /**
83  * A NFS request
84  *
85  */
86 struct nfs_request {
87  /** Reference counter */
88  struct refcnt refcnt;
89  /** Data transfer interface */
90  struct interface xfer;
91 
95 
99 
103 
105 
106  char * hostname;
107  struct nfs_uri uri;
108 
112 
113  size_t remaining;
114  int eof;
115 };
116 
117 static void nfs_step ( struct nfs_request *nfs );
118 
119 /**
120  * Free NFS request
121  *
122  * @v refcnt Reference counter
123  */
124 static void nfs_free ( struct refcnt *refcnt ) {
125  struct nfs_request *nfs;
126 
127  nfs = container_of ( refcnt, struct nfs_request, refcnt );
128  DBGC ( nfs, "NFS_OPEN %p freed\n", nfs );
129 
130  nfs_uri_free ( &nfs->uri );
131 
132  free ( nfs->hostname );
133  free ( nfs->auth_sys.hostname );
134  free ( nfs );
135 }
136 
137 /**
138  * Mark NFS operation as complete
139  *
140  * @v nfs NFS request
141  * @v rc Return status code
142  */
143 static void nfs_done ( struct nfs_request *nfs, int rc ) {
144  if ( rc == 0 && nfs->nfs_state != NFS_CLOSED )
145  rc = -ECONNRESET;
146 
147  DBGC ( nfs, "NFS_OPEN %p completed (%s)\n", nfs, strerror ( rc ) );
148 
149  intf_shutdown ( &nfs->xfer, rc );
150  intf_shutdown ( &nfs->pm_intf, rc );
151  intf_shutdown ( &nfs->mount_intf, rc );
152  intf_shutdown ( &nfs->nfs_intf, rc );
153 }
154 
155 static int nfs_connect ( struct interface *intf, uint16_t port,
156  const char *hostname ) {
157  struct sockaddr_tcpip peer;
158  struct sockaddr_tcpip local;
159 
160  if ( ! intf || ! hostname || ! port )
161  return -EINVAL;
162 
163  memset ( &peer, 0, sizeof ( peer ) );
164  memset ( &local, 0, sizeof ( local ) );
165  peer.st_port = htons ( port );
166 
167  /* Use a local port < 1024 to avoid using the 'insecure' option in
168  * /etc/exports file. */
170 
171  return xfer_open_named_socket ( intf, SOCK_STREAM,
172  ( struct sockaddr * ) &peer, hostname,
173  ( struct sockaddr * ) &local );
174 }
175 
176 static void nfs_pm_step ( struct nfs_request *nfs ) {
177  int rc;
178 
179  if ( ! xfer_window ( &nfs->pm_intf ) )
180  return;
181 
182  if ( nfs->pm_state == NFS_PORTMAP_NONE ) {
183  DBGC ( nfs, "NFS_OPEN %p GETPORT call (mount)\n", nfs );
184 
185  rc = portmap_getport ( &nfs->pm_intf, &nfs->pm_session,
188  if ( rc != 0 )
189  goto err;
190 
191  nfs->pm_state++;
192  return;
193  }
194 
195  if ( nfs->pm_state == NFS_PORTMAP_NFSPORT ) {
196  DBGC ( nfs, "NFS_OPEN %p GETPORT call (nfs)\n", nfs );
197 
198  rc = portmap_getport ( &nfs->pm_intf, &nfs->pm_session,
201  if ( rc != 0 )
202  goto err;
203 
204  return;
205  }
206 
207  return;
208 err:
209  nfs_done ( nfs, rc );
210 }
211 
212 static int nfs_pm_deliver ( struct nfs_request *nfs,
213  struct io_buffer *io_buf,
214  struct xfer_metadata *meta __unused ) {
215  int rc;
216  struct oncrpc_reply reply;
217  struct portmap_getport_reply getport_reply;
218 
219  oncrpc_get_reply ( &nfs->pm_session, &reply, io_buf );
220  if ( reply.accept_state != 0 )
221  {
222  rc = -EPROTO;
223  goto err;
224  }
225 
226  if ( nfs->pm_state == NFS_PORTMAP_MOUNTPORT ) {
227  DBGC ( nfs, "NFS_OPEN %p got GETPORT reply (mount)\n", nfs );
228 
229  rc = portmap_get_getport_reply ( &getport_reply, &reply );
230  if ( rc != 0 )
231  goto err;
232 
233  rc = nfs_connect ( &nfs->mount_intf, getport_reply.port,
234  nfs->hostname );
235  if ( rc != 0 )
236  goto err;
237 
238  nfs->pm_state++;
239  nfs_pm_step ( nfs );
240 
241  goto done;
242  }
243 
244  if ( nfs->pm_state == NFS_PORTMAP_NFSPORT ) {
245  DBGC ( nfs, "NFS_OPEN %p got GETPORT reply (nfs)\n", nfs );
246 
247  rc = portmap_get_getport_reply ( &getport_reply, &reply );
248  if ( rc != 0 )
249  goto err;
250 
251  rc = nfs_connect ( &nfs->nfs_intf, getport_reply.port,
252  nfs->hostname );
253  if ( rc != 0 )
254  goto err;
255 
256  intf_shutdown ( &nfs->pm_intf, 0 );
257  nfs->pm_state++;
258 
259  goto done;
260  }
261 
262  rc = -EPROTO;
263 err:
264  nfs_done ( nfs, rc );
265 done:
266  free_iob ( io_buf );
267  return 0;
268 }
269 
270 static void nfs_mount_step ( struct nfs_request *nfs ) {
271  int rc;
272 
273  if ( ! xfer_window ( &nfs->mount_intf ) )
274  return;
275 
276  if ( nfs->mount_state == NFS_MOUNT_NONE ) {
277  DBGC ( nfs, "NFS_OPEN %p MNT call (%s)\n", nfs,
278  nfs_uri_mountpoint ( &nfs->uri ) );
279 
280  rc = mount_mnt ( &nfs->mount_intf, &nfs->mount_session,
281  nfs_uri_mountpoint ( &nfs->uri ) );
282  if ( rc != 0 )
283  goto err;
284 
285  nfs->mount_state++;
286  return;
287  }
288 
289  if ( nfs->mount_state == NFS_MOUNT_UMNT ) {
290  DBGC ( nfs, "NFS_OPEN %p UMNT call\n", nfs );
291 
292  rc = mount_umnt ( &nfs->mount_intf, &nfs->mount_session,
293  nfs_uri_mountpoint ( &nfs->uri ) );
294  if ( rc != 0 )
295  goto err;
296  }
297 
298  return;
299 err:
300  nfs_done ( nfs, rc );
301 }
302 
303 static int nfs_mount_deliver ( struct nfs_request *nfs,
304  struct io_buffer *io_buf,
305  struct xfer_metadata *meta __unused ) {
306  int rc;
307  struct oncrpc_reply reply;
308  struct mount_mnt_reply mnt_reply;
309 
310  oncrpc_get_reply ( &nfs->mount_session, &reply, io_buf );
311  if ( reply.accept_state != 0 )
312  {
313  rc = -EPROTO;
314  goto err;
315  }
316 
317  if ( nfs->mount_state == NFS_MOUNT_MNT ) {
318  DBGC ( nfs, "NFS_OPEN %p got MNT reply\n", nfs );
319  rc = mount_get_mnt_reply ( &mnt_reply, &reply );
320  if ( rc != 0 ) {
321  switch ( mnt_reply.status ) {
322  case MNT3ERR_NOTDIR:
323  case MNT3ERR_NOENT:
324  case MNT3ERR_ACCES:
325  break;
326 
327  default:
328  goto err;
329  }
330 
331  if ( ! strcmp ( nfs_uri_mountpoint ( &nfs->uri ),
332  "/" ) )
333  goto err;
334 
335  if ( ( rc = nfs_uri_next_mountpoint ( &nfs->uri ) ) )
336  goto err;
337 
338  DBGC ( nfs, "NFS_OPEN %p MNT failed retrying with " \
339  "%s\n", nfs, nfs_uri_mountpoint ( &nfs->uri ) );
340 
341  nfs->mount_state--;
342  nfs_mount_step ( nfs );
343 
344  goto done;
345  }
346 
347  nfs->current_fh = mnt_reply.fh;
348  nfs->nfs_state = NFS_LOOKUP;
349  nfs_step ( nfs );
350 
351  goto done;
352  }
353 
354  if ( nfs->mount_state == NFS_MOUNT_UMNT ) {
355  DBGC ( nfs, "NFS_OPEN %p got UMNT reply\n", nfs );
356  nfs_done ( nfs, 0 );
357 
358  goto done;
359  }
360 
361  rc = -EPROTO;
362 err:
363  nfs_done ( nfs, rc );
364 done:
365  free_iob ( io_buf );
366  return 0;
367 }
368 
369 static void nfs_step ( struct nfs_request *nfs ) {
370  int rc;
371  char *path_component;
372 
373  if ( ! xfer_window ( &nfs->nfs_intf ) )
374  return;
375 
376  if ( nfs->nfs_state == NFS_LOOKUP ) {
377  path_component = nfs_uri_next_path_component ( &nfs->uri );
378 
379  DBGC ( nfs, "NFS_OPEN %p LOOKUP call (%s)\n", nfs,
380  path_component );
381 
382  rc = nfs_lookup ( &nfs->nfs_intf, &nfs->nfs_session,
383  &nfs->current_fh, path_component );
384  if ( rc != 0 )
385  goto err;
386 
387  nfs->nfs_state++;
388  return;
389  }
390 
391 
392  if ( nfs->nfs_state == NFS_READLINK ) {
393  DBGC ( nfs, "NFS_OPEN %p READLINK call\n", nfs );
394 
395  rc = nfs_readlink ( &nfs->nfs_intf, &nfs->nfs_session,
396  &nfs->readlink_fh );
397  if ( rc != 0 )
398  goto err;
399 
400  nfs->nfs_state++;
401  return;
402  }
403 
404  if ( nfs->nfs_state == NFS_READ ) {
405  DBGC ( nfs, "NFS_OPEN %p READ call\n", nfs );
406 
407  rc = nfs_read ( &nfs->nfs_intf, &nfs->nfs_session,
408  &nfs->current_fh, nfs->file_offset,
409  NFS_RSIZE );
410  if ( rc != 0 )
411  goto err;
412 
413  nfs->nfs_state++;
414  return;
415  }
416 
417  return;
418 err:
419  nfs_done ( nfs, rc );
420 }
421 
422 static int nfs_deliver ( struct nfs_request *nfs,
423  struct io_buffer *io_buf,
424  struct xfer_metadata *meta __unused ) {
425  int rc;
426  struct oncrpc_reply reply;
427 
428  if ( nfs->remaining == 0 ) {
429  oncrpc_get_reply ( &nfs->nfs_session, &reply, io_buf );
430  if ( reply.accept_state != 0 ) {
431  rc = -EPROTO;
432  goto err;
433  }
434  }
435 
436  if ( nfs->nfs_state == NFS_LOOKUP_SENT ) {
437  struct nfs_lookup_reply lookup_reply;
438 
439  DBGC ( nfs, "NFS_OPEN %p got LOOKUP reply\n", nfs );
440 
441  rc = nfs_get_lookup_reply ( &lookup_reply, &reply );
442  if ( rc != 0 )
443  goto err;
444 
445  if ( lookup_reply.ent_type == NFS_ATTR_SYMLINK ) {
446  nfs->readlink_fh = lookup_reply.fh;
447  nfs->nfs_state = NFS_READLINK;
448  } else {
449  nfs->current_fh = lookup_reply.fh;
450 
451  if ( nfs->uri.lookup_pos[0] == '\0' )
452  nfs->nfs_state = NFS_READ;
453  else
454  nfs->nfs_state--;
455  }
456 
457  nfs_step ( nfs );
458  goto done;
459  }
460 
461  if ( nfs->nfs_state == NFS_READLINK_SENT ) {
462  char *path;
463  struct nfs_readlink_reply readlink_reply;
464 
465  DBGC ( nfs, "NFS_OPEN %p got READLINK reply\n", nfs );
466 
467  rc = nfs_get_readlink_reply ( &readlink_reply, &reply );
468  if ( rc != 0 )
469  goto err;
470 
471  if ( readlink_reply.path_len == 0 )
472  {
473  rc = -EINVAL;
474  goto err;
475  }
476 
477  if ( ! ( path = strndup ( readlink_reply.path,
478  readlink_reply.path_len ) ) )
479  {
480  rc = -ENOMEM;
481  goto err;
482  }
483 
484  nfs_uri_symlink ( &nfs->uri, path );
485  free ( path );
486 
487  DBGC ( nfs, "NFS_OPEN %p new path: %s\n", nfs,
488  nfs->uri.path );
489 
490  nfs->nfs_state = NFS_LOOKUP;
491  nfs_step ( nfs );
492  goto done;
493  }
494 
495  if ( nfs->nfs_state == NFS_READ_SENT ) {
496  if ( nfs->remaining == 0 ) {
497  DBGC ( nfs, "NFS_OPEN %p got READ reply\n", nfs );
498 
499  struct nfs_read_reply read_reply;
500 
501  rc = nfs_get_read_reply ( &read_reply, &reply );
502  if ( rc != 0 )
503  goto err;
504 
505  if ( nfs->file_offset == 0 ) {
506  DBGC2 ( nfs, "NFS_OPEN %p size: %llu bytes\n",
507  nfs, read_reply.filesize );
508 
509  xfer_seek ( &nfs->xfer, read_reply.filesize );
510  xfer_seek ( &nfs->xfer, 0 );
511  }
512 
513  nfs->file_offset += read_reply.count;
514  nfs->remaining = read_reply.count;
515  nfs->eof = read_reply.eof;
516  }
517 
518  size_t len = iob_len ( io_buf );
519  if ( len > nfs->remaining )
520  iob_unput ( io_buf, len - nfs->remaining );
521 
522  nfs->remaining -= iob_len ( io_buf );
523 
524  DBGC ( nfs, "NFS_OPEN %p got %zd bytes\n", nfs,
525  iob_len ( io_buf ) );
526 
527  rc = xfer_deliver_iob ( &nfs->xfer, iob_disown ( io_buf ) );
528  if ( rc != 0 )
529  goto err;
530 
531  if ( nfs->remaining == 0 ) {
532  if ( ! nfs->eof ) {
533  nfs->nfs_state--;
534  nfs_step ( nfs );
535  } else {
536  intf_shutdown ( &nfs->nfs_intf, 0 );
537  nfs->nfs_state++;
538  nfs->mount_state++;
539  nfs_mount_step ( nfs );
540  }
541  }
542 
543  return 0;
544  }
545 
546  rc = -EPROTO;
547 err:
548  nfs_done ( nfs, rc );
549 done:
550  free_iob ( io_buf );
551  return 0;
552 }
553 
554 /*****************************************************************************
555  * Interfaces
556  *
557  */
558 
560  INTF_OP ( intf_close, struct nfs_request *, nfs_done ),
561 };
562 
563 /** NFS data transfer interface descriptor */
565  INTF_DESC ( struct nfs_request, xfer, nfs_xfer_operations );
566 
568  INTF_OP ( intf_close, struct nfs_request *, nfs_done ),
571 };
572 
574  INTF_DESC ( struct nfs_request, pm_intf, nfs_pm_operations );
575 
577  INTF_OP ( intf_close, struct nfs_request *, nfs_done ),
580 };
581 
583  INTF_DESC ( struct nfs_request, mount_intf, nfs_mount_operations );
584 
586  INTF_OP ( intf_close, struct nfs_request *, nfs_done ),
589 };
590 
592  INTF_DESC_PASSTHRU ( struct nfs_request, nfs_intf, nfs_operations,
593  xfer );
594 
595 /*****************************************************************************
596  *
597  * URI opener
598  *
599  */
600 
601 static int nfs_parse_uri ( struct nfs_request *nfs, const struct uri *uri ) {
602  int rc;
603 
604  if ( ! uri || ! uri->host || ! uri->path )
605  return -EINVAL;
606 
607  if ( ( rc = nfs_uri_init ( &nfs->uri, uri ) ) != 0 )
608  return rc;
609 
610  if ( ! ( nfs->hostname = strdup ( uri->host ) ) ) {
611  rc = -ENOMEM;
612  goto err_hostname;
613  }
614 
615  DBGC ( nfs, "NFS_OPEN %p URI parsed: (mountpoint=%s, path=%s)\n",
616  nfs, nfs_uri_mountpoint ( &nfs->uri), nfs->uri.path );
617 
618  return 0;
619 
620 err_hostname:
621  nfs_uri_free ( &nfs->uri );
622  return rc;
623 }
624 
625 /**
626  * Initiate a NFS connection
627  *
628  * @v xfer Data transfer interface
629  * @v uri Uniform Resource Identifier
630  * @ret rc Return status code
631  */
632 static int nfs_open ( struct interface *xfer, struct uri *uri ) {
633  int rc;
634  struct nfs_request *nfs;
635 
636  nfs = zalloc ( sizeof ( *nfs ) );
637  if ( ! nfs )
638  return -ENOMEM;
639 
640  rc = nfs_parse_uri( nfs, uri );
641  if ( rc != 0 )
642  goto err_uri;
643 
644  rc = oncrpc_init_cred_sys ( &nfs->auth_sys );
645  if ( rc != 0 )
646  goto err_cred;
647 
648  ref_init ( &nfs->refcnt, nfs_free );
649  intf_init ( &nfs->xfer, &nfs_xfer_desc, &nfs->refcnt );
650  intf_init ( &nfs->pm_intf, &nfs_pm_desc, &nfs->refcnt );
651  intf_init ( &nfs->mount_intf, &nfs_mount_desc, &nfs->refcnt );
652  intf_init ( &nfs->nfs_intf, &nfs_desc, &nfs->refcnt );
653 
657 
658  DBGC ( nfs, "NFS_OPEN %p connecting to port mapper (%s:%d)...\n", nfs,
659  nfs->hostname, PORTMAP_PORT );
660 
661  rc = nfs_connect ( &nfs->pm_intf, PORTMAP_PORT, nfs->hostname );
662  if ( rc != 0 )
663  goto err_connect;
664 
665  /* Attach to parent interface, mortalise self, and return */
666  intf_plug_plug ( &nfs->xfer, xfer );
667  ref_put ( &nfs->refcnt );
668 
669  return 0;
670 
671 err_connect:
672  free ( nfs->auth_sys.hostname );
673 err_cred:
674  nfs_uri_free ( &nfs->uri );
675  free ( nfs->hostname );
676 err_uri:
677  free ( nfs );
678  return rc;
679 }
680 
681 /** NFS URI opener */
682 struct uri_opener nfs_uri_opener __uri_opener = {
683  .scheme = "nfs",
684  .open = nfs_open,
685 };
void nfs_uri_free(struct nfs_uri *uri)
Definition: nfs_uri.c:145
struct interface nfs_intf
Definition: nfs_open.c:94
#define EINVAL
Invalid argument.
Definition: errno.h:429
An object interface operation.
Definition: interface.h:18
#define ECONNRESET
Connection reset.
Definition: errno.h:364
TCP/IP socket address.
Definition: tcpip.h:76
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void xfer_window_changed(struct interface *intf)
Report change of flow control window.
Definition: xfer.c:147
unsigned short uint16_t
Definition: stdint.h:11
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:250
FILE_SECBOOT(FORBIDDEN)
int mount_get_mnt_reply(struct mount_mnt_reply *mnt_reply, struct oncrpc_reply *reply)
Parse an MNT reply.
Definition: mount.c:93
enum nfs_pm_state pm_state
Definition: nfs_open.c:96
struct oncrpc_session mount_session
Definition: nfs_open.c:101
Data transfer metadata.
Definition: xfer.h:23
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
Definition: interface.c:279
static void nfs_done(struct nfs_request *nfs, int rc)
Mark NFS operation as complete.
Definition: nfs_open.c:143
int xfer_deliver_iob(struct interface *intf, struct io_buffer *iobuf)
Deliver datagram as I/O buffer without metadata.
Definition: xfer.c:256
FEATURE(FEATURE_PROTOCOL, "NFS", DHCP_EB_FEATURE_NFS, 1)
#define ONCRPC_NFS
NFS protocol number.
Definition: nfs.h:16
A NFS file handle.
Definition: nfs.h:74
uint32_t count
Bytes read.
Definition: nfs.h:116
#define FEATURE_PROTOCOL
Network protocols.
Definition: features.h:22
int nfs_get_read_reply(struct nfs_read_reply *read_reply, struct oncrpc_reply *reply)
Parse a READ reply.
Definition: nfs.c:243
int nfs_get_lookup_reply(struct nfs_lookup_reply *lookup_reply, struct oncrpc_reply *reply)
Parse a LOOKUP reply.
Definition: nfs.c:156
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:65
Error codes.
struct interface xfer
Data transfer interface.
Definition: nfs_open.c:90
struct nfs_uri uri
Definition: nfs_open.c:107
static void nfs_init_session(struct oncrpc_session *session, struct oncrpc_cred *credential)
Prepare an ONC RPC session to be used as a NFS session.
Definition: nfs.h:137
static int nfs_mount_deliver(struct nfs_request *nfs, struct io_buffer *io_buf, struct xfer_metadata *meta __unused)
Definition: nfs_open.c:303
I/O buffers.
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:153
size_t remaining
Definition: nfs_open.c:113
static struct interface_operation nfs_operations[]
Definition: nfs_open.c:585
static void nfs_free(struct refcnt *refcnt)
Free NFS request.
Definition: nfs_open.c:124
#define DBGC(...)
Definition: compiler.h:505
A NFS request.
Definition: nfs_open.c:86
struct nfs_fh fh
File handle.
Definition: nfs.h:89
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition: interface.c:108
unsigned long long uint64_t
Definition: stdint.h:13
static struct interface_operation nfs_pm_operations[]
Definition: nfs_open.c:567
uint32_t accept_state
Definition: oncrpc.h:66
static struct interface_descriptor nfs_xfer_desc
NFS data transfer interface descriptor.
Definition: nfs_open.c:564
enum nfs_mount_state mount_state
Definition: nfs_open.c:97
#define NFS_VERS
NFS protocol version.
Definition: nfs.h:19
Bind to a privileged port (less than 1024)
Definition: tcpip.h:67
Uniform Resource Identifiers.
static int nfs_connect(struct interface *intf, uint16_t port, const char *hostname)
Definition: nfs_open.c:155
#define ONCRPC_MOUNT
NFS MOUNT protocol number.
Definition: mount.h:15
uint32_t eof
End-of-File indicator.
Definition: nfs.h:118
#define PORTMAP_PROTO_TCP
TCP protocol number.
Definition: portmap.h:26
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition: xfer.c:117
struct uri_opener nfs_uri_opener __uri_opener
NFS URI opener.
Definition: nfs_open.c:682
uint64_t file_offset
Definition: nfs_open.c:111
int nfs_lookup(struct interface *intf, struct oncrpc_session *session, const struct nfs_fh *fh, const char *filename)
Send a LOOKUP request.
Definition: nfs.c:98
struct oncrpc_cred_sys auth_sys
Definition: nfs_open.c:104
int nfs_read(struct interface *intf, struct oncrpc_session *session, const struct nfs_fh *fh, uint64_t offset, uint32_t count)
Send a READ request.
Definition: nfs.c:137
char * lookup_pos
Definition: nfs_uri.h:18
Data transfer interfaces.
A reference counter.
Definition: refcnt.h:27
static void portmap_init_session(struct oncrpc_session *session, struct oncrpc_cred *credential)
Prepare an ONC RPC session to be used as a PORTMAP session.
Definition: portmap.h:50
static struct interface_descriptor nfs_desc
Definition: nfs_open.c:591
A NFS LOOKUP reply.
Definition: nfs.h:83
#define ENOMEM
Not enough space.
Definition: errno.h:535
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:217
enum nfs_attr_type ent_type
Entity type.
Definition: nfs.h:87
u8 port
Port number.
Definition: CIB_PRM.h:31
Assertions.
struct nfs_fh fh
Root file handle.
Definition: mount.h:50
static int nfs_open(struct interface *xfer, struct uri *uri)
Initiate a NFS connection.
Definition: nfs_open.c:632
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:36
struct nfs_fh readlink_fh
Definition: nfs_open.c:109
An object interface.
Definition: interface.h:125
int portmap_get_getport_reply(struct portmap_getport_reply *getport_reply, struct oncrpc_reply *reply)
Parse a GETPORT reply.
Definition: portmap.c:82
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
int oncrpc_init_cred_sys(struct oncrpc_cred_sys *auth_sys)
Initialize an ONC RPC AUTH SYS credential structure.
Definition: oncrpc.c:84
ring len
Length.
Definition: dwmac.h:231
nfs_pm_state
Definition: nfs_open.c:57
const char * path
Path (after URI decoding)
Definition: uri.h:81
static struct interface_descriptor nfs_pm_desc
Definition: nfs_open.c:573
const char * scheme
URI protocol name.
Definition: open.h:54
enum nfs_state nfs_state
Definition: nfs_open.c:98
Transport-network layer interface.
Feature list.
static struct interface_operation nfs_xfer_operations[]
Definition: nfs_open.c:559
#define MOUNT_VERS
NFS MOUNT protocol version.
Definition: mount.h:17
int oncrpc_get_reply(struct oncrpc_session *session __unused, struct oncrpc_reply *reply, struct io_buffer *io_buf)
Parse an I/O buffer to extract a ONC RPC REPLY.
Definition: oncrpc.c:215
SUN ONC RPC protocol.
#define EPROTO
Protocol error.
Definition: errno.h:625
int xfer_seek(struct interface *intf, off_t offset)
Seek to position.
Definition: xfer.c:352
Generalized socket address structure.
Definition: socket.h:97
An object interface descriptor.
Definition: interface.h:56
#define iob_unput(iobuf, len)
Definition: iobuf.h:140
nfs_mount_state
Definition: nfs_open.c:64
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:55
#define MNT3ERR_NOENT
No such file or directory.
Definition: mount.h:25
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:662
int nfs_uri_init(struct nfs_uri *nfs_uri, const struct uri *uri)
Definition: nfs_uri.c:34
#define PORTMAP_PORT
PORTMAP default port.
Definition: portmap.h:16
A NFS READ reply.
Definition: nfs.h:110
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:160
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:33
char * strdup(const char *src)
Duplicate string.
Definition: string.c:394
uint32_t status
Reply status.
Definition: mount.h:48
struct interface mount_intf
Definition: nfs_open.c:93
char * hostname
Definition: oncrpc.h:54
#define SOCK_STREAM
Definition: socket.h:25
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition: xfer.c:195
struct oncrpc_session pm_session
Definition: nfs_open.c:100
Data transfer interface opening.
char * nfs_uri_mountpoint(const struct nfs_uri *uri)
Definition: nfs_uri.c:56
const char * host
Host name.
Definition: uri.h:77
static int nfs_parse_uri(struct nfs_request *nfs, const struct uri *uri)
Definition: nfs_open.c:601
struct nfs_fh current_fh
Definition: nfs_open.c:110
static void nfs_pm_step(struct nfs_request *nfs)
Definition: nfs_open.c:176
int portmap_getport(struct interface *intf, struct oncrpc_session *session, uint32_t prog, uint32_t vers, uint32_t proto)
Send a GETPORT request.
Definition: portmap.c:61
int mount_mnt(struct interface *intf, struct oncrpc_session *session, const char *mountpoint)
Send a MNT request.
Definition: mount.c:58
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:81
int nfs_readlink(struct interface *intf, struct oncrpc_session *session, const struct nfs_fh *fh)
Send a READLINK request.
Definition: nfs.c:117
#define DBGC2(...)
Definition: compiler.h:522
Network File System protocol URI handling functions.
int strcmp(const char *first, const char *second)
Compare strings.
Definition: string.c:174
Network File System protocol.
static void mount_init_session(struct oncrpc_session *session, struct oncrpc_cred *credential)
Prepare an ONC RPC session to be used as a MOUNT session.
Definition: mount.h:62
Network File System protocol.
char * hostname
Definition: nfs_open.c:106
uint16_t st_flags
Flags.
Definition: tcpip.h:80
struct oncrpc_session nfs_session
Definition: nfs_open.c:102
static struct interface_descriptor nfs_mount_desc
Definition: nfs_open.c:582
char * strndup(const char *src, size_t max)
Duplicate string.
Definition: string.c:406
A Uniform Resource Identifier.
Definition: uri.h:65
#define INTF_DESC_PASSTHRU(object_type, intf, operations, passthru)
Define an object interface descriptor with pass-through interface.
Definition: interface.h:98
struct mschapv2_challenge peer
Peer challenge.
Definition: mschapv2.h:12
static void nfs_step(struct nfs_request *nfs)
Definition: nfs_open.c:369
static void nfs_mount_step(struct nfs_request *nfs)
Definition: nfs_open.c:270
struct refcnt refcnt
Reference counter.
Definition: nfs_open.c:88
uint8_t meta
Metadata flags.
Definition: ena.h:14
SUN ONC RPC protocol.
#define DHCP_EB_FEATURE_NFS
NFS protocol.
Definition: features.h:58
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition: interface.h:204
Socket addresses.
A URI opener.
Definition: open.h:48
int nfs_get_readlink_reply(struct nfs_readlink_reply *readlink_reply, struct oncrpc_reply *reply)
Parse a READLINK reply.
Definition: nfs.c:200
int nfs_uri_symlink(struct nfs_uri *uri, const char *symlink)
Definition: nfs_uri.c:86
int mount_umnt(struct interface *intf, struct oncrpc_session *session, const char *mountpoint)
Send a UMNT request.
Definition: mount.c:76
SUN ONC RPC protocol.
Time source.
int nfs_uri_next_mountpoint(struct nfs_uri *uri)
Definition: nfs_uri.c:64
nfs_state
Definition: nfs_open.c:71
struct oncrpc_cred credential
Definition: oncrpc.h:52
A MOUNT MNT reply.
Definition: mount.h:46
String functions.
uint32_t port
Port returned.
Definition: portmap.h:37
#define htons(value)
Definition: byteswap.h:136
char * nfs_uri_next_path_component(struct nfs_uri *uri)
Definition: nfs_uri.c:123
struct bofm_section_header done
Definition: bofm_test.c:46
#define NFS_RSIZE
Definition: nfs_open.c:55
char * path
Definition: nfs_uri.h:17
NFS MOUNT protocol.
uint64_t filesize
File size.
Definition: nfs.h:114
static int nfs_deliver(struct nfs_request *nfs, struct io_buffer *io_buf, struct xfer_metadata *meta __unused)
Definition: nfs_open.c:422
int xfer_open_named_socket(struct interface *xfer, int semantics, struct sockaddr *peer, const char *name, struct sockaddr *local)
Open named socket.
Definition: resolv.c:403
#define MNT3ERR_ACCES
Permission denied.
Definition: mount.h:29
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:107
A PORTMAP GETPORT reply.
Definition: portmap.h:35
static int nfs_pm_deliver(struct nfs_request *nfs, struct io_buffer *io_buf, struct xfer_metadata *meta __unused)
Definition: nfs_open.c:212
static struct interface_operation nfs_mount_operations[]
Definition: nfs_open.c:576
void * memset(void *dest, int character, size_t len) __nonnull
#define MNT3ERR_NOTDIR
Not a directory.
Definition: mount.h:31
A persistent I/O buffer.
Definition: iobuf.h:38
struct interface pm_intf
Definition: nfs_open.c:92