X-Git-Url: https://git.wh0rd.org/?p=dump.git;a=blobdiff_plain;f=dump%2Ftape.c;h=e0b54112bb602dbb69ecead4356c96b128471d25;hp=edcf5d691925a6532dd71e8b30f75514d8190109;hb=e3956dfb7715a21919aa66dd4209a2dc1c3c82da;hpb=b8db960b14856a2ab86e044b2ffa53612d2aa489 diff --git a/dump/tape.c b/dump/tape.c index edcf5d6..e0b5411 100644 --- a/dump/tape.c +++ b/dump/tape.c @@ -37,7 +37,7 @@ #ifndef lint static const char rcsid[] = - "$Id: tape.c,v 1.91 2009/06/18 09:50:54 stelian Exp $"; + "$Id: tape.c,v 1.95 2011/06/10 13:07:29 stelian Exp $"; #endif /* not lint */ #include @@ -92,18 +92,6 @@ int write(), read(); #include -#ifdef HAVE_ZLIB -#include -#endif /* HAVE_ZLIB */ - -#ifdef HAVE_BZLIB -#include -#endif /* HAVE_BZLIB */ - -#ifdef HAVE_LZO -#include -#endif /* HAVE_LZO */ - #include "dump.h" int writesize; /* size of malloc()ed buffer for tape */ @@ -178,10 +166,15 @@ static int tapea_volume; /* value of spcl.c_tapea at volume start */ int master; /* pid of master, for sending error signals */ int tenths; /* length of tape overhead per block written */ -static int caught; /* have we caught the signal to proceed? */ -static int ready; /* have we reached the lock point without having */ +static int caught1; /* have we caught the signal to proceed? */ +static int ready1; /* have we reached the lock point without having */ + /* received the SIGUSR2 signal from the prev slave? */ +static sigjmp_buf jmpbuf1; /* where to jump to if we are ready when the */ + /* SIGUSR1 arrives from the previous slave */ +static int caught2; /* have we caught the signal to proceed? */ +static int ready2; /* have we reached the lock point without having */ /* received the SIGUSR2 signal from the prev slave? */ -static sigjmp_buf jmpbuf; /* where to jump to if we are ready when the */ +static sigjmp_buf jmpbuf2; /* where to jump to if we are ready when the */ /* SIGUSR2 arrives from the previous slave */ #ifdef USE_QFA static int gtperr = 0; @@ -211,8 +204,17 @@ static int gtperr = 0; * Neither is useful in our case, so this is easy to handle. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,49) -/* clone_flags, child_stack, parent_tidptr, child_tidptr */ +/* + * Parameters of the sys_clone syscall are + * clone_flags, child_stack, parent_tidptr, child_tidptr + * on all architectures except s390 and s390x + * s390* have child_stack, clone_flags, parent_tidptr, child_tidptr + */ +#if defined(__s390__) || defined(__s390x__) +#define CLONE_ARGS 0, SIGCHLD|CLONE_IO, NULL, NULL +#else #define CLONE_ARGS SIGCHLD|CLONE_IO, 0, NULL, NULL +#endif #else #define CLONE_ARGS SIGCHLD|CLONE_IO, 0 #endif /* LINUX_VERSION_CODE */ @@ -272,7 +274,6 @@ alloctape(void) void writerec(const void *dp, int isspcl) { - slp->req[trecno].dblk = (ext2_loff_t)0; slp->req[trecno].count = 1; /* XXX post increment triggers an egcs-1.1.2-12 bug on alpha/sparc */ @@ -989,6 +990,7 @@ restore_check_point: tapeno, slp->inode); if (tapeno < (int)TP_NINOS) volinfo[tapeno] = slp->inode; + transformation->startNewTape(transformation, NULL, 0); } } @@ -1019,15 +1021,26 @@ Exit(int status) exit(status); } +/* + * proceed - handler for SIGUSR1, used to synchronize IO between the slaves. + */ +static void +proceed1(UNUSED(int signo)) +{ + if (ready1) + siglongjmp(jmpbuf1, 1); + caught1++; +} + /* * proceed - handler for SIGUSR2, used to synchronize IO between the slaves. */ static void -proceed(UNUSED(int signo)) +proceed2(UNUSED(int signo)) { - if (ready) - siglongjmp(jmpbuf, 1); - caught++; + if (ready2) + siglongjmp(jmpbuf2, 1); + caught2++; } void @@ -1049,16 +1062,21 @@ enslave(void) sigaction(SIGTERM, &sa, NULL); /* Slave sends SIGTERM on dumpabort() */ sa.sa_handler = sigpipe; sigaction(SIGPIPE, &sa, NULL); - sa.sa_handler = proceed; + sa.sa_handler = proceed1; + sa.sa_flags = SA_RESTART; + sigaction(SIGUSR1, &sa, NULL); /* Slave sends SIGUSR1 to next slave */ + sa.sa_handler = proceed2; 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]) { - caught = 1; + caught1 = 1; + caught2 = 1; } else { - caught = 0; + caught1 = 0; + caught2 = 0; } if (socketpair(AF_UNIX, SOCK_STREAM, 0, cmd) < 0 || @@ -1131,7 +1149,9 @@ killall(void) * previous process before writing to the tape, and sends SIGUSR2 * to the next process when the tape write completes. On tape errors * a SIGUSR1 is sent to the master which then terminates all of the - * slaves. + * slaves. Each process sends SIGUSR1 to the next to signal that it + * is time to start reading from the disk, after it finishes reading + * and moves to the compression phase. */ static void doslave(int cmd, @@ -1144,15 +1164,13 @@ doslave(int cmd, int nextslave; volatile int wrote = 0, size, eot_count, bufsize; char * volatile buffer; -#if defined(HAVE_ZLIB) || defined(HAVE_BZLIB) || defined(HAVE_LZO) +#if defined(HAVE_BLOCK_TRANSFORMATION) struct tapebuf * volatile comp_buf = NULL; int compresult; volatile int do_compress = !first; unsigned long worklen; -#ifdef HAVE_LZO - lzo_align_t __LZO_MMODEL *LZO_WorkMem; -#endif -#endif /* HAVE_ZLIB || HAVE_BZLIB || HAVE_LZO */ +#endif /* HAVE_BLOCK_TRANSFORMATION */ + struct slave_results returns; #ifdef __linux__ errcode_t retval; @@ -1168,10 +1186,15 @@ doslave(int cmd, sigset_t set; sigemptyset(&set); + sigaddset(&set, SIGUSR1); sigaddset(&set, SIGUSR2); sigprocmask(SIG_BLOCK, &set, NULL); sigemptyset(&set); +#ifdef HAVE_BLOCK_TRANSFORMATION + transformation->startDiskIOProcess(transformation); +#endif /* HAVE_BLOCK_TRANSFORMATION */ + /* * Need our own seek pointer. */ @@ -1196,34 +1219,29 @@ doslave(int cmd, quit("master/slave protocol botched - didn't get pid of next slave.\n"); } -#if defined(HAVE_ZLIB) || defined(HAVE_BZLIB) || defined(HAVE_LZO) +#if defined(HAVE_BLOCK_TRANSFORMATION) /* if we're doing a compressed dump, allocate the compress buffer */ if (compressed) { int bsiz = sizeof(struct tapebuf) + writesize; - /* Add extra space to deal with compression enlarging the buffer */ - if (TP_BSIZE > writesize/16 + 67) + /* Add extra space to deal with compression or encryption enlarging the buffer */ + if (TP_BSIZE > writesize/16 + 200) bsiz += TP_BSIZE; else - bsiz += writesize/16 + 67; + bsiz += writesize/16 + 200; comp_buf = malloc(bsiz); if (comp_buf == NULL) quit("couldn't allocate a compress buffer.\n"); + transformation->initialize(transformation, 1); if (zipflag == COMPRESS_ZLIB) comp_buf->flags = COMPRESS_ZLIB; else if (zipflag == COMPRESS_BZLIB) comp_buf->flags = COMPRESS_BZLIB; - else if (zipflag == COMPRESS_LZO) { + else if (zipflag == COMPRESS_LZO) comp_buf->flags = COMPRESS_LZO; - if (lzo_init() != LZO_E_OK) quit("lzo_init failed\n"); - } else + else quit("internal error - unknown compression method: %d\n", zipflag); } -#ifdef HAVE_LZO - LZO_WorkMem = malloc(LZO1X_1_MEM_COMPRESS); - if (!LZO_WorkMem) - quit("couldn't allocate a compress buffer.\n"); -#endif -#endif /* HAVE_ZLIB || HAVE_BZLIB || HAVE_LZO */ +#endif /* HAVE_BLOCK_TRANSFORMATION */ /* * Get list of blocks to dump, read the blocks into tape buffer @@ -1231,8 +1249,18 @@ doslave(int cmd, while ((nread = dump_atomic_read( cmd, (char *)slp->req, reqsiz)) == reqsiz) { struct req *p = slp->req; + /* wait for previous slave to finish reading */ + if (sigsetjmp(jmpbuf1, 1) == 0) { + ready1 = 1; + if (!caught1) + sigsuspend(&set); + } + ready1 = 0; + caught1 = 0; + for (trecno = 0; trecno < ntrec; trecno += p->count, p += p->count) { + if (p->dblk) { /* read a disk block */ bread(p->dblk, slp->tblock[trecno], p->count * TP_BSIZE); @@ -1243,6 +1271,8 @@ doslave(int cmd, quit("master/slave protocol botched.\n"); } } + /* signal next slave to start reading */ + (void) kill(nextslave, SIGUSR1); /* Try to write the data... */ wrote = 0; @@ -1252,7 +1282,7 @@ doslave(int cmd, bufsize = writesize; /* length to write */ returns.clen = returns.unclen = bufsize; -#if defined(HAVE_ZLIB) || defined(HAVE_BZLIB) || defined(HAVE_LZO) +#if defined(HAVE_BLOCK_TRANSFORMATION) /* * When writing a compressed dump, each block except * the first one on each tape is written @@ -1265,56 +1295,15 @@ doslave(int cmd, * The first block written by each slave is not compressed * and does not have a prefix. */ - if (compressed && do_compress) { comp_buf->length = bufsize; worklen = TP_BSIZE + writesize; compresult = 1; -#ifdef HAVE_ZLIB - if (zipflag == COMPRESS_ZLIB) { - compresult = compress2(comp_buf->buf, - &worklen, - (char *)slp->tblock[0], - writesize, - compressed); - if (compresult == Z_OK) - compresult = 1; - else - compresult = 0; - } -#endif /* HAVE_ZLIB */ -#ifdef HAVE_BZLIB - if (zipflag == COMPRESS_BZLIB) { - unsigned int worklen2 = worklen; - compresult = BZ2_bzBuffToBuffCompress( - comp_buf->buf, - &worklen2, - (char *)slp->tblock[0], - writesize, - compressed, - 0, 30); - worklen = worklen2; - if (compresult == BZ_OK) - compresult = 1; - else - compresult = 0; - } -#endif /* HAVE_BZLIB */ -#ifdef HAVE_LZO - if (zipflag == COMPRESS_LZO) { - lzo_uint worklen2 = worklen; - compresult = lzo1x_1_compress((char *)slp->tblock[0],writesize, - comp_buf->buf, - &worklen2, - LZO_WorkMem); - worklen = worklen2; - if (compresult == LZO_E_OK) - compresult = 1; - else - compresult = 0; - } -#endif /* HAVE_LZO */ + // tapebuf: compressed, flags, length + compresult = transformation->compress(transformation, comp_buf, + &worklen, slp->tblock[0], writesize); + if (compresult && worklen <= ((unsigned long)writesize - 16)) { /* write the compressed buffer */ comp_buf->length = worklen; @@ -1334,15 +1323,15 @@ doslave(int cmd, } /* compress the remaining blocks if we're compressing */ do_compress = compressed; -#endif /* HAVE_ZLIB || HAVE_BZLIB || HAVE_LZO */ +#endif /* HAVE_BLOCK_TRANSFORMATION */ - if (sigsetjmp(jmpbuf, 1) == 0) { - ready = 1; - if (!caught) + if (sigsetjmp(jmpbuf2, 1) == 0) { + ready2 = 1; + if (!caught2) sigsuspend(&set); } - ready = 0; - caught = 0; + ready2 = 0; + caught2 = 0; #ifdef USE_QFA if (gTapeposfd >= 0) { @@ -1434,6 +1423,11 @@ doslave(int cmd, } #endif /* USE_QFA */ } + +#ifdef HAVE_BLOCK_TRANSFORMATION + transformation->endDiskIOProcess(transformation); +#endif /* HAVE_BLOCK_TRANSFORMATION */ + if (nread != 0) quit("error reading command pipe: %s\n", strerror(errno)); } @@ -1497,7 +1491,7 @@ SetLogicalPos(void) /* * read the current tape position */ -static int +int GetTapePos(long long *pos) { int err = 0;