From d435f57f01229cd9fa358abe32c4a93077d9090d Mon Sep 17 00:00:00 2001 From: Stelian Pop Date: Tue, 27 Jan 2004 10:37:25 +0000 Subject: [PATCH] Make -B accept a list of values. --- CHANGES | 6 ++++- dump/dump.8.in | 12 ++++++++-- dump/main.c | 63 ++++++++++++++++++++++++++++++++++++++++++-------- dump/tape.c | 15 +++++++----- 4 files changed, 78 insertions(+), 18 deletions(-) diff --git a/CHANGES b/CHANGES index 5f171bd..b382d7f 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,4 @@ -$Id: CHANGES,v 1.238 2004/01/27 10:18:17 stelian Exp $ +$Id: CHANGES,v 1.239 2004/01/27 10:37:25 stelian Exp $ Changes between versions 0.4b35 and 0.4b36 (released ?????????????????) ======================================================================= @@ -14,6 +14,10 @@ Changes between versions 0.4b35 and 0.4b36 (released ?????????????????) for reporting the bug and providing the test case. +4. Changed dump to enable the creation of volumes of different + sizes in a single run (make -B accept a list of values). + Patch contributed by Florian Zumbiehl . + Changes between versions 0.4b34 and 0.4b35 (released December 21, 2003) ======================================================================= diff --git a/dump/dump.8.in b/dump/dump.8.in index da2ba2e..61cd430 100644 --- a/dump/dump.8.in +++ b/dump/dump.8.in @@ -26,7 +26,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $Id: dump.8.in,v 1.53 2003/05/07 14:45:20 stelian Exp $ +.\" $Id: dump.8.in,v 1.54 2004/01/27 10:37:28 stelian Exp $ .\" .TH DUMP 8 "version __VERSION__ of __DATE__" BSD "System management commands" .SH NAME @@ -134,7 +134,15 @@ can detect end-of-media. When the specified size is reached, .B dump waits for you to change the volume. This option overrides the calculation of tape size based on length and density. If compression is on this limits the -size of the compressed output per volume. +size of the compressed output per volume. Multiple values may be given +as a single argument separated by commas. Each value will be used for one +dump volume in the order listed; if +.B dump +creates more volumes than the +number of values given, the last value will be used for the remaining +volumes. This is useful for filling up already partially filled media +(and then continuing with full size volumes on empty media) or mixing media +of different sizes. .TP .BI \-c Change the defaults for use with a cartridge tape drive, with a density of 8000 diff --git a/dump/main.c b/dump/main.c index a9a671d..342d4b6 100644 --- a/dump/main.c +++ b/dump/main.c @@ -37,7 +37,7 @@ #ifndef lint static const char rcsid[] = - "$Id: main.c,v 1.89 2004/01/04 10:48:35 stelian Exp $"; + "$Id: main.c,v 1.90 2004/01/27 10:37:29 stelian Exp $"; #endif /* not lint */ #include @@ -171,7 +171,7 @@ int tapepos = 0; /* assume no QFA tapeposition needed by user */ #endif /* USE_QFA */ int dokerberos = 0; /* Use Kerberos authentication */ long dev_bsize = 1; /* recalculated below */ -long blocksperfile; /* output blocks per file */ +long *blocksperfiles = NULL; /* output blocks per file(s) */ char *host = NULL; /* remote host (if any) */ int sizest = 0; /* return size estimate only */ int compressed = 0; /* use zlib to compress the output, compress level 1-9 */ @@ -186,6 +186,7 @@ char *__progname; int maxbsize = 1024*1024; /* XXX MAXBSIZE from sys/param.h */ static long numarg __P((const char *, long, long)); +static long numlistarg __P((const char *, long, long)); static void obsolete __P((int *, char **[])); static void usage __P((void)); static void do_exclude_from_file __P((char *)); @@ -285,7 +286,7 @@ main(int argc, char *argv[]) case 'B': /* blocks per output file */ unlimited = 0; - blocksperfile = numarg("number of blocks per file", + blocksperfiles = numlistarg("number of blocks per file", 1L, 0L); break; @@ -473,7 +474,7 @@ main(int argc, char *argv[]) } argc--; incompat_flags(Tflag && uflag, 'T', 'u'); - incompat_flags(aflag && blocksperfile, 'a', 'B'); + incompat_flags(aflag && blocksperfiles, 'a', 'B'); incompat_flags(aflag && cartridge, 'a', 'c'); incompat_flags(aflag && density, 'a', 'd'); incompat_flags(aflag && tsize, 'a', 's'); @@ -483,8 +484,9 @@ main(int argc, char *argv[]) tapeprefix = "standard output"; } - if (blocksperfile && !compressed) - blocksperfile = blocksperfile / ntrec * ntrec; /* round down */ + if (blocksperfiles && !compressed) + for (i = 1; i <= *blocksperfiles; i++) + blocksperfiles[i] = blocksperfiles[i] / ntrec * ntrec; /* round down */ else if (!unlimited) { /* * Determine how to default tape size and density @@ -867,9 +869,21 @@ main(int argc, char *argv[]) } else { double fetapes; - if (blocksperfile) - fetapes = (double) tapesize / blocksperfile; - else if (cartridge) { + if (blocksperfiles) { + long tapesize_left; + + tapesize_left = tapesize; + fetapes = 0; + for (i = 1; i < *blocksperfiles && tapesize_left; i++) { + fetapes++; + if (tapesize_left > blocksperfiles[i]) + tapesize_left -= blocksperfiles[i]; + else + tapesize_left = 0; + } + if (tapesize_left) + fetapes += (double)tapesize_left / blocksperfiles[*blocksperfiles]; + } else if (cartridge) { /* Estimate number of tapes, assuming streaming stops at the end of each block written, and not in mid-block. Assume no erroneous blocks; this can be compensated @@ -1117,6 +1131,37 @@ numarg(const char *meaning, long vmin, long vmax) return (val); } +/* + * The same as numarg, just that it expects a comma separated list of numbers + * and returns an array of longs with the first element containing the number + * values in that array. + */ +static long +numlistarg(const char *meaning, long vmin, long vmax) +{ + char *p; + long *vals,*curval; + long valnum; + + p = optarg; + vals = NULL; + valnum = 0; + do { + valnum++; + if ( !(vals = realloc(vals, (valnum + 1) * sizeof(*vals))) ) + errx(X_STARTUP, "allocating memory failed"); + curval = vals + valnum; + *curval = strtol(p, &p, 10); + if (*p && *p!=',') + errx(X_STARTUP, "illegal %s -- %s", meaning, optarg); + if (*curval < vmin || (vmax && *curval > vmax)) + errx(X_STARTUP, "%s must be between %ld and %ld", meaning, vmin, vmax); + *vals = valnum; + if (*p) p++; + } while(*p); + return (vals); +} + void sig(int signo) { diff --git a/dump/tape.c b/dump/tape.c index f55334b..156abff 100644 --- a/dump/tape.c +++ b/dump/tape.c @@ -37,7 +37,7 @@ #ifndef lint static const char rcsid[] = - "$Id: tape.c,v 1.79 2003/11/22 16:52:16 stelian Exp $"; + "$Id: tape.c,v 1.80 2004/01/27 10:37:29 stelian Exp $"; #endif /* not lint */ #include @@ -105,7 +105,8 @@ int write(), read(); int writesize; /* size of malloc()ed buffer for tape */ long lastspclrec = -1; /* tape block number of last written header */ int trecno = 0; /* next record to write in current block */ -extern long blocksperfile; /* number of blocks per output file */ +extern long *blocksperfiles; /* number of blocks per output file(s) */ +long blocksperfiles_current; /* current position in blocksperfiles */ long blocksthisvol; /* number of blocks on current output file */ extern int ntrec; /* blocking factor on tape */ extern int cartridge; @@ -197,7 +198,7 @@ alloctape(void) * repositioning after stopping, i.e, streaming mode, where the gap is * variable, 0.30" to 0.45". The gap is maximal when the tape stops. */ - if (blocksperfile == 0 && !unlimited) + if (!blocksperfiles && !unlimited) tenths = (cartridge ? 16 : density == 625 ? 5 : 8); else { tenths = 0; @@ -484,9 +485,9 @@ flushtape(void) blockswritten += ntrec; blocksthisvol += ntrec; if (!pipeout && !unlimited) { - if (blocksperfile) { - if ( compressed ? (bytes_written - tapea_bytes + SLAVES * (writesize + sizeof(struct tapebuf))) >= (((long long)blocksperfile) * 1024) - : blocksthisvol >= blocksperfile ) { + if (blocksperfiles[blocksperfiles_current]) { + if ( compressed ? (bytes_written - tapea_bytes + SLAVES * (writesize + sizeof(struct tapebuf))) >= (((long long)blocksperfiles[blocksperfiles_current]) * 1024) + : blocksthisvol >= blocksperfiles[blocksperfiles_current] ) { close_rewind(); startnewtape(0); } @@ -871,6 +872,8 @@ restore_check_point: tape[MAXPATHLEN - 1] = '\0'; msg("Dumping volume %d on %s\n", tapeno, tape); } + if (blocksperfiles_current < *blocksperfiles) + blocksperfiles_current++; #ifdef RDUMP while ((tapefd = (host ? rmtopen(tape, O_WRONLY|O_CREAT|O_TRUNC) : pipeout ? fileno(stdout) : -- 2.39.5