xref: /titanic_50/usr/src/cmd/backup/dump/dumponline.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright (c) 1991,1996,1998 by Sun Microsystems, Inc.
24*7c478bd9Sstevel@tonic-gate  * All rights reserved.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*7c478bd9Sstevel@tonic-gate 
29*7c478bd9Sstevel@tonic-gate #include "dump.h"
30*7c478bd9Sstevel@tonic-gate #include <math.h>
31*7c478bd9Sstevel@tonic-gate #include <limits.h>
32*7c478bd9Sstevel@tonic-gate 
33*7c478bd9Sstevel@tonic-gate /*
34*7c478bd9Sstevel@tonic-gate  * Uncomment if using mmap'ing of files for pre-fetch.
35*7c478bd9Sstevel@tonic-gate  * #define ENABLE_MMAP 1
36*7c478bd9Sstevel@tonic-gate  */
37*7c478bd9Sstevel@tonic-gate 
38*7c478bd9Sstevel@tonic-gate struct inodesc {
39*7c478bd9Sstevel@tonic-gate 	ino_t	id_inumber;		/* inode number */
40*7c478bd9Sstevel@tonic-gate 	long	id_gen;			/* generation number */
41*7c478bd9Sstevel@tonic-gate 	struct inodesc *id_next;	/* next on linked list */
42*7c478bd9Sstevel@tonic-gate };
43*7c478bd9Sstevel@tonic-gate 
44*7c478bd9Sstevel@tonic-gate static struct inodesc	ilist;		/* list of used inodesc structs */
45*7c478bd9Sstevel@tonic-gate static struct inodesc	*last;		/* last inodesc init'd or matched */
46*7c478bd9Sstevel@tonic-gate static struct inodesc	*freeinodesc;	/* free list of inodesc structs */
47*7c478bd9Sstevel@tonic-gate static struct inodesc	**ialloc;	/* allocated chunks, for freeing */
48*7c478bd9Sstevel@tonic-gate static int		nchunks;	/* number of allocations */
49*7c478bd9Sstevel@tonic-gate 
50*7c478bd9Sstevel@tonic-gate #ifdef ENABLE_MMAP /* XXX part of mmap support */
51*7c478bd9Sstevel@tonic-gate /*
52*7c478bd9Sstevel@tonic-gate  * If an mmap'ed file is truncated as it is being dumped or
53*7c478bd9Sstevel@tonic-gate  * faulted in, we are delivered a SIGBUS.
54*7c478bd9Sstevel@tonic-gate  */
55*7c478bd9Sstevel@tonic-gate static jmp_buf	truncate_buf;
56*7c478bd9Sstevel@tonic-gate static void	(*savebus)();
57*7c478bd9Sstevel@tonic-gate static int	incopy;
58*7c478bd9Sstevel@tonic-gate 
59*7c478bd9Sstevel@tonic-gate #ifdef __STDC__
60*7c478bd9Sstevel@tonic-gate static void onsigbus(int);
61*7c478bd9Sstevel@tonic-gate #else
62*7c478bd9Sstevel@tonic-gate static void onsigbus();
63*7c478bd9Sstevel@tonic-gate #endif
64*7c478bd9Sstevel@tonic-gate 
65*7c478bd9Sstevel@tonic-gate #endif	/* ENABLE_MMAP */
66*7c478bd9Sstevel@tonic-gate 
67*7c478bd9Sstevel@tonic-gate #ifdef DEBUG
68*7c478bd9Sstevel@tonic-gate extern int xflag;
69*7c478bd9Sstevel@tonic-gate #endif
70*7c478bd9Sstevel@tonic-gate 
71*7c478bd9Sstevel@tonic-gate #ifdef ENABLE_MMAP /* XXX part of mmap support */
72*7c478bd9Sstevel@tonic-gate static void
onsigbus(sig)73*7c478bd9Sstevel@tonic-gate onsigbus(sig)
74*7c478bd9Sstevel@tonic-gate 	int	sig;
75*7c478bd9Sstevel@tonic-gate {
76*7c478bd9Sstevel@tonic-gate 	if (!incopy) {
77*7c478bd9Sstevel@tonic-gate 		dumpabort();
78*7c478bd9Sstevel@tonic-gate 		/*NOTREACHED*/
79*7c478bd9Sstevel@tonic-gate 	}
80*7c478bd9Sstevel@tonic-gate 	incopy = 0;
81*7c478bd9Sstevel@tonic-gate 	longjmp(truncate_buf, 1);
82*7c478bd9Sstevel@tonic-gate 	/*NOTREACHED*/
83*7c478bd9Sstevel@tonic-gate }
84*7c478bd9Sstevel@tonic-gate #endif	/* ENABLE_MMAP */
85*7c478bd9Sstevel@tonic-gate 
86*7c478bd9Sstevel@tonic-gate void
87*7c478bd9Sstevel@tonic-gate #ifdef __STDC__
allocino(void)88*7c478bd9Sstevel@tonic-gate allocino(void)
89*7c478bd9Sstevel@tonic-gate #else
90*7c478bd9Sstevel@tonic-gate allocino()
91*7c478bd9Sstevel@tonic-gate #endif
92*7c478bd9Sstevel@tonic-gate {
93*7c478bd9Sstevel@tonic-gate 	ino_t maxino;
94*7c478bd9Sstevel@tonic-gate 	size_t nused;
95*7c478bd9Sstevel@tonic-gate 
96*7c478bd9Sstevel@tonic-gate 	maxino = (unsigned)(sblock->fs_ipg * sblock->fs_ncg);
97*7c478bd9Sstevel@tonic-gate 	if (maxino > ULONG_MAX) {
98*7c478bd9Sstevel@tonic-gate 		msg(gettext("allocino: filesystem too large\n"));
99*7c478bd9Sstevel@tonic-gate 		dumpabort();
100*7c478bd9Sstevel@tonic-gate 		/*NOTREACHED*/
101*7c478bd9Sstevel@tonic-gate 	}
102*7c478bd9Sstevel@tonic-gate 	/* LINTED maxino guaranteed to fit into a size_t by above test */
103*7c478bd9Sstevel@tonic-gate 	nused =  maxino - sblock->fs_cstotal.cs_nifree;
104*7c478bd9Sstevel@tonic-gate 	freeinodesc = (struct inodesc *)xcalloc(nused, sizeof (*freeinodesc));
105*7c478bd9Sstevel@tonic-gate 	if (freeinodesc == (struct inodesc *)0) {
106*7c478bd9Sstevel@tonic-gate 		msg(gettext("%s: out of memory\n"), "allocino");
107*7c478bd9Sstevel@tonic-gate 		dumpabort();
108*7c478bd9Sstevel@tonic-gate 		/*NOTREACHED*/
109*7c478bd9Sstevel@tonic-gate 	}
110*7c478bd9Sstevel@tonic-gate 	last = &ilist;
111*7c478bd9Sstevel@tonic-gate 	ialloc =
112*7c478bd9Sstevel@tonic-gate 	    (struct inodesc **)xmalloc(2*sizeof (*ialloc));
113*7c478bd9Sstevel@tonic-gate 	ialloc[0] = freeinodesc;
114*7c478bd9Sstevel@tonic-gate 	ialloc[1] = (struct inodesc *)0;
115*7c478bd9Sstevel@tonic-gate 	nchunks = 1;
116*7c478bd9Sstevel@tonic-gate }
117*7c478bd9Sstevel@tonic-gate 
118*7c478bd9Sstevel@tonic-gate void
119*7c478bd9Sstevel@tonic-gate #ifdef __STDC__
freeino(void)120*7c478bd9Sstevel@tonic-gate freeino(void)
121*7c478bd9Sstevel@tonic-gate #else
122*7c478bd9Sstevel@tonic-gate freeino()
123*7c478bd9Sstevel@tonic-gate #endif
124*7c478bd9Sstevel@tonic-gate {
125*7c478bd9Sstevel@tonic-gate 	int i;
126*7c478bd9Sstevel@tonic-gate 
127*7c478bd9Sstevel@tonic-gate 	if (ialloc == (struct inodesc **)0)
128*7c478bd9Sstevel@tonic-gate 		return;
129*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < nchunks; i++)
130*7c478bd9Sstevel@tonic-gate 		if (ialloc[i] != 0)
131*7c478bd9Sstevel@tonic-gate 			free(ialloc[i]);
132*7c478bd9Sstevel@tonic-gate 	free(ialloc);
133*7c478bd9Sstevel@tonic-gate 	ialloc = (struct inodesc **)0;
134*7c478bd9Sstevel@tonic-gate }
135*7c478bd9Sstevel@tonic-gate 
136*7c478bd9Sstevel@tonic-gate void
resetino(ino)137*7c478bd9Sstevel@tonic-gate resetino(ino)
138*7c478bd9Sstevel@tonic-gate 	ino_t	ino;
139*7c478bd9Sstevel@tonic-gate {
140*7c478bd9Sstevel@tonic-gate 	last = ilist.id_next;
141*7c478bd9Sstevel@tonic-gate 	while (last && last->id_inumber < ino)
142*7c478bd9Sstevel@tonic-gate 		last = last->id_next;
143*7c478bd9Sstevel@tonic-gate }
144*7c478bd9Sstevel@tonic-gate 
145*7c478bd9Sstevel@tonic-gate char *
unrawname(cp)146*7c478bd9Sstevel@tonic-gate unrawname(cp)
147*7c478bd9Sstevel@tonic-gate 	char *cp;
148*7c478bd9Sstevel@tonic-gate {
149*7c478bd9Sstevel@tonic-gate 	char *dp;
150*7c478bd9Sstevel@tonic-gate 	extern char *getfullblkname();
151*7c478bd9Sstevel@tonic-gate 
152*7c478bd9Sstevel@tonic-gate 	dp = getfullblkname(cp);
153*7c478bd9Sstevel@tonic-gate 	if (dp == 0)
154*7c478bd9Sstevel@tonic-gate 		return (0);
155*7c478bd9Sstevel@tonic-gate 	if (*dp == '\0') {
156*7c478bd9Sstevel@tonic-gate 		free(dp);
157*7c478bd9Sstevel@tonic-gate 		return (0);
158*7c478bd9Sstevel@tonic-gate 	}
159*7c478bd9Sstevel@tonic-gate 	if (dp == cp)		/* caller wants to always free() dp */
160*7c478bd9Sstevel@tonic-gate 		dp = strdup(cp);
161*7c478bd9Sstevel@tonic-gate 
162*7c478bd9Sstevel@tonic-gate 	return (dp);
163*7c478bd9Sstevel@tonic-gate }
164*7c478bd9Sstevel@tonic-gate 
165*7c478bd9Sstevel@tonic-gate /*
166*7c478bd9Sstevel@tonic-gate  * Determine if specified device is mounted at
167*7c478bd9Sstevel@tonic-gate  * specified mount point.  Returns 1 if mounted,
168*7c478bd9Sstevel@tonic-gate  * 0 if not mounted, -1 on error.
169*7c478bd9Sstevel@tonic-gate  */
170*7c478bd9Sstevel@tonic-gate int
lf_ismounted(devname,dirname)171*7c478bd9Sstevel@tonic-gate lf_ismounted(devname, dirname)
172*7c478bd9Sstevel@tonic-gate 	char	*devname;	/* name of device (raw or block) */
173*7c478bd9Sstevel@tonic-gate 	char	*dirname;	/* name of f/s mount point */
174*7c478bd9Sstevel@tonic-gate {
175*7c478bd9Sstevel@tonic-gate 	struct stat64 st;
176*7c478bd9Sstevel@tonic-gate 	char	*blockname;	/* name of block device */
177*7c478bd9Sstevel@tonic-gate 	dev_t	dev;
178*7c478bd9Sstevel@tonic-gate 	int	saverr;
179*7c478bd9Sstevel@tonic-gate 
180*7c478bd9Sstevel@tonic-gate 	if ((blockname = unrawname(devname)) == NULL) {
181*7c478bd9Sstevel@tonic-gate 		msg(gettext("Cannot obtain block name from `%s'\n"), devname);
182*7c478bd9Sstevel@tonic-gate 		return (-1);
183*7c478bd9Sstevel@tonic-gate 	}
184*7c478bd9Sstevel@tonic-gate 	if (stat64(blockname, &st) < 0) {
185*7c478bd9Sstevel@tonic-gate 		saverr = errno;
186*7c478bd9Sstevel@tonic-gate 		msg(gettext("Cannot obtain status of device `%s': %s\n"),
187*7c478bd9Sstevel@tonic-gate 		    blockname, strerror(saverr));
188*7c478bd9Sstevel@tonic-gate 		free(blockname);
189*7c478bd9Sstevel@tonic-gate 		return (-1);
190*7c478bd9Sstevel@tonic-gate 	}
191*7c478bd9Sstevel@tonic-gate 	free(blockname);
192*7c478bd9Sstevel@tonic-gate 	dev = st.st_rdev;
193*7c478bd9Sstevel@tonic-gate 	if (stat64(dirname, &st) < 0) {
194*7c478bd9Sstevel@tonic-gate 		saverr = errno;
195*7c478bd9Sstevel@tonic-gate 		msg(gettext("Cannot obtain status of device `%s': %s\n"),
196*7c478bd9Sstevel@tonic-gate 		    dirname, strerror(saverr));
197*7c478bd9Sstevel@tonic-gate 		return (-1);
198*7c478bd9Sstevel@tonic-gate 	}
199*7c478bd9Sstevel@tonic-gate 	if (dev == st.st_dev)
200*7c478bd9Sstevel@tonic-gate 		return (1);
201*7c478bd9Sstevel@tonic-gate 	return (0);
202*7c478bd9Sstevel@tonic-gate }
203*7c478bd9Sstevel@tonic-gate 
204*7c478bd9Sstevel@tonic-gate #ifdef ENABLE_MMAP /* XXX mapped-file support */
205*7c478bd9Sstevel@tonic-gate #define	MINMAPSIZE	1024*1024
206*7c478bd9Sstevel@tonic-gate #define	MAXMAPSIZE	1024*1024*32
207*7c478bd9Sstevel@tonic-gate 
208*7c478bd9Sstevel@tonic-gate static caddr_t	mapbase;	/* base of mapped data */
209*7c478bd9Sstevel@tonic-gate static caddr_t	mapend;		/* last byte of mapped data */
210*7c478bd9Sstevel@tonic-gate static size_t	mapsize;	/* amount of mapped data */
211*7c478bd9Sstevel@tonic-gate /*
212*7c478bd9Sstevel@tonic-gate  * Map a file prior to dumping and start faulting in its
213*7c478bd9Sstevel@tonic-gate  * pages.  Stop if we catch a signal indicating our turn
214*7c478bd9Sstevel@tonic-gate  * to dump has arrived.  If the file is truncated out from
215*7c478bd9Sstevel@tonic-gate  * under us, immediately return.
216*7c478bd9Sstevel@tonic-gate  * NB:  the base of the mapped data may not coincide
217*7c478bd9Sstevel@tonic-gate  * exactly to the requested offset, due to alignment
218*7c478bd9Sstevel@tonic-gate  * constraints.
219*7c478bd9Sstevel@tonic-gate  */
220*7c478bd9Sstevel@tonic-gate caddr_t
mapfile(fd,offset,bytes,fetch)221*7c478bd9Sstevel@tonic-gate mapfile(fd, offset, bytes, fetch)
222*7c478bd9Sstevel@tonic-gate 	int	fd;
223*7c478bd9Sstevel@tonic-gate 	off_t	offset;		/* offset within file */
224*7c478bd9Sstevel@tonic-gate 	off_t	bytes;		/* number of bytes to map */
225*7c478bd9Sstevel@tonic-gate 	int	fetch;		/* start faulting in pages */
226*7c478bd9Sstevel@tonic-gate {
227*7c478bd9Sstevel@tonic-gate 	/*LINTED [c used during pre-fetch faulting]*/
228*7c478bd9Sstevel@tonic-gate 	volatile char c, *p;
229*7c478bd9Sstevel@tonic-gate 	int stride = (int)sysconf(_SC_PAGESIZE);
230*7c478bd9Sstevel@tonic-gate 	extern int caught;		/* pre-fetch until set */
231*7c478bd9Sstevel@tonic-gate 	caddr_t	mapstart;		/* beginning of file's mapped data */
232*7c478bd9Sstevel@tonic-gate 	off_t	mapoffset;		/* page-aligned offset */
233*7c478bd9Sstevel@tonic-gate 	int	saverr;
234*7c478bd9Sstevel@tonic-gate 
235*7c478bd9Sstevel@tonic-gate 	mapbase = mapend = (caddr_t)0;
236*7c478bd9Sstevel@tonic-gate 
237*7c478bd9Sstevel@tonic-gate 	if (bytes == 0)
238*7c478bd9Sstevel@tonic-gate 		return ((caddr_t)0);
239*7c478bd9Sstevel@tonic-gate 	/*
240*7c478bd9Sstevel@tonic-gate 	 * mmap the file for reading
241*7c478bd9Sstevel@tonic-gate 	 */
242*7c478bd9Sstevel@tonic-gate 	mapoffset = offset & ~(stride - 1);
243*7c478bd9Sstevel@tonic-gate 	/* LINTED: "bytes" will always fit into a size_t */
244*7c478bd9Sstevel@tonic-gate 	mapsize = bytes + (offset - mapoffset);
245*7c478bd9Sstevel@tonic-gate 	if (mapsize > MAXMAPSIZE)
246*7c478bd9Sstevel@tonic-gate 		mapsize = MAXMAPSIZE;
247*7c478bd9Sstevel@tonic-gate 	while ((mapbase = mmap((caddr_t)0, mapsize, PROT_READ,
248*7c478bd9Sstevel@tonic-gate 	    MAP_SHARED, fd, mapoffset)) == (caddr_t)-1 &&
249*7c478bd9Sstevel@tonic-gate 	    errno == ENOMEM && mapsize >= MINMAPSIZE) {
250*7c478bd9Sstevel@tonic-gate 		/*
251*7c478bd9Sstevel@tonic-gate 		 * Due to address space limitations, we
252*7c478bd9Sstevel@tonic-gate 		 * may not be able to map as much as we want.
253*7c478bd9Sstevel@tonic-gate 		 */
254*7c478bd9Sstevel@tonic-gate 		mapsize /= 2;	/* exponential back-off */
255*7c478bd9Sstevel@tonic-gate 	}
256*7c478bd9Sstevel@tonic-gate 
257*7c478bd9Sstevel@tonic-gate 	if (mapbase == (caddr_t)-1) {
258*7c478bd9Sstevel@tonic-gate 		saverr = errno;
259*7c478bd9Sstevel@tonic-gate 		msg(gettext("Cannot map file at inode `%lu' into memory: %s\n"),
260*7c478bd9Sstevel@tonic-gate 			ino, strerror(saverr));
261*7c478bd9Sstevel@tonic-gate 		/* XXX why not call dumpailing() here? */
262*7c478bd9Sstevel@tonic-gate 		if (!query(gettext(
263*7c478bd9Sstevel@tonic-gate 	    "Do you want to attempt to continue? (\"yes\" or \"no\") "))) {
264*7c478bd9Sstevel@tonic-gate 			dumpabort();
265*7c478bd9Sstevel@tonic-gate 			/*NOTREACHED*/
266*7c478bd9Sstevel@tonic-gate 		}
267*7c478bd9Sstevel@tonic-gate 		mapbase = (caddr_t)0;
268*7c478bd9Sstevel@tonic-gate 		return ((caddr_t)0);
269*7c478bd9Sstevel@tonic-gate 	}
270*7c478bd9Sstevel@tonic-gate 
271*7c478bd9Sstevel@tonic-gate 	(void) madvise(mapbase, mapsize, MADV_SEQUENTIAL);
272*7c478bd9Sstevel@tonic-gate 	mapstart = mapbase + (offset - mapoffset);
273*7c478bd9Sstevel@tonic-gate 	mapend = mapbase + (mapsize - 1);
274*7c478bd9Sstevel@tonic-gate 
275*7c478bd9Sstevel@tonic-gate 	if (!fetch)
276*7c478bd9Sstevel@tonic-gate 		return (mapstart);
277*7c478bd9Sstevel@tonic-gate 
278*7c478bd9Sstevel@tonic-gate 	if (setjmp(truncate_buf) == 0) {
279*7c478bd9Sstevel@tonic-gate 		savebus = signal(SIGBUS, onsigbus);
280*7c478bd9Sstevel@tonic-gate 		/*
281*7c478bd9Sstevel@tonic-gate 		 * Touch each page to pre-fetch by faulting.  At least
282*7c478bd9Sstevel@tonic-gate 		 * one of c or *p must be declared volatile, lest the
283*7c478bd9Sstevel@tonic-gate 		 * optimizer eliminate the assignment in the loop.
284*7c478bd9Sstevel@tonic-gate 		 */
285*7c478bd9Sstevel@tonic-gate 		incopy = 1;
286*7c478bd9Sstevel@tonic-gate 		for (p = mapbase; !caught && p <= mapend; p += stride) {
287*7c478bd9Sstevel@tonic-gate 			/* LINTED: c is used for its side-effects */
288*7c478bd9Sstevel@tonic-gate 			c = *p;
289*7c478bd9Sstevel@tonic-gate 		}
290*7c478bd9Sstevel@tonic-gate 		incopy = 0;
291*7c478bd9Sstevel@tonic-gate 	}
292*7c478bd9Sstevel@tonic-gate #ifdef DEBUG
293*7c478bd9Sstevel@tonic-gate 	else
294*7c478bd9Sstevel@tonic-gate 		/* XGETTEXT:  #ifdef DEBUG only */
295*7c478bd9Sstevel@tonic-gate 		msg(gettext(
296*7c478bd9Sstevel@tonic-gate 			"FILE TRUNCATED (fault): Interrupting pre-fetch\n"));
297*7c478bd9Sstevel@tonic-gate #endif
298*7c478bd9Sstevel@tonic-gate 	(void) signal(SIGBUS, savebus);
299*7c478bd9Sstevel@tonic-gate 	return (mapstart);
300*7c478bd9Sstevel@tonic-gate }
301*7c478bd9Sstevel@tonic-gate 
302*7c478bd9Sstevel@tonic-gate void
303*7c478bd9Sstevel@tonic-gate #ifdef __STDC__
unmapfile(void)304*7c478bd9Sstevel@tonic-gate unmapfile(void)
305*7c478bd9Sstevel@tonic-gate #else
306*7c478bd9Sstevel@tonic-gate unmapfile()
307*7c478bd9Sstevel@tonic-gate #endif
308*7c478bd9Sstevel@tonic-gate {
309*7c478bd9Sstevel@tonic-gate 	if (mapbase) {
310*7c478bd9Sstevel@tonic-gate 		/* XXX we're unmapping it, so what does this gain us? */
311*7c478bd9Sstevel@tonic-gate 		(void) msync(mapbase, mapsize, MS_ASYNC|MS_INVALIDATE);
312*7c478bd9Sstevel@tonic-gate 		(void) munmap(mapbase, mapsize);
313*7c478bd9Sstevel@tonic-gate 		mapbase = (caddr_t)0;
314*7c478bd9Sstevel@tonic-gate 	}
315*7c478bd9Sstevel@tonic-gate }
316*7c478bd9Sstevel@tonic-gate #endif	/* ENABLE_MMAP */
317*7c478bd9Sstevel@tonic-gate 
318*7c478bd9Sstevel@tonic-gate void
319*7c478bd9Sstevel@tonic-gate #ifdef __STDC__
activepass(void)320*7c478bd9Sstevel@tonic-gate activepass(void)
321*7c478bd9Sstevel@tonic-gate #else
322*7c478bd9Sstevel@tonic-gate activepass()
323*7c478bd9Sstevel@tonic-gate #endif
324*7c478bd9Sstevel@tonic-gate {
325*7c478bd9Sstevel@tonic-gate 	static int passno = 1;			/* active file pass number */
326*7c478bd9Sstevel@tonic-gate 	char *ext, *old;
327*7c478bd9Sstevel@tonic-gate 	char buf[3000];
328*7c478bd9Sstevel@tonic-gate 	static char defext[] = ".retry";
329*7c478bd9Sstevel@tonic-gate 
330*7c478bd9Sstevel@tonic-gate 	if (pipeout) {
331*7c478bd9Sstevel@tonic-gate 		msg(gettext("Cannot re-dump active files to `%s'\n"), tape);
332*7c478bd9Sstevel@tonic-gate 		dumpabort();
333*7c478bd9Sstevel@tonic-gate 		/*NOTREACHED*/
334*7c478bd9Sstevel@tonic-gate 	}
335*7c478bd9Sstevel@tonic-gate 
336*7c478bd9Sstevel@tonic-gate 	if (active > 1)
337*7c478bd9Sstevel@tonic-gate 		(void) snprintf(buf, sizeof (buf), gettext(
338*7c478bd9Sstevel@tonic-gate 		    "%d files were active and will be re-dumped\n"), active);
339*7c478bd9Sstevel@tonic-gate 	else
340*7c478bd9Sstevel@tonic-gate 		(void) snprintf(buf, sizeof (buf), gettext(
341*7c478bd9Sstevel@tonic-gate 		    "1 file was active and will be re-dumped\n"));
342*7c478bd9Sstevel@tonic-gate 	msg(buf);
343*7c478bd9Sstevel@tonic-gate 
344*7c478bd9Sstevel@tonic-gate 	doingactive++;
345*7c478bd9Sstevel@tonic-gate 	active = 0;
346*7c478bd9Sstevel@tonic-gate 	reset();			/* reset tape params */
347*7c478bd9Sstevel@tonic-gate 	spcl.c_ddate = spcl.c_date;	/* chain with last dump/pass */
348*7c478bd9Sstevel@tonic-gate 
349*7c478bd9Sstevel@tonic-gate 	/*
350*7c478bd9Sstevel@tonic-gate 	 * If archiving, create a new
351*7c478bd9Sstevel@tonic-gate 	 * archive file.
352*7c478bd9Sstevel@tonic-gate 	 */
353*7c478bd9Sstevel@tonic-gate 	if (archivefile) {
354*7c478bd9Sstevel@tonic-gate 		old = archivefile;
355*7c478bd9Sstevel@tonic-gate 
356*7c478bd9Sstevel@tonic-gate 		ext = strstr(old, defext);
357*7c478bd9Sstevel@tonic-gate 		if (ext != (char *)NULL)
358*7c478bd9Sstevel@tonic-gate 			*ext = '\0'; /* just want the base name */
359*7c478bd9Sstevel@tonic-gate 
360*7c478bd9Sstevel@tonic-gate 		/* The two is for the trailing \0 and rounding up log10() */
361*7c478bd9Sstevel@tonic-gate 		archivefile = xmalloc(strlen(old) + strlen(defext) +
362*7c478bd9Sstevel@tonic-gate 		    (int)log10((double)passno) + 2);
363*7c478bd9Sstevel@tonic-gate 
364*7c478bd9Sstevel@tonic-gate 		/* Always fits */
365*7c478bd9Sstevel@tonic-gate 		(void) sprintf(archivefile, "%s%s%d", old, defext, passno);
366*7c478bd9Sstevel@tonic-gate 		free(old);
367*7c478bd9Sstevel@tonic-gate 	}
368*7c478bd9Sstevel@tonic-gate 
369*7c478bd9Sstevel@tonic-gate 	if (tapeout) {
370*7c478bd9Sstevel@tonic-gate 		if (isrewind(to)) {
371*7c478bd9Sstevel@tonic-gate 			/*
372*7c478bd9Sstevel@tonic-gate 			 * A "rewind" tape device.  When we do
373*7c478bd9Sstevel@tonic-gate 			 * the close, we will lose our position.
374*7c478bd9Sstevel@tonic-gate 			 * Be nice and switch volumes.
375*7c478bd9Sstevel@tonic-gate 			 */
376*7c478bd9Sstevel@tonic-gate 			(void) snprintf(buf, sizeof (buf), gettext(
377*7c478bd9Sstevel@tonic-gate 		"Warning - cannot dump active files to rewind device `%s'\n"),
378*7c478bd9Sstevel@tonic-gate 				tape);
379*7c478bd9Sstevel@tonic-gate 			msg(buf);
380*7c478bd9Sstevel@tonic-gate 			close_rewind();
381*7c478bd9Sstevel@tonic-gate 			changevol();
382*7c478bd9Sstevel@tonic-gate 		} else {
383*7c478bd9Sstevel@tonic-gate 			trewind();
384*7c478bd9Sstevel@tonic-gate 			doposition = 0;
385*7c478bd9Sstevel@tonic-gate 			filenum++;
386*7c478bd9Sstevel@tonic-gate 		}
387*7c478bd9Sstevel@tonic-gate 	} else {
388*7c478bd9Sstevel@tonic-gate 		/*
389*7c478bd9Sstevel@tonic-gate 		 * Not a tape.  Do a volume switch.
390*7c478bd9Sstevel@tonic-gate 		 * This will advance to the next file
391*7c478bd9Sstevel@tonic-gate 		 * if using a sequence of files, next
392*7c478bd9Sstevel@tonic-gate 		 * diskette if using diskettes, or
393*7c478bd9Sstevel@tonic-gate 		 * let the user move the old file out
394*7c478bd9Sstevel@tonic-gate 		 * of the way.
395*7c478bd9Sstevel@tonic-gate 		 */
396*7c478bd9Sstevel@tonic-gate 		close_rewind();
397*7c478bd9Sstevel@tonic-gate 		changevol();	/* switch files */
398*7c478bd9Sstevel@tonic-gate 	}
399*7c478bd9Sstevel@tonic-gate 	(void) snprintf(buf, sizeof (buf), gettext(
400*7c478bd9Sstevel@tonic-gate 	    "Dumping active files (retry pass %d) to `%s'\n"), passno, tape);
401*7c478bd9Sstevel@tonic-gate 	msg(buf);
402*7c478bd9Sstevel@tonic-gate 	passno++;
403*7c478bd9Sstevel@tonic-gate }
404