* 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
- *
+ * Stelian Pop <pop@cybercable.fr>, 1999-2000
*/
/*-
*/
#ifndef lint
-#if 0
-static char sccsid[] = "@(#)tape.c 8.4 (Berkeley) 5/1/95";
-#endif
static const char rcsid[] =
- "$Id: tape.c,v 1.3 1999/10/11 12:59:19 stelian Exp $";
+ "$Id: tape.c,v 1.17 2000/03/10 10:03:09 stelian Exp $";
#endif /* not lint */
#ifdef __linux__
#include <setjmp.h>
#include <signal.h>
#include <stdio.h>
+#include <compaterr.h>
#ifdef __STDC__
#include <stdlib.h>
#include <string.h>
int write(), read();
#endif
-#ifdef __linux__
+#ifdef __linux__
#include <ext2fs/ext2fs.h>
#endif
+
#include "dump.h"
int writesize; /* size of malloc()ed buffer for tape */
extern int cartridge;
extern char *host;
char *nexttape;
+extern pid_t rshpid;
+int eot_code = 1;
static ssize_t atomic_read __P((int, void *, size_t));
static ssize_t atomic_write __P((int, const void *, size_t));
static void flushtape __P((void));
static void killall __P((void));
static void rollforward __P((void));
+static int system_command __P((const char *, const char *, int));
/*
* Concurrent dump mods (Caltech) - disk block reading and tape writing
time_t tnow, ttaken;
int blocks;
+#ifdef __linux__
+ (void)time4(&tnow);
+#else
(void)time(&tnow);
+#endif
ttaken = tnow - tstart_volume;
blocks = spcl.c_tapea - tapea_volume;
- msg("Volume %d completed at: %s", tapeno, ctime(&tnow));
+ msg("Volume %d completed at: %s", tapeno,
+#ifdef __linux__
+ ctime4(&tnow));
+#else
+ ctime(&tnow));
+#endif
if (ttaken > 0) {
msg("Volume %d took %d:%02d:%02d\n", tapeno,
ttaken / 3600, (ttaken % 3600) / 60, ttaken % 60);
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),
timeest();
}
-void
+/*
+ * Executes the command in a shell.
+ * Returns -1 if an error occured, the exit status of
+ * the command on success.
+ */
+int system_command(const char *command, const char *device, int volnum) {
+ int pid, status;
+ char commandstr[4096];
+
+ pid = fork();
+ if (pid == -1) {
+ perror(" DUMP: unable to fork");
+ return -1;
+ }
+ if (pid == 0) {
+ setuid(getuid());
+ setgid(getgid());
+ snprintf(commandstr, sizeof(commandstr), "%s %s %d", command, device, volnum);
+ commandstr[sizeof(commandstr) - 1] = '\0';
+ execl("/bin/sh", "sh", "-c", commandstr, NULL);
+ perror(" DUMP: unable to execute shell");
+ exit(-1);
+ }
+ do {
+ if (waitpid(pid, &status, 0) == -1) {
+ if (errno != EINTR) {
+ perror(" DUMP: waitpid error");
+ return -1;
+ }
+ } else {
+ if (WIFEXITED(status))
+ return WEXITSTATUS(status);
+ else
+ return -1;
+ }
+ } while(1);
+}
+
+time_t
trewind(void)
{
int f;
while (wait((int *)NULL) >= 0) /* wait for any signals from slaves */
/* void */;
- if (pipeout)
- return;
+ if (!pipeout) {
- msg("Closing %s\n", tape);
+ msg("Closing %s\n", tape);
#ifdef RDUMP
- if (host) {
- rmtclose();
- while (rmtopen(tape, 0) < 0)
- sleep(10);
- rmtclose();
- return;
- }
+ if (host) {
+ rmtclose();
+ while (rmtopen(tape, 0) < 0)
+ sleep(10);
+ rmtclose();
+ }
+ else
+#else
+ {
+ (void) close(tapefd);
+ while ((f = open(tape, 0)) < 0)
+ sleep (10);
+ (void) close(f);
+ }
#endif
- (void) close(tapefd);
- while ((f = open(tape, 0)) < 0)
- sleep (10);
- (void) close(f);
+ eot_code = 1;
+ 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);
+ }
+ }
+ return do_stats();
}
+
void
close_rewind(void)
{
- time_t tstart_changevol, tend_changevol;
-
- trewind();
- (void)do_stats();
- if (nexttape)
+ (void)trewind();
+ if (nexttape || Mflag || (eot_code == 0) )
return;
-#ifdef __linux__
- (void)time4(&(tstart_changevol));
-#else
- (void)time((time_t *)&(tstart_changevol));
-#endif
if (!nogripe) {
msg("Change Volumes: Mount volume #%d\n", tapeno+1);
broadcast("CHANGE DUMP VOLUMES!\7\7\n");
dumpabort(0);
/*NOTREACHED*/
}
-#ifdef __linux__
- (void)time4(&(tend_changevol));
-#else
- (void)time((time_t *)&(tend_changevol));
-#endif
- if ((tstart_changevol != (time_t)-1) && (tend_changevol != (time_t)-1))
- tstart_writing += (tend_changevol - tstart_changevol);
}
void
interrupt_save = signal(SIGINT, SIG_IGN);
parentpid = getpid();
tapea_volume = spcl.c_tapea;
- (void)time(&tstart_volume);
+#ifdef __linux__
+ (void)time4(&tstart_volume);
+#else
+ (void)time((&tstart_volume);
+#endif
restore_check_point:
(void)signal(SIGINT, interrupt_save);
tapeno+1, parentpid, childpid);
#endif /* TDEBUG */
while ((waitpid = wait(&status)) != childpid)
- msg("Parent %d waiting for child %d has another child %d return\n",
+ if (waitpid != rshpid)
+ msg("Parent %d waiting for child %d has another child %d return\n",
parentpid, childpid, waitpid);
if (status & 0xFF) {
msg("Child %d returns LOB status %o\n",
* the remaining names for subsequent volumes.
*/
tapeno++; /* current tape sequence */
- if (nexttape || strchr(tape, ',')) {
+ if (Mflag) {
+ snprintf(tape, MAXPATHLEN, "%s%03d", tapeprefix, tapeno);
+ tape[MAXPATHLEN - 1] = '\0';
+ msg("Dumping volume %d on %s\n", tapeno, tape);
+ }
+ else if (nexttape || strchr(tapeprefix, ',')) {
if (nexttape && *nexttape)
- tape = nexttape;
- if ((p = strchr(tape, ',')) != NULL) {
+ tapeprefix = nexttape;
+ if ((p = strchr(tapeprefix, ',')) != NULL) {
*p = '\0';
nexttape = p + 1;
} else
nexttape = NULL;
+ strncpy(tape, tapeprefix, MAXPATHLEN);
+ tape[MAXPATHLEN - 1] = '\0';
msg("Dumping volume %d on %s\n", tapeno, tape);
}
#ifdef RDUMP
- while ((tapefd = (host ? rmtopen(tape, 2) :
- pipeout ? 1 : open(tape, O_WRONLY|O_CREAT, 0666))) < 0)
+ while ((tapefd = (host ? rmtopen(tape, 2) : pipeout ?
+ fileno(stdout) :
+ open(tape, O_WRONLY|O_CREAT, 0666))) < 0)
#else
- while ((tapefd = (pipeout ? 1 :
+ while ((tapefd = (pipeout ? fileno(stdout) :
open(tape, O_WRONLY|O_CREAT, 0666))) < 0)
#endif
{
spcl.c_flags |= DR_NEWHEADER;
writeheader((ino_t)slp->inode);
spcl.c_flags &=~ DR_NEWHEADER;
- msg("Volume %d started at: %s", tapeno, ctime(&tstart_volume));
+ msg("Volume %d started at: %s", tapeno,
+#ifdef __linux__
+ ctime4(&tstart_volume));
+#else
+ ctime(&tstart_volume));
+#endif
if (tapeno > 1)
msg("Volume %d begins with blocks from inode %d\n",
tapeno, slp->inode);
quit("slave couldn't reopen disk: %s\n", strerror(errno));
#ifdef __linux__
ext2fs_close(fs);
- retval = ext2fs_open(disk, 0, 0, 0, unix_io_manager, &fs);
+ retval = dump_fs_open(disk, &fs);
if (retval)
- quit("slave couldn't reopen disk: %s\n", strerror(errno));
+ quit("slave couldn't reopen disk: %s\n", error_message(retval));
#endif /* __linux__ */
/*
{
int got, need = count;
- while ((got = read(fd, buf, need)) > 0 && (need -= got) > 0)
- (char *)buf += got;
+ do {
+ while ((got = read(fd, buf, need)) > 0 && (need -= got) > 0)
+ (char *)buf += got;
+ } while (got == -1 && errno == EINTR);
return (got < 0 ? got : count - need);
}
{
int got, need = count;
- while ((got = write(fd, buf, need)) > 0 && (need -= got) > 0)
- (char *)buf += got;
+ do {
+ while ((got = write(fd, buf, need)) > 0 && (need -= got) > 0)
+ (char *)buf += got;
+ } while (got == -1 && errno == EINTR);
return (got < 0 ? got : count - need);
}