⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nfs_vfsops.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* @(#)nfs_vfsops.c 1.1 92/07/30 SMI *//* * Copyright (c) 1986 by Sun Microsystems, Inc. */#include <sys/param.h>#include "boot/systm.h"#include <sys/user.h>#include <sys/vfs.h>#include "boot/vnode.h"#include <sys/pathname.h>#include <sys/uio.h>#include <sys/socket.h>#include <sys/kernel.h>#include <netinet/in.h>#include <rpc/types.h>#include <rpc/xdr.h>#include <rpc/auth.h>#include <rpc/clnt.h>#include <rpc/pmap_rmt.h>#include <rpc/pmap_prot.h>#include <rpcsvc/bootparam.h>#include "boot/nfs.h"#include <nfs/nfs_clnt.h>#include <nfs/rnode.h>#include <sys/mount.h>#include <net/if.h>#include <net/if_arp.h>#include <netinet/if_ether.h>#include <net/route.h>#include <rpcsvc/mount.h>#include <sys/bootconf.h>#include <sys/ioctl.h>#include <stand/saio.h>extern	struct	ifnet	*if_ifwithaf();extern	int	verbosemode;struct vnode *nfsrootvp();struct vnode *makenfsnode();int nfsmntno;#ifdef NFSDEBUGstatic	int	nfsdebug = 10;#endif#undef NFS_RETRIES#define	    NFS_RETRIES	    10	/* times to retry request *//* * nfs vfs operations. */int nfs_root();int nfs_statfs();int nfs_mountroot();extern int nfs_badop();struct vfsops nfs_vfsops = {	nfs_badop,	/* nfs_mount, */	nfs_badop,	/* nfs_unmount, */	nfs_root,		/* nfs_root, */	nfs_statfs,	nfs_badop,	/* nfs_sync, */	nfs_badop,	nfs_mountroot,	nfs_badop,	/* nfs_swapvp, */};/* * Fake up a user structure. */#undef	u;extern	struct	user	u;int	ethernet_started = 0;/* * Called by vfs_mountroot when nfs is going to be mounted as root */nfs_mountroot(vfsp, vpp, name)	struct vfs *vfsp;	struct vnode **vpp;	char *name;{	struct sockaddr_in root_sin;	struct vnode *rtvp;	char *root_path;	char root_hostname[MAXHOSTNAMELEN+1];	char root_name[MAXHOSTNAMELEN+1];	fhandle_t root_fhandle;	int rc;	enum	clnt_stat	status;	int	error;	/*	 * Extra code to ensure that we open the	 * ethernet device and initialise the inet	 * tables.	 */	if (ethernet_started == 0) {		ethersetup();		domaininit();		ip_init();		ethernet_started = 1;		}	/*	 * Ensure that the routing table entry	 * gets made.	 */	error = whoami();	if (error != 0) {		printf ("Boot: bad dialog with bootparam server:  ");		errno_print(error);		printf("(errno 0x%x\n", error);		return (error);	}	strcpy(root_name, "root");	getfsname("root", root_name);	if (root_name[0] == (char)0)  {		strcpy(root_name, "root");		printf("root name: root\n");	}	root_path = kmem_alloc(MAX_MACHINE_NAME + 1);	do {		rc = getfile(root_name, root_hostname,		    (struct sockaddr *)&root_sin, root_path);	} while (rc == ETIMEDOUT);#ifdef	NFSDEBUG	dprint(nfsdebug, 6,		"nfs_mountroot: root_path '%s'\n", root_path);#endif	/* NFSDEBUG */	if (rc) {		kmem_free(root_path, MAX_MACHINE_NAME + 1);		return (rc);	}	rc = mountrpc(&root_sin, root_path, &root_fhandle);	if (rc) {		printf("Boot: NFS mount of '%s:%s' failed\n", root_hostname,		    root_path);		kmem_free(root_path, MAX_MACHINE_NAME + 1);		return (rc);	}	rtvp = nfsrootvp(vfsp, &root_sin, &root_fhandle, root_hostname);	if (rtvp) {#ifdef	NFSDEBUG		dprint(nfsdebug, 6,			"nfs_mountroot: rtvp 0x%x\n", rtvp);#endif	/* NFSDEBUG */		if (rc = vfs_add((struct vnode *)0, vfsp, 0)) {			kmem_free(root_path, MAX_MACHINE_NAME + 1);			return (rc);		}		vfs_unlock(rtvp->v_vfsp);		*vpp = rtvp;		{			register char *nm;			(void) strcpy(name, root_hostname);			for (nm = name; *nm; nm++)				;			*nm++ = ':';			(void) strcpy(nm, root_path);		}		kmem_free(root_path, MAX_MACHINE_NAME + 1);		return (0);	}	printf ("Boot: root file system already mounted\n");	kmem_free(root_path, MAX_MACHINE_NAME + 1);	return (EBUSY);}/* * pmapper remote-call-service interface. * This routine is used to call the pmapper remote call service * which will look up a service program in the port maps, and then * remotely call that routine with the given parameters.  This allows * programs to do a lookup and call in one step.*/static enum clnt_statpmap_rmtcall(call_addr, prog, vers, proc, xdrargs, argsp, xdrres, resp, tout,	    resp_addr)	struct sockaddr_in *call_addr;	u_long prog, vers, proc;	xdrproc_t xdrargs, xdrres;	caddr_t argsp, resp;	struct timeval tout;	struct sockaddr_in *resp_addr;{	register CLIENT *client;	struct rmtcallargs a;	struct rmtcallres r;	enum clnt_stat stat, clntkudp_callit_addr();	u_long port;	call_addr->sin_port = htons(PMAPPORT);	client = clntkudp_create(call_addr, PMAPPROG, PMAPVERS, 10, u.u_cred);	if (client != (CLIENT *)NULL) {		a.prog = prog;		a.vers = vers;		a.proc = proc;		a.args_ptr = argsp;		a.xdr_args = xdrargs;		r.port_ptr = &port;		r.results_ptr = resp;		r.xdr_results = xdrres;		if (verbosemode) {			printf("call portmapper: ");			printf("to "); inet_print(call_addr->sin_addr);			printf(" port %d:  prog %d vers %d proc %d\n",				call_addr->sin_port, a.prog, a.vers, a.proc);		}		stat = clntkudp_callit_addr(client, PMAPPROC_CALLIT,			xdr_rmtcall_args, (caddr_t)&a, xdr_rmtcallres,			(caddr_t)&r, tout, resp_addr, 1);		if (verbosemode) {			printf("portmapper reply ");			clntstat_print(stat);			printf("\n");		}		resp_addr->sin_port = port;		CLNT_DESTROY(client);	} else {		printf("Boot: remote call failed - ");		printf("couldn't create client handle\n");	}	return (stat);}struct clntstat {	long	status;	char	*name;} clntstat[] = {	RPC_SUCCESS,		"succeeded",	RPC_CANTENCODEARGS,	"failed:  can't encode arguments",	RPC_CANTDECODERES,	"failed:  can't decode results",	RPC_CANTSEND,		"failed:  failure in sending call",	RPC_CANTRECV,		"failed:  failure in receiving result",	RPC_TIMEDOUT,		"timed out",	RPC_INTR,		"failed:  call interrupted",	RPC_VERSMISMATCH,	"failed:  rpc versions not compatible",	RPC_AUTHERROR,		"failed:  authentication error",	RPC_PROGUNAVAIL,	"failed:  program not available",	RPC_PROGVERSMISMATCH,	"failed:  program version mismatched",	RPC_PROCUNAVAIL,	"failed:  procedure unavailable",	RPC_CANTDECODEARGS,	"failed:  decode arguments error",	RPC_SYSTEMERROR,	"failed:  RPC_SYSTEMERROR",	RPC_UNKNOWNHOST,	"failed:  unknown host name",	RPC_UNKNOWNPROTO,	"failed:  unknown protocol",	RPC_PMAPFAILURE,	"failed:  the pmapper failed in its call",	RPC_PROGNOTREGISTERED,	"failed:  remote program is not registered",	RPC_FAILED,		"failed:  RPC_FAILED",	-1,			""};clntstat_print(stat)long	stat;{	int	i;	char	*name = "failed:  unknown status";	for (i = 0; clntstat[i].status != -1; i++)		if (stat == clntstat[i].status) {			name = clntstat[i].name;			break;		}	printf(name);	printf(" (status %d)", stat);}static struct sockaddr_in bootparam_addr;extern	struct in_addr my_in_addr;extern struct ether_addr destetheraddr;static intwhoami(){	struct sockaddr_in sa;	struct ifnet *ifp;	struct bp_whoami_arg arg;	struct bp_whoami_res res;	struct timeval tv;	ip_addr_t *ip;	struct in_addr *ip1;	struct in_addr *inp;	enum clnt_stat status;	int error;	struct rtentry rtentry;	struct sockaddr_in *sin;	enum clnt_stat callrpc();	int	msg;	bzero(&sa, sizeof sa);	ifp = if_ifwithaf(AF_INET);	if (ifp == 0) {		printf ("Boot: cannot open INET interface\n");		return (EHOSTUNREACH);	}	if (!address_known(ifp)) {		revarp_myaddr(ifp);	}	/*	 * Set interface broadcast address to 255.255.255.255	 */	ip1 = &(((struct sockaddr_in *)	    &(ifp->if_addrlist->ifa_broadaddr))->sin_addr);	ip1->s_addr = 0xFFFFFFFF;	sa = *((struct sockaddr_in *)&(ifp->if_addrlist->ifa_broadaddr));	arg.client_address.address_type = IP_ADDR_TYPE;	ip = &arg.client_address.bp_address.ip_addr;	inp = &((struct sockaddr_in *)&(ifp->if_addrlist->ifa_addr))->sin_addr;	ip->net = inp->s_net;	ip->host = inp->s_host;	ip->lh = inp->s_lh;	ip->impno = inp->s_impno;	/* initial timeout before displaying warning msg */	tv.tv_sec = 4;	tv.tv_usec = 0;	hostnamelen = 0;	res.client_name = (bp_machine_name_t) kmem_alloc(MAX_MACHINE_NAME + 1);	if (res.client_name == NULL) {		printf ("Boot: out of memory\n");		return (ENOMEM);	}	res.domain_name = (bp_machine_name_t) kmem_alloc(MAX_MACHINE_NAME + 1);	if (res.domain_name == NULL) {		printf ("Boot: out of memory\n");		return (ENOMEM);	}	for (;;) {		msg = 0;		status = pmap_rmtcall(&sa, (u_long)BOOTPARAMPROG,		    (u_long)BOOTPARAMVERS, BOOTPARAMPROC_WHOAMI,		    xdr_bp_whoami_arg, (char *)&arg,		    xdr_bp_whoami_res, (char *)&res,		    tv, &bootparam_addr);		if (status == RPC_TIMEDOUT) {			if (msg == 0) {				printf("%s%s\n", "No bootparam server",					" responding; still trying");				msg = 1;			}			tv.tv_sec = 60;			continue;		}		break;	}	if (status != RPC_SUCCESS) {		printf("Boot: RPC call ");		clntstat_print(status);		printf("\n");		return (EIO);	/* generic errno */	}	if (verbosemode) {		printf("got machine_name %s ", res.client_name);		printf("domain_name %s ", res.domain_name);		printf("router_address ");		inet_print(res.router_address.bp_address.ip_addr);		printf("\n");	}	if (msg)		printf("Bootparam response received\n");	(void) set_ether_addr(bootparam_addr.sin_addr,		(struct ether_addr *) &destetheraddr);	hostnamelen = strlen(res.client_name);	if (hostnamelen > sizeof hostname) {	    printf("Boot: hostname returned by bootparam server is too long");	    printf("Boot: hostname '%s'\n", res.client_name);	    return (ENAMETOOLONG);	}	if (hostnamelen > 0) {		bcopy(res.client_name, hostname, hostnamelen);		hostname[hostnamelen] = '\0';	} else {		printf("Boot: null host name returned by bootparam server\n");		return (ENXIO);	}	kmem_free(res.client_name, MAX_MACHINE_NAME);	printf("hostname: %s\n", hostname);	domainnamelen = strlen(res.domain_name);	if (domainnamelen > sizeof domainname) {	    printf("Boot: domainname returned by bootparam server is too long");	    printf("Boot: domainname '%s'\n", res.domain_name);	    return (ENAMETOOLONG);	}	if (domainnamelen > 0) {		bcopy(res.domain_name, domainname, domainnamelen);		printf("domainname: %s\n", domainname);	} else {		printf("Boot: null domain name returned by bootparam server\n");	}	kmem_free(res.domain_name, MAX_MACHINE_NAME);	if (res.router_address.address_type == IP_ADDR_TYPE) {		sin = (struct sockaddr_in *) &rtentry.rt_dst;		bzero(sin, sizeof *sin);		sin->sin_family = AF_INET;		sin = (struct sockaddr_in *) &rtentry.rt_gateway;		bzero(sin, sizeof *sin);		sin->sin_family = AF_INET;		sin->sin_addr.s_net = res.router_address.bp_address.ip_addr.net;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -