Return to BSD News archive
Path: sserve!newshost.anu.edu.au!munnari.oz.au!spool.mu.edu!howland.reston.ans.net!gatech!news-feed-1.peachnet.edu!emory!ogicse!psgrain!percy!agora!implode!davidg
From: davidg@implode.rain.com (David Greenman)
Newsgroups: comp.os.386bsd.questions
Subject: Re: Diskless 386bsd ??
Message-ID: <C74wG3.106@implode.rain.com>
Date: 16 May 93 19:21:38 GMT
Article-I.D.: implode.C74wG3.106
Organization: Delta Systems, Portland, OR.
Lines: 959
A friend of mine looked through his alt.sources archive and found
the following.
-DG
# This is a shell archive. Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file". Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
# 319
#
echo x - 319
sed 's/^X//' >319 << 'END-of-319'
XNewsgroups: comp.os.386bsd.development
XPath: percy!psgrain!uunet!usc!cs.utexas.edu!utnut!torn!mcshub!martin
XFrom: martin@innovus.com (Martin Renters)
XSubject: diskless 386bsd patches
XMessage-ID: <1993Mar22.053826.17787@mcshub.dcss.mcmaster.ca>
XSender: usenet@mcshub.dcss.mcmaster.ca
XNntp-Posting-Host: foxtrot.innovus.com
XOrganization: Innovus Inc., Hamilton, Ontario, Canada
XDate: Mon, 22 Mar 1993 05:38:26 GMT
XLines: 929
X
XHere are the patches required to allow diskless 386bsd operation. The
Xfollowing should be considered a BETA release since, while it provides
Xthe diskless functionality, it still has some rough edges. In particular,
Xthe setup program searches for a magic cookie in the kernel which it
Xthen patches with the appropriate nfs_diskless structure, the hostname
Xis not set up by the setup program, no boot rom exists yet, etc.
X
XTo configure a diskless 386bsd kernel:
X
X 1) un-shar the following file and apply the patch file 'diffs.out'
X
X 2) do a make install in /usr/src/usr.sbin/config to recompile the config
X program
X
X 3) create a kernel description file in /sys/i386/conf, making sure
X to add:
X
X option DISKLESS
X config "386bsd" swap on nfs size 50000
X
X The size in the above example indicates the number of 512 byte blocks
X of swap space configured (ie: 25Mb). An example configuration is
X included in the file DISKLESS in this package
X
X 4) generate a kernel:
X
X /usr/sbin/config DISKLESS
X cd ../../compile/DISKLESS
X make
X
X 5) Compile the program 'setup.c' on the NFS server which will provide
X the root and swap file systems. This program has been tested on
X HP-UX 9.0 (350 and 720) and a 386bsd system. It requires the use
X of the getfh() system call which takes a filename as a parameter.
X It will not work with versions that require a file descriptor
X (HP-UX 8.X comes to mind). nfsdiskless.h must match
X /sys/nfs/nfsdiskless.h on the 386bsd system. diskless.h contains
X excerpts from socket.h, mount.h, if.h and nfsv2.h
X
X 6) copy the kernel created in step 4 into the directory the setup program
X lives in.
X
X 7) ./setup -intf <your interface> -rootfs <your root> -swap <your swapfile>
X -hostname <diskless hostname> -netmask <diskless netmask>
X
X eg: ./setup -intf we0 -rootfs /var/386bsd -swap /var/swap/alpha
X -hostname alpha -netmask 255.255.255.0
X
X 8) copy the resulting 386bsd file to a tinyBSD boot floppy. You will
X probably need to remove most of the other files on the disk to make
X enough space.
X
X 9) Boot with the disk. You will probably have to modify the /etc/rc
X script so it doesn't try and fsck a non-existant filesystem, etc.
X If you get a panic "nfs swap" it probably means you haven't exported
X your filesystems correctly.
X
X
XProblem areas:
X
X 1) NFS on 386bsd does not support the flock() system call. This prevents
X the passwd(1) program and others from working. A wordaround would be
X to use lock-files if the flock() function is not supported.
X
X 2) The setup program cannot re-setup a kernel. This is because the
X magic cookie is overwritten. A better way of patching the kernel
X would be to use the symbol table in the executable, but this is not
X portable (easily at 1am in the morning)
X
X 3) The hostname should be configured by the setup program.
X
XAcknowledgements:
X
X Wolfgang Solfrank (ws@tools.de) provided input and some of the patches
X from his implementation.
X
X The setup program is loosely based on a similar program in the 4.4BSD
X distribution.
X
X
XHave fun...
X
XMartin Renters martin@innovus.com
X
X
X# This is a shell archive. Remove anything before this line,
X# then unpack it by saving it in a file and typing "sh file".
X#
X# Wrapped by Martin Renters <martin@foxtrot> on Sun Mar 21 23:22:03 1993
X#
X# This archive contains:
X# diffs.out DISKLESS setup.c diskless.h
X# nfsdiskless.h
X#
X
XLANG=""; export LANG
XPATH=/bin:/usr/bin:$PATH; export PATH
X
Xecho x - diffs.out
Xcat >diffs.out <<'@EOF'
X
X*** /mnt/usr/src/sys.386bsd/i386/i386/pmap.c Tue Jan 26 20:11:25 1993
X--- /sys/i386/i386/pmap.c Sat Jan 30 10:24:35 1993
X***************
X*** 999,1004 ****
X--- 999,1005 ----
X #endif
X npv = (pv_entry_t)
X malloc(sizeof *npv, M_VMPVENT, M_NOWAIT);
X+ if (npv == NULL) panic("pmap_enter: malloc returned NULL");
X npv->pv_va = va;
X npv->pv_pmap = pmap;
X npv->pv_next = pv->pv_next;
X*** /mnt/usr/src/sys.386bsd/i386/i386/autoconf.c Tue Jul 14 18:53:09 1992
X--- /sys/i386/i386/autoconf.c Fri Jan 29 16:48:38 1993
X***************
X*** 142,147 ****
X--- 142,150 ----
X */
X setroot()
X {
X+ #ifdef DISKLESS
X+ return;
X+ #else
X int majdev, mindev, unit, part, adaptor;
X dev_t temp, orootdev;
X struct swdevt *swp;
X***************
X*** 189,192 ****
X--- 192,196 ----
X if (temp == dumpdev)
X dumpdev = swdevt[0].sw_dev;
X #endif
X+ #endif /* DISKLESS */
X }
X*** /mnt/usr/src/sys.386bsd/kern/vfs_conf.c Mon May 25 02:43:56 1992
X--- /sys/kern/vfs_conf.c Fri Jan 29 15:07:30 1993
X***************
X*** 40,47 ****
X--- 40,49 ----
X * This specifies the filesystem used to mount the root.
X * This specification should be done by /etc/config.
X */
X+ #ifndef DISKLESS
X extern int ufs_mountroot();
X int (*mountroot)() = ufs_mountroot;
X+ #endif
X
X /*
X * These define the root filesystem and device.
X*** /mnt/usr/src/sys.386bsd/nfs/nfsdiskless.h Tue Dec 24 14:24:15 1991
X--- /sys/nfs/nfsdiskless.h Sun Mar 21 18:23:19 1993
X***************
X*** 44,49 ****
X--- 44,50 ----
X * For now it is statically initialized in swapvmunix.c, but someday a primary
X * bootstrap should fill it in.
X */
X+ #define NFSMNAMELEN 64
X struct nfs_diskless {
X struct ifaliasreq myif; /* Info. for partial ifconfig */
X struct sockaddr mygateway; /* Default gateway for "route add" */
X***************
X*** 50,58 ****
X struct nfs_args swap_args; /* Mount args for swap file */
X u_char swap_fh[NFS_FHSIZE]; /* Swap file's file handle */
X struct sockaddr swap_saddr; /* Address of swap server */
X! char *swap_hostnam; /* Host name for mount pt */
X struct nfs_args root_args; /* Mount args for root fs */
X u_char root_fh[NFS_FHSIZE]; /* File handle of root dir */
X struct sockaddr root_saddr; /* Address of root server */
X! char *root_hostnam; /* Host name for mount pt */
X };
X--- 51,59 ----
X struct nfs_args swap_args; /* Mount args for swap file */
X u_char swap_fh[NFS_FHSIZE]; /* Swap file's file handle */
X struct sockaddr swap_saddr; /* Address of swap server */
X! char swap_hostnam[NFSMNAMELEN]; /* Host name for mount pt */
X struct nfs_args root_args; /* Mount args for root fs */
X u_char root_fh[NFS_FHSIZE]; /* File handle of root dir */
X struct sockaddr root_saddr; /* Address of root server */
X! char root_hostnam[NFSMNAMELEN]; /* Host name for mount pt */
X };
X*** /mnt/usr/src/sys.386bsd/vm/swap_pager.c Tue Jan 26 20:16:16 1993
X--- /sys/vm/swap_pager.c Fri Jan 29 19:55:33 1993
X***************
X*** 593,598 ****
X--- 593,599 ----
X splx(s);
X bp->b_flags = B_BUSY | (flags & B_READ);
X bp->b_proc = &proc0; /* XXX (but without B_PHYS set this is ok) */
X+ bp->b_rcred = bp->b_wcred = bp->b_proc->p_ucred; /* DISKLESS (WS)*/
X bp->b_un.b_addr = (caddr_t)kva;
X bp->b_blkno = swb->swb_block + btodb(off);
X VHOLD(swapdev_vp);
X***************
X*** 625,630 ****
X--- 626,633 ----
X spc->spc_m = m;
X bp->b_flags |= B_CALL;
X bp->b_iodone = swap_pager_iodone;
X+ bp->b_dirtyoff = 0; /* DISKLESS: (WS) */
X+ bp->b_dirtyend = bp->b_bcount;
X s = splbio();
X swp->sw_poip++;
X queue_enter(&swap_pager_inuse, spc, swp_clean_t, spc_list);
X*** bak/config.y Fri Mar 19 16:50:57 1993
X--- /usr/src/usr.sbin/config/config.y Fri Mar 19 18:42:33 1993
X***************
X*** 244,250 ****
X = {
X struct file_list *fl = newswap();
X
X! if (eq($1, "generic"))
X fl->f_fn = $1;
X else {
X fl->f_swapdev = nametodev($1, 0, 'b');
X--- 244,250 ----
X = {
X struct file_list *fl = newswap();
X
X! if (eq($1, "generic") || eq($1,"nfs"))
X fl->f_fn = $1;
X else {
X fl->f_swapdev = nametodev($1, 0, 'b');
X***************
X*** 641,647 ****
X */
X if (system->f_fn)
X return;
X! if (eq(fl->f_fn, "generic"))
X system->f_fn = ns(fl->f_fn);
X else
X system->f_fn = ns(system->f_needs);
X--- 641,647 ----
X */
X if (system->f_fn)
X return;
X! if (eq(fl->f_fn, "generic") || eq(fl->f_fn, "nfs"))
X system->f_fn = ns(fl->f_fn);
X else
X system->f_fn = ns(system->f_needs);
X***************
X*** 812,818 ****
X {
X char buf[BUFSIZ];
X register struct file_list *swap;
X! int generic;
X
X if (fl == 0 || fl->f_type != SYSTEMSPEC) {
X yyerror("internal error, bad system specification");
X--- 812,818 ----
X {
X char buf[BUFSIZ];
X register struct file_list *swap;
X! int generic,nfs;
X
X if (fl == 0 || fl->f_type != SYSTEMSPEC) {
X yyerror("internal error, bad system specification");
X***************
X*** 820,826 ****
X }
X swap = fl->f_next;
X generic = swap && swap->f_type == SWAPSPEC && eq(swap->f_fn, "generic");
X! if (fl->f_rootdev == NODEV && !generic) {
X yyerror("no root device specified");
X exit(1);
X }
X--- 820,827 ----
X }
X swap = fl->f_next;
X generic = swap && swap->f_type == SWAPSPEC && eq(swap->f_fn, "generic");
X! nfs = swap && swap->f_type == SWAPSPEC && eq(swap->f_fn, "nfs");
X! if (fl->f_rootdev == NODEV && !generic && !nfs) {
X yyerror("no root device specified");
X exit(1);
X }
X***************
X*** 912,918 ****
X {
X
X for (;fl && fl->f_type == SWAPSPEC; fl = fl->f_next) {
X! if (eq(fl->f_fn, "generic"))
X continue;
X if (alreadychecked(fl->f_swapdev, checked, pchecked))
X continue;
X--- 913,919 ----
X {
X
X for (;fl && fl->f_type == SWAPSPEC; fl = fl->f_next) {
X! if (eq(fl->f_fn, "generic") || eq(fl->f_fn, "nfs"))
X continue;
X if (alreadychecked(fl->f_swapdev, checked, pchecked))
X continue;
X*** bak/mkswapconf.c Fri Mar 19 16:50:57 1993
X--- /usr/src/usr.sbin/config/mkswapconf.c Sat Mar 20 21:27:38 1993
X***************
X*** 79,84 ****
X--- 79,93 ----
X }
X fprintf(fp, "#include \"sys/param.h\"\n");
X fprintf(fp, "#include \"sys/conf.h\"\n");
X+ if (eq(fl->f_fn, "nfs")) {
X+ fprintf(fp, "#include \"../sys/socket.h\"\n");
X+ fprintf(fp, "#include \"../sys/mount.h\"\n");
X+ fprintf(fp, "#include \"../net/if.h\"\n");
X+ fprintf(fp, "#include \"../nfs/nfsv2.h\"\n");
X+ fprintf(fp, "#include \"../nfs/nfsdiskless.h\"\n");
X+ fprintf(fp, "\nextern int nfs_mountroot();\n");
X+ fprintf(fp, "\nint (*mountroot)() = nfs_mountroot;\n");
X+ }
X fprintf(fp, "\n");
X /*
X * If there aren't any swap devices
X***************
X*** 105,110 ****
X--- 114,124 ----
X } while (swap && swap->f_type == SWAPSPEC);
X fprintf(fp, "\t{ 0, 0, 0 }\n");
X fprintf(fp, "};\n");
X+ if (eq(fl->f_fn, "nfs")) {
X+ fprintf(fp,"struct nfs_diskless nfs_diskless = {\n");
X+ fprintf(fp," { { 'D', 'i', 'S', 'k', 'L', 'e', 'S', 's', '\\0' }}\n");
X+ fprintf(fp,"};\n");
X+ }
X fclose(fp);
X return (swap);
X }
X@EOF
X
Xchmod 640 diffs.out
X
Xecho x - DISKLESS
Xcat >DISKLESS <<'@EOF'
X#
X# DISKLESS - Diskless 386bsd with DDB
X#
Xmachine "i386"
Xcpu "i386"
Xident DISKLESS
Xtimezone 5 dst
Xmaxusers 10
Xoptions INET,NFS,UFS,DISKLESS,XSERVER
Xoptions "COMPAT_43"
Xoptions "TCP_COMPAT_42"
X
Xconfig "386bsd" swap on nfs size 50000
X
Xcontroller isa0
X#controller wd0 at isa? port "IO_WD1" bio irq 14 vector wdintr
X#disk wd0 at wd0 drive 0
X#disk wd0 at wd0 drive 1
X
Xcontroller fd0 at isa? port "IO_FD1" bio irq 6 drq 2 vector fdintr
Xdisk fd0 at fd0 drive 0
Xdisk fd1 at fd0 drive 1
X
X#controller as0 at isa? port 0x330 bio irq 11 drq 5 vector asintr
X#disk as0 at as0 drive 0
X#disk as1 at as0 drive 1
X
Xdevice pc0 at isa? port "IO_KBD" tty irq 1 vector pcrint
Xdevice npx0 at isa? port "IO_NPX" irq 13 vector npxintr
Xdevice com1 at isa? port "IO_COM1" tty irq 4 vector comintr
X#device com2 at isa? port "IO_COM2" tty irq 3 vector comintr
X
Xdevice we0 at isa? port 0x280 net irq 3 iomem 0xd0000 iosiz 8192 vector weintr
X#device ne0 at isa? port 0x320 net irq 3 vector neintr
X#device ec0 at isa? port 0x250 net irq 2 iomem 0xd8000 iosiz 8192 vector ecintr
X
Xdevice wt0 at isa? port 0x300 bio irq 5 drq 1 vector wtintr
X
Xpseudo-device loop
Xpseudo-device ether
Xpseudo-device sl 2
Xpseudo-device log
Xpseudo-device ddb
Xpseudo-device pty 4
X
Xpseudo-device swappager
Xpseudo-device vnodepager
Xpseudo-device devpager
X@EOF
X
Xchmod 640 DISKLESS
X
Xecho x - setup.c
Xcat >setup.c <<'@EOF'
X/*************************************************************************
X
XDiskless Configuration Program
X
XBased loosely on the 4.4BSD diskless setup code
X
X*************************************************************************/
X#include <stdio.h>
X#include <fcntl.h>
X#include <sys/stat.h>
X#include <netdb.h>
X
X#include "diskless.h"
X#include "nfsdiskless.h"
X
X#ifndef i386 /* Most other systems BIG ENDIAN */
X#define BIG_ENDIAN
X#endif
X
Xstruct nfs_diskless nfs_diskless;
X
X#define MAGIC_COOKIE "DiSkLeSs"
X#define NFS_SOCKET 2049
X
X#define KW_HELP 0
X#define KW_INTERFACE 1
X#define KW_ROOTFS 2
X#define KW_SWAP 3
X#define KW_RSIZE 4
X#define KW_WSIZE 5
X#define KW_NETMASK 6
X#define KW_HOSTNAME 7
X#define KW_KERNEL 8
X
Xstruct {
X char *name;
X int keyval;
X} keywords[] = {
X { "-intf", KW_INTERFACE },
X { "-rootfs", KW_ROOTFS },
X { "-swap", KW_SWAP },
X { "-netmask", KW_NETMASK },
X { "-rsize", KW_RSIZE },
X { "-wsize", KW_WSIZE },
X { "-hostname", KW_HOSTNAME },
X { "-kernel", KW_KERNEL },
X { NULL, KW_HELP }
X};
X
Xchar *hostname = "386bsd";
Xchar *kernel = "386bsd";
Xchar *rootpath = "/var/386bsd";
Xchar *swappath = "/var/swap/386bsd";
Xchar servername[256];
Xint rsize = 8192;
Xint wsize = 8192;
X
Xmain(argc, argv)
X int argc; char *argv[];
X{
X int fd,i,j,cmd;
X unsigned int broadcast, netmask, myip;
X struct hostent *hp;
X struct stat statbuf;
X char buf[1024];
X char *p, *q;
X
X netmask = 0;
X bzero(&nfs_diskless, 0, sizeof(struct nfs_diskless));
X strcpy(nfs_diskless.myif.ifra_name,"we0");
X nfs_diskless.myif.ifra_addr.sa_len = sizeof(struct sockaddr);
X nfs_diskless.myif.ifra_addr.sa_family = AF_INET;
X nfs_diskless.myif.ifra_broadaddr.sa_len = sizeof(struct sockaddr);
X nfs_diskless.myif.ifra_broadaddr.sa_family = AF_INET;
X nfs_diskless.myif.ifra_mask.sa_len = sizeof(struct sockaddr);
X nfs_diskless.myif.ifra_mask.sa_family = AF_UNSPEC;
X nfs_diskless.swap_args.sotype = i386order(SOCK_DGRAM);
X nfs_diskless.swap_args.flags = i386order(NFSMNT_WSIZE | NFSMNT_RSIZE);
X nfs_diskless.swap_args.timeo = i386order(10);
X nfs_diskless.swap_args.retrans = i386order(100);
X nfs_diskless.swap_saddr.sa_len = sizeof(struct sockaddr);
X nfs_diskless.swap_saddr.sa_family = AF_INET;
X nfs_diskless.root_args.sotype = i386order(SOCK_DGRAM);
X nfs_diskless.root_args.flags = i386order(NFSMNT_WSIZE | NFSMNT_RSIZE);
X nfs_diskless.root_args.timeo = i386order(10);
X nfs_diskless.root_args.retrans = i386order(100);
X nfs_diskless.root_saddr.sa_len = sizeof(struct sockaddr);
X nfs_diskless.root_saddr.sa_family = AF_INET;
X
X if (gethostname(servername, 256) < 0) {
X fprintf(stderr,"%s: unable to get host server name\n",argv[0]);
X exit(2);
X }
X if ((hp = gethostbyname(servername)) == NULL) {
X fprintf(stderr,"%s: unable to get host address\n",argv[0]);
X exit(2);
X }
X nfs_diskless.swap_saddr.sa_data[0] = nfs_diskless.root_saddr.sa_data[0]
X = NFS_SOCKET >> 8;
X nfs_diskless.swap_saddr.sa_data[1] = nfs_diskless.root_saddr.sa_data[1]
X = NFS_SOCKET & 0x00FF;
X bcopy(*hp->h_addr_list, &nfs_diskless.swap_saddr.sa_data[2], 4);
X bcopy(*hp->h_addr_list, &nfs_diskless.root_saddr.sa_data[2], 4);
X
X i = 1;
X while (i < argc) {
X cmd = KW_HELP;
X for (j=0; keywords[j].name; j++) {
X if (!strcmp(keywords[j].name, argv[i])) {
X if ((i+1) < argc) {
X cmd = keywords[j].keyval;
X break;
X }
X }
X }
X switch(cmd) {
X case KW_HELP:
X help(argv[0], argv[i]);
X exit(2);
X case KW_INTERFACE:
X if (strlen(argv[i+1]) >= IFNAMSIZ) {
X fprintf(stderr,
X "%s: interface name '%s' too long.\n",
X argv[0], argv[i+1]);
X exit(2);
X }
X strcpy(nfs_diskless.myif.ifra_name, argv[i+1]);
X i += 2;
X break;
X case KW_ROOTFS:
X rootpath = argv[i+1];
X i += 2;
X break;
X case KW_SWAP:
X swappath = argv[i+1];
X i += 2;
X break;
X case KW_RSIZE:
X rsize = atoi(argv[i+1]);
X i += 2;
X break;
X case KW_WSIZE:
X wsize = atoi(argv[i+1]);
X i += 2;
X break;
X case KW_NETMASK:
X netmask = inet_addr(argv[i+1]);
X i +=2;
X break;
X case KW_HOSTNAME:
X hostname = argv[i+1];
X i += 2;
X break;
X case KW_KERNEL:
X kernel = argv[i+1];
X i += 2;
X break;
X }
X }
X nfs_diskless.swap_args.rsize = i386order(rsize);
X nfs_diskless.swap_args.wsize = i386order(wsize);
X nfs_diskless.root_args.rsize = i386order(rsize);
X nfs_diskless.root_args.wsize = i386order(wsize);
X if ((hp = gethostbyname(hostname)) == NULL) {
X fprintf(stderr,"%s: unable to get diskless address\n",argv[0]);
X exit(2);
X }
X bcopy(*hp->h_addr_list, &nfs_diskless.myif.ifra_addr.sa_data[2], 4);
X if (!netmask) {
X unsigned char net;
X net = nfs_diskless.myif.ifra_addr.sa_data[2];
X if (net <= 127)
X netmask = inet_addr("255.0.0.0");
X else if (net < 192)
X netmask = inet_addr("255.255.0.0");
X else netmask = inet_addr("255.255.255.0");
X }
X bcopy(*hp->h_addr_list, &myip, 4);
X broadcast = (myip & netmask) | ~netmask;
X bcopy(&broadcast, &nfs_diskless.myif.ifra_broadaddr.sa_data[2], 4);
X bcopy(&netmask, &nfs_diskless.myif.ifra_mask.sa_data[2], 4);
X if (stat(rootpath, &statbuf) < 0) {
X fprintf(stderr,"%s: unable to stat '%s'\n",
X argv[0],rootpath);
X exit(2);
X }
X if (!S_ISDIR(statbuf.st_mode)) {
X fprintf(stderr,"%s: '%s' is not a directory\n",
X argv[0],rootpath);
X exit(2);
X }
X if (getfh(rootpath, nfs_diskless.root_fh) < 0) {
X fprintf(stderr,"%s: unable to get handle for '%s'\n",
X argv[0],rootpath);
X exit(2);
X }
X sprintf(buf,"%s:%s",servername, rootpath);
X buf[NFSMNAMELEN-1] = 0;
X strcpy(nfs_diskless.root_hostnam,buf);
X printf("root is on %s\n",nfs_diskless.root_hostnam);
X if (stat(swappath, &statbuf) < 0) {
X fprintf(stderr,"%s: unable to stat '%s'\n",
X argv[0],swappath);
X exit(2);
X }
X if (!S_ISREG(statbuf.st_mode)) {
X fprintf(stderr,"%s: '%s' is not a regular file\n",
X argv[0],swappath);
X exit(2);
X }
X if (getfh(swappath, nfs_diskless.swap_fh) < 0) {
X fprintf(stderr,"%s: unable to get handle for '%s'\n",
X argv[0],swappath);
X exit(2);
X }
X sprintf(buf,"%s:%s",servername, swappath);
X buf[NFSMNAMELEN-1] = 0;
X strcpy(nfs_diskless.swap_hostnam,buf);
X printf("swap is on %s\n",nfs_diskless.swap_hostnam);
X
X /***********************/
X /* Now update kernel */
X /***********************/
X if (stat(kernel, &statbuf) < 0) {
X fprintf(stderr,"%s: unable to stat '%s'\n",
X argv[0],kernel);
X exit(2);
X }
X if ((fd = open(kernel, O_RDWR)) < 0) {
X fprintf(stderr,"%s: unable to open kernel file '%s'\n",
X argv[0],kernel);
X exit(2);
X }
X if ((p = q = malloc(statbuf.st_size)) == NULL) {
X fprintf(stderr,"%s: unable to allocate memory for kernel\n",
X argv[0]);
X exit(2);
X }
X if (read(fd, p, statbuf.st_size) != statbuf.st_size) {
X fprintf(stderr,"%s: unable to read kernel\n",
X argv[0]);
X exit(2);
X }
X while ((q < (p + statbuf.st_size)) && memcmp(q, MAGIC_COOKIE,
X sizeof(MAGIC_COOKIE) - 1)) q++;
X if (q == (p+statbuf.st_size)) {
X fprintf(stderr,"%s: unable to find magic cookie in kernel '%s'\n",
X argv[0],kernel);
X exit(2);
X }
X printf("kernel size = %d bytes, nfs_diskless at offset %d\n",
X statbuf.st_size, q-p);
X bcopy(&nfs_diskless, q, sizeof(struct nfs_diskless));
X if (lseek(fd, 0L, SEEK_SET) < 0) {
X fprintf(stderr,"%s: unable to rewind kernel '%s'\n",
X argv[0],kernel);
X exit(2);
X }
X if (write(fd, p, statbuf.st_size) != statbuf.st_size) {
X fprintf(stderr,"%s: unable to write to kernel '%s'\n",
X argv[0],kernel);
X exit(2);
X }
X close(fd);
X}
X
X/********************************************************************
XHELP - Print help message
X********************************************************************/
Xhelp(prog, keywd)
X char *prog, *keywd;
X{
X int i;
X fprintf(stderr,"%s: invalid keyword '%s' or not enough parameters\n",prog,keywd);
X fprintf(stderr," valid keywords: ");
X for (i=0; keywords[i].name; i++) fprintf(stderr,"%s ", keywords[i].name);
X fprintf(stderr,"\n");
X}
X
X/*********************************************************************
XI386ORDER - Byte swap
X*********************************************************************/
Xi386order(i)
X unsigned int i;
X{
X#ifdef BIG_ENDIAN
X return( ((i >> 24) & 0x000000FF) |
X ((i >> 8) & 0x0000FF00) |
X ((i << 8) & 0x00FF0000) |
X ((i << 24) & 0xFF000000));
X#else
X return(i);
X#endif
X}
X@EOF
X
Xchmod 640 setup.c
X
Xecho x - diskless.h
Xcat >diskless.h <<'@EOF'
X/*
X * Copyright (c) 1982,1985,1986,1988 Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms, with or without
X * modification, are permitted provided that the following conditions
X * are met:
X * 1. Redistributions of source code must retain the above copyright
X * notice, this list of conditions and the following disclaimer.
X * 2. Redistributions in binary form must reproduce the above copyright
X * notice, this list of conditions and the following disclaimer in the
X * documentation and/or other materials provided with the distribution.
X * 3. All advertising materials mentioning features or use of this software
X * must display the following acknowledgement:
X * This product includes software developed by the University of
X * California, Berkeley and its contributors.
X * 4. Neither the name of the University nor the names of its contributors
X * may be used to endorse or promote products derived from this software
X * without specific prior written permission.
X *
X * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
X * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
X * SUCH DAMAGE.
X *
X * @(#)socket.h 7.13 (Berkeley) 4/20/91
X */
X
X/*
X * Definitions related to sockets: types, address families, options.
X */
X
X/*
X * Types
X */
X#define SOCK_STREAM 1 /* stream socket */
X#define SOCK_DGRAM 2 /* datagram socket */
X#define SOCK_RAW 3 /* raw-protocol interface */
X#define SOCK_RDM 4 /* reliably-delivered message */
X#define SOCK_SEQPACKET 5 /* sequenced packet stream */
X
X/*
X * Option flags per-socket.
X */
X#define SO_DEBUG 0x0001 /* turn on debugging info recording */
X#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */
X#define SO_REUSEADDR 0x0004 /* allow local address reuse */
X#define SO_KEEPALIVE 0x0008 /* keep connections alive */
X#define SO_DONTROUTE 0x0010 /* just use interface addresses */
X#define SO_BROADCAST 0x0020 /* permit sending of broadcast msgs */
X#define SO_USELOOPBACK 0x0040 /* bypass hardware when possible */
X#define SO_LINGER 0x0080 /* linger on close if data present */
X#define SO_OOBINLINE 0x0100 /* leave received OOB data in line */
X
X/*
X * Additional options, not kept in so_options.
X */
X#define SO_SNDBUF 0x1001 /* send buffer size */
X#define SO_RCVBUF 0x1002 /* receive buffer size */
X#define SO_SNDLOWAT 0x1003 /* send low-water mark */
X#define SO_RCVLOWAT 0x1004 /* receive low-water mark */
X#define SO_SNDTIMEO 0x1005 /* send timeout */
X#define SO_RCVTIMEO 0x1006 /* receive timeout */
X#define SO_ERROR 0x1007 /* get error status and clear */
X#define SO_TYPE 0x1008 /* get socket type */
X
X/*
X * Structure used for manipulating linger option.
X */
Xstruct linger {
X int l_onoff; /* option on/off */
X int l_linger; /* linger time */
X};
X
X/*
X * Level number for (get/set)sockopt() to apply to socket itself.
X */
X#define SOL_SOCKET 0xffff /* options for socket level */
X
X/*
X * Address families.
X */
X#define AF_UNSPEC 0 /* unspecified */
X#define AF_UNIX 1 /* local to host (pipes, portals) */
X#define AF_INET 2 /* internetwork: UDP, TCP, etc. */
X#define AF_IMPLINK 3 /* arpanet imp addresses */
X#define AF_PUP 4 /* pup protocols: e.g. BSP */
X#define AF_CHAOS 5 /* mit CHAOS protocols */
X#define AF_NS 6 /* XEROX NS protocols */
X#define AF_ISO 7 /* ISO protocols */
X#define AF_OSI AF_ISO
X#define AF_ECMA 8 /* european computer manufacturers */
X#define AF_DATAKIT 9 /* datakit protocols */
X#define AF_CCITT 10 /* CCITT protocols, X.25 etc */
X#define AF_SNA 11 /* IBM SNA */
X#define AF_DECnet 12 /* DECnet */
X#define AF_DLI 13 /* DEC Direct data link interface */
X#define AF_LAT 14 /* LAT */
X#define AF_HYLINK 15 /* NSC Hyperchannel */
X#define AF_APPLETALK 16 /* Apple Talk */
X#define AF_ROUTE 17 /* Internal Routing Protocol */
X#define AF_LINK 18 /* Link layer interface */
X#define pseudo_AF_XTP 19 /* eXpress Transfer Protocol (no AF) */
X
X#define AF_MAX 20
X
X/*
X * Structure used by kernel to store most
X * addresses.
X */
Xstruct sockaddr {
X u_char sa_len; /* total length */
X u_char sa_family; /* address family */
X char sa_data[14]; /* actually longer; address value */
X};
X
X#define IFNAMSIZ 16
X
Xstruct ifaliasreq {
X char ifra_name[IFNAMSIZ]; /* if name, e.g. "en0" */
X struct sockaddr ifra_addr;
X struct sockaddr ifra_broadaddr;
X struct sockaddr ifra_mask;
X};
X
X
X/*
X * File Handle (32 bytes for version 2), variable up to 1024 for version 3
X */
X
X#define NFS_FHSIZE 32
Xtypedef struct { u_char f[NFS_FHSIZE] } nfsv2fh_t;
X/*
X * Arguments to mount NFS
X */
Xstruct nfs_args {
X struct sockaddr *addr; /* file server address */
X int sotype; /* Socket type */
X int proto; /* and Protocol */
X nfsv2fh_t *fh; /* File handle to be mounted */
X int flags; /* flags */
X int wsize; /* write size in bytes */
X int rsize; /* read size in bytes */
X int timeo; /* initial timeout in .1 secs */
X int retrans; /* times to retry send */
X char *hostname; /* server's name */
X};
X/*
X * NFS mount option flags
X */
X#define NFSMNT_SOFT 0x0001 /* soft mount (hard is default) */
X#define NFSMNT_WSIZE 0x0002 /* set write size */
X#define NFSMNT_RSIZE 0x0004 /* set read size */
X#define NFSMNT_TIMEO 0x0008 /* set initial timeout */
X#define NFSMNT_RETRANS 0x0010 /* set number of request retrys */
X#define NFSMNT_HOSTNAME 0x0020 /* set hostname for error printf */
X#define NFSMNT_INT 0x0040 /* allow interrupts on hard mount */
X#define NFSMNT_NOCONN 0x0080 /* Don't Connect the socket */
X#define NFSMNT_SCKLOCK 0x0100 /* Lock socket against others */
X#define NFSMNT_WANTSCK 0x0200 /* Want a socket lock */
X#define NFSMNT_SPONGY 0x0400 /* spongy mount (soft for stat and lookup) */
X#define NFSMNT_COMPRESS 0x0800 /* Compress nfs rpc xdr */
X#define NFSMNT_LOCKBITS (NFSMNT_SCKLOCK | NFSMNT_WANTSCK)
X
X@EOF
X
Xchmod 644 diskless.h
X
Xecho x - nfsdiskless.h
Xcat >nfsdiskless.h <<'@EOF'
X/*
X * Copyright (c) 1991 The Regents of the University of California.
X * All rights reserved.
X *
X * This code is derived from software contributed to Berkeley by
X * Rick Macklem at The University of Guelph.
X *
X * Redistribution and use in source and binary forms, with or without
X * modification, are permitted provided that the following conditions
X * are met:
X * 1. Redistributions of source code must retain the above copyright
X * notice, this list of conditions and the following disclaimer.
X * 2. Redistributions in binary form must reproduce the above copyright
X * notice, this list of conditions and the following disclaimer in the
X * documentation and/or other materials provided with the distribution.
X * 3. All advertising materials mentioning features or use of this software
X * must display the following acknowledgement:
X * This product includes software developed by the University of
X * California, Berkeley and its contributors.
X * 4. Neither the name of the University nor the names of its contributors
X * may be used to endorse or promote products derived from this software
X * without specific prior written permission.
X *
X * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
X * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
X * SUCH DAMAGE.
X *
X * @(#)nfsdiskless.h 7.1 (Berkeley) 3/4/91
X */
X
X/*
X * Structure that must be initialized for a diskless nfs client.
X * This structure is used by nfs_mountroot() to set up the root and swap
X * vnodes plus do a partial ifconfig(8) and route(8) so that the critical net
X * interface can communicate with the server.
X * For now it is statically initialized in swapvmunix.c, but someday a primary
X * bootstrap should fill it in.
X */
X#define NFSMNAMELEN 64
Xstruct nfs_diskless {
X struct ifaliasreq myif; /* Info. for partial ifconfig */
X struct sockaddr mygateway; /* Default gateway for "route add" */
X struct nfs_args swap_args; /* Mount args for swap file */
X u_char swap_fh[NFS_FHSIZE]; /* Swap file's file handle */
X struct sockaddr swap_saddr; /* Address of swap server */
X char swap_hostnam[NFSMNAMELEN]; /* Host name for mount pt */
X struct nfs_args root_args; /* Mount args for root fs */
X u_char root_fh[NFS_FHSIZE]; /* File handle of root dir */
X struct sockaddr root_saddr; /* Address of root server */
X char root_hostnam[NFSMNAMELEN]; /* Host name for mount pt */
X};
X@EOF
X
Xchmod 640 nfsdiskless.h
X
Xexit 0
END-of-319
exit