]> git.wh0rd.org - dump.git/blobdiff - dump/tape.c
Small patch for LZO functionality.
[dump.git] / dump / tape.c
index 0dffa3a7cba384772f087967cf0356e4236412a8..1990be91bbb952a43c767f985abb3df27ab01775 100644 (file)
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -41,7 +37,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: tape.c,v 1.67 2002/04/11 14:51:09 stelian Exp $";
+       "$Id: tape.c,v 1.77 2003/04/18 07:47:57 stelian Exp $";
 #endif /* not lint */
 
 #include <config.h>
@@ -99,6 +95,10 @@ int    write(), read();
 #include <bzlib.h>
 #endif /* HAVE_BZLIB */
 
+#ifdef HAVE_LZO
+#include <minilzo.h>
+#endif /* HAVE_LZO */
+
 #include "dump.h"
 
 int    writesize;              /* size of malloc()ed buffer for tape */
@@ -110,13 +110,16 @@ extern    int ntrec;              /* blocking factor on tape */
 extern int cartridge;
 char   *nexttape;
 extern  pid_t rshpid;
-int    eot_code = 1;
 long long tapea_bytes = 0;     /* bytes_written at start of current volume */
 static int magtapeout;         /* output is really a tape */
 
 static ssize_t dump_atomic_read __P((int, void *, size_t));
 static ssize_t dump_atomic_write __P((int, const void *, size_t));
+#ifdef WRITEDEBUG
 static void doslave __P((int, int, int));
+#else
+static void doslave __P((int, int));
+#endif
 static void enslave __P((void));
 static void flushtape __P((void));
 static void killall __P((void));
@@ -233,14 +236,14 @@ writerec(const void *dp, int isspcl)
        *(union u_spcl *)(*(nextblock)) = *(union u_spcl *)dp;
 
        /* Need to write it to the archive file */
-       if (Afile < 0 && isspcl && (spcl.c_type == TS_END))
-               Afile = -Afile;
-       if (Afile > 0) {
+       if (! AfileActive && isspcl && (spcl.c_type == TS_END))
+               AfileActive = 1;
+       if (AfileActive && Afile >= 0) {
                /* When we dump an inode which is not a directory,
                 * it means we ended the archive contents */
                if (isspcl && (spcl.c_type == TS_INODE) &&
                    ((spcl.c_dinode.di_mode & S_IFMT) != IFDIR))
-                       Afile = -Afile;
+                       AfileActive = 0;
                else {
                        union u_spcl tmp;
                        tmp = *(union u_spcl *)dp;
@@ -311,7 +314,7 @@ tperror(int errnum)
 }
 
 static void
-sigpipe(int signo)
+sigpipe(UNUSED(int signo))
 {
 
        quit("Broken pipe\n");
@@ -332,7 +335,7 @@ do_stats(void)
        blocks = spcl.c_tapea - tapea_volume;
        msg("Volume %d completed at: %s", tapeno, ctime(&tnow));
        if (! compressed)
-               msg("Volume %d %ld tape blocks (%.2fMB)\n", tapeno, 
+               msg("Volume %d %ld blocks (%.2fMB)\n", tapeno, 
                        blocks, ((double)blocks * TP_BSIZE / 1048576));
        if (ttaken > 0) {
                long volkb = (bytes_written - tapea_bytes) / 1024;
@@ -479,7 +482,7 @@ flushtape(void)
        blocksthisvol += ntrec;
        if (!pipeout && !unlimited) {
                if (blocksperfile) {
-                       if ( compressed ? (bytes_written - tapea_bytes + SLAVES * (writesize + sizeof(struct tapebuf))) >= blocksperfile * 1024
+                       if ( compressed ? (bytes_written - tapea_bytes + SLAVES * (writesize + sizeof(struct tapebuf))) >= (((long long)blocksperfile) * 1024)
                                        : blocksthisvol >= blocksperfile ) {
                                close_rewind();
                                startnewtape(0);
@@ -542,7 +545,7 @@ trewind(void)
 #ifdef RDUMP
                if (host) {
                        rmtclose();
-                       while (rmtopen(tape, 0) < 0)
+                       while (rmtopen(tape, O_RDONLY) < 0)
                                sleep(10);
                        rmtclose();
                }
@@ -551,20 +554,11 @@ trewind(void)
                {
                        (void) close(tapefd);
                        if (!fifoout) {
-                               while ((f = OPEN(tape, 0)) < 0)
+                               while ((f = OPEN(tape, O_RDONLY)) < 0)
                                        sleep (10);
                                (void) close(f);
                        }
                }
-               eot_code = 1;
-               if (eot_script && spcl.c_type != TS_END) {
-                       msg("Launching %s\n", eot_script);
-                       eot_code = system_command(eot_script, tape, tapeno);
-               }
-               if (eot_code != 0 && eot_code != 1) {
-                       msg("Dump aborted by the end of tape script\n");
-                       dumpabort(0);
-               }
        }
        return do_stats();
 }
@@ -573,8 +567,19 @@ trewind(void)
 void
 close_rewind(void)
 {
+       int eot_code = 1;
        (void)trewind();
-       if (nexttape || Mflag || (eot_code == 0) )
+       if (nexttape || Mflag)
+               return;
+       if (eot_script) {
+               msg("Launching %s\n", eot_script);
+               eot_code = system_command(eot_script, tape, tapeno);
+       }
+       if (eot_code != 0 && eot_code != 1) {
+               msg("Dump aborted by the end of tape script\n");
+               dumpabort(0);
+       }
+       if (eot_code == 0)
                return;
        if (!nogripe) {
                msg("Change Volumes: Mount volume #%d\n", tapeno+1);
@@ -864,12 +869,12 @@ restore_check_point:
                        msg("Dumping volume %d on %s\n", tapeno, tape);
                }
 #ifdef RDUMP
-               while ((tapefd = (host ? rmtopen(tape, 2) : pipeout ? 
+               while ((tapefd = (host ? rmtopen(tape, O_WRONLY|O_CREAT|O_TRUNC) : pipeout ? 
                        fileno(stdout) : 
-                       OPEN(tape, O_WRONLY|O_CREAT, 0666))) < 0)
+                       OPEN(tape, O_WRONLY|O_CREAT|O_TRUNC, 0666))) < 0)
 #else
                while ((tapefd = (pipeout ? fileno(stdout) :
-                                 OPEN(tape, O_RDWR|O_CREAT, 0666))) < 0)
+                                 OPEN(tape, O_WRONLY|O_CREAT|O_TRUNC, 0666))) < 0)
 #endif
                    {
                        msg("Cannot open output \"%s\": %s\n", tape, 
@@ -914,13 +919,13 @@ restore_check_point:
                if (tapeno > 1)
                        msg("Volume %d begins with blocks from inode %d\n",
                                tapeno, slp->inode);
-               if (tapeno < TP_NINOS)
+               if (tapeno < (int)TP_NINOS)
                        volinfo[tapeno] = slp->inode;
        }
 }
 
 void
-dumpabort(int signo)
+dumpabort(UNUSED(int signo))
 {
 
        if (master != 0 && master != getpid())
@@ -950,7 +955,7 @@ Exit(int status)
  * proceed - handler for SIGUSR2, used to synchronize IO between the slaves.
  */
 static void
-proceed(int signo)
+proceed(UNUSED(int signo))
 {
        if (ready)
                siglongjmp(jmpbuf, 1);
@@ -1011,7 +1016,11 @@ enslave(void)
                            != sizeof i)
                                quit("master/slave protocol botched 3\n");
 #endif
-                       doslave(cmd[0], i, (slaves[i].pid == slp->pid));
+                       doslave(cmd[0], 
+#ifdef WRITEDEBUG
+                               i, 
+#endif
+                               (slaves[i].pid == slp->pid));
                        Exit(X_FINOK);
                }
                else
@@ -1057,20 +1066,28 @@ killall(void)
  * slaves.
  */
 static void
-doslave(int cmd, int slave_number, int first)
+doslave(int cmd, 
+#ifdef WRITEDEBUG
+       int slave_number, 
+#endif
+       int first)
 {
        int nread;
-       int nextslave, size, eot_count, bufsize;
-       volatile int wrote = 0;
-       char *buffer;
-#if defined(HAVE_ZLIB) || defined(HAVE_BZLIB)
-       struct tapebuf *comp_buf = NULL;
-       int compresult, do_compress = !first;
+       int nextslave;
+       volatile int wrote = 0, size, eot_count, bufsize;
+       char * volatile buffer;
+#if defined(HAVE_ZLIB) || defined(HAVE_BZLIB) || defined(HAVE_LZO)
+       struct tapebuf * volatile comp_buf = NULL;
+       int compresult;
+       volatile int do_compress = !first;
        unsigned long worklen;
 #ifdef HAVE_BZLIB
        unsigned int worklen2;
 #endif
-#endif /* HAVE_ZLIB || HAVE_BZLIB */
+#ifdef HAVE_LZO
+       lzo_align_t __LZO_MMODEL *LZO_WorkMem;
+#endif
+#endif /* HAVE_ZLIB || HAVE_BZLIB || HAVE_LZO */
        struct slave_results returns;
 #ifdef __linux__
        errcode_t retval;
@@ -1111,18 +1128,34 @@ doslave(int cmd, int slave_number, int first)
                quit("master/slave protocol botched - didn't get pid of next slave.\n");
        }
 
-#if defined(HAVE_ZLIB) || defined(HAVE_BZLIB)
+#if defined(HAVE_ZLIB) || defined(HAVE_BZLIB) || defined(HAVE_LZO)
        /* if we're doing a compressed dump, allocate the compress buffer */
        if (compressed) {
-               comp_buf = malloc(sizeof(struct tapebuf) + TP_BSIZE + writesize);
+               int bsiz = sizeof(struct tapebuf) + writesize;
+               /* Add extra space to deal with compression enlarging the buffer */
+               if (TP_BSIZE > writesize/16 + 67)
+                       bsiz += TP_BSIZE;
+               else
+                       bsiz += writesize/16 + 67;
+               comp_buf = malloc(bsiz);
                if (comp_buf == NULL)
                        quit("couldn't allocate a compress buffer.\n");
-               if (bzipflag)
-                       comp_buf->flags = COMPRESS_BZLIB;
-               else
+               if (zipflag == COMPRESS_ZLIB)
                        comp_buf->flags = COMPRESS_ZLIB;
+               else if (zipflag == COMPRESS_BZLIB)
+                       comp_buf->flags = COMPRESS_BZLIB;
+                else if (zipflag == COMPRESS_LZO) {
+                       comp_buf->flags = COMPRESS_LZO;
+                       if (lzo_init() != LZO_E_OK) quit("lzo_init failed\n");
+                } else 
+                       quit("internal error - unknown compression method: %d\n", zipflag);
        }
-#endif /* HAVE_ZLIB || HAVE_BZLIB */
+#ifdef HAVE_LZO
+       LZO_WorkMem = malloc(LZO1X_1_MEM_COMPRESS);
+       if (!LZO_WorkMem)
+               quit("couldn't allocate a compress buffer.\n");
+#endif
+#endif /* HAVE_ZLIB || HAVE_BZLIB || HAVE_LZO */
 
        /*
         * Get list of blocks to dump, read the blocks into tape buffer
@@ -1151,7 +1184,7 @@ doslave(int cmd, int slave_number, int first)
                bufsize = writesize;                    /* length to write */
                returns.clen = returns.unclen = bufsize;
 
-#if defined(HAVE_ZLIB) || defined(HAVE_BZLIB)
+#if defined(HAVE_ZLIB) || defined(HAVE_BZLIB) || defined(HAVE_LZO)
                /* 
                 * When writing a compressed dump, each block except
                 * the first one on each tape is written
@@ -1170,7 +1203,7 @@ doslave(int cmd, int slave_number, int first)
                        worklen = TP_BSIZE + writesize;
                        compresult = 1;
 #ifdef HAVE_ZLIB
-                       if (!bzipflag) {
+                       if (zipflag == COMPRESS_ZLIB) {
                                compresult = compress2(comp_buf->buf, 
                                                       &worklen,
                                                       (char *)slp->tblock[0],
@@ -1183,7 +1216,7 @@ doslave(int cmd, int slave_number, int first)
                        }
 #endif /* HAVE_ZLIB */
 #ifdef HAVE_BZLIB
-                       if (bzipflag) {
+                       if (zipflag == COMPRESS_BZLIB) {
                                worklen2 = worklen;
                                compresult = BZ2_bzBuffToBuffCompress(
                                                       comp_buf->buf,
@@ -1200,7 +1233,19 @@ doslave(int cmd, int slave_number, int first)
                        }
 
 #endif /* HAVE_BZLIB */
-                       if (compresult && worklen <= (writesize - 16)) {
+#ifdef HAVE_LZO
+                       if (zipflag == COMPRESS_LZO) {
+                               compresult = lzo1x_1_compress((char *)slp->tblock[0],writesize,
+                                                              comp_buf->buf,
+                                                             (lzo_uintp)&worklen,
+                                                              LZO_WorkMem);
+                               if (compresult == LZO_E_OK)
+                                       compresult = 1;
+                               else
+                                       compresult = 0;
+                       }
+#endif /* HAVE_LZO */
+                       if (compresult && worklen <= ((unsigned long)writesize - 16)) {
                                /* write the compressed buffer */
                                comp_buf->length = worklen;
                                comp_buf->compressed = 1;
@@ -1219,7 +1264,7 @@ doslave(int cmd, int slave_number, int first)
                }
                /* compress the remaining blocks if we're compressing */
                do_compress = compressed;
-#endif /* HAVE_ZLIB  || HAVE_BZLIB */
+#endif /* HAVE_ZLIB  || HAVE_BZLIB || HAVE_LZO */
 
                if (sigsetjmp(jmpbuf, 1) == 0) {
                        ready = 1;
@@ -1264,11 +1309,12 @@ doslave(int cmd, int slave_number, int first)
 #ifdef WRITEDEBUG
                        printf("slave %d wrote %d\n", slave_number, wrote);
 #endif
-                       if (wrote < 0)
+                       if (wrote < 0 && errno != ENOSPC)
                                break;
-                       if (wrote == 0)
+                       if (wrote == 0 || (wrote < 0 && errno == ENOSPC))
                                eot_count++;
-                       size += wrote;
+                       else
+                               size += wrote;
                }
 
 #ifdef WRITEDEBUG
@@ -1323,7 +1369,7 @@ dump_atomic_read(int fd, void *buf, size_t count)
                while ((got = read(fd, buf, need)) > 0 && (need -= got) > 0)
                        (char *)buf += got;
        } while (got == -1 && errno == EINTR);
-       return (got < 0 ? got : count - need);
+       return (got < 0 ? got : (ssize_t)count - need);
 }
 
 /*
@@ -1340,7 +1386,7 @@ dump_atomic_write(int fd, const void *buf, size_t count)
                while ((got = write(fd, buf, need)) > 0 && (need -= got) > 0)
                        (char *)buf += got;
        } while (got == -1 && errno == EINTR);
-       return (got < 0 ? got : count - need);
+       return (got < 0 ? got : (ssize_t)count - need);
 }
 
 
@@ -1393,7 +1439,7 @@ MkTapeString(struct s_spcl *spclptr, long long curtapepos) {
                 tapeno, 
                 curtapepos);
        gTps[sizeof(gTps) - 1] = '\0';
-       if (write(gTapeposfd, gTps, strlen(gTps)) != strlen(gTps)) {
+       if (write(gTapeposfd, gTps, strlen(gTps)) != (ssize_t)strlen(gTps)) {
                warn("error writing tapepos file.\n");
        }
 }