X-Git-Url: https://git.wh0rd.org/?p=dump.git;a=blobdiff_plain;f=dump%2Ftape.c;h=69715003e67bf772103bfad8d0b5d996a64c03ec;hp=f4133942dd332a771d667c211c7c6c6a46bdea54;hb=30a43325fdf58f596d4219fcabb6d46b8d884bdf;hpb=d339304329df2d458e54c02eac10a27cb31d9cb1 diff --git a/dump/tape.c b/dump/tape.c index f413394..6971500 100644 --- a/dump/tape.c +++ b/dump/tape.c @@ -40,7 +40,7 @@ #ifndef lint static const char rcsid[] = - "$Id: tape.c,v 1.13 2000/02/26 01:35:48 stelian Exp $"; + "$Id: tape.c,v 1.19 2000/05/28 16:24:14 stelian Exp $"; #endif /* not lint */ #ifdef __linux__ @@ -73,6 +73,7 @@ static const char rcsid[] = #include #include #include +#include #ifdef __STDC__ #include #include @@ -97,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)); @@ -105,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 @@ -402,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; @@ -435,32 +476,44 @@ 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 #endif - (void) close(tapefd); - while ((f = open(tape, 0)) < 0) - sleep (10); - (void) close(f); + { + (void) close(tapefd); + while ((f = open(tape, 0)) < 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(); } + void close_rewind(void) { - trewind(); - (void)do_stats(); - if (nexttape || Mflag) + (void)trewind(); + if (nexttape || Mflag || (eot_code == 0) ) return; if (!nogripe) { msg("Change Volumes: Mount volume #%d\n", tapeno+1); @@ -564,12 +617,13 @@ rollforward(void) } slp->req[0] = *q; nextblock = slp->tblock; - if (q->dblk == 0) + if (q->dblk == 0) { #ifdef __linux__ - *(union u_spcl *)(*(nextblock)++) = *(union u_spcl *)tslp->tblock; -#else - nextblock++; + /* XXX post increment triggers an egcs-1.1.2-12 bug on alpha/sparc */ + *(union u_spcl *)(*nextblock) = *(union u_spcl *)tslp->tblock; #endif + nextblock++; + } trecno = 1; /* @@ -623,17 +677,21 @@ startnewtape(int top) int status; int waitpid; char *p; + #ifdef __linux__ - void (*interrupt_save) __P((int signo)); + sigset_t sigs; + sigemptyset(&sigs); + sigaddset(&sigs, SIGINT); + sigprocmask(SIG_BLOCK, &sigs, NULL); #else /* __linux__ */ #ifdef sunos void (*interrupt_save)(); #else sig_t interrupt_save; #endif + interrupt_save = signal(SIGINT, SIG_IGN); #endif /* __linux__ */ - interrupt_save = signal(SIGINT, SIG_IGN); parentpid = getpid(); tapea_volume = spcl.c_tapea; #ifdef __linux__ @@ -643,7 +701,11 @@ startnewtape(int top) #endif restore_check_point: +#ifdef __linux__ + sigprocmask(SIG_UNBLOCK, &sigs, NULL); +#else (void)signal(SIGINT, interrupt_save); +#endif /* * All signals are inherited... */ @@ -659,7 +721,11 @@ restore_check_point: * until the child doing all of the work returns. * don't catch the interrupt */ +#ifdef __linux__ + sigprocmask(SIG_BLOCK, &sigs, NULL); +#else signal(SIGINT, SIG_IGN); +#endif #ifdef TDEBUG msg("Tape: %d; parent process: %d child process %d\n", tapeno+1, parentpid, childpid); @@ -715,8 +781,8 @@ restore_check_point: */ tapeno++; /* current tape sequence */ if (Mflag) { - snprintf(tape, NAME_MAX, "%s%03d", tapeprefix, tapeno); - tape[NAME_MAX - 1] = '\0'; + 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, ',')) { @@ -727,8 +793,8 @@ restore_check_point: nexttape = p + 1; } else nexttape = NULL; - strncpy(tape, tapeprefix, NAME_MAX); - tape[NAME_MAX - 1] = '\0'; + strncpy(tape, tapeprefix, MAXPATHLEN); + tape[MAXPATHLEN - 1] = '\0'; msg("Dumping volume %d on %s\n", tapeno, tape); } #ifdef RDUMP @@ -807,10 +873,9 @@ Exit(int status) static void proceed(int signo) { - + caught++; if (ready) siglongjmp(jmpbuf, 1); - caught++; } void @@ -825,10 +890,17 @@ enslave(void) master = getpid(); - signal(SIGTERM, dumpabort); /* Slave sends SIGTERM on dumpabort() */ - signal(SIGPIPE, sigpipe); - signal(SIGUSR1, tperror); /* Slave sends SIGUSR1 on tape errors */ - signal(SIGUSR2, proceed); /* Slave sends SIGUSR2 to next slave */ + { struct sigaction sa; + 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 */ + } for (i = 0; i < SLAVES; i++) { if (i == slp - &slaves[0]) { @@ -845,12 +917,15 @@ enslave(void) slaves[i].fd = cmd[1]; slaves[i].sent = 0; if (slaves[i].pid == 0) { /* Slave starts up here */ + sigset_t sigs; for (j = 0; j <= i; j++) (void) close(slaves[j].fd); - signal(SIGINT, SIG_IGN); /* Master handles this */ + sigemptyset(&sigs); + sigaddset(&sigs, SIGINT); /* Master handles this */ #if defined(SIGINFO) - signal(SIGINFO, SIG_IGN); + sigaddset(&sigs, SIGINFO); #endif + sigprocmask(SIG_BLOCK, &sigs, NULL); #ifdef LINUX_FORK_BUG if (atomic_write( cmd[0], (char *) &i, sizeof i) @@ -950,7 +1025,7 @@ doslave(int cmd, int slave_number) quit("master/slave protocol botched.\n"); } } - if (setjmp(jmpbuf) == 0) { + if (sigsetjmp(jmpbuf, 1) == 0) { ready = 1; if (!caught) (void) pause();