usr/src/stand/lib/fs/nfs/mount.c
author ss146032
Wed, 18 Jan 2006 09:04:19 -0800
changeset 1288 317cceffd26d
parent 1230 b5ac481933a3
permissions -rw-r--r--
6372261 Lint error generated from putback of 6216419
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     1
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     2
 * CDDL HEADER START
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     3
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
1230
b5ac481933a3 6216419 boot-net stalls while waiting for ARP reply generated for IP outside the client's subnet....
ss146032
parents: 0
diff changeset
     5
 * Common Development and Distribution License (the "License").
b5ac481933a3 6216419 boot-net stalls while waiting for ARP reply generated for IP outside the client's subnet....
ss146032
parents: 0
diff changeset
     6
 * You may not use this file except in compliance with the License.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     7
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     8
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     9
 * or http://www.opensolaris.org/os/licensing.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    10
 * See the License for the specific language governing permissions
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    11
 * and limitations under the License.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    12
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    13
 * When distributing Covered Code, include this CDDL HEADER in each
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    14
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    15
 * If applicable, add the following below this CDDL HEADER, with the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    16
 * fields enclosed by brackets "[]" replaced with your own identifying
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    17
 * information: Portions Copyright [yyyy] [name of copyright owner]
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    18
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    19
 * CDDL HEADER END
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    20
 */
1230
b5ac481933a3 6216419 boot-net stalls while waiting for ARP reply generated for IP outside the client's subnet....
ss146032
parents: 0
diff changeset
    21
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    22
/*
1230
b5ac481933a3 6216419 boot-net stalls while waiting for ARP reply generated for IP outside the client's subnet....
ss146032
parents: 0
diff changeset
    23
 * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    24
 * Use is subject to license terms.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    25
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    26
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    27
/*	Copyright (c) 1988 AT&T */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    28
/*	All Rights Reserved */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    29
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    30
#pragma ident	"%Z%%M%	%I%	%E% SMI"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    31
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    32
#include <sys/utsname.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    33
#include <sys/types.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    34
#include <sys/socket.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    35
#include <netinet/in.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    36
#include <rpc/types.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    37
#include <rpc/auth.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    38
#include <sys/t_lock.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    39
#include <netdb.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    40
#include "clnt.h"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    41
#include <rpc/xdr.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    42
#include <rpc/rpc_msg.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    43
#include <rpc/rpc.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    44
#include "brpc.h"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    45
#include "auth_inet.h"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    46
#include "pmap.h"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    47
#include <rpcsvc/nfs_prot.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    48
#include <rpcsvc/nfs4_prot.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    49
#include "nfs_inet.h"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    50
#include <rpcsvc/bootparam.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    51
#include <dhcp_impl.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    52
#include <rpcsvc/mount.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    53
#include <sys/promif.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    54
#include <sys/salib.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    55
#include "socket_inet.h"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    56
#include "ipv4.h"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    57
#include "mac.h"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    58
#include <sys/bootdebug.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    59
#include <errno.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    60
#include "dhcpv4.h"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    61
#include <sys/mntent.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    62
1230
b5ac481933a3 6216419 boot-net stalls while waiting for ARP reply generated for IP outside the client's subnet....
ss146032
parents: 0
diff changeset
    63
/* ARP timeout in milliseconds for BOOTP/RARP */
b5ac481933a3 6216419 boot-net stalls while waiting for ARP reply generated for IP outside the client's subnet....
ss146032
parents: 0
diff changeset
    64
#define	ARP_INETBOOT_TIMEOUT 1000
b5ac481933a3 6216419 boot-net stalls while waiting for ARP reply generated for IP outside the client's subnet....
ss146032
parents: 0
diff changeset
    65
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    66
struct nfs_file		roothandle;			/* root file handle */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    67
static char		root_hostname[SYS_NMLN];	/* server hostname */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    68
static char		my_hostname[MAXHOSTNAMELEN];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    69
static char		root_pathbuf[NFS_MAXPATHLEN];	/* the root's path */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    70
static char		root_boot_file[NFS_MAXPATHLEN];	/* optional boot file */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    71
static struct sockaddr_in root_to;			/* server sock ip */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    72
							/* in network order */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    73
CLIENT			*root_CLIENT = NULL;		/* CLIENT handle */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    74
int dontroute = FALSE;	/* In case rarp/bootparams was selected */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    75
char			rootopts[MAX_PATH_LEN];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    76
static gid_t		fake_gids = 1;	/* fake gids list for auth_unix */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    77
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    78
extern void set_default_filename(char *);	/* boot.c */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    79
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    80
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    81
 * xdr routines used by mount.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    82
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    83
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    84
bool_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    85
xdr_fhstatus(XDR *xdrs, struct fhstatus *fhsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    86
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    87
	if (!xdr_int(xdrs, (int *)&fhsp->fhs_status))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    88
		return (FALSE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    89
	if (fhsp->fhs_status == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    90
		return (xdr_fhandle(xdrs, fhsp->fhstatus_u.fhs_fhandle));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    91
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    92
	return (TRUE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    93
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    94
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    95
bool_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    96
xdr_fhandle(XDR *xdrs, fhandle fhp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    97
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    98
	return (xdr_opaque(xdrs, (char *)fhp, NFS_FHSIZE));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    99
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   100
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   101
bool_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   102
xdr_path(XDR *xdrs, char **pathp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   103
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   104
	return (xdr_string(xdrs, pathp, MNTPATHLEN));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   105
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   106
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   107
bool_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   108
xdr_fhandle3(XDR *xdrs, fhandle3 *objp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   109
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   110
	return (xdr_bytes(xdrs, (char **)&objp->fhandle3_val,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   111
				(uint_t *)&objp->fhandle3_len, FHSIZE3));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   112
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   113
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   114
bool_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   115
xdr_mountstat3(XDR *xdrs, mountstat3 *objp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   116
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   117
	return (xdr_enum(xdrs, (enum_t *)objp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   118
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   119
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   120
bool_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   121
xdr_mountres3_ok(XDR *xdrs, mountres3_ok *objp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   122
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   123
	if (!xdr_fhandle3(xdrs, &objp->fhandle))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   124
		return (FALSE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   125
	return (xdr_array(xdrs, (char **)&objp->auth_flavors.auth_flavors_val,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   126
			(uint_t *)&objp->auth_flavors.auth_flavors_len, ~0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   127
			sizeof (int), (xdrproc_t)xdr_int));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   128
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   129
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   130
bool_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   131
xdr_mountres3(XDR *xdrs, mountres3 *objp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   132
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   133
	if (!xdr_mountstat3(xdrs, &objp->fhs_status))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   134
		return (FALSE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   135
	if (objp->fhs_status == MNT_OK)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   136
		return (xdr_mountres3_ok(xdrs, &objp->mountres3_u.mountinfo));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   137
	return (TRUE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   138
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   139
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   140
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   141
nfsmountroot(char *path, struct nfs_file *filep)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   142
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   143
	int		rexmit;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   144
	int		resp_wait;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   145
	enum clnt_stat	status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   146
	struct fhstatus	root_tmp;			/* to pass to rpc/xdr */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   147
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   148
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   149
	 * Wait up to 16 secs for first response, retransmitting expon.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   150
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   151
	rexmit = 0;	/* default retransmission interval */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   152
	resp_wait = 16;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   153
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   154
	do {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   155
		status = brpc_call((rpcprog_t)MOUNTPROG, (rpcvers_t)MOUNTVERS,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   156
		    (rpcproc_t)MOUNTPROC_MNT, xdr_path, (caddr_t)&path,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   157
		    xdr_fhstatus, (caddr_t)&(root_tmp), rexmit, resp_wait,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   158
		    &root_to, NULL, AUTH_UNIX);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   159
		if (status == RPC_TIMEDOUT) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   160
			dprintf("boot: %s:%s mount server not responding.\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   161
			    root_hostname, path);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   162
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   163
		rexmit = resp_wait;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   164
		resp_wait = 0;	/* use default wait time. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   165
	} while (status == RPC_TIMEDOUT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   166
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   167
	if ((status != RPC_SUCCESS) || (root_tmp.fhs_status != 0)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   168
		nfs_error(root_tmp.fhs_status);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   169
		root_to.sin_port = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   170
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   171
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   172
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   173
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   174
	 * Since the mount succeeded, we'll mark the filep's
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   175
	 * status as NFS_OK, and its type as NFDIR. If these
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   176
	 * points aren't the case, then we wouldn't be here.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   177
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   178
	bcopy(&root_tmp.fhstatus_u.fhs_fhandle, &filep->fh.fh2, FHSIZE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   179
	filep->ftype.type2 = NFDIR;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   180
	filep->version = NFS_VERSION;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   181
	nfs_readsize = nfs_readsize <  NFS_MAXDATA ? nfs_readsize : NFS_MAXDATA;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   182
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   183
	 * Set a reasonable lower limit on readsize
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   184
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   185
	nfs_readsize = (nfs_readsize != 0 && nfs_readsize < 512) ?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   186
							512 : nfs_readsize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   187
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   188
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   189
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   190
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   191
setup_root_vars(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   192
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   193
	size_t		buflen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   194
	uint16_t	readsize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   195
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   196
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   197
	 * Root server name. Required.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   198
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   199
	buflen = sizeof (root_hostname);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   200
	if (dhcp_getinfo(DSYM_VENDOR, VS_NFSMNT_ROOTSRVR_NAME, 0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   201
	    root_hostname, &buflen)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   202
		root_hostname[buflen] = '\0';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   203
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   204
		dprintf("BOUND: Missing Root Server Name Option\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   205
		errno = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   206
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   207
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   208
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   209
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   210
	 * Root server IP. Required.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   211
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   212
	buflen = sizeof (root_to.sin_addr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   213
	if (!dhcp_getinfo(DSYM_VENDOR, VS_NFSMNT_ROOTSRVR_IP, 0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   214
	    &root_to.sin_addr, &buflen)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   215
		dprintf("BOUND: Missing Root Server IP Option\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   216
		errno = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   217
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   218
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   219
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   220
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   221
	 * Root path Required.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   222
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   223
	buflen = sizeof (root_pathbuf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   224
	if (dhcp_getinfo(DSYM_VENDOR, VS_NFSMNT_ROOTPATH, 0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   225
	    root_pathbuf, &buflen)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   226
		root_pathbuf[buflen] = '\0';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   227
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   228
		dprintf("BOUND: Missing Root Path Option\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   229
		errno = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   230
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   231
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   232
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   233
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   234
	 * Optional Bootfile path.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   235
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   236
	buflen = sizeof (root_boot_file);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   237
	if (dhcp_getinfo(DSYM_VENDOR, VS_NFSMNT_BOOTFILE, 0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   238
		    root_boot_file, &buflen)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   239
		root_boot_file[buflen] = '\0';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   240
		dprintf("BOUND: Optional Boot File is: %s\n", root_boot_file);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   241
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   242
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   243
	/* if we got a boot file name, use it as the default */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   244
	if (root_boot_file[0] != '\0')
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   245
		set_default_filename(root_boot_file);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   246
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   247
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   248
	 * Set the NFS read size. The mount code will adjust it to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   249
	 * the maximum size.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   250
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   251
	buflen = sizeof (readsize);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   252
	if (dhcp_getinfo(DSYM_VENDOR, VS_BOOT_NFS_READSIZE, 0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   253
	    &readsize, &buflen)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   254
		nfs_readsize = ntohs(readsize);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   255
		if (boothowto & RB_VERBOSE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   256
			printf("Boot NFS read size: %d\n", nfs_readsize);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   257
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   258
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   259
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   260
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   261
	 * Optional rootopts.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   262
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   263
	buflen = sizeof (rootopts);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   264
	if (dhcp_getinfo(DSYM_VENDOR, VS_NFSMNT_ROOTOPTS, 0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   265
	    rootopts, &buflen)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   266
		rootopts[buflen] = '\0';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   267
		dprintf("BOUND: Optional Rootopts is: %s\n", rootopts);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   268
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   269
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   270
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   271
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   272
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   273
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   274
mnt3_error(enum mountstat3 status)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   275
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   276
	if (!(boothowto & RB_DEBUG))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   277
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   278
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   279
	switch (status) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   280
	case MNT_OK:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   281
		printf("Mount: No error.\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   282
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   283
	case MNT3ERR_PERM:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   284
		printf("Mount: Not owner.\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   285
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   286
	case MNT3ERR_NOENT:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   287
		printf("Mount: No such file or directory.\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   288
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   289
	case MNT3ERR_IO:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   290
		printf("Mount: I/O error.\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   291
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   292
	case MNT3ERR_ACCES:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   293
		printf("Mount: Permission denied.\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   294
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   295
	case MNT3ERR_NOTDIR:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   296
		printf("Mount: Not a directory.\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   297
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   298
	case MNT3ERR_INVAL:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   299
		printf("Mount: Invalid argument.\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   300
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   301
	case MNT3ERR_NAMETOOLONG:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   302
		printf("Mount: File name too long.\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   303
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   304
	case MNT3ERR_NOTSUPP:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   305
		printf("Mount: Operation not supported.\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   306
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   307
	case MNT3ERR_SERVERFAULT:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   308
		printf("Mount: Server fault.\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   309
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   310
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   311
		printf("Mount: unknown error.\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   312
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   313
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   314
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   315
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   316
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   317
nfs3mountroot(char *path, struct nfs_file *filep)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   318
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   319
	int		rexmit;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   320
	int		resp_wait;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   321
	struct mountres3 res3;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   322
	enum clnt_stat	status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   323
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   324
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   325
	 * Wait up to 16 secs for first response, retransmitting expon.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   326
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   327
	rexmit = 0;	/* default retransmission interval */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   328
	resp_wait = 16;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   329
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   330
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   331
	 * Try to mount using V3
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   332
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   333
	do {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   334
		bzero(&res3, sizeof (struct mountres3));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   335
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   336
		status = brpc_call((rpcprog_t)MOUNTPROG, (rpcvers_t)MOUNTVERS3,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   337
		    (rpcproc_t)MOUNTPROC_MNT, xdr_path, (caddr_t)&path,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   338
		    xdr_mountres3, (caddr_t)&res3, rexmit, resp_wait,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   339
		    &root_to, NULL, AUTH_UNIX);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   340
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   341
		if (status != RPC_TIMEDOUT)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   342
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   343
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   344
		dprintf("boot: %s:%s mount server not responding.\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   345
			    root_hostname, path);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   346
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   347
		rexmit = resp_wait;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   348
		resp_wait = 0;	/* use default wait time. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   349
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   350
		xdr_free(xdr_mountres3, (caddr_t)&res3);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   351
	} while (status == RPC_TIMEDOUT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   352
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   353
	if ((status != RPC_SUCCESS) || (res3.fhs_status != MNT_OK)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   354
		mnt3_error(res3.fhs_status);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   355
		root_to.sin_port = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   356
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   357
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   358
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   359
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   360
	 * Since the mount succeeded, we'll mark the filep's
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   361
	 * status as NFS_OK, and its type as NF3DIR. If these
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   362
	 * points aren't the case, then we wouldn't be here.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   363
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   364
	filep->fh.fh3.len = res3.mountres3_u.mountinfo.fhandle.fhandle3_len;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   365
	bcopy(res3.mountres3_u.mountinfo.fhandle.fhandle3_val,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   366
			filep->fh.fh3.data,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   367
			filep->fh.fh3.len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   368
	filep->ftype.type3 = NF3DIR;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   369
	filep->version = NFS_V3;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   370
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   371
	 * Hardwire in a known reasonable upper limit of 32K
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   372
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   373
	nfs_readsize = nfs_readsize <  32 * 1024 ? nfs_readsize : 32 * 1024;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   374
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   375
	 * Set a reasonable lower limit on readsize
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   376
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   377
	nfs_readsize = (nfs_readsize != 0 && nfs_readsize < 512) ?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   378
							512 : nfs_readsize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   379
	xdr_free(xdr_mountres3, (caddr_t)&res3);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   380
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   381
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   382
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   383
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   384
 * Setup v4 client for inetboot
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   385
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   386
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   387
nfs4init(char *path, uint16_t nfs_port)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   388
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   389
	struct timeval	wait;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   390
	int		fd = -1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   391
	int		error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   392
	enum clnt_stat	rpc_stat;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   393
	struct nfs_file	rootpath;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   394
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   395
	wait.tv_sec = RPC_RCVWAIT_MSEC / 1000;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   396
	wait.tv_usec = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   397
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   398
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   399
	 * If we haven't explicitly set the port number, set to the standard
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   400
	 * 2049 and don't cause a rpcbind request.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   401
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   402
	if (nfs_port == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   403
		nfs_port = 2049;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   404
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   405
	root_to.sin_port = htons(nfs_port);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   406
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   407
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   408
	 * Support TCP only
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   409
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   410
	root_CLIENT = clntbtcp_create(&root_to, NFS_PROGRAM,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   411
					NFS_V4, wait, &fd,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   412
					NFS4BUF_SIZE, NFS4BUF_SIZE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   413
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   414
	if (root_CLIENT == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   415
		root_to.sin_port = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   416
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   417
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   418
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   419
	root_CLIENT->cl_auth =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   420
			authunix_create(my_hostname, 0, 1, 1, &fake_gids);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   421
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   422
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   423
	 * Send NULL proc the server first to see if V4 exists
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   424
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   425
	rpc_stat = CLNT_CALL(root_CLIENT, NFSPROC4_NULL, xdr_void, NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   426
				xdr_void, NULL, wait);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   427
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   428
	if (rpc_stat != RPC_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   429
		dprintf("boot: NULL proc failed NFSv4 service not available\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   430
		AUTH_DESTROY(root_CLIENT->cl_auth);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   431
		CLNT_DESTROY(root_CLIENT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   432
		root_to.sin_port = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   433
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   434
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   435
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   436
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   437
	 * Do a lookup to get to the root_path.  This is nice since it can
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   438
	 * handle multicomponent lookups.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   439
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   440
	roothandle.version = NFS_V4;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   441
	roothandle.ftype.type4 = NF4DIR;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   442
	roothandle.fh.fh4.len = 0;		/* Force a PUTROOTFH */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   443
	roothandle.offset = (uint_t)0;		/* it's a directory! */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   444
	error = lookup(path, &rootpath, TRUE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   445
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   446
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   447
		printf("boot: lookup %s failed\n", path);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   448
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   449
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   450
	roothandle = rootpath;	/* structure copy */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   451
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   452
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   453
	 * Hardwire in a known reasonable upper limit of 32K
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   454
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   455
	nfs_readsize = nfs_readsize <  32 * 1024 ? nfs_readsize : 32 * 1024;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   456
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   457
	 * Set a reasonable lower limit on readsize
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   458
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   459
	nfs_readsize = (nfs_readsize != 0 && nfs_readsize < 512) ?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   460
							512 : nfs_readsize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   461
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   462
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   463
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   464
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   465
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   466
atoi(const char *p)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   467
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   468
	int n;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   469
	int c, neg = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   470
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   471
	if (!isdigit(c = *p)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   472
		while (c == ' ' || c == '\t' || c == '\n')
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   473
			c = *++p;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   474
		switch (c) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   475
		case '-':
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   476
			neg++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   477
			/* FALLTHROUGH */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   478
		case '+':
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   479
			c = *++p;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   480
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   481
		if (!isdigit(c))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   482
			return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   483
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   484
	for (n = '0' - c; isdigit(c = *++p); ) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   485
		n *= 10; /* two steps to avoid unnecessary overflow */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   486
		n += '0' - c; /* accum neg to avoid surprises at MAX */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   487
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   488
	return (neg ? n : -n);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   489
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   490
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   491
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   492
 * Parse suboptions from a string.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   493
 * Same as getsubopt(3C).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   494
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   495
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   496
getsubopt(char **optionsp, char * const *tokens, char **valuep)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   497
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   498
	char *s = *optionsp, *p;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   499
	int i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   500
	size_t optlen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   501
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   502
	*valuep = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   503
	if (*s == '\0')
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   504
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   505
	p = strchr(s, ',');		/* find next option */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   506
	if (p == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   507
		p = s + strlen(s);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   508
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   509
		*p++ = '\0';		/* mark end and point to next */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   510
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   511
	*optionsp = p;			/* point to next option */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   512
	p = strchr(s, '=');		/* find value */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   513
	if (p == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   514
		optlen = strlen(s);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   515
		*valuep = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   516
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   517
		optlen = p - s;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   518
		*valuep = ++p;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   519
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   520
	for (i = 0; tokens[i] != NULL; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   521
		if ((optlen == strlen(tokens[i])) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   522
		    (strncmp(s, tokens[i], optlen) == 0))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   523
			return (i);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   524
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   525
	/* no match, point value at option and return error */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   526
	*valuep = s;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   527
	return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   528
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   529
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   530
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   531
 * The only interesting NFS mount options for initiating the kernel
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   532
 * all others are ignored.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   533
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   534
static char *optlist[] = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   535
#define	OPT_RSIZE	0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   536
	MNTOPT_RSIZE,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   537
#define	OPT_TIMEO	1
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   538
	MNTOPT_TIMEO,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   539
#define	OPT_VERS	2
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   540
	MNTOPT_VERS,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   541
#define	OPT_PROTO	3
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   542
	MNTOPT_PROTO,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   543
#define	OPT_PORT	4
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   544
	MNTOPT_PORT,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   545
	NULL
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   546
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   547
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   548
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   549
 * This routine will open a device as it is known by the V2 OBP. It
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   550
 * then goes thru the stuff necessary to initialize the network device,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   551
 * get our network parameters, (using DHCP or rarp/bootparams), and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   552
 * finally actually go and get the root filehandle. Sound like fun?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   553
 * Suuurrrree. Take a look.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   554
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   555
 * Returns 0 if things worked. -1 if we crashed and burned.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   556
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   557
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   558
boot_nfs_mountroot(char *str)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   559
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   560
	int		status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   561
	enum clnt_stat	rpc_stat;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   562
	char		*root_path = &root_pathbuf[0];	/* to make XDR happy */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   563
	struct timeval	wait;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   564
	int		fd;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   565
	int		bufsize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   566
	char		*opts, *val;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   567
	int		nfs_version = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   568
	int		istcp = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   569
	int		nfs_port = 0;	/* Cause pmap to get port */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   570
	struct sockaddr_in tmp_addr;	/* throw away */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   571
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   572
	if (root_CLIENT != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   573
		AUTH_DESTROY(root_CLIENT->cl_auth);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   574
		CLNT_DESTROY(root_CLIENT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   575
		root_CLIENT = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   576
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   577
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   578
	root_to.sin_family = AF_INET;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   579
	root_to.sin_addr.s_addr = htonl(INADDR_ANY);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   580
	root_to.sin_port = htons(0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   581
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   582
	mac_init(str);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   583
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   584
	(void) ipv4_setpromiscuous(TRUE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   585
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   586
	if (get_netconfig_strategy() == NCT_BOOTP_DHCP) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   587
		if (boothowto & RB_VERBOSE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   588
			printf("Using BOOTP/DHCP...\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   589
		if (dhcp() != 0 || setup_root_vars() != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   590
			(void) ipv4_setpromiscuous(FALSE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   591
			if (boothowto & RB_VERBOSE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   592
				printf("BOOTP/DHCP configuration failed!\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   593
			return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   594
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   595
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   596
		/* now that we have an IP address, turn off promiscuous mode */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   597
		(void) ipv4_setpromiscuous(FALSE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   598
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   599
		/* Use RARP/BOOTPARAMS. RARP will try forever... */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   600
		if (boothowto & RB_VERBOSE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   601
			printf("Using RARP/BOOTPARAMS...\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   602
		mac_call_rarp();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   603
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   604
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   605
		 * Since there is no way to determine our netmask, and therefore
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   606
		 * figure out if the router we got is useful, we assume all
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   607
		 * services are local. Use DHCP if this bothers you.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   608
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   609
		dontroute = TRUE;
1230
b5ac481933a3 6216419 boot-net stalls while waiting for ARP reply generated for IP outside the client's subnet....
ss146032
parents: 0
diff changeset
   610
		/*
b5ac481933a3 6216419 boot-net stalls while waiting for ARP reply generated for IP outside the client's subnet....
ss146032
parents: 0
diff changeset
   611
		 * We are trying to keep the ARP response
b5ac481933a3 6216419 boot-net stalls while waiting for ARP reply generated for IP outside the client's subnet....
ss146032
parents: 0
diff changeset
   612
		 * timeout on the lower side with BOOTP/RARP.
b5ac481933a3 6216419 boot-net stalls while waiting for ARP reply generated for IP outside the client's subnet....
ss146032
parents: 0
diff changeset
   613
		 * We are doing this for BOOTP/RARP where policy
b5ac481933a3 6216419 boot-net stalls while waiting for ARP reply generated for IP outside the client's subnet....
ss146032
parents: 0
diff changeset
   614
		 * doesn't allow to route the packets outside
b5ac481933a3 6216419 boot-net stalls while waiting for ARP reply generated for IP outside the client's subnet....
ss146032
parents: 0
diff changeset
   615
		 * the subnet as it has no idea about the
b5ac481933a3 6216419 boot-net stalls while waiting for ARP reply generated for IP outside the client's subnet....
ss146032
parents: 0
diff changeset
   616
		 * netmask. By doing so, we are reducing
b5ac481933a3 6216419 boot-net stalls while waiting for ARP reply generated for IP outside the client's subnet....
ss146032
parents: 0
diff changeset
   617
		 * ARP response timeout for any packet destined
b5ac481933a3 6216419 boot-net stalls while waiting for ARP reply generated for IP outside the client's subnet....
ss146032
parents: 0
diff changeset
   618
		 * for outside booting clients subnet. Client can
b5ac481933a3 6216419 boot-net stalls while waiting for ARP reply generated for IP outside the client's subnet....
ss146032
parents: 0
diff changeset
   619
		 * not expect such ARP replies and will finally
b5ac481933a3 6216419 boot-net stalls while waiting for ARP reply generated for IP outside the client's subnet....
ss146032
parents: 0
diff changeset
   620
		 * timeout after a long delay. This would cause
b5ac481933a3 6216419 boot-net stalls while waiting for ARP reply generated for IP outside the client's subnet....
ss146032
parents: 0
diff changeset
   621
		 * booting client to get stalled for a longer
b5ac481933a3 6216419 boot-net stalls while waiting for ARP reply generated for IP outside the client's subnet....
ss146032
parents: 0
diff changeset
   622
		 * time. We can not avoid accepting any outside
b5ac481933a3 6216419 boot-net stalls while waiting for ARP reply generated for IP outside the client's subnet....
ss146032
parents: 0
diff changeset
   623
		 * subnet packets accidentally destined for the
b5ac481933a3 6216419 boot-net stalls while waiting for ARP reply generated for IP outside the client's subnet....
ss146032
parents: 0
diff changeset
   624
		 * booting client.
b5ac481933a3 6216419 boot-net stalls while waiting for ARP reply generated for IP outside the client's subnet....
ss146032
parents: 0
diff changeset
   625
		 */
b5ac481933a3 6216419 boot-net stalls while waiting for ARP reply generated for IP outside the client's subnet....
ss146032
parents: 0
diff changeset
   626
		mac_set_arp_timeout(ARP_INETBOOT_TIMEOUT);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   627
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   628
		/* now that we have an IP address, turn off promiscuous mode */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   629
		(void) ipv4_setpromiscuous(FALSE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   630
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   631
		/* get our hostname */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   632
		if (whoami() == FALSE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   633
			return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   634
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   635
		/* get our bootparams. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   636
		if (getfile("root", root_hostname, &root_to.sin_addr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   637
		    root_pathbuf) == FALSE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   638
			return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   639
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   640
		/* get our rootopts. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   641
		(void) getfile("rootopts", root_hostname, &tmp_addr.sin_addr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   642
		    rootopts);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   643
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   644
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   645
	/* mount root */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   646
	if (boothowto & RB_VERBOSE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   647
		printf("root server: %s (%s)\n", root_hostname,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   648
		    inet_ntoa(root_to.sin_addr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   649
		printf("root directory: %s\n", root_pathbuf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   650
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   651
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   652
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   653
	 * Assumes we've configured the stack and thus know our
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   654
	 * IP address/hostname, either by using DHCP or rarp/bootparams.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   655
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   656
	gethostname(my_hostname, sizeof (my_hostname));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   657
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   658
	wait.tv_sec = RPC_RCVWAIT_MSEC / 1000;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   659
	wait.tv_usec = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   660
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   661
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   662
	 * Parse out the interesting root options, if an invalid
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   663
	 * or unknown option is provided, silently ignore it and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   664
	 * use the defaults.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   665
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   666
	opts = rootopts;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   667
	while (*opts) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   668
		int ival;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   669
		switch (getsubopt(&opts, optlist, &val)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   670
		case OPT_RSIZE:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   671
			if (val == NULL || !isdigit(*val))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   672
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   673
			nfs_readsize = atoi(val);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   674
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   675
		case OPT_TIMEO:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   676
			if (val == NULL || !isdigit(*val))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   677
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   678
			ival = atoi(val);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   679
			wait.tv_sec = ival / 10;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   680
			wait.tv_usec = (ival % 10) * 100000;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   681
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   682
		case OPT_VERS:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   683
			if (val == NULL || !isdigit(*val))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   684
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   685
			nfs_version = atoi(val);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   686
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   687
		case OPT_PROTO:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   688
			if (val == NULL || isdigit(*val))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   689
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   690
			if ((strncmp(val, "udp", 3) == 0))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   691
				istcp = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   692
			else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   693
				istcp = 1;	/* must be tcp */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   694
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   695
		case OPT_PORT:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   696
			if (val == NULL || !isdigit(*val))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   697
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   698
			nfs_port = atoi(val);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   699
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   700
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   701
			 * Currently nfs_dlinet.c doesn't support setting
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   702
			 * the root NFS port. Delete this when it does.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   703
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   704
			nfs_port = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   705
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   706
		default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   707
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   708
			 * Unknown options are silently ignored
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   709
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   710
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   711
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   712
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   713
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   714
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   715
	 * If version is set, then try that version first.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   716
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   717
	switch (nfs_version) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   718
	case NFS_VERSION:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   719
		if (nfsmountroot(root_path, &roothandle) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   720
			goto domount;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   721
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   722
	case NFS_V3:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   723
		if (nfs3mountroot(root_path, &roothandle) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   724
			goto domount;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   725
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   726
	case NFS_V4:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   727
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   728
		 * With v4 we skip the mount and go straight to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   729
		 * setting the root filehandle.  Because of this we
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   730
		 * do things slightly differently and obtain our
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   731
		 * client handle first.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   732
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   733
		if (istcp && nfs4init(root_path, nfs_port) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   734
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   735
			 * If v4 init succeeded then we are done.  Just return.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   736
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   737
			return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   738
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   739
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   740
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   741
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   742
	 * If there was no chosen version or the chosen version failed
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   743
	 * try all versions in order, this may still fail to boot
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   744
	 * at the kernel level if the options are not right, but be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   745
	 * generous at this early stage.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   746
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   747
	if (istcp && nfs4init(root_path, nfs_port) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   748
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   749
		 * If v4 init succeeded then we are done.  Just return.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   750
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   751
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   752
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   753
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   754
	if (nfs3mountroot(root_path, &roothandle) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   755
		goto domount;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   756
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   757
	if ((status = nfsmountroot(root_path, &roothandle)) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   758
		return (status);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   759
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   760
domount:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   761
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   762
	 * Only v2 and v3 go on from here.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   763
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   764
	roothandle.offset = (uint_t)0;		/* it's a directory! */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   765
	root_to.sin_port = htons(nfs_port);	/* NFS is next after mount */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   766
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   767
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   768
	 * Create the CLIENT handle for NFS operations
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   769
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   770
	if (roothandle.version == NFS_VERSION)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   771
		bufsize = NFSBUF_SIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   772
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   773
		bufsize = NFS3BUF_SIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   774
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   775
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   776
	 * First try TCP then UDP (unless UDP asked for explicitly), if mountd
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   777
	 * alows this version but neither transport is available we are stuck.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   778
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   779
	if (istcp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   780
		fd = -1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   781
		root_CLIENT = clntbtcp_create(&root_to, NFS_PROGRAM,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   782
			roothandle.version, wait, &fd, bufsize, bufsize);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   783
		if (root_CLIENT != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   784
			root_CLIENT->cl_auth =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   785
			    authunix_create(my_hostname, 0, 1, 1, &fake_gids);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   786
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   787
			 * Send NULL proc, check if the server really exists
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   788
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   789
			rpc_stat = CLNT_CALL(root_CLIENT, 0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   790
					xdr_void, NULL, xdr_void, NULL, wait);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   791
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   792
			if (rpc_stat == RPC_SUCCESS)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   793
				return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   794
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   795
			AUTH_DESTROY(root_CLIENT->cl_auth);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   796
			CLNT_DESTROY(root_CLIENT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   797
			root_CLIENT = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   798
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   799
		/* Fall through to UDP case */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   800
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   801
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   802
	fd = -1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   803
	root_CLIENT = clntbudp_bufcreate(&root_to, NFS_PROGRAM,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   804
			roothandle.version, wait, &fd, bufsize, bufsize);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   805
	if (root_CLIENT == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   806
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   807
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   808
	root_CLIENT->cl_auth =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   809
			    authunix_create(my_hostname, 0, 1, 1, &fake_gids);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   810
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   811
	 * Send NULL proc, check if the server really exists
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   812
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   813
	rpc_stat = CLNT_CALL(root_CLIENT, 0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   814
				xdr_void, NULL, xdr_void, NULL, wait);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   815
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   816
	if (rpc_stat == RPC_SUCCESS)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   817
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   818
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   819
	AUTH_DESTROY(root_CLIENT->cl_auth);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   820
	CLNT_DESTROY(root_CLIENT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   821
	root_CLIENT = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   822
	return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   823
}