X-Git-Url: https://git.wh0rd.org/?a=blobdiff_plain;f=dump%2Ftape.c;h=45828a52f742e782b48582be691317487a9e8070;hb=365a7c7c86abbe2b0a1e76e4e9fc8523bd73a8a1;hp=1b28c41e6e6307a9a9f662d36fc243c0b28045c3;hpb=f34aca37d19fe46de9acb22249565dfb6491ab2f;p=dump.git diff --git a/dump/tape.c b/dump/tape.c index 1b28c41..45828a5 100644 --- a/dump/tape.c +++ b/dump/tape.c @@ -2,7 +2,7 @@ * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit * Remy Card , 1994-1997 - * Stelian Pop , 1999 + * Stelian Pop , 1999-2000 */ /*- @@ -40,7 +40,7 @@ #ifndef lint static const char rcsid[] = - "$Id: tape.c,v 1.7 1999/11/02 09:35:56 tiniou Exp $"; + "$Id: tape.c,v 1.17 2000/03/10 10:03:09 stelian Exp $"; #endif /* not lint */ #ifdef __linux__ @@ -73,6 +73,7 @@ static const char rcsid[] = #include #include #include +#include #ifdef __STDC__ #include #include @@ -81,9 +82,10 @@ static const char rcsid[] = int write(), read(); #endif -#ifdef __linux__ +#ifdef __linux__ #include #endif + #include "dump.h" int writesize; /* size of malloc()ed buffer for tape */ @@ -96,6 +98,7 @@ 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)); @@ -104,6 +107,7 @@ static void enslave __P((void)); 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 @@ -310,6 +314,8 @@ statussig(int notused) #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), @@ -399,7 +405,45 @@ flushtape(void) 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; @@ -432,32 +476,45 @@ trewind(void) 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) { - trewind(); - (void)do_stats(); - if (nexttape) + (void)trewind(); + if (nexttape || Mflag || (eot_code == 0) ) return; if (!nogripe) { msg("Change Volumes: Mount volume #%d\n", tapeno+1); @@ -711,21 +768,29 @@ restore_check_point: * 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 { @@ -908,9 +973,9 @@ doslave(int cmd, int slave_number) 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__ */ /* @@ -1021,8 +1086,10 @@ atomic_read(int fd, void *buf, size_t count) { 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); } @@ -1036,7 +1103,9 @@ atomic_write(int fd, const void *buf, size_t count) { 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); }