📄 nfs_vfsops.c
字号:
sin->sin_addr.s_host = res.router_address.bp_address.ip_addr.host; sin->sin_addr.s_lh = res.router_address.bp_address.ip_addr.lh; sin->sin_addr.s_impno = res.router_address.bp_address.ip_addr.impno; rtentry.rt_flags = RTF_GATEWAY | RTF_UP; error = rtrequest(SIOCADDRT, &rtentry);#ifdef NFSDEBUG if (error) { printf("Boot: bad routing request: "); errno_print(error); printf("\n"); } else { dprint(nfsdebug, 6, "whoami: rtrequest OK\n"); }#endif /* NFSDEBUG */ } else { printf("Boot: bootparam sever returned unknown "); printf("gateway addr family %d\n", res.router_address.address_type); } return (0);}static enum clnt_statcallrpc(sin, prognum, versnum, procnum, inproc, in, outproc, out) struct sockaddr_in *sin; int prognum, versnum, procnum; xdrproc_t inproc, outproc; char *in, *out;{ CLIENT *cl; struct timeval tv; enum clnt_stat cl_stat; cl = clntkudp_create(sin, (u_long)prognum, (u_long)versnum, 10, u.u_cred); tv.tv_sec = 4; tv.tv_usec = 0; cl_stat = CLNT_CALL(cl, procnum, inproc, in, outproc, out, tv); AUTH_DESTROY(cl->cl_auth); CLNT_DESTROY(cl); return (cl_stat);}static intgetfile(fileid, server_name, server_address, server_path) char *fileid; char *server_name; struct sockaddr *server_address; char *server_path;{ struct bp_getfile_arg arg; struct bp_getfile_res res; enum clnt_stat status; int tries; int error; int msg; if (verbosemode) printf("getfile: %s\n", fileid); arg.client_name = hostname; arg.file_id = fileid; bzero(&res, sizeof res); if (bootparam_addr.sin_addr.s_addr == 0) { error = whoami(); if (error) { printf ("Boot: dialog with bootparam server failed\n"); return (error); } } res.server_name = (bp_machine_name_t) kmem_alloc(MAX_MACHINE_NAME + 1); res.server_path = (bp_machine_name_t) kmem_alloc(MAX_MACHINE_NAME + 1); if (res.server_name == NULL || res.server_path == NULL) { printf ("Boot: out of memory\n"); error = ENOMEM; goto bad; } for (tries = 0; tries < 20; tries++) { msg = 0; if (verbosemode) { printf("requesting bootparam getfile from "); inet_print(bootparam_addr.sin_addr); printf("\n"); } status = callrpc(&bootparam_addr, BOOTPARAMPROG, BOOTPARAMVERS, BOOTPARAMPROC_GETFILE, xdr_bp_getfile_arg, (char *)&arg, xdr_bp_getfile_res, (char *)&res); if (status == RPC_TIMEDOUT) { if (msg == 0) { printf("%s%s\n", "No bootparam server", " responding; still trying"); msg = 1; } continue; } break; } if (status != RPC_SUCCESS) { if (status == RPC_TIMEDOUT) { printf ("Boot: dialog with bootparam server timed out\n"); error = ETIMEDOUT; } else { error = (int)status; printf ("Boot: dialog with bootparam server "); clntstat_print(error); printf("\n"); } goto bad; } if (verbosemode) { printf("got server_name %s ", res.server_name); printf(" server_address "); inet_print(res.server_address.bp_address.ip_addr); printf(" server_path %s\n", res.server_path); } if (msg == 1) printf("Response received from bootparams server\n"); (void) strcpy(server_name, res.server_name); printf("server name '%s'\n", server_name); switch (res.server_address.address_type) { case IP_ADDR_TYPE: bzero(server_address, sizeof *server_address); server_address->sa_family = AF_INET; ((struct sockaddr_in *)server_address)->sin_addr.s_net = res.server_address.bp_address.ip_addr.net; ((struct sockaddr_in *)server_address)->sin_addr.s_host = res.server_address.bp_address.ip_addr.host; ((struct sockaddr_in *)server_address)->sin_addr.s_lh = res.server_address.bp_address.ip_addr.lh; ((struct sockaddr_in *)server_address)->sin_addr.s_impno = res.server_address.bp_address.ip_addr.impno; /* * Set the server ether_address. */ (void) set_ether_addr( ((struct sockaddr_in *)server_address)->sin_addr, &destetheraddr); if (verbosemode) { printf("server ether address: "); ether_print(&destetheraddr); printf("\n"); } break; default: printf("Boot: bootparam server returned unknown address type %d\n", res.server_address.address_type); error = EPROTONOSUPPORT; goto bad; } (void) strcpy(server_path, res.server_path); printf("root pathname '%s'\n", server_path); kmem_free(res.server_name, MAX_MACHINE_NAME + 1); kmem_free(res.server_path, MAX_MACHINE_NAME + 1); if (*server_name == '\0' || *server_path == '\0' || res.server_address.bp_address.ip_addr.net == 0 && res.server_address.bp_address.ip_addr.host == 0 && res.server_address.bp_address.ip_addr.lh == 0 && res.server_address.bp_address.ip_addr.impno == 0) { return (-1); } else { return (0); }bad: printf("Boot: can't get bootparam server to answer for this client: "); clntstat_print(error); printf("\n"); if (res.server_name) { kmem_free(res.server_name, MAX_MACHINE_NAME + 1); } if (res.server_path) { kmem_free(res.server_path, MAX_MACHINE_NAME + 1); } return (error);}/* * Call mount daemon on server sin to mount path. * sin_port is set to nfs port and fh is the fhandle * returned from the server. */staticmountrpc(sin, path, fh) struct sockaddr_in *sin; char *path; fhandle_t *fh;{ struct fhstatus fhs; enum clnt_stat status; int msg = 0; status = pmap_kgetport(sin, (u_long)MOUNTPROG, (u_long)MOUNTVERS, (u_long)IPPROTO_UDP); if (status != RPC_SUCCESS) { printf("Boot: cannot get port for mount service: "); clntstat_print(status); printf("Boot: unable to mount '%s'\n", path); return (status); } if (sin->sin_port == 0) { printf( "Boot: mount daemon not registered with remote portmapper\n"); return (RPC_PROGNOTREGISTERED); } do { if (verbosemode) printf("mount '%s'\n", path); status = callrpc(sin, MOUNTPROG, MOUNTVERS, MOUNTPROC_MNT, xdr_bp_path_t, (char *)&path, xdr_fhstatus, (char *)&fhs); if ((status == RPC_TIMEDOUT) && (msg == 0)) { printf("Remote mount daemon not responding\n"); msg = 1; } } while (status == RPC_TIMEDOUT); if (status != RPC_SUCCESS) { printf("Boot: unable to mount '%s': ", path); clntstat_print(status); printf("\n"); return (status); } else if (msg) printf("Mount ok\n"); sin->sin_port = htons(NFS_PORT); *fh = fhs.fhs_fh; if (fhs.fhs_status != 0) { printf("Boot: mount failed: "); errno_print(fhs.fhs_status); printf("\n"); } return (fhs.fhs_status);}struct vnode *nfsrootvp(vfsp, sin, fh, servername) struct vfs *vfsp; /* vfs of fs, if NULL amke one */ struct sockaddr_in *sin; /* server address */ fhandle_t *fh; /* swap file fhandle */ char *servername; /* swap server name */{ struct vnode *rtvp = NULL; /* the server's root */ struct mntinfo *mi = NULL; /* mount info, pointed at by vfs */ struct vattr va; /* root vnode attributes */ struct nfsfattr na; /* root vnode attributes in nfs form */ struct statfs sb; /* server's file system stats */ struct ifnet *ifp; /* interface */ extern struct ifnet loif; /* * Get the internet address for the first AF_INET interface * using reverse arp. This is not quite right because the * interface may not be ethernet! XXX */ if ((ifp = if_ifwithaf(AF_INET)) == 0 /* NEVER || ifp == &loif */) { printf("Boot:: no INET interface\n"); return (NULL); } if (!address_known(ifp)) { revarp_myaddr(ifp); } /* * create a mount record and link it to the vfs struct */ mi = (struct mntinfo *)kmem_alloc((u_int)sizeof (*mi)); bzero((caddr_t)mi, sizeof (*mi)); mi->mi_hard = 1; mi->mi_addr = *sin; mi->mi_retrans = NFS_RETRIES; mi->mi_timeo = NFS_TIMEO; mi->mi_mntno = nfsmntno++; bcopy(servername, mi->mi_hostname, HOSTNAMESZ); /* * Make a vfs struct for nfs. We do this here instead of below * because rtvp needs a vfs before we can do a getattr on it. */ vfsp->vfs_fsid.val[0] = mi->mi_mntno; vfsp->vfs_fsid.val[1] = MOUNT_NFS; vfsp->vfs_data = (caddr_t)mi; /* * Make the root vnode, use it to get attributes, then remake it * with the attributes */ rtvp = makenfsnode(fh, (struct nfsfattr *) 0, vfsp); if ((rtvp->v_flag & VROOT) != 0) { printf ("Boot: unable to make a root vnode\n"); goto bad; } rtvp->v_flag |= VROOT; if (VOP_GETATTR(rtvp, &va, u.u_cred)) { printf ("Boot: unable to get attributes of root\n"); goto bad; } VN_RELE(rtvp); vattr_to_nattr(&va, &na); rtvp = makenfsnode(fh, &na, vfsp); rtvp->v_flag |= VROOT; mi->mi_rootvp = rtvp; /* * Get server's filesystem stats. Use these to set transfer * sizes, filesystem block size, and read-only. */ if (VFS_STATFS(vfsp, &sb)) { printf ("Boot: unable to stat root file system\n"); goto bad; } mi->mi_tsize = min(NFS_MAXDATA, (u_int)nfstsize()); /* * Set filesystem block size to at least CLBYTES and at most MAXBSIZE */ mi->mi_bsize = MAX(va.va_blocksize, CLBYTES); mi->mi_bsize = MIN(mi->mi_bsize, MAXBSIZE); vfsp->vfs_bsize = mi->mi_bsize; /* * Need credentials in the rtvp so do_bio can find them. */ crhold(u.u_cred); vtor(rtvp)->r_cred = u.u_cred; return (rtvp);bad: printf("nfsrootvp: bad\n"); if (mi) { kmem_free((caddr_t)mi, sizeof (*mi)); } return (NULL);}/* * find root of nfs */intnfs_root(vfsp, vpp) struct vfs *vfsp; struct vnode **vpp;{ *vpp = (struct vnode *)((struct mntinfo *)vfsp->vfs_data)->mi_rootvp; (*vpp)->v_count++; return (0);}/* * Get file system statistics. */intnfs_statfs(vfsp, sbp)register struct vfs *vfsp;struct statfs *sbp;{ struct nfsstatfs fs; struct mntinfo *mi; fhandle_t *fh; int error = 0; mi = vftomi(vfsp); fh = vtofh(mi->mi_rootvp);#ifdef NFSDEBUG dprint(nfsdebug, 4, "nfs_statfs vfs %x\n", vfsp);#endif error = rfscall(mi, RFS_STATFS, xdr_fhandle, (caddr_t)fh, xdr_statfs, (caddr_t)&fs, u.u_cred); if (!error) { error = geterrno(fs.fs_status); } else { printf ("Boot: can't stat file system: "); errno_print(error); printf("\n"); goto bad; } if (!error) { if (mi->mi_stsize) { mi->mi_stsize = MIN(mi->mi_stsize, fs.fs_tsize); } else { mi->mi_stsize = fs.fs_tsize; } sbp->f_bsize = fs.fs_bsize; sbp->f_blocks = fs.fs_blocks; sbp->f_bfree = fs.fs_bfree; sbp->f_bavail = fs.fs_bavail; /* * XXX This is wrong - should be a real fsid */ bcopy((caddr_t)&vfsp->vfs_fsid, (caddr_t)&sbp->f_fsid, sizeof (fsid_t)); }bad:#ifdef NFSDEBUG dprint(nfsdebug, 4, "nfs_statfs returning %d\n", error);#endif return (error);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -