svn commit: r362444 - head/sbin/dump

Colin Percival cperciva at tarsnap.com
Sat Jun 20 20:12:47 UTC 2020


Thanks for backing this out, Warner.

I'd like to change "slave" to "worker" here (which I think is a reasonably
neutral and entirely inoffensive term), and in the process perhaps make some
associated grammatical changes (since "enworker" is dubious at best).

To avoid causing any further issues: If anyone objects to the word "worker"
please let me know in the next ~48 hours.  I think there's enough people
reading svn-src-all that I can anticipate feedback now if anyone will care
deeply about that word.

Colin Percival

On 2020-06-20 13:06, Warner Losh wrote:
> Author: imp
> Date: Sat Jun 20 20:06:14 2020
> New Revision: 362444
> URL: https://svnweb.freebsd.org/changeset/base/362444
> 
> Log:
>   Revert -r362422.
>   
>   While whimsical, there's too much negative energy around minion as well as the
>   positive.
> 
> Modified:
>   head/sbin/dump/tape.c
> 
> Modified: head/sbin/dump/tape.c
> ==============================================================================
> --- head/sbin/dump/tape.c	Sat Jun 20 18:50:18 2020	(r362443)
> +++ head/sbin/dump/tape.c	Sat Jun 20 20:06:14 2020	(r362444)
> @@ -75,19 +75,19 @@ static	char *nexttape;
>  static	FILE *popenfp = NULL;
>  
>  static	int atomic(ssize_t (*)(), int, char *, int);
> -static	void dominion(int, int);
> -static	void enminion(void);
> +static	void doslave(int, int);
> +static	void enslave(void);
>  static	void flushtape(void);
>  static	void killall(void);
>  static	void rollforward(void);
>  
>  /*
>   * 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
>   * 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.
> - * The following structure defines the instruction packets sent to minions.
> + * sends writeheader()'s and lists of daddr's to the slaves via pipes.
> + * The following structure defines the instruction packets sent to slaves.
>   */
>  struct req {
>  	ufs2_daddr_t dblk;
> @@ -95,20 +95,20 @@ struct req {
>  };
>  static int reqsiz;
>  
> -#define MINIONS 3		/* 1 minion writing, 1 reading, 1 for slack */
> -static struct minion {
> +#define SLAVES 3		/* 1 slave writing, 1 reading, 1 for slack */
> +static struct slave {
>  	int64_t tapea;		/* header number at start of this chunk */
>  	int64_t firstrec;	/* record number of this block */
>  	int count;		/* count to next header (used for TS_TAPE */
>  				/* after EOT) */
>  	int inode;		/* inode that we are currently dealing with */
> -	int fd;			/* FD for this minion */
> -	int pid;		/* PID for this minion */
> -	int sent;		/* 1 == we've sent this minion requests */
> +	int fd;			/* FD for this slave */
> +	int pid;		/* PID for this slave */
> +	int sent;		/* 1 == we've sent this slave requests */
>  	char (*tblock)[TP_BSIZE]; /* buffer for data blocks */
>  	struct req *req;	/* buffer for requests */
> -} minions[MINIONS+1];
> -static struct minion *mlp;
> +} slaves[SLAVES+1];
> +static struct slave *slp;
>  
>  static char	(*nextblock)[TP_BSIZE];
>  
> @@ -116,9 +116,9 @@ static int master;	/* pid of master, for sending error
>  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 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 */
> -			/* SIGUSR2 arrives from the previous minion */
> +			/* SIGUSR2 arrives from the previous slave */
>  
>  int
>  alloctape(void)
> @@ -143,20 +143,20 @@ alloctape(void)
>  	 * packets, so flushtape() can write them together with one 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 *)
>  		    malloc((unsigned)(reqsiz + writesize + pgoff + TP_BSIZE));
>  		if (buf == NULL)
>  			return(0);
> -		minions[i].tblock = (char (*)[TP_BSIZE])
> +		slaves[i].tblock = (char (*)[TP_BSIZE])
>  		    (((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];
> -	mlp->count = 1;
> -	mlp->tapea = 0;
> -	mlp->firstrec = 0;
> -	nextblock = mlp->tblock;
> +	slp = &slaves[0];
> +	slp->count = 1;
> +	slp->tapea = 0;
> +	slp->firstrec = 0;
> +	nextblock = slp->tblock;
>  	return(1);
>  }
>  
> @@ -164,8 +164,8 @@ void
>  writerec(char *dp, int isspcl)
>  {
>  
> -	mlp->req[trecno].dblk = (ufs2_daddr_t)0;
> -	mlp->req[trecno].count = 1;
> +	slp->req[trecno].dblk = (ufs2_daddr_t)0;
> +	slp->req[trecno].count = 1;
>  	/* Can't do a structure assignment due to alignment problems */
>  	bcopy(dp, *(nextblock)++, sizeof (union u_spcl));
>  	if (isspcl)
> @@ -185,8 +185,8 @@ dumpblock(ufs2_daddr_t blkno, int size)
>  	dblkno = fsbtodb(sblock, blkno);
>  	tpblks = size >> tp_bshift;
>  	while ((avail = MIN(tpblks, ntrec - trecno)) > 0) {
> -		mlp->req[trecno].dblk = dblkno;
> -		mlp->req[trecno].count = avail;
> +		slp->req[trecno].dblk = dblkno;
> +		slp->req[trecno].count = avail;
>  		trecno += avail;
>  		spcl.c_tapea += avail;
>  		if (trecno >= ntrec)
> @@ -232,27 +232,27 @@ flushtape(void)
>  	int i, blks, got;
>  	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));
> -	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])
> -		mlp = &minions[0];
> +	if (++slp >= &slaves[SLAVES])
> +		slp = &slaves[0];
>  
> -	/* Read results back from next minion */
> -	if (mlp->sent) {
> -		if (atomic(read, mlp->fd, (char *)&got, sizeof got)
> +	/* Read results back from next slave */
> +	if (slp->sent) {
> +		if (atomic(read, slp->fd, (char *)&got, sizeof got)
>  		    != sizeof got) {
>  			perror("  DUMP: error reading command pipe in master");
>  			dumpabort(0);
>  		}
> -		mlp->sent = 0;
> +		slp->sent = 0;
>  
>  		/* Check for end of tape */
>  		if (got < writesize) {
> @@ -262,15 +262,15 @@ flushtape(void)
>  			 * Drain the results, don't care what the values were.
>  			 * If we read them here then trewind won't...
>  			 */
> -			for (i = 0; i < MINIONS; i++) {
> -				if (minions[i].sent) {
> -					if (atomic(read, minions[i].fd,
> +			for (i = 0; i < SLAVES; i++) {
> +				if (slaves[i].sent) {
> +					if (atomic(read, slaves[i].fd,
>  					    (char *)&got, sizeof got)
>  					    != sizeof got) {
>  						perror("  DUMP: error reading command pipe in master");
>  						dumpabort(0);
>  					}
> -					minions[i].sent = 0;
> +					slaves[i].sent = 0;
>  				}
>  			}
>  
> @@ -288,11 +288,11 @@ flushtape(void)
>  			if (spcl.c_addr[i] != 0)
>  				blks++;
>  	}
> -	mlp->count = lastspclrec + blks + 1 - spcl.c_tapea;
> -	mlp->tapea = spcl.c_tapea;
> -	mlp->firstrec = lastfirstrec + ntrec;
> -	mlp->inode = curino;
> -	nextblock = mlp->tblock;
> +	slp->count = lastspclrec + blks + 1 - spcl.c_tapea;
> +	slp->tapea = spcl.c_tapea;
> +	slp->firstrec = lastfirstrec + ntrec;
> +	slp->inode = curino;
> +	nextblock = slp->tblock;
>  	trecno = 0;
>  	asize += tenths;
>  	blockswritten += ntrec;
> @@ -312,7 +312,7 @@ trewind(void)
>  	int f;
>  	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
>  		 * what the return values were, since if we detect EOT after
> @@ -321,22 +321,22 @@ trewind(void)
>  		 *
>  		 * fixme: punt for now.
>  		 */
> -		if (minions[f].sent) {
> -			if (atomic(read, minions[f].fd, (char *)&got, sizeof got)
> +		if (slaves[f].sent) {
> +			if (atomic(read, slaves[f].fd, (char *)&got, sizeof got)
>  			    != sizeof got) {
>  				perror("  DUMP: error reading command pipe in master");
>  				dumpabort(0);
>  			}
> -			minions[f].sent = 0;
> +			slaves[f].sent = 0;
>  			if (got != writesize) {
>  				msg("EOT detected in last 2 tape records!\n");
>  				msg("Use a longer tape, decrease the size estimate\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 */;
>  
>  	if (pipeout)
> @@ -396,29 +396,29 @@ void
>  rollforward(void)
>  {
>  	struct req *p, *q, *prev;
> -	struct minion *tmlp;
> +	struct slave *tslp;
>  	int i, size, got;
>  	int64_t savedtapea;
>  	union u_spcl *ntb, *otb;
> -	tmlp = &minions[MINIONS];
> -	ntb = (union u_spcl *)tmlp->tblock[1];
> +	tslp = &slaves[SLAVES];
> +	ntb = (union u_spcl *)tslp->tblock[1];
>  
>  	/*
> -	 * Each of the N minions should have requests that need to
> -	 * be replayed on the next tape.  Use the extra minion buffers
> -	 * (minions[MINIONS]) to construct request lists to be sent to
> -	 * each minion in turn.
> +	 * Each of the N slaves should have requests that need to
> +	 * be replayed on the next tape.  Use the extra slave buffers
> +	 * (slaves[SLAVES]) to construct request lists to be sent to
> +	 * each slave in turn.
>  	 */
> -	for (i = 0; i < MINIONS; i++) {
> -		q = &tmlp->req[1];
> -		otb = (union u_spcl *)mlp->tblock;
> +	for (i = 0; i < SLAVES; i++) {
> +		q = &tslp->req[1];
> +		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;
> -		for (p = mlp->req; p->count > 0; p += p->count) {
> +		for (p = slp->req; p->count > 0; p += p->count) {
>  			*q = *p;
>  			if (p->dblk == 0)
>  				*ntb++ = *otb++; /* copy the datablock also */
> @@ -433,26 +433,26 @@ rollforward(void)
>  			ntb--;
>  		q -= 1;
>  		q->count = 0;
> -		q = &tmlp->req[0];
> +		q = &tslp->req[0];
>  		if (i == 0) {
>  			q->dblk = 0;
>  			q->count = 1;
>  			trecno = 0;
> -			nextblock = tmlp->tblock;
> +			nextblock = tslp->tblock;
>  			savedtapea = spcl.c_tapea;
> -			spcl.c_tapea = mlp->tapea;
> +			spcl.c_tapea = slp->tapea;
>  			startnewtape(0);
>  			spcl.c_tapea = savedtapea;
>  			lastspclrec = savedtapea - 1;
>  		}
>  		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");
>  			dumpabort(0);
>  		}
> -		mlp->sent = 1;
> -		if (++mlp >= &minions[MINIONS])
> -			mlp = &minions[0];
> +		slp->sent = 1;
> +		if (++slp >= &slaves[SLAVES])
> +			slp = &slaves[0];
>  
>  		q->count = 1;
>  
> @@ -464,34 +464,34 @@ rollforward(void)
>  			 */
>  			q->dblk = prev->dblk +
>  				prev->count * (TP_BSIZE / DEV_BSIZE);
> -			ntb = (union u_spcl *)tmlp->tblock;
> +			ntb = (union u_spcl *)tslp->tblock;
>  		} else {
>  			/*
>  			 * It wasn't a disk block.  Copy the data to its
>  			 * new location in the buffer.
>  			 */
>  			q->dblk = 0;
> -			*((union u_spcl *)tmlp->tblock) = *ntb;
> -			ntb = (union u_spcl *)tmlp->tblock[1];
> +			*((union u_spcl *)tslp->tblock) = *ntb;
> +			ntb = (union u_spcl *)tslp->tblock[1];
>  		}
>  	}
> -	mlp->req[0] = *q;
> -	nextblock = mlp->tblock;
> +	slp->req[0] = *q;
> +	nextblock = slp->tblock;
>  	if (q->dblk == 0)
>  		nextblock++;
>  	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!
>  	 */
> -	if (mlp->sent) {
> -		if (atomic(read, mlp->fd, (char *)&got, sizeof got)
> +	if (slp->sent) {
> +		if (atomic(read, slp->fd, (char *)&got, sizeof got)
>  		    != sizeof got) {
>  			perror("  DUMP: error reading command pipe in master");
>  			dumpabort(0);
>  		}
> -		mlp->sent = 0;
> +		slp->sent = 0;
>  
>  		if (got != writesize) {
>  			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)
>  			close(tapefd);	/* Give up our copy of it. */
>  		signal(SIGINFO, infosch);
> @@ -643,18 +643,18 @@ restore_check_point:
>  		blocksthisvol = 0;
>  		if (top)
>  			newtape++;		/* new tape signal */
> -		spcl.c_count = mlp->count;
> +		spcl.c_count = slp->count;
>  		/*
>  		 * measure firstrec in TP_BSIZE units since restore doesn't
>  		 * know the correct ntrec value...
>  		 */
> -		spcl.c_firstrec = mlp->firstrec;
> +		spcl.c_firstrec = slp->firstrec;
>  		spcl.c_volume++;
>  		spcl.c_type = TS_TAPE;
> -		writeheader((ino_t)mlp->inode);
> +		writeheader((ino_t)slp->inode);
>  		if (tapeno > 1)
>  			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
>  proceed(int signo __unused)
> @@ -699,45 +699,45 @@ proceed(int signo __unused)
>  }
>  
>  void
> -enminion(void)
> +enslave(void)
>  {
>  	int cmd[2];
>  	int i, j;
>  
>  	master = getpid();
>  
> -	signal(SIGTERM, dumpabort);  /* Minion sends SIGTERM on dumpabort() */
> +	signal(SIGTERM, dumpabort);  /* Slave sends SIGTERM on dumpabort() */
>  	signal(SIGPIPE, sigpipe);
> -	signal(SIGUSR1, tperror);    /* Minion sends SIGUSR1 on tape errors */
> -	signal(SIGUSR2, proceed);    /* Minion sends SIGUSR2 to next minion */
> +	signal(SIGUSR1, tperror);    /* Slave sends SIGUSR1 on tape errors */
> +	signal(SIGUSR2, proceed);    /* Slave sends SIGUSR2 to next slave */
>  
> -	for (i = 0; i < MINIONS; i++) {
> -		if (i == mlp - &minions[0]) {
> +	for (i = 0; i < SLAVES; i++) {
> +		if (i == slp - &slaves[0]) {
>  			caught = 1;
>  		} else {
>  			caught = 0;
>  		}
>  
>  		if (socketpair(AF_UNIX, SOCK_STREAM, 0, cmd) < 0 ||
> -		    (minions[i].pid = fork()) < 0)
> -			quit("too many minions, %d (recompile smaller): %s\n",
> +		    (slaves[i].pid = fork()) < 0)
> +			quit("too many slaves, %d (recompile smaller): %s\n",
>  			    i, strerror(errno));
>  
> -		minions[i].fd = cmd[1];
> -		minions[i].sent = 0;
> -		if (minions[i].pid == 0) { 	    /* Minion starts up here */
> +		slaves[i].fd = cmd[1];
> +		slaves[i].sent = 0;
> +		if (slaves[i].pid == 0) { 	    /* Slave starts up here */
>  			for (j = 0; j <= i; j++)
> -			        (void) close(minions[j].fd);
> +			        (void) close(slaves[j].fd);
>  			signal(SIGINT, SIG_IGN);    /* Master handles this */
> -			dominion(cmd[0], i);
> +			doslave(cmd[0], i);
>  			Exit(X_FINOK);
>  		}
>  	}
>  
> -	for (i = 0; i < MINIONS; i++)
> -		(void) atomic(write, minions[i].fd,
> -			      (char *) &minions[(i + 1) % MINIONS].pid,
> -		              sizeof minions[0].pid);
> +	for (i = 0; i < SLAVES; i++)
> +		(void) atomic(write, slaves[i].fd,
> +			      (char *) &slaves[(i + 1) % SLAVES].pid,
> +		              sizeof slaves[0].pid);
>  
>  	master = 0;
>  }
> @@ -747,10 +747,10 @@ killall(void)
>  {
>  	int i;
>  
> -	for (i = 0; i < MINIONS; i++)
> -		if (minions[i].pid > 0) {
> -			(void) kill(minions[i].pid, SIGKILL);
> -			minions[i].sent = 0;
> +	for (i = 0; i < SLAVES; i++)
> +		if (slaves[i].pid > 0) {
> +			(void) kill(slaves[i].pid, SIGKILL);
> +			slaves[i].sent = 0;
>  		}
>  }
>  
> @@ -762,42 +762,42 @@ killall(void)
>   * get the lock back for the next cycle by swapping descriptors.
>   */
>  static void
> -dominion(int cmd, int minion_number)
> +doslave(int cmd, int slave_number)
>  {
>  	int nread;
> -	int nextminion, size, wrote, eot_count;
> +	int nextslave, size, wrote, eot_count;
>  
>  	/*
>  	 * Need our own seek pointer.
>  	 */
>  	(void) close(diskfd);
>  	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))
> -	    != sizeof nextminion) {
> -		quit("master/minion protocol botched - didn't get pid of next minion.\n");
> +	if ((nread = atomic(read, cmd, (char *)&nextslave, sizeof nextslave))
> +	    != sizeof nextslave) {
> +		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
>  	 */
> -	while ((nread = atomic(read, cmd, (char *)mlp->req, reqsiz)) == reqsiz) {
> -		struct req *p = mlp->req;
> +	while ((nread = atomic(read, cmd, (char *)slp->req, reqsiz)) == reqsiz) {
> +		struct req *p = slp->req;
>  
>  		for (trecno = 0; trecno < ntrec;
>  		     trecno += p->count, p += p->count) {
>  			if (p->dblk) {
> -				blkread(p->dblk, mlp->tblock[trecno],
> +				blkread(p->dblk, slp->tblock[trecno],
>  					p->count * TP_BSIZE);
>  			} else {
>  				if (p->count != 1 || atomic(read, cmd,
> -				    (char *)mlp->tblock[trecno],
> +				    (char *)slp->tblock[trecno],
>  				    TP_BSIZE) != TP_BSIZE)
> -				       quit("master/minion protocol botched.\n");
> +				       quit("master/slave protocol botched.\n");
>  			}
>  		}
>  		if (setjmp(jmpbuf) == 0) {
> @@ -816,14 +816,14 @@ dominion(int cmd, int minion_number)
>  		while (eot_count < 10 && size < writesize) {
>  #ifdef RDUMP
>  			if (host)
> -				wrote = rmtwrite(mlp->tblock[0]+size,
> +				wrote = rmtwrite(slp->tblock[0]+size,
>  				    writesize-size);
>  			else
>  #endif
> -				wrote = write(tapefd, mlp->tblock[0]+size,
> +				wrote = write(tapefd, slp->tblock[0]+size,
>  				    writesize-size);
>  #ifdef WRITEDEBUG
> -			printf("minion %d wrote %d\n", minion_number, wrote);
> +			printf("slave %d wrote %d\n", slave_number, wrote);
>  #endif
>  			if (wrote < 0)
>  				break;
> @@ -834,8 +834,8 @@ dominion(int cmd, int minion_number)
>  
>  #ifdef WRITEDEBUG
>  		if (size != writesize)
> -		 printf("minion %d only wrote %d out of %d bytes and gave up.\n",
> -		     minion_number, size, writesize);
> +		 printf("slave %d only wrote %d out of %d bytes and gave up.\n",
> +		     slave_number, size, writesize);
>  #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.
>  		 */
> -		(void) kill(nextminion, SIGUSR2);
> +		(void) kill(nextslave, SIGUSR2);
>  	}
>  	if (nread != 0)
>  		quit("error reading command pipe: %s\n", strerror(errno));
> 

-- 
Colin Percival
Security Officer Emeritus, FreeBSD | The power to serve
Founder, Tarsnap | www.tarsnap.com | Online backups for the truly paranoid


More information about the svn-src-head mailing list