17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
227c478bd9Sstevel@tonic-gate /*
237c478bd9Sstevel@tonic-gate  * Copyright (c) 1991,1996,1998 by Sun Microsystems, Inc.
247c478bd9Sstevel@tonic-gate  * All rights reserved.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate #include "dump.h"
287c478bd9Sstevel@tonic-gate #include <math.h>
297c478bd9Sstevel@tonic-gate #include <limits.h>
307c478bd9Sstevel@tonic-gate 
317c478bd9Sstevel@tonic-gate /*
327c478bd9Sstevel@tonic-gate  * Uncomment if using mmap'ing of files for pre-fetch.
337c478bd9Sstevel@tonic-gate  * #define ENABLE_MMAP 1
347c478bd9Sstevel@tonic-gate  */
357c478bd9Sstevel@tonic-gate 
367c478bd9Sstevel@tonic-gate struct inodesc {
377c478bd9Sstevel@tonic-gate 	ino_t	id_inumber;		/* inode number */
387c478bd9Sstevel@tonic-gate 	long	id_gen;			/* generation number */
397c478bd9Sstevel@tonic-gate 	struct inodesc *id_next;	/* next on linked list */
407c478bd9Sstevel@tonic-gate };
417c478bd9Sstevel@tonic-gate 
42*e0dfa398SToomas Soome char	*archivefile;
43*e0dfa398SToomas Soome char	*tape;
44*e0dfa398SToomas Soome 
45*e0dfa398SToomas Soome int	active;
46*e0dfa398SToomas Soome int	doingactive;
47*e0dfa398SToomas Soome int	doposition;
48*e0dfa398SToomas Soome int	pipeout;
49*e0dfa398SToomas Soome int	tapeout;
50*e0dfa398SToomas Soome int	to;
51*e0dfa398SToomas Soome 
52*e0dfa398SToomas Soome struct fs	*sblock;
53*e0dfa398SToomas Soome union u_spcl	u_spcl;
54*e0dfa398SToomas Soome 
557c478bd9Sstevel@tonic-gate static struct inodesc	ilist;		/* list of used inodesc structs */
567c478bd9Sstevel@tonic-gate static struct inodesc	*last;		/* last inodesc init'd or matched */
577c478bd9Sstevel@tonic-gate static struct inodesc	*freeinodesc;	/* free list of inodesc structs */
587c478bd9Sstevel@tonic-gate static struct inodesc	**ialloc;	/* allocated chunks, for freeing */
597c478bd9Sstevel@tonic-gate static int		nchunks;	/* number of allocations */
607c478bd9Sstevel@tonic-gate 
617c478bd9Sstevel@tonic-gate #ifdef ENABLE_MMAP /* XXX part of mmap support */
627c478bd9Sstevel@tonic-gate /*
637c478bd9Sstevel@tonic-gate  * If an mmap'ed file is truncated as it is being dumped or
647c478bd9Sstevel@tonic-gate  * faulted in, we are delivered a SIGBUS.
657c478bd9Sstevel@tonic-gate  */
667c478bd9Sstevel@tonic-gate static jmp_buf	truncate_buf;
677c478bd9Sstevel@tonic-gate static void	(*savebus)();
687c478bd9Sstevel@tonic-gate static int	incopy;
697c478bd9Sstevel@tonic-gate 
707c478bd9Sstevel@tonic-gate static void onsigbus(int);
717c478bd9Sstevel@tonic-gate 
727c478bd9Sstevel@tonic-gate #endif	/* ENABLE_MMAP */
737c478bd9Sstevel@tonic-gate 
747c478bd9Sstevel@tonic-gate #ifdef DEBUG
757c478bd9Sstevel@tonic-gate extern int xflag;
767c478bd9Sstevel@tonic-gate #endif
777c478bd9Sstevel@tonic-gate 
787c478bd9Sstevel@tonic-gate #ifdef ENABLE_MMAP /* XXX part of mmap support */
797c478bd9Sstevel@tonic-gate static void
onsigbus(int sig)80*e0dfa398SToomas Soome onsigbus(int sig)
817c478bd9Sstevel@tonic-gate {
827c478bd9Sstevel@tonic-gate 	if (!incopy) {
837c478bd9Sstevel@tonic-gate 		dumpabort();
847c478bd9Sstevel@tonic-gate 		/*NOTREACHED*/
857c478bd9Sstevel@tonic-gate 	}
867c478bd9Sstevel@tonic-gate 	incopy = 0;
877c478bd9Sstevel@tonic-gate 	longjmp(truncate_buf, 1);
887c478bd9Sstevel@tonic-gate 	/*NOTREACHED*/
897c478bd9Sstevel@tonic-gate }
907c478bd9Sstevel@tonic-gate #endif	/* ENABLE_MMAP */
917c478bd9Sstevel@tonic-gate 
927c478bd9Sstevel@tonic-gate void
allocino(void)937c478bd9Sstevel@tonic-gate allocino(void)
947c478bd9Sstevel@tonic-gate {
957c478bd9Sstevel@tonic-gate 	ino_t maxino;
967c478bd9Sstevel@tonic-gate 	size_t nused;
977c478bd9Sstevel@tonic-gate 
987c478bd9Sstevel@tonic-gate 	maxino = (unsigned)(sblock->fs_ipg * sblock->fs_ncg);
997c478bd9Sstevel@tonic-gate 	if (maxino > ULONG_MAX) {
1007c478bd9Sstevel@tonic-gate 		msg(gettext("allocino: filesystem too large\n"));
1017c478bd9Sstevel@tonic-gate 		dumpabort();
1027c478bd9Sstevel@tonic-gate 		/*NOTREACHED*/
1037c478bd9Sstevel@tonic-gate 	}
1047c478bd9Sstevel@tonic-gate 	/* LINTED maxino guaranteed to fit into a size_t by above test */
1057c478bd9Sstevel@tonic-gate 	nused =  maxino - sblock->fs_cstotal.cs_nifree;
1067c478bd9Sstevel@tonic-gate 	freeinodesc = (struct inodesc *)xcalloc(nused, sizeof (*freeinodesc));
1077c478bd9Sstevel@tonic-gate 	if (freeinodesc == (struct inodesc *)0) {
1087c478bd9Sstevel@tonic-gate 		msg(gettext("%s: out of memory\n"), "allocino");
1097c478bd9Sstevel@tonic-gate 		dumpabort();
1107c478bd9Sstevel@tonic-gate 		/*NOTREACHED*/
1117c478bd9Sstevel@tonic-gate 	}
1127c478bd9Sstevel@tonic-gate 	last = &ilist;
1137c478bd9Sstevel@tonic-gate 	ialloc =
1147c478bd9Sstevel@tonic-gate 	    (struct inodesc **)xmalloc(2*sizeof (*ialloc));
1157c478bd9Sstevel@tonic-gate 	ialloc[0] = freeinodesc;
1167c478bd9Sstevel@tonic-gate 	ialloc[1] = (struct inodesc *)0;
1177c478bd9Sstevel@tonic-gate 	nchunks = 1;
1187c478bd9Sstevel@tonic-gate }
1197c478bd9Sstevel@tonic-gate 
1207c478bd9Sstevel@tonic-gate void
freeino(void)1217c478bd9Sstevel@tonic-gate freeino(void)
1227c478bd9Sstevel@tonic-gate {
1237c478bd9Sstevel@tonic-gate 	int i;
1247c478bd9Sstevel@tonic-gate 
1257c478bd9Sstevel@tonic-gate 	if (ialloc == (struct inodesc **)0)
1267c478bd9Sstevel@tonic-gate 		return;
1277c478bd9Sstevel@tonic-gate 	for (i = 0; i < nchunks; i++)
1287c478bd9Sstevel@tonic-gate 		if (ialloc[i] != 0)
1297c478bd9Sstevel@tonic-gate 			free(ialloc[i]);
1307c478bd9Sstevel@tonic-gate 	free(ialloc);
1317c478bd9Sstevel@tonic-gate 	ialloc = (struct inodesc **)0;
1327c478bd9Sstevel@tonic-gate }
1337c478bd9Sstevel@tonic-gate 
1347c478bd9Sstevel@tonic-gate void
resetino(ino_t ino)135*e0dfa398SToomas Soome resetino(ino_t ino)
1367c478bd9Sstevel@tonic-gate {
1377c478bd9Sstevel@tonic-gate 	last = ilist.id_next;
1387c478bd9Sstevel@tonic-gate 	while (last && last->id_inumber < ino)
1397c478bd9Sstevel@tonic-gate 		last = last->id_next;
1407c478bd9Sstevel@tonic-gate }
1417c478bd9Sstevel@tonic-gate 
1427c478bd9Sstevel@tonic-gate char *
unrawname(char * cp)143*e0dfa398SToomas Soome unrawname(char *cp)
1447c478bd9Sstevel@tonic-gate {
1457c478bd9Sstevel@tonic-gate 	char *dp;
1467c478bd9Sstevel@tonic-gate 	extern char *getfullblkname();
1477c478bd9Sstevel@tonic-gate 
1487c478bd9Sstevel@tonic-gate 	dp = getfullblkname(cp);
1497c478bd9Sstevel@tonic-gate 	if (dp == 0)
1507c478bd9Sstevel@tonic-gate 		return (0);
1517c478bd9Sstevel@tonic-gate 	if (*dp == '\0') {
1527c478bd9Sstevel@tonic-gate 		free(dp);
1537c478bd9Sstevel@tonic-gate 		return (0);
1547c478bd9Sstevel@tonic-gate 	}
1557c478bd9Sstevel@tonic-gate 	if (dp == cp)		/* caller wants to always free() dp */
1567c478bd9Sstevel@tonic-gate 		dp = strdup(cp);
1577c478bd9Sstevel@tonic-gate 
1587c478bd9Sstevel@tonic-gate 	return (dp);
1597c478bd9Sstevel@tonic-gate }
1607c478bd9Sstevel@tonic-gate 
1617c478bd9Sstevel@tonic-gate /*
1627c478bd9Sstevel@tonic-gate  * Determine if specified device is mounted at
1637c478bd9Sstevel@tonic-gate  * specified mount point.  Returns 1 if mounted,
1647c478bd9Sstevel@tonic-gate  * 0 if not mounted, -1 on error.
1657c478bd9Sstevel@tonic-gate  */
1667c478bd9Sstevel@tonic-gate int
lf_ismounted(char * devname,char * dirname)167*e0dfa398SToomas Soome lf_ismounted(char *devname, char *dirname)
1687c478bd9Sstevel@tonic-gate {
1697c478bd9Sstevel@tonic-gate 	struct stat64 st;
1707c478bd9Sstevel@tonic-gate 	char	*blockname;	/* name of block device */
1717c478bd9Sstevel@tonic-gate 	dev_t	dev;
1727c478bd9Sstevel@tonic-gate 	int	saverr;
1737c478bd9Sstevel@tonic-gate 
1747c478bd9Sstevel@tonic-gate 	if ((blockname = unrawname(devname)) == NULL) {
1757c478bd9Sstevel@tonic-gate 		msg(gettext("Cannot obtain block name from `%s'\n"), devname);
1767c478bd9Sstevel@tonic-gate 		return (-1);
1777c478bd9Sstevel@tonic-gate 	}
1787c478bd9Sstevel@tonic-gate 	if (stat64(blockname, &st) < 0) {
1797c478bd9Sstevel@tonic-gate 		saverr = errno;
1807c478bd9Sstevel@tonic-gate 		msg(gettext("Cannot obtain status of device `%s': %s\n"),
1817c478bd9Sstevel@tonic-gate 		    blockname, strerror(saverr));
1827c478bd9Sstevel@tonic-gate 		free(blockname);
1837c478bd9Sstevel@tonic-gate 		return (-1);
1847c478bd9Sstevel@tonic-gate 	}
1857c478bd9Sstevel@tonic-gate 	free(blockname);
1867c478bd9Sstevel@tonic-gate 	dev = st.st_rdev;
1877c478bd9Sstevel@tonic-gate 	if (stat64(dirname, &st) < 0) {
1887c478bd9Sstevel@tonic-gate 		saverr = errno;
1897c478bd9Sstevel@tonic-gate 		msg(gettext("Cannot obtain status of device `%s': %s\n"),
1907c478bd9Sstevel@tonic-gate 		    dirname, strerror(saverr));
1917c478bd9Sstevel@tonic-gate 		return (-1);
1927c478bd9Sstevel@tonic-gate 	}
1937c478bd9Sstevel@tonic-gate 	if (dev == st.st_dev)
1947c478bd9Sstevel@tonic-gate 		return (1);
1957c478bd9Sstevel@tonic-gate 	return (0);
1967c478bd9Sstevel@tonic-gate }
1977c478bd9Sstevel@tonic-gate 
1987c478bd9Sstevel@tonic-gate #ifdef ENABLE_MMAP /* XXX mapped-file support */
1997c478bd9Sstevel@tonic-gate #define	MINMAPSIZE	1024*1024
2007c478bd9Sstevel@tonic-gate #define	MAXMAPSIZE	1024*1024*32
2017c478bd9Sstevel@tonic-gate 
2027c478bd9Sstevel@tonic-gate static caddr_t	mapbase;	/* base of mapped data */
2037c478bd9Sstevel@tonic-gate static caddr_t	mapend;		/* last byte of mapped data */
2047c478bd9Sstevel@tonic-gate static size_t	mapsize;	/* amount of mapped data */
2057c478bd9Sstevel@tonic-gate /*
2067c478bd9Sstevel@tonic-gate  * Map a file prior to dumping and start faulting in its
2077c478bd9Sstevel@tonic-gate  * pages.  Stop if we catch a signal indicating our turn
2087c478bd9Sstevel@tonic-gate  * to dump has arrived.  If the file is truncated out from
2097c478bd9Sstevel@tonic-gate  * under us, immediately return.
2107c478bd9Sstevel@tonic-gate  * NB:  the base of the mapped data may not coincide
2117c478bd9Sstevel@tonic-gate  * exactly to the requested offset, due to alignment
2127c478bd9Sstevel@tonic-gate  * constraints.
2137c478bd9Sstevel@tonic-gate  */
2147c478bd9Sstevel@tonic-gate caddr_t
mapfile(int fd,off_t offset,off_t bytes,int fetch)215*e0dfa398SToomas Soome mapfile(int fd, off_t offset, off_t bytes, int fetch)
2167c478bd9Sstevel@tonic-gate {
2177c478bd9Sstevel@tonic-gate 	/*LINTED [c used during pre-fetch faulting]*/
2187c478bd9Sstevel@tonic-gate 	volatile char c, *p;
2197c478bd9Sstevel@tonic-gate 	int stride = (int)sysconf(_SC_PAGESIZE);
2207c478bd9Sstevel@tonic-gate 	extern int caught;		/* pre-fetch until set */
2217c478bd9Sstevel@tonic-gate 	caddr_t	mapstart;		/* beginning of file's mapped data */
2227c478bd9Sstevel@tonic-gate 	off_t	mapoffset;		/* page-aligned offset */
2237c478bd9Sstevel@tonic-gate 	int	saverr;
2247c478bd9Sstevel@tonic-gate 
2257c478bd9Sstevel@tonic-gate 	mapbase = mapend = (caddr_t)0;
2267c478bd9Sstevel@tonic-gate 
2277c478bd9Sstevel@tonic-gate 	if (bytes == 0)
2287c478bd9Sstevel@tonic-gate 		return ((caddr_t)0);
2297c478bd9Sstevel@tonic-gate 	/*
2307c478bd9Sstevel@tonic-gate 	 * mmap the file for reading
2317c478bd9Sstevel@tonic-gate 	 */
2327c478bd9Sstevel@tonic-gate 	mapoffset = offset & ~(stride - 1);
2337c478bd9Sstevel@tonic-gate 	/* LINTED: "bytes" will always fit into a size_t */
2347c478bd9Sstevel@tonic-gate 	mapsize = bytes + (offset - mapoffset);
2357c478bd9Sstevel@tonic-gate 	if (mapsize > MAXMAPSIZE)
2367c478bd9Sstevel@tonic-gate 		mapsize = MAXMAPSIZE;
2377c478bd9Sstevel@tonic-gate 	while ((mapbase = mmap((caddr_t)0, mapsize, PROT_READ,
2387c478bd9Sstevel@tonic-gate 	    MAP_SHARED, fd, mapoffset)) == (caddr_t)-1 &&
2397c478bd9Sstevel@tonic-gate 	    errno == ENOMEM && mapsize >= MINMAPSIZE) {
2407c478bd9Sstevel@tonic-gate 		/*
2417c478bd9Sstevel@tonic-gate 		 * Due to address space limitations, we
2427c478bd9Sstevel@tonic-gate 		 * may not be able to map as much as we want.
2437c478bd9Sstevel@tonic-gate 		 */
2447c478bd9Sstevel@tonic-gate 		mapsize /= 2;	/* exponential back-off */
2457c478bd9Sstevel@tonic-gate 	}
2467c478bd9Sstevel@tonic-gate 
2477c478bd9Sstevel@tonic-gate 	if (mapbase == (caddr_t)-1) {
2487c478bd9Sstevel@tonic-gate 		saverr = errno;
2497c478bd9Sstevel@tonic-gate 		msg(gettext("Cannot map file at inode `%lu' into memory: %s\n"),
250*e0dfa398SToomas Soome 		    ino, strerror(saverr));
2517c478bd9Sstevel@tonic-gate 		/* XXX why not call dumpailing() here? */
2527c478bd9Sstevel@tonic-gate 		if (!query(gettext(
2537c478bd9Sstevel@tonic-gate 	    "Do you want to attempt to continue? (\"yes\" or \"no\") "))) {
2547c478bd9Sstevel@tonic-gate 			dumpabort();
2557c478bd9Sstevel@tonic-gate 			/*NOTREACHED*/
2567c478bd9Sstevel@tonic-gate 		}
2577c478bd9Sstevel@tonic-gate 		mapbase = (caddr_t)0;
2587c478bd9Sstevel@tonic-gate 		return ((caddr_t)0);
2597c478bd9Sstevel@tonic-gate 	}
2607c478bd9Sstevel@tonic-gate 
2617c478bd9Sstevel@tonic-gate 	(void) madvise(mapbase, mapsize, MADV_SEQUENTIAL);
2627c478bd9Sstevel@tonic-gate 	mapstart = mapbase + (offset - mapoffset);
2637c478bd9Sstevel@tonic-gate 	mapend = mapbase + (mapsize - 1);
2647c478bd9Sstevel@tonic-gate 
2657c478bd9Sstevel@tonic-gate 	if (!fetch)
2667c478bd9Sstevel@tonic-gate 		return (mapstart);
2677c478bd9Sstevel@tonic-gate 
2687c478bd9Sstevel@tonic-gate 	if (setjmp(truncate_buf) == 0) {
2697c478bd9Sstevel@tonic-gate 		savebus = signal(SIGBUS, onsigbus);
2707c478bd9Sstevel@tonic-gate 		/*
2717c478bd9Sstevel@tonic-gate 		 * Touch each page to pre-fetch by faulting.  At least
2727c478bd9Sstevel@tonic-gate 		 * one of c or *p must be declared volatile, lest the
2737c478bd9Sstevel@tonic-gate 		 * optimizer eliminate the assignment in the loop.
2747c478bd9Sstevel@tonic-gate 		 */
2757c478bd9Sstevel@tonic-gate 		incopy = 1;
2767c478bd9Sstevel@tonic-gate 		for (p = mapbase; !caught && p <= mapend; p += stride) {
2777c478bd9Sstevel@tonic-gate 			/* LINTED: c is used for its side-effects */
2787c478bd9Sstevel@tonic-gate 			c = *p;
2797c478bd9Sstevel@tonic-gate 		}
2807c478bd9Sstevel@tonic-gate 		incopy = 0;
2817c478bd9Sstevel@tonic-gate 	}
2827c478bd9Sstevel@tonic-gate #ifdef DEBUG
2837c478bd9Sstevel@tonic-gate 	else
2847c478bd9Sstevel@tonic-gate 		/* XGETTEXT:  #ifdef DEBUG only */
2857c478bd9Sstevel@tonic-gate 		msg(gettext(
286*e0dfa398SToomas Soome 		    "FILE TRUNCATED (fault): Interrupting pre-fetch\n"));
2877c478bd9Sstevel@tonic-gate #endif
2887c478bd9Sstevel@tonic-gate 	(void) signal(SIGBUS, savebus);
2897c478bd9Sstevel@tonic-gate 	return (mapstart);
2907c478bd9Sstevel@tonic-gate }
2917c478bd9Sstevel@tonic-gate 
2927c478bd9Sstevel@tonic-gate void
unmapfile(void)2937c478bd9Sstevel@tonic-gate unmapfile(void)
2947c478bd9Sstevel@tonic-gate {
2957c478bd9Sstevel@tonic-gate 	if (mapbase) {
2967c478bd9Sstevel@tonic-gate 		/* XXX we're unmapping it, so what does this gain us? */
2977c478bd9Sstevel@tonic-gate 		(void) msync(mapbase, mapsize, MS_ASYNC|MS_INVALIDATE);
2987c478bd9Sstevel@tonic-gate 		(void) munmap(mapbase, mapsize);
2997c478bd9Sstevel@tonic-gate 		mapbase = (caddr_t)0;
3007c478bd9Sstevel@tonic-gate 	}
3017c478bd9Sstevel@tonic-gate }
3027c478bd9Sstevel@tonic-gate #endif	/* ENABLE_MMAP */
3037c478bd9Sstevel@tonic-gate 
3047c478bd9Sstevel@tonic-gate void
activepass(void)3057c478bd9Sstevel@tonic-gate activepass(void)
3067c478bd9Sstevel@tonic-gate {
3077c478bd9Sstevel@tonic-gate 	static int passno = 1;			/* active file pass number */
3087c478bd9Sstevel@tonic-gate 	char *ext, *old;
3097c478bd9Sstevel@tonic-gate 	char buf[3000];
3107c478bd9Sstevel@tonic-gate 	static char defext[] = ".retry";
3117c478bd9Sstevel@tonic-gate 
3127c478bd9Sstevel@tonic-gate 	if (pipeout) {
3137c478bd9Sstevel@tonic-gate 		msg(gettext("Cannot re-dump active files to `%s'\n"), tape);
3147c478bd9Sstevel@tonic-gate 		dumpabort();
3157c478bd9Sstevel@tonic-gate 		/*NOTREACHED*/
3167c478bd9Sstevel@tonic-gate 	}
3177c478bd9Sstevel@tonic-gate 
3187c478bd9Sstevel@tonic-gate 	if (active > 1)
3197c478bd9Sstevel@tonic-gate 		(void) snprintf(buf, sizeof (buf), gettext(
3207c478bd9Sstevel@tonic-gate 		    "%d files were active and will be re-dumped\n"), active);
3217c478bd9Sstevel@tonic-gate 	else
3227c478bd9Sstevel@tonic-gate 		(void) snprintf(buf, sizeof (buf), gettext(
3237c478bd9Sstevel@tonic-gate 		    "1 file was active and will be re-dumped\n"));
3247c478bd9Sstevel@tonic-gate 	msg(buf);
3257c478bd9Sstevel@tonic-gate 
3267c478bd9Sstevel@tonic-gate 	doingactive++;
3277c478bd9Sstevel@tonic-gate 	active = 0;
3287c478bd9Sstevel@tonic-gate 	reset();			/* reset tape params */
3297c478bd9Sstevel@tonic-gate 	spcl.c_ddate = spcl.c_date;	/* chain with last dump/pass */
3307c478bd9Sstevel@tonic-gate 
3317c478bd9Sstevel@tonic-gate 	/*
3327c478bd9Sstevel@tonic-gate 	 * If archiving, create a new
3337c478bd9Sstevel@tonic-gate 	 * archive file.
3347c478bd9Sstevel@tonic-gate 	 */
3357c478bd9Sstevel@tonic-gate 	if (archivefile) {
3367c478bd9Sstevel@tonic-gate 		old = archivefile;
3377c478bd9Sstevel@tonic-gate 
3387c478bd9Sstevel@tonic-gate 		ext = strstr(old, defext);
3397c478bd9Sstevel@tonic-gate 		if (ext != (char *)NULL)
3407c478bd9Sstevel@tonic-gate 			*ext = '\0'; /* just want the base name */
3417c478bd9Sstevel@tonic-gate 
3427c478bd9Sstevel@tonic-gate 		/* The two is for the trailing \0 and rounding up log10() */
3437c478bd9Sstevel@tonic-gate 		archivefile = xmalloc(strlen(old) + strlen(defext) +
3447c478bd9Sstevel@tonic-gate 		    (int)log10((double)passno) + 2);
3457c478bd9Sstevel@tonic-gate 
3467c478bd9Sstevel@tonic-gate 		/* Always fits */
3477c478bd9Sstevel@tonic-gate 		(void) sprintf(archivefile, "%s%s%d", old, defext, passno);
3487c478bd9Sstevel@tonic-gate 		free(old);
3497c478bd9Sstevel@tonic-gate 	}
3507c478bd9Sstevel@tonic-gate 
3517c478bd9Sstevel@tonic-gate 	if (tapeout) {
3527c478bd9Sstevel@tonic-gate 		if (isrewind(to)) {
3537c478bd9Sstevel@tonic-gate 			/*
3547c478bd9Sstevel@tonic-gate 			 * A "rewind" tape device.  When we do
3557c478bd9Sstevel@tonic-gate 			 * the close, we will lose our position.
3567c478bd9Sstevel@tonic-gate 			 * Be nice and switch volumes.
3577c478bd9Sstevel@tonic-gate 			 */
3587c478bd9Sstevel@tonic-gate 			(void) snprintf(buf, sizeof (buf), gettext(
359*e0dfa398SToomas Soome 			    "Warning - cannot dump active files to rewind "
360*e0dfa398SToomas Soome 			    "device `%s'\n"), tape);
3617c478bd9Sstevel@tonic-gate 			msg(buf);
3627c478bd9Sstevel@tonic-gate 			close_rewind();
3637c478bd9Sstevel@tonic-gate 			changevol();
3647c478bd9Sstevel@tonic-gate 		} else {
3657c478bd9Sstevel@tonic-gate 			trewind();
3667c478bd9Sstevel@tonic-gate 			doposition = 0;
3677c478bd9Sstevel@tonic-gate 			filenum++;
3687c478bd9Sstevel@tonic-gate 		}
3697c478bd9Sstevel@tonic-gate 	} else {
3707c478bd9Sstevel@tonic-gate 		/*
3717c478bd9Sstevel@tonic-gate 		 * Not a tape.  Do a volume switch.
3727c478bd9Sstevel@tonic-gate 		 * This will advance to the next file
3737c478bd9Sstevel@tonic-gate 		 * if using a sequence of files, next
3747c478bd9Sstevel@tonic-gate 		 * diskette if using diskettes, or
3757c478bd9Sstevel@tonic-gate 		 * let the user move the old file out
3767c478bd9Sstevel@tonic-gate 		 * of the way.
3777c478bd9Sstevel@tonic-gate 		 */
3787c478bd9Sstevel@tonic-gate 		close_rewind();
3797c478bd9Sstevel@tonic-gate 		changevol();	/* switch files */
3807c478bd9Sstevel@tonic-gate 	}
3817c478bd9Sstevel@tonic-gate 	(void) snprintf(buf, sizeof (buf), gettext(
3827c478bd9Sstevel@tonic-gate 	    "Dumping active files (retry pass %d) to `%s'\n"), passno, tape);
3837c478bd9Sstevel@tonic-gate 	msg(buf);
3847c478bd9Sstevel@tonic-gate 	passno++;
3857c478bd9Sstevel@tonic-gate }
386