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