#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 <config.h>
#include <protocols/dumprestore.h>
-#ifdef HAVE_ZLIB
-#include <zlib.h>
-#endif /* HAVE_ZLIB */
-
-#ifdef HAVE_BZLIB
-#include <bzlib.h>
-#endif /* HAVE_BZLIB */
-
-#ifdef HAVE_LZO
-#include <minilzo.h>
-#endif /* HAVE_LZO */
-
#include "dump.h"
int writesize; /* size of malloc()ed buffer for tape */
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;
* 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 */
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 */
tapeno, slp->inode);
if (tapeno < (int)TP_NINOS)
volinfo[tapeno] = slp->inode;
+ transformation->startNewTape(transformation, NULL, 0);
}
}
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
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 ||
* 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,
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;
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.
*/
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
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);
quit("master/slave protocol botched.\n");
}
}
+ /* signal next slave to start reading */
+ (void) kill(nextslave, SIGUSR1);
/* Try to write the data... */
wrote = 0;
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
* 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;
}
/* 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) {
}
#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));
}
/*
* read the current tape position
*/
-static int
+int
GetTapePos(long long *pos)
{
int err = 0;