]> git.wh0rd.org - dump.git/blobdiff - dump/tape.c
Fix a bug in dump where waiting too much when changing tapes causes the volume to...
[dump.git] / dump / tape.c
index 91474418c3bef907d6acd6c0df6ecb5442bb8836..2db739cf91b19e5e0df7ae845e62618358cf8e5a 100644 (file)
@@ -2,7 +2,8 @@
  *     Ported to Linux's Second Extended File System as part of the
  *     dump and restore backup suit
  *     Remy Card <card@Linux.EU.Org>, 1994-1997
- *     Stelian Pop <pop@cybercable.fr>, 1999-2000
+ *     Stelian Pop <pop@noos.fr>, 1999-2000
+ *     Stelian Pop <pop@noos.fr> - AlcĂ´ve <www.alcove.fr>, 2000
  */
 
 /*-
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: tape.c,v 1.22 2000/08/21 10:45:40 stelian Exp $";
+       "$Id: tape.c,v 1.30 2001/02/16 13:38:47 stelian Exp $";
 #endif /* not lint */
 
+#include <config.h>
 #ifdef __linux__
 #include <sys/types.h>
 #include <linux/types.h>
@@ -234,24 +236,27 @@ dumpblock(daddr_t blkno, int size)
 int    nogripe = 0;
 
 static void
-tperror(int signo)
+tperror(int errnum)
 {
 
        if (pipeout) {
-               msg("write error on %s\n", tape);
+               msg("write error on %s: %s\n", tape, strerror(errnum));
                quit("Cannot recover\n");
                /* NOTREACHED */
        }
-       msg("write error %d blocks into volume %d\n", blocksthisvol, tapeno);
+       msg("write error %d blocks into volume %d: %s\n", blocksthisvol, tapeno, strerror(errnum));
        broadcast("DUMP WRITE ERROR!\n");
-       if (!query("Do you want to restart?"))
-               dumpabort(0);
-       msg("Closing this volume.  Prepare to restart with new media;\n");
-       msg("this dump volume will be rewritten.\n");
-       killall();
-       nogripe = 1;
-       close_rewind();
-       Exit(X_REWRITE);
+       if (query("Do you want to rewrite this volume?")) {
+               msg("Closing this volume.  Prepare to restart with new media;\n");
+               msg("this dump volume will be rewritten.\n");
+               killall();
+               nogripe = 1;
+               close_rewind();
+               Exit(X_REWRITE);
+       }
+       if (query("Do you want to start the next tape?"))
+               return;
+       dumpabort(0);
 }
 
 static void
@@ -284,6 +289,8 @@ do_stats(void)
 #else
                                          ctime(&tnow));
 #endif
+       msg("Volume %d: %ld tape blocks (%.2fMB)\n", tapeno, 
+               blocks, ((double)blocks * TP_BSIZE / 1048576));
        if (ttaken > 0) {
                msg("Volume %d took %d:%02d:%02d\n", tapeno,
                        ttaken / 3600, (ttaken % 3600) / 60, ttaken % 60);
@@ -294,36 +301,55 @@ do_stats(void)
        return(tnow);
 }
 
+char *
+mktimeest(time_t tnow)
+{
+       static char msgbuf[128];
+       time_t deltat;
+
+       msgbuf[0] = '\0';
+
+       if (blockswritten < 500)
+               return NULL;
+       if (blockswritten > tapesize)
+               tapesize = blockswritten;
+       deltat = tstart_writing - tnow + (1.0 * (tnow - tstart_writing))
+               / blockswritten * tapesize;
+       if (tnow > tstart_volume)
+               (void)snprintf(msgbuf, sizeof(msgbuf),
+                       "%3.2f%% done at %ld KB/s, finished in %d:%02d\n",
+                       (blockswritten * 100.0) / tapesize,
+                       (spcl.c_tapea - tapea_volume) / (tnow - tstart_volume),
+                       (int)(deltat / 3600), (int)((deltat % 3600) / 60));
+       else
+               (void)snprintf(msgbuf, sizeof(msgbuf),
+                       "%3.2f%% done, finished in %d:%02d\n",
+                       (blockswritten * 100.0) / tapesize,
+                       (int)(deltat / 3600), (int)((deltat % 3600) / 60));
+
+       return msgbuf;
+}
+
 #if defined(SIGINFO)
 /*
  * statussig --
  *     information message upon receipt of SIGINFO
- *     (derived from optr.c::timeest())
  */
 void
 statussig(int notused)
 {
-       time_t  tnow, deltat;
-       char    msgbuf[128];
+       time_t tnow;
        int save_errno = errno;
+       char *buf;
 
-       if (blockswritten < 500)
-               return;
 #ifdef __linux__
        (void) time4(&tnow);
 #else
        (void) time((time_t *) &tnow);
 #endif
-       if (blockswritten > tapesize)
-               tapesize = blockswritten;
-       deltat = tstart_writing - tnow + (1.0 * (tnow - tstart_writing))
-               / blockswritten * tapesize;
-       (void)snprintf(msgbuf, sizeof(msgbuf),
-               "%3.2f%% done at %ld KB/s, finished in %d:%02d\n",
-               (blockswritten * 100.0) / tapesize,
-               (spcl.c_tapea - tapea_volume) / (tnow - tstart_volume),
-               (int)(deltat / 3600), (int)((deltat % 3600) / 60));
-       write(STDERR_FILENO, msgbuf, strlen(msgbuf));
+       buf = mktimeest(tnow);
+       if (buf)
+               write(STDERR_FILENO, buf, strlen(buf));
        errno = save_errno;
 }
 #endif
@@ -356,6 +382,10 @@ flushtape(void)
                }
                slp->sent = 0;
 
+               /* Check for errors */
+               if (got < 0)
+                       tperror(-got);
+               
                /* Check for end of tape */
                if (got < writesize) {
                        msg("End of tape detected\n");
@@ -469,6 +499,10 @@ trewind(void)
                                dumpabort(0);
                        }
                        slaves[f].sent = 0;
+
+                       if (got < 0)
+                               tperror(-got);
+
                        if (got != writesize) {
                                msg("EOT detected in last 2 tape records!\n");
                                msg("Use a longer tape, decrease the size estimate\n");
@@ -642,6 +676,9 @@ rollforward(void)
                }
                slp->sent = 0;
 
+               if (got < 0)
+                       tperror(-got);
+
                if (got != writesize) {
                        quit("EOT detected at start of the tape!\n");
                }
@@ -895,17 +932,12 @@ enslave(void)
        master = getpid();
 
     {  struct sigaction sa;
-#if    HAVE_SIGACTION_SA_SIGACTION
-       sa.sa_sigaction = NULL;
-#endif
+       memset(&sa, 0, sizeof sa);
        sigemptyset(&sa.sa_mask);
-       sa.sa_flags = 0;
        sa.sa_handler = dumpabort;
        sigaction(SIGTERM, &sa, NULL); /* Slave sends SIGTERM on dumpabort() */
        sa.sa_handler = sigpipe;
        sigaction(SIGPIPE, &sa, NULL);
-       sa.sa_handler = tperror;
-       sigaction(SIGUSR1, &sa, NULL); /* Slave sends SIGUSR1 on tape errors */
        sa.sa_handler = proceed;
        sa.sa_flags = SA_RESTART;
        sigaction(SIGUSR2, &sa, NULL); /* Slave sends SIGUSR2 to next slave */
@@ -990,7 +1022,6 @@ doslave(int cmd, int slave_number)
        register int nread;
        int nextslave, size, eot_count;
        volatile int wrote = 0;
-       sigset_t sigset;
 #ifdef __linux__
        errcode_t retval;
 #endif
@@ -1083,19 +1114,17 @@ doslave(int cmd, int slave_number)
                if (eot_count > 0)
                        size = 0;
 
-               if (wrote < 0) {
-                       (void) kill(master, SIGUSR1);
-                       sigemptyset(&sigset);
-                       sigaddset(&sigset, SIGINT);
-                       for (;;)
-                               sigsuspend(&sigset);
-               } else {
-                       /*
-                        * pass size of write back to master
-                        * (for EOT handling)
-                        */
-                       (void) atomic_write( cmd, (char *)&size, sizeof size);
-               }
+               /*
+                * pass errno back to master for special handling
+                */
+               if (wrote < 0)
+                       size = -errno;
+
+               /*
+                * pass size of write back to master
+                * (for EOT handling)
+                */
+               (void) atomic_write( cmd, (char *)&size, sizeof size);
 
                /*
                 * If partial write, don't want next slave to go.