* 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.23 2000/08/30 08:55:21 stelian Exp $";
+ "$Id: tape.c,v 1.28 2000/12/21 15:01:54 stelian Exp $";
#endif /* not lint */
+#include <config.h>
#ifdef __linux__
#include <sys/types.h>
#include <linux/types.h>
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
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;
+ (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));
+
+ 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
}
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");
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");
}
slp->sent = 0;
+ if (got < 0)
+ tperror(-got);
+
if (got != writesize) {
quit("EOT detected at start of the tape!\n");
}
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 */
register int nread;
int nextslave, size, eot_count;
volatile int wrote = 0;
- sigset_t sigset;
#ifdef __linux__
errcode_t retval;
#endif
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.