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