mouse@mcgill-vision.UUCP (der Mouse ) (06/30/87)
[Comment on the below: it sure as heck isn't seismo, so it must be sun. I try to avoid that site anyway, as the cwruecmp!sun link has been marked DEAD in cwruecmp's map for quite a while now. ++bsa] This is part 1 of 2. Read the README (first thing in the archive) to see what it's part 1 of. I had to split up even this tiny thing because someone, either sun or seismo (not sure which), has a 10000 byte limit on mail (yes, only ten thousand bytes). der Mouse (mouse@mcgill-vision.uucp) #! /bin/sh # # Shar: Shell Archiver # # This archive created Sun Jun 28 17:50:43 1987 # Run this through sh to create: # README echo x - README \(5589 characters\) sed 's/^X//' > README << \SHAR_EOF Xfiledisk: a pseudo disk driver for UNIX. This driver makes a normal X file look like a filesystem volume. X X Currently in use on 4.3BSD. Originally developed on 4.2BSD, X but the 4.2 version is buried in the mists of the past, so all X this says is that it won't take much to make it work on 4.2. I X have attempted to use a somewhat modified version of this under X mtXinu 4.3+NFS but unfortunately it keeps crashing the system X for reasons yet to be discovered. I haven't dared even try to X make it work on a Sun. I won't, either, until we get source. X XYou should have received: X X - README (this file) X - filedisk.c X - fdconn.c X - fddisc.c X XYou will need to: X X - Put filedisk.c somewhere; I'll assume it's in X ../local/filedisk.c (that's where we have it). If you put X it somewhere else, change the filename in the next item to X point to wherever you did put it. X X - Put a line Xlocal/filedisk.c optional memdisk X in ../conf/files.YOURSYSTEMNAME. For example, our X configuration is in ../conf/LARRY and the kernel is built in X ../LARRY; the file with the above line is then X ../conf/files.LARRY (clear enough?). X X - Put a line Xpseudo-device filedisk 1 X in ../conf/YOURSYSTEMNAME. The 1 specifies how many pseudo X disk devices you want to configure in; you may want to X increase it. X X - Edit conf.c. This file is in ../vax for VAX and MicroVAX X configurations and seems to be in ../sun (rather than X ../machine, which is a link to sun2 or sun3 depending on X which sort of Sun you have) for Suns. You will need to X insert the following, somewhere early (before both cdevsw[] X and bdevsw[]). X#include "filedisk.h" X#if NFILEDISK > 0 Xextern int filediskopen(); Xextern int filediskstrategy(); Xextern int filediskread(); Xextern int filediskwrite(); Xextern int filediskioctl(); Xextern int filedisksize(); X#else X#define filediskopen nodev X#define filediskstrategy nodev X#define filediskread nodev X#define filediskwrite nodev X#define filediskioctl nodev X#define filedisksize nodev X#endif X Now you need to add a device to each of bdevsw[] and X cdevsw[]. The bdevsw entry should look like X { filediskopen, nulldev, filediskstrategy,nodev, /* 10 */ X filedisksize, 0 }, X (the 10 should be changed to whatever number you choose to X put it at). The cdevsw entry should look like X filediskopen, nulldev, filediskread, filediskwrite, /* 34 */ X filediskioctl, nulldev, nulldev, 0, X seltrue, 0, X again, with the 34 changed to whatever is appropriate. X X - add two #define lines to ../h/ioctl.h: X#define LIOC_FSF_SET _IOW(l,1,char *) /* setup filedisk */ X#define LIOC_FSF_CLEAR _IO(l,2) /* clear filedisk */ X XYou can now re-run config and rebuild your kernel. X XIf I haven't forgotten anything (:-), it should run fine. Test the new Xkernel. When you are satisfied that adding the filedisk driver hasn't Xbroken anything else, you can try it out: X X - Create entries in /dev. We use /dev/filedisk0 and X /dev/rfiledisk0 (just 0 since we have just one configured X in; if we had two, they'd be filedisk0/rfiledisk0 and X filedisk1/rfiledisk1). X X - Compile fdconn.c and fddisc.c; put the binaries wherever you X feel appropriate. As with any disk drive, the /dev entries X should be mode xx0, probably mode 600 is best, unless you X wouldn't mind entrusting all your users with your root X password. Fdconn and fddisc must be able to open the raw X device /dev/rfiledisk0 (or rfiledisk1, or 2, or...) in order X to function. X XNow to test it. I should explain what fdconn and fddisc do. Fdconn Xconnects a pseudo-disk unit to a file; fddisc breaks the connection Xcreated by fdconn. A pseudo-disk unit must be connected to a file Xbefore it can do anything useful, of course. X XLet's test it by just creating a half-meg file and using that as our Xfilesystem. First let's create the half-meg file: X Xdd if=/dev/full bs=....uh, what, you mean this is the filedisk Xdistribution rather than the /dev/full driver distribution? ;-) X Xyes | dd conv=sync bs=65536 count=8 > bigfile X X(65536*8 is 512k; conv=sync makes dd pad each bufferful to the bs= Xfigure.) After a few seconds, dd will report 0+8 records in, 8+0 Xrecords out. Then you will get a "Broken pipe" message, which you Xshould ignore. Now we connect this to unit 0: X X# fdconn 0 bigfile X XNow /dev/filedisk0 and /dev/rfiledisk0 are pseudo-filesystems Xcontaining lots of junk. Let's make a filesystem there: X X# /etc/mkfs /dev/rfiledisk0 1024 X....mkfs messages.... X XNow sync the disk just to be safe. It works just as well to run fsck Xon it, I find; but if you do neither, I have had it crash mysteriously Xsometimes (I suspect that some critical filesystem data, like Xsuperblocks, is still waiting to be written to the disk, because the Xmkfs used /dev/rfiledisk0 instead of /dev/filedisk0). X X# sync X XNow we can mount it somewhere: X X# /etc/mount /dev/filedisk0 /mnt X XAnd away we go! Note that you pay two penalties for using this driver. XOne is speed, of course; the other is storage space, since there is all Xthe usual filesystem overhead. Most of the uses for this driver are Xsuch that these really don't matter. For example, recently I wanted to Xbuild a boot tape with a slightly non-standard mini-root filesystem on Xit. So I just used dd to copy the mini-root off the tape onto a disk Xfile and then used this driver to mount the mini-root filesystem Xsomewhere. Then of course it was trivial to arrange things on the Xmini-root as I wanted them. Then just unmount and run fddisc, and use Xdd to put it back on tape. X X der Mouse X X (mouse@mcgill-vision.uucp) SHAR_EOF if test 5589 -ne "`wc -c README`" then echo shar: error transmitting README \(should have been 5589 characters\) fi exit 0 # end of shell archive
mouse@mcgill-vision.UUCP (der Mouse ) (06/30/87)
This is part 2 of 2. Read the README (in part 1) to see what it's part 2 of. I had to split up even this tiny thing because someone, either sun or seismo (not sure which), has a 10000 byte limit on mail (yes, only ten thousand bytes). der Mouse (mouse@mcgill-vision.uucp) #! /bin/sh # # Shar: Shell Archiver # # This archive created Sun Jun 28 17:50:43 1987 # Run this through sh to create: # filedisk.c # fdconn.c # fddisc.c echo x - filedisk.c \(4378 characters\) sed 's/^X//' > filedisk.c << \SHAR_EOF X/* X * Filesystem-in-a-file pseudo-disk driver. X */ X X#include "filedisk.h" X X#if NFILEDISK > 0 X X#include "../h/param.h" X#include "../h/systm.h" X#include "../h/ioctl.h" X#include "../h/buf.h" X#include "../h/conf.h" X#include "../h/dir.h" X#include "../h/file.h" X#include "../h/inode.h" X#include "../h/namei.h" X#include "../h/user.h" X#include "../h/proc.h" X#include "../h/uio.h" X#include "../h/mount.h" X#include "../h/fs.h" X#include "../h/kernel.h" X Xstatic struct fdinfo { X int alive; X int unit; X struct inode *ino; X int nblocks; } info[NFILEDISK]; Xstatic int didinit = 0; X X#define OKUNIT(u) (((u)>=0)&&((u)<NFILEDISK)) X Xfilediskopen(dev,flag) Xdev_t dev; Xint flag; X{ X int unit; X X#ifdef lint X flag = flag; X#endif X if (! didinit) X { for (unit=0;unit<NFILEDISK;unit++) X { info[unit].alive = 0; X info[unit].unit = unit; X } X didinit = 1; X } X unit = minor(dev); X if (!OKUNIT(unit)) X { return(ENXIO); X } X return(0); X} X Xfilediskstrategy(bp) Xstruct buf *bp; X{ X int s; X X if (! buf_ok(bp)) X { return; X } X s = splhigh(); X splx(s); X if (s != 0) X { printf("IPL=%d\n",s); X panic("filediskstrategy: high ipl\n"); X } X else X { doionow(bp); X } X} X Xfilediskread(dev,uio) Xdev_t dev; Xstruct uio *uio; X{ X static struct buf b; X int unit; X X unit = minor(dev); X if (!OKUNIT(unit)) X { return(ENXIO); X } X return(physio(filediskstrategy,&b,dev,B_READ,minphys,uio)); X} X Xfilediskwrite(dev,uio) Xdev_t dev; Xstruct uio *uio; X{ X static struct buf b; X int unit; X X unit = minor(dev); X if (!OKUNIT(unit)) X { return(ENXIO); X } X return(physio(filediskstrategy,&b,dev,B_WRITE,minphys,uio)); X} X Xstatic int unit_mounted(unit) Xint unit; X{ X struct mount *mp; X int s; X dev_t dev; X X s = spl4(); /* as long as ipl > 0, (u)mounts can't happen */ X for (mp= &mount[0];mp<&mount[NMOUNT];mp++) X { if (mp->m_bufp != 0) X { dev = mp->m_dev; X if ( (bdevsw[major(dev)].d_strategy == filediskstrategy) && X (minor(dev) == unit) ) X { splx(s); X return(1); X } X } X } X splx(s); X return(0); X} X Xfilediskioctl(dev,cmd,data,flag) Xdev_t dev; Xint cmd; Xcaddr_t data; Xint flag; X{ X int unit; X int rv; X struct inode *ip; X register struct nameidata *ndp; X X#ifdef lint X flag = flag; X#endif X unit = minor(dev); X rv = EIO; X switch (cmd) X { case LIOC_FSF_SET: X if (! suser()) X { rv = EPERM; X break; X } X if (info[unit].alive) X { rv = EBUSY; X break; X } X ndp = &u.u_nd; X ndp->ni_segflg = UIO_USERSPACE; X ndp->ni_dirp = *(char **)data; X ndp->ni_nameiop = LOOKUP | FOLLOW; X ip = namei(ndp); X if (ip == 0) X { rv = u.u_error; X break; X } X if ((ip->i_mode&IFMT) != IFREG) X { iput(ip); X rv = EINVAL; X break; X } X info[unit].ino = ip; X info[unit].nblocks = btodb(ip->i_size); X info[unit].alive = 1; X iunlock(ip); X rv = 0; X break; X case LIOC_FSF_CLEAR: X if (! suser()) X { rv = EPERM; X break; X } X if (unit_mounted(unit)) X { rv = EBUSY; X break; X } X if (info[unit].alive) X { info[unit].alive = 0; X irele(info[unit].ino); X rv = 0; X } X else X { rv = ENXIO; X } X break; X } X return(rv); X} X Xfilediskdump() X{ X return(ENXIO); X} X Xfiledisksize(dev) Xdev_t dev; X{ X int unit; X X unit = minor(dev); X if ((unit < 0) || (unit >= NFILEDISK) || !info[unit].alive) X { return(-1); X } X return(info[unit].nblocks); X} X Xfilediskreset(uban) Xint uban; X{ X printf("filedisk reset on %d?\n",uban); X} X Xstatic int buf_ok(bp) Xstruct buf *bp; X{ X int unit; X int nblk; X X#define FAIL() return((bp->b_flags|=B_ERROR),(iodone(bp)),0) X unit = minor(bp->b_dev); X if (bp->b_bcount & (DEV_BSIZE-1)) X { FAIL(); X } X nblk = btodb(bp->b_bcount); X if (! info[unit].alive) X { FAIL(); X } X if ( (bp->b_blkno < 0) || X (bp->b_blkno+nblk > info[unit].nblocks) ) X { FAIL(); X } X if (! info[unit].ino) X { FAIL(); X } X return(1); X#undef FAIL X} X Xstatic doionow(bp) Xstruct buf *bp; X{ X int unit = minor(bp->b_dev); X struct inode *ip = info[unit].ino; X X ilock(ip); X if (bp->b_flags & B_READ) X { bp->b_error = rdwri( UIO_READ, X ip, X bp->b_un.b_addr, X bp->b_bcount, X dbtob(bp->b_blkno), X 1, X &bp->b_resid ); X if (bp->b_error) X { bp->b_flags |= B_ERROR; X } X } X else X { bp->b_error = rdwri( UIO_WRITE, X ip, X bp->b_un.b_addr, X bp->b_bcount, X dbtob(bp->b_blkno), X 1, X &bp->b_resid ); X if (bp->b_error) X { bp->b_flags |= B_ERROR; X } X } X iunlock(ip); X iodone(bp); X} X X#endif SHAR_EOF if test 4378 -ne "`wc -c filedisk.c`" then echo shar: error transmitting filedisk.c \(should have been 4378 characters\) fi echo x - fdconn.c \(664 characters\) sed 's/^X//' > fdconn.c << \SHAR_EOF X#include <stdio.h> X#include <sys/file.h> X#include <sys/ioctl.h> X Xchar **argvec; X X/* usage: fdconn <unit> <filename> */ X Xchar dname[64]; Xint dfd; X Xmain(ac,av) Xint ac; Xchar **av; X{ X int unit; X X argvec = av; X if (ac != 3) X { fprintf(stderr,"Usage: %s unit file\n",argvec[0]); X exit(1); X } X unit = atoi(av[1]); X sprintf(dname,"/dev/rfiledisk%d",unit); X dfd = open(dname,O_RDWR,0); X if (dfd < 0) X { fprintf(stderr,"%s: cannot open %s: ",argvec[0],dname); X perror((char *)0); X exit(1); X } X if (ioctl(dfd,LIOC_FSF_SET,&av[2]) < 0) X { fprintf(stderr,"%s: cannot connect %s to %s: ",argvec[0],dname,av[2]); X perror((char *)0); X exit(1); X } X exit(0); X} SHAR_EOF if test 664 -ne "`wc -c fdconn.c`" then echo shar: error transmitting fdconn.c \(should have been 664 characters\) fi echo x - fddisc.c \(636 characters\) sed 's/^X//' > fddisc.c << \SHAR_EOF X#include <stdio.h> X#include <sys/file.h> X#include <sys/ioctl.h> X Xchar **argvec; X X/* usage: fddisc <unit> */ X Xchar dname[64]; Xint dfd; X Xmain(ac,av) Xint ac; Xchar **av; X{ X int unit; X X argvec = av; X if (ac != 2) X { fprintf(stderr,"Usage: %s unit\n",argvec[0]); X exit(1); X } X unit = atoi(av[1]); X sprintf(dname,"/dev/rfiledisk%d",unit); X dfd = open(dname,O_RDWR,0); X if (dfd < 0) X { fprintf(stderr,"%s: cannot open %s: ",argvec[0],dname); X perror((char *)0); X exit(1); X } X if (ioctl(dfd,LIOC_FSF_CLEAR,0) < 0) X { fprintf(stderr,"%s: cannot disconnect %s: ",argvec[0],dname); X perror((char *)0); X exit(1); X } X exit(0); X} SHAR_EOF if test 636 -ne "`wc -c fddisc.c`" then echo shar: error transmitting fddisc.c \(should have been 636 characters\) fi exit 0 # end of shell archive