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
20FILE_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
63
70
81
82/**
83 * A NFS request
84 *
85 */
87 /** Reference counter */
88 struct refcnt refcnt;
89 /** Data transfer interface */
91
95
99
103
105
106 char * hostname;
107 struct nfs_uri uri;
108
112
113 size_t remaining;
114 int eof;
115};
116
117static void nfs_step ( struct nfs_request *nfs );
118
119/**
120 * Free NFS request
121 *
122 * @v refcnt Reference counter
123 */
124static 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 */
143static 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
155static 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
176static 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;
208err:
209 nfs_done ( nfs, rc );
210}
211
212static 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;
263err:
264 nfs_done ( nfs, rc );
265done:
266 free_iob ( io_buf );
267 return 0;
268}
269
270static 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;
299err:
300 nfs_done ( nfs, rc );
301}
302
303static 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;
362err:
363 nfs_done ( nfs, rc );
364done:
365 free_iob ( io_buf );
366 return 0;
367}
368
369static 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;
418err:
419 nfs_done ( nfs, rc );
420}
421
422static 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;
547err:
548 nfs_done ( nfs, rc );
549done:
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
572
574 INTF_DESC ( struct nfs_request, pm_intf, nfs_pm_operations );
575
581
583 INTF_DESC ( struct nfs_request, mount_intf, nfs_mount_operations );
584
590
593 xfer );
594
595/*****************************************************************************
596 *
597 * URI opener
598 *
599 */
600
601static 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
620err_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 */
632static 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
671err_connect:
672 free ( nfs->auth_sys.hostname );
673err_cred:
674 nfs_uri_free ( &nfs->uri );
675 free ( nfs->hostname );
676err_uri:
677 free ( nfs );
678 return rc;
679}
680
681/** NFS URI opener */
682struct uri_opener nfs_uri_opener __uri_opener = {
683 .scheme = "nfs",
684 .open = nfs_open,
685};
u8 port
Port number.
Definition CIB_PRM.h:3
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
unsigned short uint16_t
Definition stdint.h:11
unsigned long long uint64_t
Definition stdint.h:13
Assertions.
struct bofm_section_header done
Definition bofm_test.c:46
ring len
Length.
Definition dwmac.h:226
uint8_t meta
Metadata flags.
Definition ena.h:3
Error codes.
#define __unused
Declare a variable or data structure as unused.
Definition compiler.h:573
#define SOCK_STREAM
Definition socket.h:25
#define DBGC2(...)
Definition compiler.h:522
#define DBGC(...)
Definition compiler.h:505
#define DHCP_EB_FEATURE_NFS
NFS protocol.
Definition features.h:58
#define FEATURE_PROTOCOL
Network protocols.
Definition features.h:22
#define EINVAL
Invalid argument.
Definition errno.h:429
#define EPROTO
Protocol error.
Definition errno.h:625
#define ENOMEM
Not enough space.
Definition errno.h:535
#define ECONNRESET
Connection reset.
Definition errno.h:364
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:926
#define htons(value)
Definition byteswap.h:136
Transport-network layer interface.
@ TCPIP_BIND_PRIVILEGED
Bind to a privileged port (less than 1024)
Definition tcpip.h:67
Time source.
String functions.
void * memset(void *dest, int character, size_t len) __nonnull
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition interface.c:250
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition interface.c:108
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
Definition interface.c:279
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition interface.h:81
#define INTF_DESC_PASSTHRU(object_type, intf, operations, passthru)
Define an object interface descriptor with pass-through interface.
Definition interface.h:98
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition interface.h:204
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition interface.h:33
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition iobuf.c:153
I/O buffers.
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition iobuf.h:217
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:160
#define iob_unput(iobuf, len)
Definition iobuf.h:140
Feature list.
#define FEATURE(category, text, feature_opt, version)
Declare a feature.
Definition features.h:101
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:662
int mount_umnt(struct interface *intf, struct oncrpc_session *session, const char *mountpoint)
Send a UMNT request.
Definition mount.c:76
int mount_mnt(struct interface *intf, struct oncrpc_session *session, const char *mountpoint)
Send a MNT request.
Definition mount.c:58
int mount_get_mnt_reply(struct mount_mnt_reply *mnt_reply, struct oncrpc_reply *reply)
Parse an MNT reply.
Definition mount.c:93
NFS MOUNT protocol.
#define MOUNT_VERS
NFS MOUNT protocol version.
Definition mount.h:17
#define MNT3ERR_NOENT
No such file or directory.
Definition mount.h:25
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
#define MNT3ERR_NOTDIR
Not a directory.
Definition mount.h:31
#define MNT3ERR_ACCES
Permission denied.
Definition mount.h:29
#define ONCRPC_MOUNT
NFS MOUNT protocol number.
Definition mount.h:15
struct mschapv2_challenge peer
Peer challenge.
Definition mschapv2.h:1
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
int nfs_readlink(struct interface *intf, struct oncrpc_session *session, const struct nfs_fh *fh)
Send a READLINK request.
Definition nfs.c:117
#define NFS_READ
NFS READ procedure.
Definition nfs.c:52
#define NFS_READLINK
NFS READLINK procedure.
Definition nfs.c:50
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
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
int nfs_get_readlink_reply(struct nfs_readlink_reply *readlink_reply, struct oncrpc_reply *reply)
Parse a READLINK reply.
Definition nfs.c:200
#define NFS_LOOKUP
NFS LOOKUP procedure.
Definition nfs.c:48
Network File System protocol.
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
#define ONCRPC_NFS
NFS protocol number.
Definition nfs.h:16
#define NFS_VERS
NFS protocol version.
Definition nfs.h:19
@ NFS_ATTR_SYMLINK
Definition nfs.h:67
static struct interface_operation nfs_pm_operations[]
Definition nfs_open.c:567
static struct interface_descriptor nfs_desc
Definition nfs_open.c:591
static int nfs_open(struct interface *xfer, struct uri *uri)
Initiate a NFS connection.
Definition nfs_open.c:632
static struct interface_descriptor nfs_pm_desc
Definition nfs_open.c:573
static void nfs_step(struct nfs_request *nfs)
Definition nfs_open.c:369
static void nfs_free(struct refcnt *refcnt)
Free NFS request.
Definition nfs_open.c:124
static int nfs_parse_uri(struct nfs_request *nfs, const struct uri *uri)
Definition nfs_open.c:601
#define NFS_RSIZE
Definition nfs_open.c:55
static int nfs_connect(struct interface *intf, uint16_t port, const char *hostname)
Definition nfs_open.c:155
static void nfs_mount_step(struct nfs_request *nfs)
Definition nfs_open.c:270
static struct interface_operation nfs_operations[]
Definition nfs_open.c:585
static int nfs_mount_deliver(struct nfs_request *nfs, struct io_buffer *io_buf, struct xfer_metadata *meta __unused)
Definition nfs_open.c:303
nfs_mount_state
Definition nfs_open.c:64
@ NFS_MOUNT_NONE
Definition nfs_open.c:65
@ NFS_MOUNT_CLOSED
Definition nfs_open.c:68
@ NFS_MOUNT_MNT
Definition nfs_open.c:66
@ NFS_MOUNT_UMNT
Definition nfs_open.c:67
static struct interface_operation nfs_xfer_operations[]
Definition nfs_open.c:559
static struct interface_operation nfs_mount_operations[]
Definition nfs_open.c:576
nfs_pm_state
Definition nfs_open.c:57
@ NFS_PORTMAP_NONE
Definition nfs_open.c:58
@ MFS_PORTMAP_CLOSED
Definition nfs_open.c:61
@ NFS_PORTMAP_NFSPORT
Definition nfs_open.c:60
@ NFS_PORTMAP_MOUNTPORT
Definition nfs_open.c:59
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_descriptor nfs_mount_desc
Definition nfs_open.c:582
static struct interface_descriptor nfs_xfer_desc
NFS data transfer interface descriptor.
Definition nfs_open.c:564
static void nfs_pm_step(struct nfs_request *nfs)
Definition nfs_open.c:176
static void nfs_done(struct nfs_request *nfs, int rc)
Mark NFS operation as complete.
Definition nfs_open.c:143
static int nfs_deliver(struct nfs_request *nfs, struct io_buffer *io_buf, struct xfer_metadata *meta __unused)
Definition nfs_open.c:422
nfs_state
Definition nfs_open.c:71
@ NFS_LOOKUP_SENT
Definition nfs_open.c:74
@ NFS_CLOSED
Definition nfs_open.c:79
@ NFS_READ_SENT
Definition nfs_open.c:78
@ NFS_NONE
Definition nfs_open.c:72
@ NFS_READLINK_SENT
Definition nfs_open.c:76
Network File System protocol.
int nfs_uri_next_mountpoint(struct nfs_uri *uri)
Definition nfs_uri.c:64
char * nfs_uri_next_path_component(struct nfs_uri *uri)
Definition nfs_uri.c:123
void nfs_uri_free(struct nfs_uri *uri)
Definition nfs_uri.c:145
char * nfs_uri_mountpoint(const struct nfs_uri *uri)
Definition nfs_uri.c:56
int nfs_uri_symlink(struct nfs_uri *uri, const char *symlink)
Definition nfs_uri.c:86
int nfs_uri_init(struct nfs_uri *nfs_uri, const struct uri *uri)
Definition nfs_uri.c:34
Network File System protocol URI handling functions.
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
int oncrpc_init_cred_sys(struct oncrpc_cred_sys *auth_sys)
Initialize an ONC RPC AUTH SYS credential structure.
Definition oncrpc.c:84
SUN ONC RPC protocol.
SUN ONC RPC protocol.
Data transfer interface opening.
#define __uri_opener
Register a URI opener.
Definition open.h:68
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 portmap_get_getport_reply(struct portmap_getport_reply *getport_reply, struct oncrpc_reply *reply)
Parse a GETPORT reply.
Definition portmap.c:82
SUN ONC RPC protocol.
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
#define PORTMAP_PORT
PORTMAP default port.
Definition portmap.h:16
#define PORTMAP_PROTO_TCP
TCP protocol number.
Definition portmap.h:26
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
#define ref_put(refcnt)
Drop reference to object.
Definition refcnt.h:107
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition refcnt.h:65
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
Socket addresses.
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
int strcmp(const char *first, const char *second)
Compare strings.
Definition string.c:174
char * strdup(const char *src)
Duplicate string.
Definition string.c:394
char * strndup(const char *src, size_t max)
Duplicate string.
Definition string.c:406
An object interface descriptor.
Definition interface.h:56
An object interface operation.
Definition interface.h:18
An object interface.
Definition interface.h:125
A persistent I/O buffer.
Definition iobuf.h:38
A MOUNT MNT reply.
Definition mount.h:46
uint32_t status
Reply status.
Definition mount.h:48
struct nfs_fh fh
Root file handle.
Definition mount.h:50
A NFS file handle.
Definition nfs.h:74
A NFS LOOKUP reply.
Definition nfs.h:83
enum nfs_attr_type ent_type
Entity type.
Definition nfs.h:87
struct nfs_fh fh
File handle.
Definition nfs.h:89
A NFS READ reply.
Definition nfs.h:110
uint32_t count
Bytes read.
Definition nfs.h:116
uint32_t eof
End-of-File indicator.
Definition nfs.h:118
uint64_t filesize
File size.
Definition nfs.h:114
A NFS request.
Definition nfs_open.c:86
struct oncrpc_session pm_session
Definition nfs_open.c:100
struct interface nfs_intf
Definition nfs_open.c:94
enum nfs_mount_state mount_state
Definition nfs_open.c:97
enum nfs_pm_state pm_state
Definition nfs_open.c:96
struct nfs_uri uri
Definition nfs_open.c:107
size_t remaining
Definition nfs_open.c:113
struct interface xfer
Data transfer interface.
Definition nfs_open.c:90
struct nfs_fh current_fh
Definition nfs_open.c:110
enum nfs_state nfs_state
Definition nfs_open.c:98
struct interface pm_intf
Definition nfs_open.c:92
char * hostname
Definition nfs_open.c:106
struct oncrpc_session nfs_session
Definition nfs_open.c:102
struct refcnt refcnt
Reference counter.
Definition nfs_open.c:88
struct oncrpc_cred_sys auth_sys
Definition nfs_open.c:104
struct nfs_fh readlink_fh
Definition nfs_open.c:109
uint64_t file_offset
Definition nfs_open.c:111
struct oncrpc_session mount_session
Definition nfs_open.c:101
struct interface mount_intf
Definition nfs_open.c:93
char * path
Definition nfs_uri.h:17
char * lookup_pos
Definition nfs_uri.h:18
char * hostname
Definition oncrpc.h:54
struct oncrpc_cred credential
Definition oncrpc.h:52
uint32_t accept_state
Definition oncrpc.h:66
A PORTMAP GETPORT reply.
Definition portmap.h:35
uint32_t port
Port returned.
Definition portmap.h:37
A reference counter.
Definition refcnt.h:27
TCP/IP socket address.
Definition tcpip.h:76
uint16_t st_flags
Flags.
Definition tcpip.h:80
Generalized socket address structure.
Definition socket.h:97
A URI opener.
Definition open.h:48
A Uniform Resource Identifier.
Definition uri.h:65
const char * path
Path (after URI decoding)
Definition uri.h:81
const char * host
Host name.
Definition uri.h:77
Data transfer metadata.
Definition xfer.h:23
Uniform Resource Identifiers.
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition xfer.c:117
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition xfer.c:195
void xfer_window_changed(struct interface *intf)
Report change of flow control window.
Definition xfer.c:147
int xfer_seek(struct interface *intf, off_t offset)
Seek to position.
Definition xfer.c:352
int xfer_deliver_iob(struct interface *intf, struct io_buffer *iobuf)
Deliver datagram as I/O buffer without metadata.
Definition xfer.c:256
Data transfer interfaces.