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