summaryrefslogtreecommitdiffstats
path: root/sys/boot/i386
diff options
context:
space:
mode:
authorrmacklem <rmacklem@FreeBSD.org>2010-09-02 01:05:10 +0000
committerrmacklem <rmacklem@FreeBSD.org>2010-09-02 01:05:10 +0000
commit5621f791d2277c43041de7701e15cbcfa9b6dd87 (patch)
tree61e4f8789b29083716b575e9c8df7f45d4b286f7 /sys/boot/i386
parent30d230c44b5007382cac1f9efd96e9ffd503d225 (diff)
downloadFreeBSD-src-5621f791d2277c43041de7701e15cbcfa9b6dd87.zip
FreeBSD-src-5621f791d2277c43041de7701e15cbcfa9b6dd87.tar.gz
Modify pxe.c to use the version of nfs_getrootfh() that returns
the file handle's size and was recently committed to lib/libstand/nfs.c. This allows pxeboot to use NFSv3 and work correcty for non-FreeBSD as well as FreeBSD NFS servers. If built with OLD_NFSV2 defined, the old code that predated this patch will be used. Tested by: danny at cs.huji.ac.il
Diffstat (limited to 'sys/boot/i386')
-rw-r--r--sys/boot/i386/libi386/pxe.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/sys/boot/i386/libi386/pxe.c b/sys/boot/i386/libi386/pxe.c
index 5629d90..0caee6a 100644
--- a/sys/boot/i386/libi386/pxe.c
+++ b/sys/boot/i386/libi386/pxe.c
@@ -409,6 +409,7 @@ pxe_perror(int err)
* Reach inside the libstand NFS code and dig out an NFS handle
* for the root filesystem.
*/
+#ifdef OLD_NFSV2
struct nfs_iodesc {
struct iodesc *iodesc;
off_t off;
@@ -456,6 +457,64 @@ pxe_setnfshandle(char *rootpath)
sprintf(cp, "X");
setenv("boot.nfsroot.nfshandle", buf, 1);
}
+#else /* !OLD_NFSV2 */
+
+#define NFS_V3MAXFHSIZE 64
+
+struct nfs_iodesc {
+ struct iodesc *iodesc;
+ off_t off;
+ uint32_t fhsize;
+ u_char fh[NFS_V3MAXFHSIZE];
+ /* structure truncated */
+};
+extern struct nfs_iodesc nfs_root_node;
+extern int rpc_port;
+
+static void
+pxe_rpcmountcall()
+{
+ struct iodesc *d;
+ int error;
+
+ if (!(d = socktodesc(pxe_sock)))
+ return;
+ d->myport = htons(--rpc_port);
+ d->destip = rootip;
+ if ((error = nfs_getrootfh(d, rootpath, &nfs_root_node.fhsize,
+ nfs_root_node.fh)) != 0) {
+ printf("NFS MOUNT RPC error: %d\n", error);
+ nfs_root_node.fhsize = 0;
+ }
+ nfs_root_node.iodesc = d;
+}
+
+static void
+pxe_setnfshandle(char *rootpath)
+{
+ int i;
+ u_char *fh;
+ char buf[2 * NFS_V3MAXFHSIZE + 3], *cp;
+
+ /*
+ * If NFS files were never opened, we need to do mount call
+ * ourselves. Use nfs_root_node.iodesc as flag indicating
+ * previous NFS usage.
+ */
+ if (nfs_root_node.iodesc == NULL)
+ pxe_rpcmountcall();
+
+ fh = &nfs_root_node.fh[0];
+ buf[0] = 'X';
+ cp = &buf[1];
+ for (i = 0; i < nfs_root_node.fhsize; i++, cp += 2)
+ sprintf(cp, "%02x", fh[i]);
+ sprintf(cp, "X");
+ setenv("boot.nfsroot.nfshandle", buf, 1);
+ sprintf(buf, "%d", nfs_root_node.fhsize);
+ setenv("boot.nfsroot.nfshandlelen", buf, 1);
+}
+#endif /* OLD_NFSV2 */
void
pxenv_call(int func)
OpenPOWER on IntegriCloud