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 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__ 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__ 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 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 * 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 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 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__ 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__ 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