iPXE
Data Structures | Defines | Enumerations | Functions | Variables
nfs_open.c File Reference

Network File System protocol. More...

#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <libgen.h>
#include <byteswap.h>
#include <ipxe/time.h>
#include <ipxe/socket.h>
#include <ipxe/tcpip.h>
#include <ipxe/in.h>
#include <ipxe/iobuf.h>
#include <ipxe/xfer.h>
#include <ipxe/open.h>
#include <ipxe/uri.h>
#include <ipxe/features.h>
#include <ipxe/nfs.h>
#include <ipxe/nfs_open.h>
#include <ipxe/oncrpc.h>
#include <ipxe/oncrpc_iob.h>
#include <ipxe/portmap.h>
#include <ipxe/mount.h>
#include <ipxe/nfs_uri.h>

Go to the source code of this file.

Data Structures

struct  nfs_request
 A NFS request. More...

Defines

#define NFS_RSIZE   100000

Enumerations

enum  nfs_pm_state { NFS_PORTMAP_NONE = 0, NFS_PORTMAP_MOUNTPORT, NFS_PORTMAP_NFSPORT, MFS_PORTMAP_CLOSED }
enum  nfs_mount_state { NFS_MOUNT_NONE = 0, NFS_MOUNT_MNT, NFS_MOUNT_UMNT, NFS_MOUNT_CLOSED }
enum  nfs_state {
  NFS_NONE = 0, NFS_LOOKUP, NFS_LOOKUP_SENT, NFS_READLINK,
  NFS_READLINK_SENT, NFS_READ, NFS_READ_SENT, NFS_CLOSED
}

Functions

 FEATURE (FEATURE_PROTOCOL,"NFS", DHCP_EB_FEATURE_NFS, 1)
static void nfs_step (struct nfs_request *nfs)
static void nfs_free (struct refcnt *refcnt)
 Free NFS request.
static void nfs_done (struct nfs_request *nfs, int rc)
 Mark NFS operation as complete.
static int nfs_connect (struct interface *intf, uint16_t port, const char *hostname)
static void nfs_pm_step (struct nfs_request *nfs)
static int nfs_pm_deliver (struct nfs_request *nfs, struct io_buffer *io_buf, struct xfer_metadata *meta __unused)
static void nfs_mount_step (struct nfs_request *nfs)
static int nfs_mount_deliver (struct nfs_request *nfs, struct io_buffer *io_buf, struct xfer_metadata *meta __unused)
static int nfs_deliver (struct nfs_request *nfs, struct io_buffer *io_buf, struct xfer_metadata *meta __unused)
static int nfs_parse_uri (struct nfs_request *nfs, const struct uri *uri)
static int nfs_open (struct interface *xfer, struct uri *uri)
 Initiate a NFS connection.

Variables

static struct interface_operation nfs_xfer_operations []
static struct interface_descriptor nfs_xfer_desc
 NFS data transfer interface descriptor.
static struct interface_operation nfs_pm_operations []
static struct interface_descriptor nfs_pm_desc
static struct interface_operation nfs_mount_operations []
static struct interface_descriptor nfs_mount_desc
static struct interface_operation nfs_operations []
static struct interface_descriptor nfs_desc
struct uri_opener nfs_uri_opener __uri_opener
 NFS URI opener.

Detailed Description

Network File System protocol.

Definition in file nfs_open.c.


Define Documentation

#define NFS_RSIZE   100000

Definition at line 53 of file nfs_open.c.

Referenced by nfs_step().


Enumeration Type Documentation

Enumerator:
NFS_PORTMAP_NONE 
NFS_PORTMAP_MOUNTPORT 
NFS_PORTMAP_NFSPORT 
MFS_PORTMAP_CLOSED 

Definition at line 55 of file nfs_open.c.

Enumerator:
NFS_MOUNT_NONE 
NFS_MOUNT_MNT 
NFS_MOUNT_UMNT 
NFS_MOUNT_CLOSED 

Definition at line 62 of file nfs_open.c.

enum nfs_state
Enumerator:
NFS_NONE 
NFS_LOOKUP 
NFS_LOOKUP_SENT 
NFS_READLINK 
NFS_READLINK_SENT 
NFS_READ 
NFS_READ_SENT 
NFS_CLOSED 

Definition at line 69 of file nfs_open.c.


Function Documentation

FEATURE ( FEATURE_PROTOCOL  ,
"NFS"  ,
DHCP_EB_FEATURE_NFS  ,
 
)
static void nfs_step ( struct nfs_request nfs) [static]

Definition at line 367 of file nfs_open.c.

References nfs_request::current_fh, DBGC, nfs_request::file_offset, nfs_done(), nfs_request::nfs_intf, NFS_LOOKUP, nfs_lookup(), NFS_READ, nfs_read(), NFS_READLINK, nfs_readlink(), NFS_RSIZE, nfs_request::nfs_session, nfs_request::nfs_state, nfs_uri_next_path_component(), rc, nfs_request::readlink_fh, nfs_request::uri, and xfer_window().

Referenced by nfs_deliver(), and nfs_mount_deliver().

                                                 {
        int     rc;
        char    *path_component;

        if ( ! xfer_window ( &nfs->nfs_intf ) )
                return;

        if ( nfs->nfs_state == NFS_LOOKUP ) {
                path_component = nfs_uri_next_path_component ( &nfs->uri );

                DBGC ( nfs, "NFS_OPEN %p LOOKUP call (%s)\n", nfs,
                       path_component );

                rc = nfs_lookup ( &nfs->nfs_intf, &nfs->nfs_session,
                                  &nfs->current_fh, path_component );
                if ( rc != 0 )
                        goto err;

                nfs->nfs_state++;
                return;
        }


        if ( nfs->nfs_state == NFS_READLINK ) {
                DBGC ( nfs, "NFS_OPEN %p READLINK call\n", nfs );

                rc = nfs_readlink ( &nfs->nfs_intf, &nfs->nfs_session,
                                    &nfs->readlink_fh );
                if ( rc != 0 )
                        goto err;

                nfs->nfs_state++;
                return;
        }

        if ( nfs->nfs_state == NFS_READ ) {
                DBGC ( nfs, "NFS_OPEN %p READ call\n", nfs );

                rc = nfs_read ( &nfs->nfs_intf, &nfs->nfs_session,
                                &nfs->current_fh, nfs->file_offset,
                                NFS_RSIZE );
                if ( rc != 0 )
                        goto err;

                nfs->nfs_state++;
                return;
        }

        return;
err:
        nfs_done ( nfs, rc );
}
static void nfs_free ( struct refcnt refcnt) [static]

Free NFS request.

Parameters:
refcntReference counter

Definition at line 122 of file nfs_open.c.

References nfs_request::auth_sys, container_of, DBGC, free, oncrpc_cred_sys::hostname, nfs_request::hostname, nfs_uri_free(), and nfs_request::uri.

Referenced by nfs_open().

                                               {
        struct nfs_request      *nfs;

        nfs = container_of ( refcnt, struct nfs_request, refcnt );
        DBGC ( nfs, "NFS_OPEN %p freed\n", nfs );

        nfs_uri_free ( &nfs->uri );

        free ( nfs->hostname );
        free ( nfs->auth_sys.hostname );
        free ( nfs );
}
static void nfs_done ( struct nfs_request nfs,
int  rc 
) [static]

Mark NFS operation as complete.

Parameters:
nfsNFS request
rcReturn status code

Definition at line 141 of file nfs_open.c.

References DBGC, ECONNRESET, intf_shutdown(), nfs_request::mount_intf, NFS_CLOSED, nfs_request::nfs_intf, nfs_request::nfs_state, nfs_request::pm_intf, strerror(), and nfs_request::xfer.

Referenced by nfs_deliver(), nfs_mount_deliver(), nfs_mount_step(), nfs_pm_deliver(), nfs_pm_step(), and nfs_step().

                                                         {
        if ( rc == 0 && nfs->nfs_state != NFS_CLOSED )
                rc = -ECONNRESET;

        DBGC ( nfs, "NFS_OPEN %p completed (%s)\n", nfs, strerror ( rc ) );

        intf_shutdown ( &nfs->xfer, rc );
        intf_shutdown ( &nfs->pm_intf, rc );
        intf_shutdown ( &nfs->mount_intf, rc );
        intf_shutdown ( &nfs->nfs_intf, rc );
}
static int nfs_connect ( struct interface intf,
uint16_t  port,
const char *  hostname 
) [static]

Definition at line 153 of file nfs_open.c.

References EINVAL, htons, memset(), SOCK_STREAM, sockaddr_tcpip::st_flags, sockaddr_tcpip::st_port, TCPIP_BIND_PRIVILEGED, and xfer_open_named_socket().

Referenced by nfs_open(), and nfs_pm_deliver().

                                                {
        struct sockaddr_tcpip   peer;
        struct sockaddr_tcpip   local;

        if ( ! intf || ! hostname || ! port )
                return -EINVAL;

        memset ( &peer, 0, sizeof ( peer ) );
        memset ( &local, 0, sizeof ( local ) );
        peer.st_port = htons ( port );

        /* Use a local port < 1024 to avoid using the 'insecure' option in
         * /etc/exports file. */
        local.st_flags = TCPIP_BIND_PRIVILEGED;

        return xfer_open_named_socket ( intf, SOCK_STREAM,
                                        ( struct sockaddr * ) &peer, hostname,
                                        ( struct sockaddr * ) &local );
}
static void nfs_pm_step ( struct nfs_request nfs) [static]

Definition at line 174 of file nfs_open.c.

References DBGC, MOUNT_VERS, nfs_done(), NFS_PORTMAP_NFSPORT, NFS_PORTMAP_NONE, NFS_VERS, ONCRPC_MOUNT, ONCRPC_NFS, nfs_request::pm_intf, nfs_request::pm_session, nfs_request::pm_state, portmap_getport(), PORTMAP_PROTO_TCP, rc, and xfer_window().

Referenced by nfs_pm_deliver().

                                                    {
        int     rc;

        if ( ! xfer_window ( &nfs->pm_intf ) )
                return;

        if ( nfs->pm_state == NFS_PORTMAP_NONE ) {
                DBGC ( nfs, "NFS_OPEN %p GETPORT call (mount)\n", nfs );

                rc = portmap_getport ( &nfs->pm_intf, &nfs->pm_session,
                                       ONCRPC_MOUNT, MOUNT_VERS,
                                       PORTMAP_PROTO_TCP );
                if ( rc != 0 )
                        goto err;

                nfs->pm_state++;
                return;
        }

        if ( nfs->pm_state == NFS_PORTMAP_NFSPORT ) {
                DBGC ( nfs, "NFS_OPEN %p GETPORT call (nfs)\n", nfs );

                rc = portmap_getport ( &nfs->pm_intf, &nfs->pm_session,
                                       ONCRPC_NFS, NFS_VERS,
                                       PORTMAP_PROTO_TCP );
                if ( rc != 0 )
                        goto err;

                return;
        }

        return;
err:
        nfs_done ( nfs, rc );
}
static int nfs_pm_deliver ( struct nfs_request nfs,
struct io_buffer io_buf,
struct xfer_metadata *meta  __unused 
) [static]

Definition at line 210 of file nfs_open.c.

References oncrpc_reply::accept_state, DBGC, done, EPROTO, free_iob(), nfs_request::hostname, intf_shutdown(), nfs_request::mount_intf, nfs_connect(), nfs_done(), nfs_request::nfs_intf, nfs_pm_step(), NFS_PORTMAP_MOUNTPORT, NFS_PORTMAP_NFSPORT, oncrpc_get_reply(), nfs_request::pm_intf, nfs_request::pm_session, nfs_request::pm_state, portmap_getport_reply::port, portmap_get_getport_reply(), and rc.

                                                                  {
        int                             rc;
        struct oncrpc_reply             reply;
        struct portmap_getport_reply    getport_reply;

        oncrpc_get_reply ( &nfs->pm_session, &reply, io_buf );
        if ( reply.accept_state != 0 )
        {
                rc = -EPROTO;
                goto err;
        }

        if ( nfs->pm_state == NFS_PORTMAP_MOUNTPORT ) {
                DBGC ( nfs, "NFS_OPEN %p got GETPORT reply (mount)\n", nfs );

                rc = portmap_get_getport_reply ( &getport_reply, &reply );
                if ( rc != 0 )
                        goto err;

                rc = nfs_connect ( &nfs->mount_intf, getport_reply.port,
                                   nfs->hostname );
                if ( rc != 0 )
                        goto err;

                nfs->pm_state++;
                nfs_pm_step ( nfs );

                goto done;
        }

        if ( nfs->pm_state == NFS_PORTMAP_NFSPORT ) {
                DBGC ( nfs, "NFS_OPEN %p got GETPORT reply (nfs)\n", nfs );

                rc = portmap_get_getport_reply ( &getport_reply, &reply );
                if ( rc != 0 )
                        goto err;

                rc = nfs_connect ( &nfs->nfs_intf, getport_reply.port,
                                   nfs->hostname );
                if ( rc != 0 )
                        goto err;

                intf_shutdown ( &nfs->pm_intf, 0 );
                nfs->pm_state++;

                goto done;
        }

        rc = -EPROTO;
err:
        nfs_done ( nfs, rc );
done:
        free_iob ( io_buf );
        return 0;
}
static void nfs_mount_step ( struct nfs_request nfs) [static]

Definition at line 268 of file nfs_open.c.

References DBGC, nfs_request::mount_intf, mount_mnt(), nfs_request::mount_session, nfs_request::mount_state, mount_umnt(), nfs_done(), NFS_MOUNT_NONE, NFS_MOUNT_UMNT, nfs_uri_mountpoint(), rc, nfs_request::uri, and xfer_window().

Referenced by nfs_deliver(), and nfs_mount_deliver().

                                                       {
        int     rc;

        if ( ! xfer_window ( &nfs->mount_intf ) )
                return;

        if ( nfs->mount_state == NFS_MOUNT_NONE ) {
                DBGC ( nfs, "NFS_OPEN %p MNT call (%s)\n", nfs,
                       nfs_uri_mountpoint ( &nfs->uri ) );

                rc = mount_mnt ( &nfs->mount_intf, &nfs->mount_session,
                                 nfs_uri_mountpoint ( &nfs->uri ) );
                if ( rc != 0 )
                        goto err;

                nfs->mount_state++;
                return;
        }

        if ( nfs->mount_state == NFS_MOUNT_UMNT ) {
                DBGC ( nfs, "NFS_OPEN %p UMNT call\n", nfs );

                rc = mount_umnt ( &nfs->mount_intf, &nfs->mount_session,
                                 nfs_uri_mountpoint ( &nfs->uri ) );
                if ( rc != 0 )
                        goto err;
        }

        return;
err:
        nfs_done ( nfs, rc );
}
static int nfs_mount_deliver ( struct nfs_request nfs,
struct io_buffer io_buf,
struct xfer_metadata *meta  __unused 
) [static]

Definition at line 301 of file nfs_open.c.

References oncrpc_reply::accept_state, nfs_request::current_fh, DBGC, done, EPROTO, mount_mnt_reply::fh, free_iob(), MNT3ERR_ACCES, MNT3ERR_NOENT, MNT3ERR_NOTDIR, mount_get_mnt_reply(), nfs_request::mount_session, nfs_request::mount_state, nfs_done(), NFS_LOOKUP, NFS_MOUNT_MNT, nfs_mount_step(), NFS_MOUNT_UMNT, nfs_request::nfs_state, nfs_step(), nfs_uri_mountpoint(), nfs_uri_next_mountpoint(), oncrpc_get_reply(), rc, mount_mnt_reply::status, strcmp(), and nfs_request::uri.

                                                                     {
        int                     rc;
        struct oncrpc_reply     reply;
        struct mount_mnt_reply  mnt_reply;

        oncrpc_get_reply ( &nfs->mount_session, &reply, io_buf );
        if ( reply.accept_state != 0 )
        {
                rc = -EPROTO;
                goto err;
        }

        if ( nfs->mount_state == NFS_MOUNT_MNT ) {
                DBGC ( nfs, "NFS_OPEN %p got MNT reply\n", nfs );
                rc = mount_get_mnt_reply ( &mnt_reply, &reply );
                if ( rc != 0 ) {
                        switch ( mnt_reply.status ) {
                                case MNT3ERR_NOTDIR:
                                case MNT3ERR_NOENT:
                                case MNT3ERR_ACCES:
                                        break;

                                default:
                                        goto err;
                        }

                        if ( ! strcmp ( nfs_uri_mountpoint ( &nfs->uri ),
                                        "/" ) )
                                goto err;

                        if ( ( rc = nfs_uri_next_mountpoint ( &nfs->uri ) ) )
                                goto err;

                        DBGC ( nfs, "NFS_OPEN %p MNT failed retrying with " \
                               "%s\n", nfs, nfs_uri_mountpoint ( &nfs->uri ) );

                        nfs->mount_state--;
                        nfs_mount_step ( nfs );

                        goto done;
                }

                nfs->current_fh = mnt_reply.fh;
                nfs->nfs_state = NFS_LOOKUP;
                nfs_step ( nfs );

                goto done;
        }

        if ( nfs->mount_state == NFS_MOUNT_UMNT ) {
                DBGC ( nfs, "NFS_OPEN %p got UMNT reply\n", nfs );
                nfs_done ( nfs, 0 );

                goto done;
        }

        rc = -EPROTO;
err:
        nfs_done ( nfs, rc );
done:
        free_iob ( io_buf );
        return 0;
}
static int nfs_deliver ( struct nfs_request nfs,
struct io_buffer io_buf,
struct xfer_metadata *meta  __unused 
) [static]

Definition at line 420 of file nfs_open.c.

References oncrpc_reply::accept_state, nfs_read_reply::count, nfs_request::current_fh, DBGC, DBGC2, done, EINVAL, ENOMEM, nfs_lookup_reply::ent_type, nfs_request::eof, nfs_read_reply::eof, EPROTO, nfs_lookup_reply::fh, nfs_request::file_offset, nfs_read_reply::filesize, free, free_iob(), intf_shutdown(), iob_disown, iob_len(), iob_unput, len, nfs_uri::lookup_pos, nfs_request::mount_state, NFS_ATTR_SYMLINK, nfs_done(), nfs_get_lookup_reply(), nfs_get_read_reply(), nfs_get_readlink_reply(), nfs_request::nfs_intf, NFS_LOOKUP, NFS_LOOKUP_SENT, nfs_mount_step(), NFS_READ, NFS_READ_SENT, NFS_READLINK, NFS_READLINK_SENT, nfs_request::nfs_session, nfs_request::nfs_state, nfs_step(), nfs_uri_symlink(), oncrpc_get_reply(), nfs_uri::path, nfs_readlink_reply::path, nfs_readlink_reply::path_len, rc, nfs_request::readlink_fh, nfs_request::remaining, strndup(), nfs_request::uri, nfs_request::xfer, xfer_deliver_iob(), and xfer_seek().

                                                               {
        int                     rc;
        struct oncrpc_reply     reply;

        if ( nfs->remaining == 0 ) {
                oncrpc_get_reply ( &nfs->nfs_session, &reply, io_buf );
                if ( reply.accept_state != 0 ) {
                        rc = -EPROTO;
                        goto err;
                }
        }

        if ( nfs->nfs_state == NFS_LOOKUP_SENT ) {
                struct nfs_lookup_reply lookup_reply;

                DBGC ( nfs, "NFS_OPEN %p got LOOKUP reply\n", nfs );

                rc = nfs_get_lookup_reply ( &lookup_reply, &reply );
                if ( rc != 0 )
                        goto err;

                if ( lookup_reply.ent_type == NFS_ATTR_SYMLINK ) {
                        nfs->readlink_fh = lookup_reply.fh;
                        nfs->nfs_state   = NFS_READLINK;
                } else {
                        nfs->current_fh = lookup_reply.fh;

                        if ( nfs->uri.lookup_pos[0] == '\0' )
                                nfs->nfs_state = NFS_READ;
                        else
                                nfs->nfs_state--;
                }

                nfs_step ( nfs );
                goto done;
        }

        if ( nfs->nfs_state == NFS_READLINK_SENT ) {
                char                      *path;
                struct nfs_readlink_reply readlink_reply;

                DBGC ( nfs, "NFS_OPEN %p got READLINK reply\n", nfs );

                rc = nfs_get_readlink_reply ( &readlink_reply, &reply );
                if ( rc != 0 )
                        goto err;

                if ( readlink_reply.path_len == 0 )
                {
                        rc = -EINVAL;
                        goto err;
                }

                if ( ! ( path = strndup ( readlink_reply.path,
                                          readlink_reply.path_len ) ) )
                {
                        rc = -ENOMEM;
                        goto err;
                }

                nfs_uri_symlink ( &nfs->uri, path );
                free ( path );

                DBGC ( nfs, "NFS_OPEN %p new path: %s\n", nfs,
                       nfs->uri.path );

                nfs->nfs_state = NFS_LOOKUP;
                nfs_step ( nfs );
                goto done;
        }

        if ( nfs->nfs_state == NFS_READ_SENT ) {
                if ( nfs->remaining == 0 ) {
                        DBGC ( nfs, "NFS_OPEN %p got READ reply\n", nfs );

                        struct nfs_read_reply read_reply;

                        rc = nfs_get_read_reply ( &read_reply, &reply );
                        if ( rc != 0 )
                                goto err;

                        if ( nfs->file_offset == 0 ) {
                                DBGC2 ( nfs, "NFS_OPEN %p size: %llu bytes\n",
                                        nfs, read_reply.filesize );

                                xfer_seek ( &nfs->xfer, read_reply.filesize );
                                xfer_seek ( &nfs->xfer, 0 );
                        }

                        nfs->file_offset += read_reply.count;
                        nfs->remaining    = read_reply.count;
                        nfs->eof          = read_reply.eof;
                }

                size_t len = iob_len ( io_buf );
                if ( len > nfs->remaining )
                        iob_unput ( io_buf, len - nfs->remaining );

                nfs->remaining -= iob_len ( io_buf );

                DBGC ( nfs, "NFS_OPEN %p got %zd bytes\n", nfs,
                       iob_len ( io_buf ) );

                rc = xfer_deliver_iob ( &nfs->xfer, iob_disown ( io_buf ) );
                if ( rc != 0 )
                        goto err;

                if ( nfs->remaining == 0 ) {
                        if ( ! nfs->eof ) {
                                nfs->nfs_state--;
                                nfs_step ( nfs );
                        } else {
                                intf_shutdown ( &nfs->nfs_intf, 0 );
                                nfs->nfs_state++;
                                nfs->mount_state++;
                                nfs_mount_step ( nfs );
                        }
                }

                return 0;
        }

        rc = -EPROTO;
err:
        nfs_done ( nfs, rc );
done:
        free_iob ( io_buf );
        return 0;
}
static int nfs_parse_uri ( struct nfs_request nfs,
const struct uri uri 
) [static]

Definition at line 599 of file nfs_open.c.

References DBGC, EINVAL, ENOMEM, uri::host, nfs_request::hostname, nfs_uri_free(), nfs_uri_init(), nfs_uri_mountpoint(), nfs_uri::path, uri::path, rc, strdup(), and nfs_request::uri.

Referenced by nfs_open().

                                                                            {
        int     rc;

        if ( ! uri || ! uri->host || ! uri->path )
                return -EINVAL;

        if ( ( rc = nfs_uri_init ( &nfs->uri, uri ) ) != 0 )
                return rc;

        if ( ! ( nfs->hostname = strdup ( uri->host ) ) ) {
                rc = -ENOMEM;
                goto err_hostname;
        }

        DBGC ( nfs, "NFS_OPEN %p URI parsed: (mountpoint=%s, path=%s)\n",
               nfs, nfs_uri_mountpoint ( &nfs->uri), nfs->uri.path );

        return 0;

err_hostname:
        nfs_uri_free ( &nfs->uri );
        return rc;
}
static int nfs_open ( struct interface xfer,
struct uri uri 
) [static]

Initiate a NFS connection.

Parameters:
xferData transfer interface
uriUniform Resource Identifier
Return values:
rcReturn status code

Definition at line 630 of file nfs_open.c.

References nfs_request::auth_sys, oncrpc_cred_sys::credential, DBGC, ENOMEM, free, oncrpc_cred_sys::hostname, nfs_request::hostname, intf_init(), intf_plug_plug(), mount_init_session(), nfs_request::mount_intf, nfs_request::mount_session, nfs_connect(), nfs_free(), nfs_init_session(), nfs_request::nfs_intf, nfs_parse_uri(), nfs_request::nfs_session, nfs_uri_free(), oncrpc_init_cred_sys(), nfs_request::pm_intf, nfs_request::pm_session, portmap_init_session(), PORTMAP_PORT, rc, ref_init, ref_put, nfs_request::refcnt, nfs_request::uri, nfs_request::xfer, and zalloc().

                                                                {
        int                     rc;
        struct nfs_request      *nfs;

        nfs = zalloc ( sizeof ( *nfs ) );
        if ( ! nfs )
                return -ENOMEM;

        rc = nfs_parse_uri( nfs, uri );
        if ( rc != 0 )
                goto err_uri;

        rc = oncrpc_init_cred_sys ( &nfs->auth_sys );
        if ( rc != 0 )
                goto err_cred;

        ref_init ( &nfs->refcnt, nfs_free );
        intf_init ( &nfs->xfer, &nfs_xfer_desc, &nfs->refcnt );
        intf_init ( &nfs->pm_intf, &nfs_pm_desc, &nfs->refcnt );
        intf_init ( &nfs->mount_intf, &nfs_mount_desc, &nfs->refcnt );
        intf_init ( &nfs->nfs_intf, &nfs_desc, &nfs->refcnt );

        portmap_init_session ( &nfs->pm_session, &nfs->auth_sys.credential );
        mount_init_session ( &nfs->mount_session, &nfs->auth_sys.credential );
        nfs_init_session ( &nfs->nfs_session, &nfs->auth_sys.credential );

        DBGC ( nfs, "NFS_OPEN %p connecting to port mapper (%s:%d)...\n", nfs,
               nfs->hostname, PORTMAP_PORT );

        rc = nfs_connect ( &nfs->pm_intf, PORTMAP_PORT, nfs->hostname );
        if ( rc != 0 )
                goto err_connect;

        /* Attach to parent interface, mortalise self, and return */
        intf_plug_plug ( &nfs->xfer, xfer );
        ref_put ( &nfs->refcnt );

        return 0;

err_connect:
        free ( nfs->auth_sys.hostname );
err_cred:
        nfs_uri_free ( &nfs->uri );
        free ( nfs->hostname );
err_uri:
        free ( nfs );
        return rc;
}

Variable Documentation

Initial value:
 {
        INTF_OP ( intf_close, struct nfs_request *, nfs_done ),
}

Definition at line 557 of file nfs_open.c.

Initial value:

NFS data transfer interface descriptor.

Definition at line 562 of file nfs_open.c.

Initial value:

Definition at line 565 of file nfs_open.c.

Initial value:

Definition at line 571 of file nfs_open.c.

Initial value:

Definition at line 574 of file nfs_open.c.

Initial value:

Definition at line 580 of file nfs_open.c.

Initial value:

Definition at line 583 of file nfs_open.c.

struct interface_descriptor nfs_desc [static]
Initial value:

Definition at line 589 of file nfs_open.c.

struct uri_opener nfs_uri_opener __uri_opener
Initial value:
 {
        .scheme = "nfs",
        .open   = nfs_open,
}

NFS URI opener.

Definition at line 680 of file nfs_open.c.