Revert -r362422.
While whimsical, there's too much negative energy around minion as well as the positive.
This commit is contained in:
parent
bafd96b8dd
commit
b1779ca056
252
sbin/dump/tape.c
252
sbin/dump/tape.c
@ -75,19 +75,19 @@ static char *nexttape;
|
|||||||
static FILE *popenfp = NULL;
|
static FILE *popenfp = NULL;
|
||||||
|
|
||||||
static int atomic(ssize_t (*)(), int, char *, int);
|
static int atomic(ssize_t (*)(), int, char *, int);
|
||||||
static void dominion(int, int);
|
static void doslave(int, int);
|
||||||
static void enminion(void);
|
static void enslave(void);
|
||||||
static void flushtape(void);
|
static void flushtape(void);
|
||||||
static void killall(void);
|
static void killall(void);
|
||||||
static void rollforward(void);
|
static void rollforward(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Concurrent dump mods (Caltech) - disk block reading and tape writing
|
* Concurrent dump mods (Caltech) - disk block reading and tape writing
|
||||||
* are exported to several minion processes. While one minion writes the
|
* are exported to several slave processes. While one slave writes the
|
||||||
* tape, the others read disk blocks; they pass control of the tape in
|
* tape, the others read disk blocks; they pass control of the tape in
|
||||||
* a ring via signals. The parent process traverses the file system and
|
* a ring via signals. The parent process traverses the file system and
|
||||||
* sends writeheader()'s and lists of daddr's to the minions via pipes.
|
* sends writeheader()'s and lists of daddr's to the slaves via pipes.
|
||||||
* The following structure defines the instruction packets sent to minions.
|
* The following structure defines the instruction packets sent to slaves.
|
||||||
*/
|
*/
|
||||||
struct req {
|
struct req {
|
||||||
ufs2_daddr_t dblk;
|
ufs2_daddr_t dblk;
|
||||||
@ -95,20 +95,20 @@ struct req {
|
|||||||
};
|
};
|
||||||
static int reqsiz;
|
static int reqsiz;
|
||||||
|
|
||||||
#define MINIONS 3 /* 1 minion writing, 1 reading, 1 for slack */
|
#define SLAVES 3 /* 1 slave writing, 1 reading, 1 for slack */
|
||||||
static struct minion {
|
static struct slave {
|
||||||
int64_t tapea; /* header number at start of this chunk */
|
int64_t tapea; /* header number at start of this chunk */
|
||||||
int64_t firstrec; /* record number of this block */
|
int64_t firstrec; /* record number of this block */
|
||||||
int count; /* count to next header (used for TS_TAPE */
|
int count; /* count to next header (used for TS_TAPE */
|
||||||
/* after EOT) */
|
/* after EOT) */
|
||||||
int inode; /* inode that we are currently dealing with */
|
int inode; /* inode that we are currently dealing with */
|
||||||
int fd; /* FD for this minion */
|
int fd; /* FD for this slave */
|
||||||
int pid; /* PID for this minion */
|
int pid; /* PID for this slave */
|
||||||
int sent; /* 1 == we've sent this minion requests */
|
int sent; /* 1 == we've sent this slave requests */
|
||||||
char (*tblock)[TP_BSIZE]; /* buffer for data blocks */
|
char (*tblock)[TP_BSIZE]; /* buffer for data blocks */
|
||||||
struct req *req; /* buffer for requests */
|
struct req *req; /* buffer for requests */
|
||||||
} minions[MINIONS+1];
|
} slaves[SLAVES+1];
|
||||||
static struct minion *mlp;
|
static struct slave *slp;
|
||||||
|
|
||||||
static char (*nextblock)[TP_BSIZE];
|
static char (*nextblock)[TP_BSIZE];
|
||||||
|
|
||||||
@ -116,9 +116,9 @@ static int master; /* pid of master, for sending error signals */
|
|||||||
static int tenths; /* length of tape used per block written */
|
static int tenths; /* length of tape used per block written */
|
||||||
static volatile sig_atomic_t caught; /* have we caught the signal to proceed? */
|
static volatile sig_atomic_t caught; /* have we caught the signal to proceed? */
|
||||||
static volatile sig_atomic_t ready; /* reached the lock point without having */
|
static volatile sig_atomic_t ready; /* reached the lock point without having */
|
||||||
/* received the SIGUSR2 signal from the prev minion? */
|
/* received the SIGUSR2 signal from the prev slave? */
|
||||||
static jmp_buf jmpbuf; /* where to jump to if we are ready when the */
|
static jmp_buf jmpbuf; /* where to jump to if we are ready when the */
|
||||||
/* SIGUSR2 arrives from the previous minion */
|
/* SIGUSR2 arrives from the previous slave */
|
||||||
|
|
||||||
int
|
int
|
||||||
alloctape(void)
|
alloctape(void)
|
||||||
@ -143,20 +143,20 @@ alloctape(void)
|
|||||||
* packets, so flushtape() can write them together with one write().
|
* packets, so flushtape() can write them together with one write().
|
||||||
* Align tape buffer on page boundary to speed up tape write().
|
* Align tape buffer on page boundary to speed up tape write().
|
||||||
*/
|
*/
|
||||||
for (i = 0; i <= MINIONS; i++) {
|
for (i = 0; i <= SLAVES; i++) {
|
||||||
buf = (char *)
|
buf = (char *)
|
||||||
malloc((unsigned)(reqsiz + writesize + pgoff + TP_BSIZE));
|
malloc((unsigned)(reqsiz + writesize + pgoff + TP_BSIZE));
|
||||||
if (buf == NULL)
|
if (buf == NULL)
|
||||||
return(0);
|
return(0);
|
||||||
minions[i].tblock = (char (*)[TP_BSIZE])
|
slaves[i].tblock = (char (*)[TP_BSIZE])
|
||||||
(((long)&buf[ntrec + 1] + pgoff) &~ pgoff);
|
(((long)&buf[ntrec + 1] + pgoff) &~ pgoff);
|
||||||
minions[i].req = (struct req *)minions[i].tblock - ntrec - 1;
|
slaves[i].req = (struct req *)slaves[i].tblock - ntrec - 1;
|
||||||
}
|
}
|
||||||
mlp = &minions[0];
|
slp = &slaves[0];
|
||||||
mlp->count = 1;
|
slp->count = 1;
|
||||||
mlp->tapea = 0;
|
slp->tapea = 0;
|
||||||
mlp->firstrec = 0;
|
slp->firstrec = 0;
|
||||||
nextblock = mlp->tblock;
|
nextblock = slp->tblock;
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,8 +164,8 @@ void
|
|||||||
writerec(char *dp, int isspcl)
|
writerec(char *dp, int isspcl)
|
||||||
{
|
{
|
||||||
|
|
||||||
mlp->req[trecno].dblk = (ufs2_daddr_t)0;
|
slp->req[trecno].dblk = (ufs2_daddr_t)0;
|
||||||
mlp->req[trecno].count = 1;
|
slp->req[trecno].count = 1;
|
||||||
/* Can't do a structure assignment due to alignment problems */
|
/* Can't do a structure assignment due to alignment problems */
|
||||||
bcopy(dp, *(nextblock)++, sizeof (union u_spcl));
|
bcopy(dp, *(nextblock)++, sizeof (union u_spcl));
|
||||||
if (isspcl)
|
if (isspcl)
|
||||||
@ -185,8 +185,8 @@ dumpblock(ufs2_daddr_t blkno, int size)
|
|||||||
dblkno = fsbtodb(sblock, blkno);
|
dblkno = fsbtodb(sblock, blkno);
|
||||||
tpblks = size >> tp_bshift;
|
tpblks = size >> tp_bshift;
|
||||||
while ((avail = MIN(tpblks, ntrec - trecno)) > 0) {
|
while ((avail = MIN(tpblks, ntrec - trecno)) > 0) {
|
||||||
mlp->req[trecno].dblk = dblkno;
|
slp->req[trecno].dblk = dblkno;
|
||||||
mlp->req[trecno].count = avail;
|
slp->req[trecno].count = avail;
|
||||||
trecno += avail;
|
trecno += avail;
|
||||||
spcl.c_tapea += avail;
|
spcl.c_tapea += avail;
|
||||||
if (trecno >= ntrec)
|
if (trecno >= ntrec)
|
||||||
@ -232,27 +232,27 @@ flushtape(void)
|
|||||||
int i, blks, got;
|
int i, blks, got;
|
||||||
int64_t lastfirstrec;
|
int64_t lastfirstrec;
|
||||||
|
|
||||||
int siz = (char *)nextblock - (char *)mlp->req;
|
int siz = (char *)nextblock - (char *)slp->req;
|
||||||
|
|
||||||
mlp->req[trecno].count = 0; /* Sentinel */
|
slp->req[trecno].count = 0; /* Sentinel */
|
||||||
|
|
||||||
if (atomic(write, mlp->fd, (char *)mlp->req, siz) != siz)
|
if (atomic(write, slp->fd, (char *)slp->req, siz) != siz)
|
||||||
quit("error writing command pipe: %s\n", strerror(errno));
|
quit("error writing command pipe: %s\n", strerror(errno));
|
||||||
mlp->sent = 1; /* we sent a request, read the response later */
|
slp->sent = 1; /* we sent a request, read the response later */
|
||||||
|
|
||||||
lastfirstrec = mlp->firstrec;
|
lastfirstrec = slp->firstrec;
|
||||||
|
|
||||||
if (++mlp >= &minions[MINIONS])
|
if (++slp >= &slaves[SLAVES])
|
||||||
mlp = &minions[0];
|
slp = &slaves[0];
|
||||||
|
|
||||||
/* Read results back from next minion */
|
/* Read results back from next slave */
|
||||||
if (mlp->sent) {
|
if (slp->sent) {
|
||||||
if (atomic(read, mlp->fd, (char *)&got, sizeof got)
|
if (atomic(read, slp->fd, (char *)&got, sizeof got)
|
||||||
!= sizeof got) {
|
!= sizeof got) {
|
||||||
perror(" DUMP: error reading command pipe in master");
|
perror(" DUMP: error reading command pipe in master");
|
||||||
dumpabort(0);
|
dumpabort(0);
|
||||||
}
|
}
|
||||||
mlp->sent = 0;
|
slp->sent = 0;
|
||||||
|
|
||||||
/* Check for end of tape */
|
/* Check for end of tape */
|
||||||
if (got < writesize) {
|
if (got < writesize) {
|
||||||
@ -262,15 +262,15 @@ flushtape(void)
|
|||||||
* Drain the results, don't care what the values were.
|
* Drain the results, don't care what the values were.
|
||||||
* If we read them here then trewind won't...
|
* If we read them here then trewind won't...
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < MINIONS; i++) {
|
for (i = 0; i < SLAVES; i++) {
|
||||||
if (minions[i].sent) {
|
if (slaves[i].sent) {
|
||||||
if (atomic(read, minions[i].fd,
|
if (atomic(read, slaves[i].fd,
|
||||||
(char *)&got, sizeof got)
|
(char *)&got, sizeof got)
|
||||||
!= sizeof got) {
|
!= sizeof got) {
|
||||||
perror(" DUMP: error reading command pipe in master");
|
perror(" DUMP: error reading command pipe in master");
|
||||||
dumpabort(0);
|
dumpabort(0);
|
||||||
}
|
}
|
||||||
minions[i].sent = 0;
|
slaves[i].sent = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -288,11 +288,11 @@ flushtape(void)
|
|||||||
if (spcl.c_addr[i] != 0)
|
if (spcl.c_addr[i] != 0)
|
||||||
blks++;
|
blks++;
|
||||||
}
|
}
|
||||||
mlp->count = lastspclrec + blks + 1 - spcl.c_tapea;
|
slp->count = lastspclrec + blks + 1 - spcl.c_tapea;
|
||||||
mlp->tapea = spcl.c_tapea;
|
slp->tapea = spcl.c_tapea;
|
||||||
mlp->firstrec = lastfirstrec + ntrec;
|
slp->firstrec = lastfirstrec + ntrec;
|
||||||
mlp->inode = curino;
|
slp->inode = curino;
|
||||||
nextblock = mlp->tblock;
|
nextblock = slp->tblock;
|
||||||
trecno = 0;
|
trecno = 0;
|
||||||
asize += tenths;
|
asize += tenths;
|
||||||
blockswritten += ntrec;
|
blockswritten += ntrec;
|
||||||
@ -312,7 +312,7 @@ trewind(void)
|
|||||||
int f;
|
int f;
|
||||||
int got;
|
int got;
|
||||||
|
|
||||||
for (f = 0; f < MINIONS; f++) {
|
for (f = 0; f < SLAVES; f++) {
|
||||||
/*
|
/*
|
||||||
* Drain the results, but unlike EOT we DO (or should) care
|
* Drain the results, but unlike EOT we DO (or should) care
|
||||||
* what the return values were, since if we detect EOT after
|
* what the return values were, since if we detect EOT after
|
||||||
@ -321,22 +321,22 @@ trewind(void)
|
|||||||
*
|
*
|
||||||
* fixme: punt for now.
|
* fixme: punt for now.
|
||||||
*/
|
*/
|
||||||
if (minions[f].sent) {
|
if (slaves[f].sent) {
|
||||||
if (atomic(read, minions[f].fd, (char *)&got, sizeof got)
|
if (atomic(read, slaves[f].fd, (char *)&got, sizeof got)
|
||||||
!= sizeof got) {
|
!= sizeof got) {
|
||||||
perror(" DUMP: error reading command pipe in master");
|
perror(" DUMP: error reading command pipe in master");
|
||||||
dumpabort(0);
|
dumpabort(0);
|
||||||
}
|
}
|
||||||
minions[f].sent = 0;
|
slaves[f].sent = 0;
|
||||||
if (got != writesize) {
|
if (got != writesize) {
|
||||||
msg("EOT detected in last 2 tape records!\n");
|
msg("EOT detected in last 2 tape records!\n");
|
||||||
msg("Use a longer tape, decrease the size estimate\n");
|
msg("Use a longer tape, decrease the size estimate\n");
|
||||||
quit("or use no size estimate at all.\n");
|
quit("or use no size estimate at all.\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(void) close(minions[f].fd);
|
(void) close(slaves[f].fd);
|
||||||
}
|
}
|
||||||
while (wait((int *)NULL) >= 0) /* wait for any signals from minions */
|
while (wait((int *)NULL) >= 0) /* wait for any signals from slaves */
|
||||||
/* void */;
|
/* void */;
|
||||||
|
|
||||||
if (pipeout)
|
if (pipeout)
|
||||||
@ -396,29 +396,29 @@ void
|
|||||||
rollforward(void)
|
rollforward(void)
|
||||||
{
|
{
|
||||||
struct req *p, *q, *prev;
|
struct req *p, *q, *prev;
|
||||||
struct minion *tmlp;
|
struct slave *tslp;
|
||||||
int i, size, got;
|
int i, size, got;
|
||||||
int64_t savedtapea;
|
int64_t savedtapea;
|
||||||
union u_spcl *ntb, *otb;
|
union u_spcl *ntb, *otb;
|
||||||
tmlp = &minions[MINIONS];
|
tslp = &slaves[SLAVES];
|
||||||
ntb = (union u_spcl *)tmlp->tblock[1];
|
ntb = (union u_spcl *)tslp->tblock[1];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Each of the N minions should have requests that need to
|
* Each of the N slaves should have requests that need to
|
||||||
* be replayed on the next tape. Use the extra minion buffers
|
* be replayed on the next tape. Use the extra slave buffers
|
||||||
* (minions[MINIONS]) to construct request lists to be sent to
|
* (slaves[SLAVES]) to construct request lists to be sent to
|
||||||
* each minion in turn.
|
* each slave in turn.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < MINIONS; i++) {
|
for (i = 0; i < SLAVES; i++) {
|
||||||
q = &tmlp->req[1];
|
q = &tslp->req[1];
|
||||||
otb = (union u_spcl *)mlp->tblock;
|
otb = (union u_spcl *)slp->tblock;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For each request in the current minion, copy it to tmlp.
|
* For each request in the current slave, copy it to tslp.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
prev = NULL;
|
prev = NULL;
|
||||||
for (p = mlp->req; p->count > 0; p += p->count) {
|
for (p = slp->req; p->count > 0; p += p->count) {
|
||||||
*q = *p;
|
*q = *p;
|
||||||
if (p->dblk == 0)
|
if (p->dblk == 0)
|
||||||
*ntb++ = *otb++; /* copy the datablock also */
|
*ntb++ = *otb++; /* copy the datablock also */
|
||||||
@ -433,26 +433,26 @@ rollforward(void)
|
|||||||
ntb--;
|
ntb--;
|
||||||
q -= 1;
|
q -= 1;
|
||||||
q->count = 0;
|
q->count = 0;
|
||||||
q = &tmlp->req[0];
|
q = &tslp->req[0];
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
q->dblk = 0;
|
q->dblk = 0;
|
||||||
q->count = 1;
|
q->count = 1;
|
||||||
trecno = 0;
|
trecno = 0;
|
||||||
nextblock = tmlp->tblock;
|
nextblock = tslp->tblock;
|
||||||
savedtapea = spcl.c_tapea;
|
savedtapea = spcl.c_tapea;
|
||||||
spcl.c_tapea = mlp->tapea;
|
spcl.c_tapea = slp->tapea;
|
||||||
startnewtape(0);
|
startnewtape(0);
|
||||||
spcl.c_tapea = savedtapea;
|
spcl.c_tapea = savedtapea;
|
||||||
lastspclrec = savedtapea - 1;
|
lastspclrec = savedtapea - 1;
|
||||||
}
|
}
|
||||||
size = (char *)ntb - (char *)q;
|
size = (char *)ntb - (char *)q;
|
||||||
if (atomic(write, mlp->fd, (char *)q, size) != size) {
|
if (atomic(write, slp->fd, (char *)q, size) != size) {
|
||||||
perror(" DUMP: error writing command pipe");
|
perror(" DUMP: error writing command pipe");
|
||||||
dumpabort(0);
|
dumpabort(0);
|
||||||
}
|
}
|
||||||
mlp->sent = 1;
|
slp->sent = 1;
|
||||||
if (++mlp >= &minions[MINIONS])
|
if (++slp >= &slaves[SLAVES])
|
||||||
mlp = &minions[0];
|
slp = &slaves[0];
|
||||||
|
|
||||||
q->count = 1;
|
q->count = 1;
|
||||||
|
|
||||||
@ -464,34 +464,34 @@ rollforward(void)
|
|||||||
*/
|
*/
|
||||||
q->dblk = prev->dblk +
|
q->dblk = prev->dblk +
|
||||||
prev->count * (TP_BSIZE / DEV_BSIZE);
|
prev->count * (TP_BSIZE / DEV_BSIZE);
|
||||||
ntb = (union u_spcl *)tmlp->tblock;
|
ntb = (union u_spcl *)tslp->tblock;
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* It wasn't a disk block. Copy the data to its
|
* It wasn't a disk block. Copy the data to its
|
||||||
* new location in the buffer.
|
* new location in the buffer.
|
||||||
*/
|
*/
|
||||||
q->dblk = 0;
|
q->dblk = 0;
|
||||||
*((union u_spcl *)tmlp->tblock) = *ntb;
|
*((union u_spcl *)tslp->tblock) = *ntb;
|
||||||
ntb = (union u_spcl *)tmlp->tblock[1];
|
ntb = (union u_spcl *)tslp->tblock[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mlp->req[0] = *q;
|
slp->req[0] = *q;
|
||||||
nextblock = mlp->tblock;
|
nextblock = slp->tblock;
|
||||||
if (q->dblk == 0)
|
if (q->dblk == 0)
|
||||||
nextblock++;
|
nextblock++;
|
||||||
trecno = 1;
|
trecno = 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clear the first minions' response. One hopes that it
|
* Clear the first slaves' response. One hopes that it
|
||||||
* worked ok, otherwise the tape is much too short!
|
* worked ok, otherwise the tape is much too short!
|
||||||
*/
|
*/
|
||||||
if (mlp->sent) {
|
if (slp->sent) {
|
||||||
if (atomic(read, mlp->fd, (char *)&got, sizeof got)
|
if (atomic(read, slp->fd, (char *)&got, sizeof got)
|
||||||
!= sizeof got) {
|
!= sizeof got) {
|
||||||
perror(" DUMP: error reading command pipe in master");
|
perror(" DUMP: error reading command pipe in master");
|
||||||
dumpabort(0);
|
dumpabort(0);
|
||||||
}
|
}
|
||||||
mlp->sent = 0;
|
slp->sent = 0;
|
||||||
|
|
||||||
if (got != writesize) {
|
if (got != writesize) {
|
||||||
quit("EOT detected at start of the tape!\n");
|
quit("EOT detected at start of the tape!\n");
|
||||||
@ -634,7 +634,7 @@ restore_check_point:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enminion(); /* Share open tape file descriptor with minions */
|
enslave(); /* Share open tape file descriptor with slaves */
|
||||||
if (popenout)
|
if (popenout)
|
||||||
close(tapefd); /* Give up our copy of it. */
|
close(tapefd); /* Give up our copy of it. */
|
||||||
signal(SIGINFO, infosch);
|
signal(SIGINFO, infosch);
|
||||||
@ -643,18 +643,18 @@ restore_check_point:
|
|||||||
blocksthisvol = 0;
|
blocksthisvol = 0;
|
||||||
if (top)
|
if (top)
|
||||||
newtape++; /* new tape signal */
|
newtape++; /* new tape signal */
|
||||||
spcl.c_count = mlp->count;
|
spcl.c_count = slp->count;
|
||||||
/*
|
/*
|
||||||
* measure firstrec in TP_BSIZE units since restore doesn't
|
* measure firstrec in TP_BSIZE units since restore doesn't
|
||||||
* know the correct ntrec value...
|
* know the correct ntrec value...
|
||||||
*/
|
*/
|
||||||
spcl.c_firstrec = mlp->firstrec;
|
spcl.c_firstrec = slp->firstrec;
|
||||||
spcl.c_volume++;
|
spcl.c_volume++;
|
||||||
spcl.c_type = TS_TAPE;
|
spcl.c_type = TS_TAPE;
|
||||||
writeheader((ino_t)mlp->inode);
|
writeheader((ino_t)slp->inode);
|
||||||
if (tapeno > 1)
|
if (tapeno > 1)
|
||||||
msg("Volume %d begins with blocks from inode %d\n",
|
msg("Volume %d begins with blocks from inode %d\n",
|
||||||
tapeno, mlp->inode);
|
tapeno, slp->inode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -687,7 +687,7 @@ Exit(status)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* proceed - handler for SIGUSR2, used to synchronize IO between the minions.
|
* proceed - handler for SIGUSR2, used to synchronize IO between the slaves.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
proceed(int signo __unused)
|
proceed(int signo __unused)
|
||||||
@ -699,45 +699,45 @@ proceed(int signo __unused)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
enminion(void)
|
enslave(void)
|
||||||
{
|
{
|
||||||
int cmd[2];
|
int cmd[2];
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
master = getpid();
|
master = getpid();
|
||||||
|
|
||||||
signal(SIGTERM, dumpabort); /* Minion sends SIGTERM on dumpabort() */
|
signal(SIGTERM, dumpabort); /* Slave sends SIGTERM on dumpabort() */
|
||||||
signal(SIGPIPE, sigpipe);
|
signal(SIGPIPE, sigpipe);
|
||||||
signal(SIGUSR1, tperror); /* Minion sends SIGUSR1 on tape errors */
|
signal(SIGUSR1, tperror); /* Slave sends SIGUSR1 on tape errors */
|
||||||
signal(SIGUSR2, proceed); /* Minion sends SIGUSR2 to next minion */
|
signal(SIGUSR2, proceed); /* Slave sends SIGUSR2 to next slave */
|
||||||
|
|
||||||
for (i = 0; i < MINIONS; i++) {
|
for (i = 0; i < SLAVES; i++) {
|
||||||
if (i == mlp - &minions[0]) {
|
if (i == slp - &slaves[0]) {
|
||||||
caught = 1;
|
caught = 1;
|
||||||
} else {
|
} else {
|
||||||
caught = 0;
|
caught = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, cmd) < 0 ||
|
if (socketpair(AF_UNIX, SOCK_STREAM, 0, cmd) < 0 ||
|
||||||
(minions[i].pid = fork()) < 0)
|
(slaves[i].pid = fork()) < 0)
|
||||||
quit("too many minions, %d (recompile smaller): %s\n",
|
quit("too many slaves, %d (recompile smaller): %s\n",
|
||||||
i, strerror(errno));
|
i, strerror(errno));
|
||||||
|
|
||||||
minions[i].fd = cmd[1];
|
slaves[i].fd = cmd[1];
|
||||||
minions[i].sent = 0;
|
slaves[i].sent = 0;
|
||||||
if (minions[i].pid == 0) { /* Minion starts up here */
|
if (slaves[i].pid == 0) { /* Slave starts up here */
|
||||||
for (j = 0; j <= i; j++)
|
for (j = 0; j <= i; j++)
|
||||||
(void) close(minions[j].fd);
|
(void) close(slaves[j].fd);
|
||||||
signal(SIGINT, SIG_IGN); /* Master handles this */
|
signal(SIGINT, SIG_IGN); /* Master handles this */
|
||||||
dominion(cmd[0], i);
|
doslave(cmd[0], i);
|
||||||
Exit(X_FINOK);
|
Exit(X_FINOK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < MINIONS; i++)
|
for (i = 0; i < SLAVES; i++)
|
||||||
(void) atomic(write, minions[i].fd,
|
(void) atomic(write, slaves[i].fd,
|
||||||
(char *) &minions[(i + 1) % MINIONS].pid,
|
(char *) &slaves[(i + 1) % SLAVES].pid,
|
||||||
sizeof minions[0].pid);
|
sizeof slaves[0].pid);
|
||||||
|
|
||||||
master = 0;
|
master = 0;
|
||||||
}
|
}
|
||||||
@ -747,10 +747,10 @@ killall(void)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < MINIONS; i++)
|
for (i = 0; i < SLAVES; i++)
|
||||||
if (minions[i].pid > 0) {
|
if (slaves[i].pid > 0) {
|
||||||
(void) kill(minions[i].pid, SIGKILL);
|
(void) kill(slaves[i].pid, SIGKILL);
|
||||||
minions[i].sent = 0;
|
slaves[i].sent = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -762,42 +762,42 @@ killall(void)
|
|||||||
* get the lock back for the next cycle by swapping descriptors.
|
* get the lock back for the next cycle by swapping descriptors.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
dominion(int cmd, int minion_number)
|
doslave(int cmd, int slave_number)
|
||||||
{
|
{
|
||||||
int nread;
|
int nread;
|
||||||
int nextminion, size, wrote, eot_count;
|
int nextslave, size, wrote, eot_count;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Need our own seek pointer.
|
* Need our own seek pointer.
|
||||||
*/
|
*/
|
||||||
(void) close(diskfd);
|
(void) close(diskfd);
|
||||||
if ((diskfd = open(disk, O_RDONLY)) < 0)
|
if ((diskfd = open(disk, O_RDONLY)) < 0)
|
||||||
quit("minion couldn't reopen disk: %s\n", strerror(errno));
|
quit("slave couldn't reopen disk: %s\n", strerror(errno));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Need the pid of the next minion in the loop...
|
* Need the pid of the next slave in the loop...
|
||||||
*/
|
*/
|
||||||
if ((nread = atomic(read, cmd, (char *)&nextminion, sizeof nextminion))
|
if ((nread = atomic(read, cmd, (char *)&nextslave, sizeof nextslave))
|
||||||
!= sizeof nextminion) {
|
!= sizeof nextslave) {
|
||||||
quit("master/minion protocol botched - didn't get pid of next minion.\n");
|
quit("master/slave protocol botched - didn't get pid of next slave.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get list of blocks to dump, read the blocks into tape buffer
|
* Get list of blocks to dump, read the blocks into tape buffer
|
||||||
*/
|
*/
|
||||||
while ((nread = atomic(read, cmd, (char *)mlp->req, reqsiz)) == reqsiz) {
|
while ((nread = atomic(read, cmd, (char *)slp->req, reqsiz)) == reqsiz) {
|
||||||
struct req *p = mlp->req;
|
struct req *p = slp->req;
|
||||||
|
|
||||||
for (trecno = 0; trecno < ntrec;
|
for (trecno = 0; trecno < ntrec;
|
||||||
trecno += p->count, p += p->count) {
|
trecno += p->count, p += p->count) {
|
||||||
if (p->dblk) {
|
if (p->dblk) {
|
||||||
blkread(p->dblk, mlp->tblock[trecno],
|
blkread(p->dblk, slp->tblock[trecno],
|
||||||
p->count * TP_BSIZE);
|
p->count * TP_BSIZE);
|
||||||
} else {
|
} else {
|
||||||
if (p->count != 1 || atomic(read, cmd,
|
if (p->count != 1 || atomic(read, cmd,
|
||||||
(char *)mlp->tblock[trecno],
|
(char *)slp->tblock[trecno],
|
||||||
TP_BSIZE) != TP_BSIZE)
|
TP_BSIZE) != TP_BSIZE)
|
||||||
quit("master/minion protocol botched.\n");
|
quit("master/slave protocol botched.\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (setjmp(jmpbuf) == 0) {
|
if (setjmp(jmpbuf) == 0) {
|
||||||
@ -816,14 +816,14 @@ dominion(int cmd, int minion_number)
|
|||||||
while (eot_count < 10 && size < writesize) {
|
while (eot_count < 10 && size < writesize) {
|
||||||
#ifdef RDUMP
|
#ifdef RDUMP
|
||||||
if (host)
|
if (host)
|
||||||
wrote = rmtwrite(mlp->tblock[0]+size,
|
wrote = rmtwrite(slp->tblock[0]+size,
|
||||||
writesize-size);
|
writesize-size);
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
wrote = write(tapefd, mlp->tblock[0]+size,
|
wrote = write(tapefd, slp->tblock[0]+size,
|
||||||
writesize-size);
|
writesize-size);
|
||||||
#ifdef WRITEDEBUG
|
#ifdef WRITEDEBUG
|
||||||
printf("minion %d wrote %d\n", minion_number, wrote);
|
printf("slave %d wrote %d\n", slave_number, wrote);
|
||||||
#endif
|
#endif
|
||||||
if (wrote < 0)
|
if (wrote < 0)
|
||||||
break;
|
break;
|
||||||
@ -834,8 +834,8 @@ dominion(int cmd, int minion_number)
|
|||||||
|
|
||||||
#ifdef WRITEDEBUG
|
#ifdef WRITEDEBUG
|
||||||
if (size != writesize)
|
if (size != writesize)
|
||||||
printf("minion %d only wrote %d out of %d bytes and gave up.\n",
|
printf("slave %d only wrote %d out of %d bytes and gave up.\n",
|
||||||
minion_number, size, writesize);
|
slave_number, size, writesize);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -862,10 +862,10 @@ dominion(int cmd, int minion_number)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If partial write, don't want next minion to go.
|
* If partial write, don't want next slave to go.
|
||||||
* Also jolts him awake.
|
* Also jolts him awake.
|
||||||
*/
|
*/
|
||||||
(void) kill(nextminion, SIGUSR2);
|
(void) kill(nextslave, SIGUSR2);
|
||||||
}
|
}
|
||||||
if (nread != 0)
|
if (nread != 0)
|
||||||
quit("error reading command pipe: %s\n", strerror(errno));
|
quit("error reading command pipe: %s\n", strerror(errno));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user