Revised mdump (multiple dump per tape utility)

sources-request at panda.UUCP sources-request at panda.UUCP
Thu Sep 12 23:33:44 AEST 1985


Mod.sources:  Volume 3, Issue 12
Submitted by: ihnp4!uiucdcs!uiucuxc.Uiuc.ARPA!paul (Paul Pomes)

[ I have included part of the description from the original release of
  mdump for those who may not have seen the first release.  Note that this
  is an UPDATE, there are files and programs that are not included with
  this module - contact me to obtain the original distribution.
    -  John P. Nelson, Moderator (decvax!genrad!panda!sources-request)
]

> Mdump and st were written to ease the pain of UNIX backups for our
> operations staff.  It's compressed the clock time needed to run a
> daily set of backups by almost two thirds.  The time savings are due
> to eliminating most of the tape mounts and waiting for tape rewinds.
> Listings are generated automatically though they can be suppressed.
> It's been in use here for about two months in its present form.
> VAX backups are done on local drives, the Pyramid 90x goes over an
> Ethernet to the VAX drives.
>
>         ...
>                                                          Anyway I
> think this will be extremely useful for some sites, handy at others,
> and pretty window dressing at the rest.

This revision incorporates suggestions contributed from the net as
well as some code cleanup engendered from a fresh look at the 
program.

The dump level for dailies and weeklies can now be specified with the
dl or wl switches.  Omitting them causes 5 and 4 to be used as the 
default level (set by #define's).

The somewhat awkward use of #define's to group printf strings together
has been eliminated in preference for moving the strings to where they're
used.  The comment  /* EDIT THIS */  now flags the location of site-
dependent strings.

Re-structuring the code inflated the patch file to be larger than the
original.  Included is the new mdump.c and mdump.8 man page.

Release 2.5 of OSx for the Pyramid 90x has changed the exit code of a
successful dump from 1 to 0.  Either revise dump.h and recompile dump,
or change mdump to check for 0 rather than 1.


         Paul Pomes

UUCP:	 {ihnp4,pur-ee,convex}!uiucdcs!uiucuxc!paul
ARPANET: paul%uiucuxc at uiuc.arpa
CSNET:	 paul%uiucuxc at uiuc.csnet
ICBM:	 40 07 N / 88 13 W
US Mail: Univ of Illinois, CSO, 1304 W Springfield Ave, Urbana, IL  61801

------ cut here ------
#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	mdump.c
#	mdump.8
sed 's/^X//' << 'SHAR_EOF' > mdump.c
X/*
X * mdump -- put daily/weekly backups onto a single tape
X *
X * Mdump simplifies the tedious process of daily and weekly backups by
X * putting all daily backups onto a single tape.  Weekly backups are
X * performed the same way.  The /etc/dumptab file defines the file
X * position on the tape each filesystem is written at and the day of
X * the week the weekly backup is done.  Filesystems that are scheduled
X * for a weekly backup are marked with a dummy file on the daily tape
X * so that file numbering remains constant.  The same is done for dailies
X * on a weekly tape.
X *
X * usage: mdump [-d] [-w] [-dl n] [-wl n] [-l] [-e] [-t day] [-f [host:]/dev/rmtx] [-db]
X *
X * -d	write daily backups with default dump level of DAILY
X *
X * -w	write weekly backups with default dump level of WEEKLY
X *
X * -dl n	write daily backups at dump level n
X *
X * -wl n	write weekly backups at dump level n
X *
X * -l	suppress generation of the listing file
X *
X * -e	run listing code after an error exit
X *
X * -t day	run mdump for day (sun - sat) instead of today
X *
X * -f [host:]/dev/rmtx	tape device name.  If the host: prefix
X *	is used, the backup tape will be written over the network to
X *	the tape drive on the named host.
X *
X * -db	Write debug information to stderr
X *
X * NOTE to installers:  Site dependent commands have been flagged in the
X * code with the comment "EDIT THIS".
X *
X * Written by Paul Pomes, University of Illinois, Computing Services Office.
X * Copyright 1985 by Paul Pomes and University of Illinois Board of Trustees
X *
X * This program may be freely reproduced and distributed provided the
X * copyright notice above is included in all copies.  It may not be
X * included in any software product or distribution sold for profit
X * without the permission of the author.
X *
X * UUCP:	{ihnp4,pur-ee,convex}!uiucdcs!uiucuxc!paul
X * ARPANET:	paul%uiucuxc at uiuc.arpa
X * CSNET:	paul%uiucuxc at uiuc.csnet
X * ICBM:	40 07 N / 88 13 W
X * US Mail:	Univ of Illinois, CSO, 1304 W Springfield Ave, Urbana, IL  61801
X *
X * $Log:	mdump.c,v $
X * Revision 1.10  85/09/11  14:06:08  root
X * Changed pr command to use two column printing instead of three.  -pbp
X * 
X * Revision 1.9  85/08/14  16:25:52  root
X * Threats of mayhem from operators induced me to re-insert -d and -w flags.
X * -pbp
X * 
X * Revision 1.8  85/08/14  13:45:47  paul
X * Revamped dump level selection with inclusion of wl and dl switches,
X * removed w and d as superfluous.  Moved commands back to the sprintfs
X * that use them.
X * 
X * Revision 1.7  85/08/07  16:30:08  paul
X * Added bare-bones System 5 defines (index -> strchr, etc).  Large hacks
X * needed to do the same for the mag tape ioctls.  Another day, far away.
X * 
X * Revision 1.6  85/08/07  16:03:57  root
X * Added n switch to dump command so that operators are notified.
X * Extremely effective annoyance feature.   -pbp
X * 
X * Revision 1.5  85/07/11  14:44:07  paul
X * Added recovery question for restore listings of filesystems with no files.
X * pbp
X * 
X * Revision 1.4  85/07/09  21:18:09  root
X * *** empty log message ***
X * 
X * Revision 1.3  85/07/05  17:13:39  root
X * Added -t day-of-week flag for enhanced error recovery.   -pbp
X * 
X * Revision 1.2  85/07/03  23:23:04  root
X * Added -e flag to force listings after "rsh mt" errors.   -pbp
X * 
X * Revision 1.1  85/07/02  13:47:46  root
X * Initial revision
X */
X
X#ifndef lint
Xstatic char	RcsId[] = "$Header: mdump.c,v 1.10 85/09/11 14:06:08 root Exp $";
X#endif
X
X#include	<stdio.h>
X#ifdef	SYS5
X#include	<string.h>
X#define		index		strchr
X#define		rindex		strrchr
X#else
X#include	<strings.h>
X#endif
X#include	<ctype.h>
X#include	<sys/time.h>
X#include	<sys/file.h>
X#include	<sys/types.h>
X#include	<sys/mtio.h>
X#include	<sys/ioctl.h>
X#include	<dumptab.h>
X
X#define		equal(s1, s2)	(strcmp(s1, s2) == 0)
X
X/* default dump levels */
X#define		DAILY		5
X#define		WEEKLY		4
X
X/* default output devices */
X#define		DEF_DEV		"/dev/rmt0"
X#define		DEF_NRDEV	"/dev/nrmt0"
X
X/* dumptab file.  must be the same as referenced by getdtent() functions */
X#define		DUMPTAB		"/etc/dumptab"
X
X/* temp file for listings */
X#define		DLIST		"/tmp/mdumpXXXXXX"
X
X/* maximum number of filesystems */
X#define		MAX_FS		30
X
X/* size of shorter strings, e.g., rhost[] */
X#define		SSTR_SIZE	12
X
X/* size of longer strings, e.g., command[] */
X#define		LSTR_SIZE	160
X
X/* copy of argv[0] for error messages */
Xchar		*self;
X
X/* resident host name */
Xchar		myname[SSTR_SIZE];
X
X/* debug messages printed if set */
Xint		debug;
X
X/* run listing code only */
Xint		elist;
X
X/* state table of tape files.  if dump_state[0] is set, then there's a dump
X * file there.  If zero, there's a dummy file on the tape instead.  If -1
X * then EOT has been reached or some other dump(8) error.  Typical usage
X * would be dump_state[dt->dt_position].
X */
Xint		dump_state[MAX_FS];
X
X/* mag tape stuff */
Xstruct mt_cmds {
X	char	*c_name;
X	int	c_code;
X	int	c_ronly;
X} com[] = {
X	{ "eof",	MTWEOF,	0 },
X	{ "fsf",	MTFSF,	1 },
X	{ "bsf",	MTBSF,	1 },
X	{ "rew",	MTREW,	1 },
X	{ 0 }
X};
X
Xextern time_t	time();
X
Xmain(argc, argv)
Xint	argc;
Xchar	**argv;
X{
X	/* a useful counter */
X	int		i;
X
X	/* flags set for default dump levels and types */
X	int		daily = 0;
X	int		weekly = 0;
X
X	/* dump level (0 to 9).  -1 indicates not selected */
X	int		dlevel = -1;	/* daily */
X	int		wlevel = -1;	/* weekly */
X
X	/* create a compact listing if set */
X	int		dlist = 1;
X
X	/* run mdump for day argument instead of today of set */
X	char		newday[4];
X
X	/* listing file */
X	char		*list_file = DLIST;
X
X	/* backup device */
X	char		*device, *nrdevice;
X
X	/* remote host name */
X	char		rhost[SSTR_SIZE];
X
X	/* time stuff */
X	struct tm	*tm;
X	time_t		clock;
X
X	/* dumptab info */
X	struct dumptab	*dt;
X
X	/* library routines */
X	char		*malloc(), *mktemp();
X
X	/* routine to set new tm->tm_wday value for -t argument */
X	struct tm	*setday();
X
X	/* squirrel a copy of *argv[0] away for use in error messages */
X	self = malloc((unsigned) (strlen(*argv) + 1));
X	(void) strcpy(self, *argv);
X
X	newday[0] = rhost[0] = '\0';
X	device = DEF_DEV;
X	nrdevice = DEF_NRDEV;
X	(void) gethostname(myname, SSTR_SIZE-1);
X	/*
X	 * parse arguments
X	 */
X	i = 1;
X	while (i < argc && *argv[i] == '-') {
X		if (equal(argv[i]+1, "db")) {
X			/* db - set debug level */
X			debug++;
X			i++;
X			fprintf(stderr, "%s: debug option enabled\n", self);
X		}
X		else if (equal(argv[i]+1, "d")) {
X			/* d - dailies of default dump level */
X			daily++;
X			i++;
X		}
X		else if (equal(argv[i]+1, "w")) {
X			/* w- weeklies of default dump level */
X			weekly++;
X			i++;
X		}
X		else if (equal(argv[i]+1, "dl")) {
X			/* dl - read daily dump level from next argument */
X			i++;
X			if ((dlevel = atoi(argv[i])) > 9) {
X				fprintf(stderr, "%s: invalid daily dump level (%d)\n", self, dlevel);
X				exit(1);
X			}
X			i++;
X		}
X		else if (equal(argv[i]+1, "wl")) {
X			/* wl - read weekly dump level from next argument */
X			i++;
X			if ((wlevel = atoi(argv[i])) > 9) {
X				fprintf(stderr, "%s: invalid weekly dump level (%d)\n", self, wlevel);
X				exit(1);
X			}
X			i++;
X		}
X		else if (equal(argv[i]+1, "l")) {
X			/* l - suppress listings of files */
X			dlist = 0;
X			i++;
X		}
X		else if (equal(argv[i]+1, "e")) {
X			/* e - run listing code only */
X			printf("Listings only - nothing will be written to tape\n");
X			elist++;
X			i++;
X		}
X		else if (equal(argv[i]+1, "t")) {
X			/* t - read new dump day-of-week from next argument */
X			i++;
X			(void) strncpy(newday, argv[i], 3);
X			i++;
X		}
X		else if (equal(argv[i]+1, "f"))
X		{
X			/*
X			 * f - read backup device from next argument
X			 * turn /dev/rmt names into /dev/nrmt
X			 */
X			char	temp[40], *p1, *p2;
X
X			i++;
X			p2 = (char *) NULL;
X			if ((p1 = index(argv[i], ':')) != 0) {
X				(void) strncpy(rhost, argv[i], p1-argv[i]+1);
X				*(index(rhost, ':')) = '\0';
X				p1++;
X			}
X			if (p1 == 0)
X				p1 = argv[i];
X			device = malloc((unsigned) (strlen(p1) + 1));
X			(void) strcpy(device, p1);
X			if ((p2 = rindex(argv[i], '/')) == 0) {
X				fprintf(stderr, "%s: Output device must be a tape drive, e.g., /dev/rmt1, uxc:/dev/rmt2\n", self);
X				exit(1);
X			}
X			p2++;
X			(void) strncpy(temp, p1, p2-p1);
X			*(temp + (p2-p1)) = '\0';
X			nrdevice = malloc((unsigned) (strlen(argv[i])+2));
X			if (*p2 == 'n')
X				(void) sprintf(nrdevice, "%s%s", temp, p2);
X			else
X				(void) sprintf(nrdevice, "%sn%s", temp, p2);
X			if (debug)
X				fprintf(stderr, "rhost %s, device %s, nrdevice %s\n", rhost, device, nrdevice);
X			i++;
X		}
X		else
X		{
X			/* command line errors */
X			fprintf(stderr, "%s: %s - bad flag\n", self, argv[i]+1);
X			fprintf(stderr, "Usage: %s [-d] [-w] [-dl n] [-wl n] [-l] [-e] [-t day] [-f [host:]/dev/rmtx] [-db]\n", self);
X			exit(1);
X		}
X	}
X	if (daily && dlevel < 0)
X		dlevel = DAILY;
X	if (weekly && wlevel < 0)
X		wlevel = WEEKLY;
X	if (wlevel < 0 && dlevel < 0) {
X		fprintf(stderr, "%s: No action specified.\n", self);
X		fprintf(stderr, "Invoke %s with at least one of the following: -d, -w, -dl n, -wl n\n", self);
X		exit(1);
X	}
X	clock = time((time_t *) 0);
X	if (*newday)
X		tm = setday(newday);
X	else
X		tm = localtime(&clock);
X	mtio(rhost, device, "rew");
X	wrt_dtinfo(rhost, nrdevice);
X	setdtent();
X	for (i = 1; (dt = getdtpos(i)); i++) {
X		if (dt->dt_weekly == tm->tm_wday) {
X			if (wlevel > -1) {
X				if (wrt_dmp(rhost, nrdevice, dt, wlevel))
X					break;
X			}
X			else
X				wrt_dummy(rhost, nrdevice, dt);
X		}
X		else {
X			if (dlevel > -1) {
X				if (wrt_dmp(rhost, nrdevice, dt, dlevel))
X					break;
X			}
X			else
X				wrt_dummy(rhost, nrdevice, dt);
X		}
X	}
X	/* write the last EOF to form EOT and rewind the tape
X	 * by using the rewind-on-close device.
X	 */
X	if (! elist) {
X		printf("Really rewinding tape\n");
X		mtio(rhost, device, "eof");
X	}
X	if (dlist) {
X		char	command[LSTR_SIZE];
X
X		(void) mktemp(list_file);
X		mtio(rhost, device, "rew");
X
X		/* skip over the zero'th file of /etc/dumptab */
X		mtio(rhost, nrdevice, "fsf");
X		setdtent();
X		for (i = 1; (dt = getdtpos(i)); i++)
X			if (list_tape(rhost, nrdevice, dt, list_file))
X				break;
X		/* EDIT THIS for preferred print command */
X		(void) sprintf(command, 
X#ifdef vax
X			"ibmprint -f -h \"%s Dlist\" %s",   /* uiucuxc */
X#else
X			"lpr -r -s -J %s_Dlist %s",	/* osiris */
X#endif
X			myname, list_file);
X		if (debug)
X			fprintf(stderr, "print command: %s\n", command);
X		if (i = (system(command) >> 8))
X			fprintf(stderr, "%s: %s exitted abnormally (%d).\n", self, command, i);
X		printf("Last rewind of tape\n");
X		mtio(rhost, device, "rew");
X	}
X	exit(0);
X}
X
X/*
X * mtio -- perform a local/remote tape operation
X *
X *	for local tapes (host[0] == '\0') use the ioctl calls.
X *	remote tapes use an rsh command.
X *
X *	parameters:
X *		host (IN) -- name of remote host, if host[0] != '\0'
X *		dev (IN) -- tape drive name
X *		cp (IN) -- tape opcode
X *	returns:
X *		none
X *	side effects:
X *		none
X *	deficiencies:
X *		any error causes an error exit from the program
X */
Xmtio(host, dev, cp)
Xchar	*host, *dev, *cp;
X{
X	struct mt_cmds	*comp;
X
X	/* tape file descriptor */
X	int		mtfd;
X
X	/* return code from system() call */
X	int		status;
X
X	/* from sys/mtio.h */
X	struct mtop	mt_com;
X
X	/* buffer for rsh command */
X	char		command[LSTR_SIZE];
X
X	if (*host == '\0') {
X		for (comp = com; comp->c_name != NULL; comp++)
X			if (strncmp(cp, comp->c_name, strlen(cp)) == 0)
X				break;
X		if (comp->c_name == NULL) {
X			fprintf(stderr, "%s: mtio: don't grok \"%s\"\n", self, cp);
X			exit(1);
X		}
X		if ((mtfd = open(dev, comp->c_ronly ? 0 : 2)) < 0) {
X			fprintf(stderr, "%s: mtio: open of ", self);
X			perror(dev);
X			exit(1);
X		}
X		mt_com.mt_op = comp->c_code;
X		mt_com.mt_count = 1;
X		if (ioctl(mtfd, MTIOCTOP, &mt_com) < 0) {
X			fprintf(stderr, "%s: mtio: %s %s %d ", self, dev,
X				comp->c_name, mt_com.mt_count);
X			perror("failed");
X			exit(1);
X		}
X		(void) close(mtfd);
X	}
X	else {
X		(void) sprintf(command, "rsh %s mt -t %s %s", host, dev, cp);
X		if (debug)
X			fprintf(stderr, "tape command %s\n", command);
X		if (status = (system(command) >> 8)) {
X			fprintf(stderr, "%s: %s exitted abnormally (%d).  Restart %s\n", self, command, status, self);
X			exit(1);
X		}
X	}
X}
X
X/*
X * wrt_dmp -- write a filesystem dump on the dump tape
X *
X *	for local tapes (host[0] == '\0') use dump
X *	remote tapes use rdump
X *
X *	parameters:
X *		host (IN) -- name of remote host if host[0] != '\0'
X *		dev (IN) -- tape drive name
X *		dt (IN) -- dumptab pointer
X *		level (IN) -- dump level (0-9)
X *	returns:
X *		0 if dump command successful, 1 if not
X *	side effects:
X *		alters dump_state table
X *	deficiencies:
X *		any error causes an error exit from the program
X */
Xwrt_dmp(host, dev, dt, level)
Xchar		*host, *dev;
Xint		level;
Xstruct dumptab	*dt;
X{
X	char	command[LSTR_SIZE];
X	int	status;
X
X	if (elist) {
X		dump_state[dt->dt_position] = 1;
X		return(0);
X	}
X	/* EDIT THIS for preferred dump command */
X	(void) sprintf(command, " dump nuf%d %s%c%s %s",
X			level, host, (*host ? ':' : ' '), dev, dt->dt_name);
X	if (*host)
X		command[0] = 'r';
X	if (debug)
X		fprintf(stderr, "dump command %s\n", command);
X	printf("Dumping %s\n", dt->dt_name);
X
X	/* dump(8) exits with 1 if all is well */
X	if ((status = (system(command) >> 8)) != 1) {
X		fprintf(stderr, "%s: %s exitted abnormally (%d).\n", self, command, status);
X		fprintf(stderr, "\tTape will rewind and create listings of the successful dumps.\n");
X		dump_state[dt->dt_position] = -1;
X		mtio(host, dev, "bsf");
X		return(1);
X	}
X	dump_state[dt->dt_position] = 1;
X	return(0);
X}
X
X/*
X * list_tape -- generate a "restore tf" listing for the current tape file
X *
X *	list_tape creates a command line to be executed by system() and
X *	re-directs the output to a listing file.
X *
X *	parameters:
X *		host (IN) -- name of remote host if host[0] != '\0'
X *		dev (IN) -- tape drive name
X *		dt (IN) -- dumptab pointer
X *		lfile (IN) -- name of listing file
X *	returns:
X *		0 for normal results, 1 if at end of tape
X *	side effects:
X *		none
X *	deficiencies:
X *		any error causes an error exit from the program
X */
Xlist_tape(host, dev, dt, lfile)
Xchar		*host, *dev, *lfile;
Xstruct dumptab	*dt;
X{
X	FILE		*fp;
X	int		status;
X	char		command[LSTR_SIZE];
X
X	if (dump_state[dt->dt_position] == 0) {
X		/* no file here so write a message on the dump listing */
X		if ((fp = fopen(lfile, "a")) == NULL) {
X			fprintf(stderr, "%s: list_tape ", self);
X			perror(lfile);
X			exit(1);
X		}
X		fprintf(fp, "\n\n\tNo dump file for %s on this tape.\n\f",
X			dt->dt_name);
X		(void) fclose(fp);
X		/* advance the tape by one tape mark */
X		printf("Skipping dummy file for %s\n", dt->dt_name);
X		mtio(host, dev, "fsf");
X		return(0);
X	}
X	else if (dump_state[dt->dt_position] == 1) {
X		/* build the appropriate restore tf command and execute it */
X		/* EDIT THIS for preferred listing command */
X		(void) sprintf(command, " restore tf %s%c%s | sort +1 | pr -2 -w132 -f -h \"%s Dump Listing of %s\" >> %s",
X			host, (*host ? ':' : ' '), dev, myname, dt->dt_name, lfile);
X		if (*host)
X			command[0] = 'r';
X		if (debug)
X			fprintf(stderr, "list command %s\n", command);
X		printf("Listing %s\n", dt->dt_name);
X		if (status = (system(command) >> 8)) {
X			char	c,d;
X
X			fprintf(stderr, "%s: %s exitted abnormally (%d).  Continue? [yn] ", self, command, status);
X			while ((d = getc(stdin)) != '\n')
X				c = d;
X			if (c != 'y')
X				exit(1);
X		}
X		/* advance the tape to end of file */
X		mtio(host, dev, "fsf");
X		return(0);
X	}
X	return(1);
X}
X
X/*
X * wrt_dtinfo -- write /etc/dumptab onto the tape
X *
X *	writing a copy of /etc/dumptab onto the tape as file #0 provides
X *	a catalogue of the tape files and insulates backup volumes from
X *	changes in /etc/dumptab.  Elsewhere on the tape it acts as a 
X *	place holder for a non-selected dump, e.g., daily on a weekly-only
X *	tape.
X *
X *	parameters:
X *		host (IN) -- name of remote host
X *		dev (IN) -- tape drive name
X *	returns:
X *		none
X *	side effects:
X *		none
X *	deficiencies:
X *		any error causes an error exit from the program
X */
Xwrt_dtinfo(host, dev)
Xchar	*host, *dev;
X{
X	char	command[LSTR_SIZE];
X	int	status;
X
X	if (elist)
X		return;
X	if (*host)
X		/* EDIT THIS for preferred method */
X		(void) sprintf(command, "rcp %s %s:/tmp/xyzzy.mdump; rsh %s \"dd if=/tmp/xyzzy.mdump of=%s bs=512; rm /tmp/xyzzy.mdump\"",
X			DUMPTAB, host, host, dev);
X	else
X		(void) sprintf(command, "dd if=%s of=%s bs=512",
X			DUMPTAB, dev);
X	printf("Copying %s to tape\n", DUMPTAB);
X	if (status = (system(command) >> 8)) {
X		fprintf(stderr, "%s: %s exitted abnormally (%d).  Restart %s\n", self, command, status, self);
X		exit(1);
X	}
X}
X
X/*
X * wrt_dummy -- write a dummy file onto the tape
X *
X *	write a dummy file onto the tape to take the place of a non-
X *	scheduled backup.  this preserves tape order.
X *
X *	parameters:
X *		host (IN) -- name of remote host
X *		dev (IN) -- tape drive name
X *		dt (IN) -- dumptab pointer
X *	returns:
X *		none
X *	side effects:
X *		alters dump_state table
X *	deficiencies:
X *		any error causes an error exit from the program
X */
Xwrt_dummy(host, dev, dt)
Xchar		*host, *dev;
Xstruct dumptab	*dt;
X{
X	char	command[LSTR_SIZE];
X	int	status;
X
X	if (elist)
X		return;
X	if (*host)
X		/* EDIT THIS for preferred method */
X		(void) sprintf(command, "rcp %s %s:/tmp/xyzzy.mdump; rsh %s \"dd if=/tmp/xyzzy.mdump of=%s bs=512; rm /tmp/xyzzy.mdump\"",
X			DUMPTAB, host, host, dev);
X	else
X		(void) sprintf(command, "dd if=%s of=%s bs=512",
X			DUMPTAB, dev);
X	printf("Writing place holder file for %s to tape\n", dt->dt_name);
X	if (status = (system(command) >> 8)) {
X		fprintf(stderr, "%s: %s exitted abnormally (%d).  Restart %s\n", self, command, status, self);
X		exit(1);
X	}
X}
X
X/*
X * setday -- set tm.tm_wday to value consistent with argument
X *
X *	tm.tm_wday has a legal range of 0 (for Sunday) to 6 (for Saturday).
X *	day is a three character string ("sun", "mon", etc) used to determine
X *	the value of tm.tm_wday.
X *
X *	parameters:
X *		day (IN/OUT) -- day of week string
X *	returns:
X *		pointer to static tm struct
X *	side effects:
X *		changes day string to all lower case
X *	deficiencies:
X *		any error causes an error exit from the program
X */
Xstruct tm *
Xsetday(day)
Xchar	*day;
X{
X	static struct tm	mtm;
X	char			*p;
X
X	for (p = day; *p; p++)
X		if (isupper(*p))
X			*p += ('a' - 'A');
X	if (equal(day, "sun"))
X		mtm.tm_wday = 0;
X	else if (equal(day, "mon"))
X		mtm.tm_wday = 1;
X	else if (equal(day, "tue"))
X		mtm.tm_wday = 2;
X	else if (equal(day, "wed"))
X		mtm.tm_wday = 3;
X	else if (equal(day, "thu"))
X		mtm.tm_wday = 4;
X	else if (equal(day, "fri"))
X		mtm.tm_wday = 5;
X	else if (equal(day, "sat"))
X		mtm.tm_wday = 6;
X	else {
X		fprintf(stderr, "%s: setday: illegal day of week (%s)\n", self, day);
X		fprintf(stderr, "\tLegal values are sun, mon, tue, etc.\n");
X		exit(1);
X	}
X	return(&mtm);
X}
SHAR_EOF
sed 's/^X//' << 'SHAR_EOF' > mdump.8
X.TH MDUMP 8 "UofI CSO"
X.SH NAME
Xmdump \- multiple dump per tape utility
X.SH SYNOPSIS
X.B mdump
X[
X.B \-d
X] [
X.B \-w
X] [
X\fB\-wl \fIn\fR
X] [
X\fB\-dl \fIn\fR
X] [
X.B \-l
X] [
X.B \-e
X] [
X\fB\-t \fIday-of-week\fR
X] [
X\fB\-f \fI[host:]/dev/rmtx\fR
X]
X.SH DESCRIPTION
X.I Mdump
Xsimplifies the backup procedure for systems with multiple filesystems
Xby putting all daily and/or weekly backups onto a single tape.
X.PP
XThe order and selection of filesystems to be dumped is determined by
X.I /etc/dumptab 
Xand by the options
X.BR \-d ,
X.BR \-w ,
X\fB\-dl \fIn\fR and
X\fB\-wl \fIn\fR.
X.B \-d
Xselects daily backups to be done at the default daily dump level of 5;
X.B \-w
Xselects weekly backups with a default dump level of 4.
XThe
X.B \-wl
Xand
X.B \-dl
Xswitches respectively take the weekly and daily dump level from the following
Xargument
X.IR n .
XSpecifying both of (
X.B \-d
Xand
X.B \-w
X) or (
X.B \-dl
Xand
X.B \-wl
X)
Xcauses daily and weekly backups to be selected.
XA dummy file is inserted on the tape for non-selected filesystems
Xto preserve file ordering.
X.PP
XThe
X.IR st (8)
Xcommand (set tape) will position the backup tape to the correct tape
Xfile for restores.
X.PP
XThe backup device is selected with the
X.B \-f
Xoption.
XRemote backup over the network is accomplished by specifying the device
Xname in the same manner as
X.IR rdump (8),
Xe.g., uiucuxc:/dev/rmt0.
X.PP
XAfter
X.I mdump
Xhas finished writing the dump files,
Xa listing of each dump will be created and sent to the \s-1IBM\s0 printers
Xunless the
X.B \-l
Xoption is given to suppress the listings.
X.PP
XIn the case of positioning errors during the listing phase of
X.IR mdump ,
Xhanging rsh commands are the usual cause,
X.B \-e
Xwill execute the listing phase of
X.I mdump
Xonly.
XAt least one of the flags
X.B \-d
Xand/or
X.B \-w
Xmust be specified in addition to the
X.B \-e
Xflag.
X.PP
XTo run
X.I mdump
Xas though it were a different day of the week, e.g.,
Xcreate or list a Monday tape on Wednesday, the 
X\fB\-t \fIday-of-week\fR
Xflag is supplied where
X.I day-of-week
Xis one of mon, tue, wed, etc.
X.SH NOTES
XIn the case where
X.I mdump
Xfound no files to dump,
Xthe subsequent listing phase will complain that
Xit "Cannot find file dump list".
X.I Mdump
Xwill print a message saying that the list command exitted abnormally
Xand ask whether to continue.
XEntering 'y' directs
X.I mdump
Xto continue listing the other filesystems.
XAny other response causes an exit.
X.SH FILES
X/etc/dumptab, /etc/dump
X.SH "SEE ALSO"
Xdumptab(5), dump(8), rdump(8), st(8)
X.SH BUGS
XNo provision is made for tape overflow.
XThis is an incentive to use 6250 bpi drives.
X.PP
XAny tape error means restarting
X.I mdump
Xfrom the beginning.
SHAR_EOF
exit 0



More information about the Mod.sources mailing list