nispa@hutcs.hut.fi (Tapani Lindgren) (02/23/88)
In article <46400003@ztivax.UUCP> freizeit@ztivax writes: > >Subject : Backup for HD asked > >if anyone has an easy way to backup the harddisk onto floppy >(for instance a version of tar which asks for a new floppy >when the old is full) sent it to the audience or to > We use PD-TAR with Bill Davidsen's BUNDLE. Here is a version of BUNDLE tuned for MINIX. PS. We could'n't make pipes work with block sizes larger than 7K. Is there a BUG in Minix? (No, that would be impossible:-) If somebody has a fix, please let the world know! ---- CUT HERE ----- #!/bin/sh # This is a shell archive. Remove anything before this line, then # unpack it by saving it in a file and typing "sh file". (Files # unpacked will be owned by you and have default permissions.) # # This archive contains: # README Makefile bundle.1 bundle.h bundle.c unbundle.c echo x - README cat > "README" << '//E*O*F README//' BUNDLE is a program that reads its standard input and writes it to a named special file in [Bsize]-byte blocks. When [Dsize] bytes have been written, bundle prompts for a new volume. UNBUNDLE does the opposite, eg. prompts for volumes, reads them, and writes to standard output. These programs are designed to be used with programs like tar, that produce a long stream of data, but don't know about volumes. Usage: "tar something | bundle [ device [ Dsize [ Bsize ]]]" or "unbundle [ device [ Dsize [ Bsize ]]] | tar something". See included manual page for more information. Bundle and Unbundle, version 1.6, were written by Bill Davidsen in August 1987, and modified for Minix Operating System by Tapani Lindgren (nispa@hutcs.hut.fi) and Pertti Kasanen (ptk@hutcs.hut.fi) in January 1988. We added a possibility to omit the arguments so the program should be easier to use. Default device names and sizes are provided for Minix with either 360K or 1.2M drives and Vaxes with a TS-11. We use Bundle with PD-TAR, posted to net some time ago. Minix tar cannot be used, since it cannot use standard input/output as the tar file. WARNING There is a "feature" in Minix file system that limits the usability of this and similiar programs: if pipes are read or written in too large hunks, the data gets lost without warning. We haven't figured out the reason yet. Instead, we try to avoid the problem by using block sizes smaller than 7K. Tapani Lindgren //E*O*F README// echo x - Makefile cat > "Makefile" << '//E*O*F Makefile//' CFLAGS = -DMINIX -DAT all: bundle unbundle bundle: bundle.c bundle.h cc $(CFLAGS) -o bundle -O bundle.c unbundle: unbundle.c bundle.h cc $(CFLAGS) -o unbundle -O unbundle.c install: all cp bundle unbundle /usr/local/bin cp bundle.1 /usr/local/man rm /usr/local/man/unbundle.1 ln /usr/local/man/bundle.1 /usr/local/man/unbundle.1 -ln -s /usr/local/man/bundle.1 /usr/man/man1 -ln -s /usr/local/man/unbundle.1 /usr/man/man1 clean: rm core *.o bundle unbundle *~ //E*O*F Makefile// echo x - bundle.1 cat > "bundle.1" << '//E*O*F bundle.1//' '\" Copyright 1986,87 by Bill Davidsen. This code may be used for '\" personal or commercial purposes. It may be freely distributed '\" in source form providing this notice is kept intact. .TH bundle 1 Local '\" Heading: name(sect) center (paren) name(sect) .SH NAME bundle \- buffer and copy \fIstdin\fR to a physicaql device unbundle \- buffer and copy a physical device to \fIstdout\fR .SH SYNOPSIS \fBbundle\fR special dev_size buf_size .br \fBunbundle\fR special buf_size .SH DESCRIPTION These programs allow a physical device to be the head or end of a pipe, allows software which does not know about volumes to operate on multi-volume sets, and improves the performance of programs such as \fItar\fR and \fIcpio\fR. .P \fBSpecial\fR is the name of a raw device, such as /dev/rmt0. \fBdev_size\fR is the size of the device, given in bytes or kilobytes. When \fBdev_size\fR bytes have been written to the output device, the operator will be prompted for a media change. \fBBuf_size\fR is the size of the buffer for the write or read. For tape this should be the desired tape block size. For disk this should be a multiple of the size of a track. For disk output writing a track at a time rather than sectors can reduce real time by a factor of three. .P If arguments are omitted, system defaults are used. For minix these \fB/dev/at0, 1200k\fR and \fB15k\fR (device name, device size and buffer size, respectively). .SH EXAMPLES ls *.c | cpio -o | bundle /dev/rfp021 395k 5k unbundle /dev/rfp021 5k | cpio -idm tar cf - /usr/local | bundle /dev/rmt0 4000k 8k unbundle /dev/rmt0 8k | tar cf - .SH WARNINGS \fIunbundle\fR reads to EOF on the input device. There is no way to read only part of a volume. If the \fBdev_size\fR is not a multiple of the \fBbuf_size\fR, bizarre errors may occur. .SH FILES /dev/\fBspecial\fR .SH SEE ALSO tar, cpio. .SH AUTHOR Bill Davidsen (ihnp4!chinet!crdos1!davidsen) '\" For more details, see man(7), as well as man(1), manroff(1), and mmt(1) //E*O*F bundle.1// echo x - bundle.h cat > "bundle.h" << '//E*O*F bundle.h//' /* definitions for bundle and unbundle */ #include <stdio.h> #ifdef DEBUG # define debug(f,v) fprintf(stderr, f, v) #else # define debug(f,v) #endif #define K <<10L /* kilobytes */ #ifdef MINIX # ifdef XT # define DEF_DNAME "/dev/fd0" # define DEF_DSIZE (360 K) # define DEF_BSIZE (6 K) /* should be 9, but minix pipes are too short */ # else # define DEF_DNAME "/dev/at0" # define DEF_DSIZE (1200 K) # define DEF_BSIZE (6 K) /* should be 15, but minix pipes are too short */ # endif #endif #ifdef BSD # ifdef VAX # define DEF_DNAME "/dev/rmt8" # define DEF_DSIZE (40000 K) # define DEF_BSIZE (20 K) # endif #endif //E*O*F bundle.h// echo x - bundle.c cat > "bundle.c" << '//E*O*F bundle.c//' /***************************************************************** | Program name: bundle.c |---------------------------------------------------------------- | accept standard input and write to a device named on the command | line. The total bytes on the device and the buffer size are | given on the command line. When the device is full, prompt | for a new medium in the device and continue. | | Command form: | bundle [ device [ Dsize [ Bsize ]]] |---------------------------------------------------------------- | Author: Bill Davidsen, 8/16/86 | Version 1.6 | Last modified: 3/6/87 | Version 1.6M for Minix Operating System | Modified by Tapani Lindgren <nispa@hutcs.hut.fi> 87-12-28 |---------------------------------------------------------------- | Copyright 1986,87 by Bill Davidsen. This code may be used for | personal or commercial purposes. It may be freely distributed | in source form providing this notice is kept intact. *****************************************************************/ #include "bundle.h" static char *SCCS = "@(#) bundle 1.6M"; usage() { fprintf (stderr, "Usage:\n bundle [ device [ DevSize [ BufSize ]]]\n"); fprintf (stderr, "Where size may be bytes (as 5120) or k (as 5k)\n"); exit (1); } main (argc, argv) int argc; char *argv[]; { char *devname; /* device name */ char *buffer, /* i/o buffer */ *malloc (); register long left; /* room left in the buffer */ long bufsize, devsize; /* buffer and device size */ long devleft = 0; /* room left on device */ int istat, /* stdin read status */ ostat, /* device write status */ dev, /* device name from open */ MediaNum = 1; /* sequential media # */ FILE *tty, *fopen (); long getsize (); /* get size from argument */ /* validate arguments */ if (argc > 4) usage(); if (argc > 1) devname = argv[1]; else devname = DEF_DNAME; if (argc > 2) devsize = getsize (argv[2]); else devsize = DEF_DSIZE; debug ("Device size %ld", devsize); if (argc > 3) bufsize = getsize (argv[3]); else bufsize = DEF_BSIZE; debug (", buffer size %ld\n", bufsize); if (devsize < 1 || devsize < bufsize) { /* invalid specification of size */ fprintf (stderr, "Invalid buffer and/or device size\n"); exit (1); } /* open the terminal for prompt */ tty = fopen ("/dev/tty", "r"); if (tty == NULL) { /* mystery failure */ fprintf (stderr, "Unable to open /dev/tty for prompt\n"); exit (1); } /* open the buffer */ buffer = malloc (bufsize); debug ("Buffer allocated\n", 0); if (buffer == NULL) { /* can't mallocate */ fprintf (stderr, "Can't allocate space for the buffer\n"); exit (1); } /* see if you can open the device */ fprintf (stderr, "Mount media #1 on %s and press RETURN\n", devname); while (getc (tty) != '\n'); dev = open (devname, 1); if (dev < 0) { /* invalid name */ fprintf (stderr, "Can't access device %s\n", devname); exit (1); } devleft = devsize; /* set media ready */ debug ("Enter copy loop\n\n", 0); /* main copy loop */ while (istat = fread (buffer, 1, (int) bufsize, stdin)) { /* until EOF */ debug ("Input read size %d\n", istat); if (devleft < istat) { /* change media */ close (dev); fprintf (stderr, "\007Mount media #%d on %s and press RETURN\n", ++MediaNum, devname); while (getc (tty) != '\n'); dev = open (devname, 1); devleft = devsize; } /* write the buffer */ ostat = write (dev, buffer, bufsize); debug ("Output write size %d\n", ostat); if (bufsize != ostat) { /* error on write */ fprintf (stderr, "Error on device write!\n"); exit (1); } devleft -= ostat; } } /* | Procedure: getsize |- | Convert the size string to bytes. If the last character is | 'k', multiply by 1024 */ long getsize (string) char *string; { register int len = strlen (string); register long val = atol (string); if (string[len - 1] == 'k') val *= 1024; return val; } //E*O*F bundle.c// echo x - unbundle.c cat > "unbundle.c" << '//E*O*F unbundle.c//' /***************************************************************** | Program: unbundle | accept input from a device and write to stdout |---------------------------------------------------------------- | Arguments: | 1) device name | 2) block size in bytes or k | Version: 1.6 | Last modified: 3/6/87 | Modified 87-12-28 by Tapani Lindgren <nispa@hutcs.hut.fi> |---------------------------------------------------------------- | Copyright 1986,87 by Bill Davidsen. This code may be used for | personal or commercial purposes. It may be freely distributed | in source form providing this notice is kept intact. ****************************************************************/ #include "bundle.h" usage() { /* bad calling sequence */ fprintf (stderr, "Usage:\n unbundle [ device [ bufsize ]]\n"); exit (1); } main (argc, argv) int argc; char *argv[]; { char *devname; char *buf, *malloc (); int bufsize, dn, mnum = 1, ch, readsize; static char *SCCSid = "@(#)unbundle 1.6"; long getsize (); /* size of buffer */ FILE *tty, *fopen(); if (argc > 3) usage(); /* try to open the device */ if (argc > 1) devname = argv[1]; else devname = DEF_DNAME; dn = open (devname, 0); if (dn < 0) { /* open failed */ fprintf (stderr, "%s: can't open device %s\n", argv[0], devname); exit (1); } close (dn); /* so I can reopen */ /* allocate the buffer */ if (argc > 2) bufsize = getsize (argv[2]); else bufsize = DEF_BSIZE; debug ("Bufsize: %d\n", bufsize); if (bufsize < 1) usage(); buf = malloc (bufsize); if (buf == NULL) { /* can't allocate the buffer */ fprintf (stderr, "Can't allocate %d byte buffer\n", bufsize); exit (1); } /* open the terminal for prompt */ tty = fopen ("/dev/tty", "r+"); if (tty == NULL) { /* mystery failure */ fprintf (stderr, "Unable to open /dev/tty for prompt\n"); exit (1); } for (;;) { /* get a fresh mount and read it */ fprintf (stderr, "\007Mount media #%d on %s and press RETURN: ", mnum++, devname); read(0, &ch, 1); dn = open (devname, 0); while (readsize = read (dn, buf, bufsize)) { write (1, buf, readsize); } close (dn); } } /* | Procedure: getsize |- | Convert the size string to bytes. If the last character is | 'k', multiply by 1024 */ long getsize (string) char *string; { register int len = strlen (string); register long val = atol (string); if (string[len - 1] == 'k') val *= 1024; return val; } //E*O*F unbundle.c// exit 0
roskos@csed-1.UUCP (Eric Roskos) (02/26/88)
This is in response to the postings on how to do backups under Minix. To handle this I am using PD tar (not the most recent version, an earlier version with some DOS support changes I couldn't get John to put in) which I modified to use multivolume support. However, I am still testing it; if there is enough interest I could post the current diffs, though. The changes to PD tar are only about 3 or 4 lines worth; fortunately it has comments in there already telling where the changes need to go. However, Minix turned out to have a bug -- at least, I guess it's a bug -- in that it does not cause an EOF when you are *writing* to the floppy disk special files and you reach the end of the disk; it only gets an EOF when you are reading. So, to use it, you have to change that too. If there's any interest in this, send me email, and if there's enough interest I can post the changes... if not I'll just email them. -- Eric Roskos, IDA (...dgis!csed-1!roskos or csed-1!roskos@HC.DSPO.GOV)
ast@cs.vu.nl (Andy Tanenbaum) (02/27/88)
In article <10579@santra.UUCP> nispa@hutcs.hut.fi (Tapani Lindgren) writes: >In article <46400003@ztivax.UUCP> freizeit@ztivax writes: >We could'n't make pipes work with block sizes larger than 7K. >Is there a BUG in Minix? (No, that would be impossible:-) >If somebody has a fix, please let the world know! It is not a bug. It is a feature. Having pipes larger than 7K would mean not using "small" files, but files with indirect blocks as pipe inodes. V7 does not allow this; neither does MINIX. There is no easy fix. Andy Tanenbaum (ast@cs.vu.nl)
rmtodd@uokmax.UUCP (Richard Michael Todd) (02/29/88)
In article <665@ast.cs.vu.nl> ast@cs.vu.nl (Andy Tanenbaum) writes: >It is not a bug. It is a feature. Having pipes larger than >7K would mean not using "small" files, but files with indirect blocks as pipe >inodes. V7 does not allow this; neither does MINIX. There is no easy fix. I think it's a bug. When you attempt to write a block greater than 7K to a file and it fails for no apparent reason, it's a violation of the Principle of Least Astonishment. Why should MINIX perpetuate all of V7's bugs? Does Sys5 have this bug? (BSD pipes aren't implemented using spare inodes, so this doesn't apply to them, and BSD doesn't freak out when you write >7k to a pipe.) Some time ago I found a way to patch MINIX FS to allow writes >7K to a pipe. It required changes to two lines, I think. Nothing else seemed to break. Unfortunately I'm at school right now and the MINIX machine's at home, so it'll be at least this weekend before I can post them. -------------------------------------------------------------------------- Richard Todd USSnail:820 Annie Court,Norman OK 73069 UUCP: {allegra!cbosgd|ihnp4}!occrsh!uokmax!rmtodd