[PATCH] making dump EINTR resistant

Alexander Leidinger <[email protected]>
Newsgroups gmane.os.freebsd.devel.audit
Message-ID <[email protected]>
Hi,

Benjamin Lewis <[email protected]> had some problems with dump, have
a look at the -current archives (Subject: "Is anyone else having trouble
with dump(8) on -current?", around May 15.).

I had such a problem on 4.x (perhaps 4.2 or 4.3) once too (I wasn't able
to reproduce it, Benjamin is able to reproduce it on -current) and wrote
the attached patch to solve the problem. Since I wrote it for 4.x, it
runs fine (actually on a 4.4 system which does daily backups to a spare
harddisk). Benjamin uses it also on a daily basis on -current.

The attached diff is against -current.

Comments?

Bye,
Alexander.

-- 
         The computer revolution is over. The computers won.

http://www.Leidinger.net                       Alexander @ Leidinger.net
  GPG fingerprint = C518 BC70 E67F 143F BE91  3365 79E2 9C60 B006 3FE7
dump.diff (text/plain, 6.5 KB)
Index: dumprmt.c
===================================================================
RCS file: /big/FreeBSD-CVS/src/sbin/dump/dumprmt.c,v
retrieving revision 1.17
diff -u -r1.17 dumprmt.c
--- dumprmt.c	20 Mar 2002 22:49:39 -0000	1.17
+++ dumprmt.c	27 Mar 2002 15:27:54 -0000
@@ -114,10 +114,13 @@
 		t.tv_sec = 0;
 		t.tv_usec = 0;
 		if (select(errfd + 1, &r, NULL, NULL, &t)) {
-			int i;
+			int i = 0;
 			char buf[2048];
 
-			if ((i = read(errfd, buf, sizeof(buf) - 1)) > 0) {
+			do {
+				i = read(errfd, buf, sizeof(buf));
+			} while ((i == -1) && (errno == EINTR));
+			if (i - 1 > 0) {
 				buf[i] = '\0';
 				msg("on %s: %s%s", rmtpeer, buf,
 					buf[i - 1] == '\n' ? "" : "\n");
@@ -243,7 +246,9 @@
 		/* rmtcall() properly sets errno for us on errors. */
 		return (n);
 	for (i = 0; i < n; i += cc) {
-		cc = read(rmtape, buf+i, n - i);
+		do {
+			cc = read(rmtape, buf+i, n - i);
+		} while ((cc == -1) && (errno == EINTR));
 		if (cc <= 0)
 			rmtconnaborted(0);
 	}
@@ -361,8 +366,12 @@
 rmtgetb(void)
 {
 	char c;
+	int ret_val;
 
-	if (read(rmtape, &c, 1) != 1)
+	do {
+		ret_val = read(rmtape, &c, 1);
+	} while ((ret_val == -1) && (errno == EINTR));
+	if (ret_val != 1)
 		rmtconnaborted(0);
 	return (c);
 }
Index: itime.c
===================================================================
RCS file: /big/FreeBSD-CVS/src/sbin/dump/itime.c,v
retrieving revision 1.11
diff -u -r1.11 itime.c
--- itime.c	20 Mar 2002 22:49:39 -0000	1.11
+++ itime.c	27 Mar 2002 14:26:39 -0000
@@ -74,7 +74,10 @@
 {
 	FILE *df;
 
-	if ((df = fopen(dumpdates, "r")) == NULL) {
+	do {
+		df = fopen(dumpdates, "r");
+	} while ((df == NULL) && (errno == EINTR));
+	if (df == NULL) {
 		if (errno != ENOENT) {
 			msg("WARNING: cannot read %s: %s\n", dumpdates,
 			    strerror(errno));
@@ -84,13 +87,19 @@
 		 * Dumpdates does not exist, make an empty one.
 		 */
 		msg("WARNING: no file `%s', making an empty one\n", dumpdates);
-		if ((df = fopen(dumpdates, "w")) == NULL) {
+		do {
+			df = fopen(dumpdates, "w");
+		} while ((df == NULL) && (errno == EINTR));
+		if (df == NULL) {
 			msg("WARNING: cannot create %s: %s\n", dumpdates,
 			    strerror(errno));
 			return;
 		}
 		(void) fclose(df);
-		if ((df = fopen(dumpdates, "r")) == NULL) {
+		do {
+			df = fopen(dumpdates, "r");
+		} while ((df == NULL) && (errno == EINTR));
+		if (df == NULL) {
 			quit("cannot read %s even after creating it: %s\n",
 			    dumpdates, strerror(errno));
 			/* NOTREACHED */
@@ -171,7 +180,10 @@
 
 	if(uflag == 0)
 		return;
-	if ((df = fopen(dumpdates, "r+")) == NULL)
+	do {
+		df = fopen(dumpdates, "r+");
+	} while ((df == NULL) && (errno == EINTR));
+	if (df == NULL)
 		quit("cannot rewrite %s: %s\n", dumpdates, strerror(errno));
 	fd = fileno(df);
 	(void) flock(fd, LOCK_EX);
Index: main.c
===================================================================
RCS file: /big/FreeBSD-CVS/src/sbin/dump/main.c,v
retrieving revision 1.36
diff -u -r1.36 main.c
--- main.c	16 May 2002 04:09:56 -0000	1.36
+++ main.c	4 Jun 2002 08:48:51 -0000
@@ -57,6 +57,7 @@
 
 #include <ctype.h>
 #include <err.h>
+#include <errno.h>
 #include <fcntl.h>
 #include <fstab.h>
 #include <signal.h>
@@ -335,7 +336,10 @@
 	else
 		msgtail("to %s\n", tape);
 
-	if ((diskfd = open(disk, O_RDONLY)) < 0)
+	do {
+		diskfd = open(disk, O_RDONLY);
+	} while((diskfd < 0) && (errno == EINTR));
+	if (diskfd < 0)
 		err(X_STARTUP, "Cannot open %s", disk);
 	if (fstat(diskfd, &sb) != 0)
 		err(X_STARTUP, "%s: stat", disk);
Index: optr.c
===================================================================
RCS file: /big/FreeBSD-CVS/src/sbin/dump/optr.c,v
retrieving revision 1.20
diff -u -r1.20 optr.c
--- optr.c	16 May 2002 04:09:56 -0000	1.20
+++ optr.c	4 Jun 2002 08:48:51 -0000
@@ -82,7 +82,10 @@
 	int	back, errcount;
 	FILE	*mytty;
 
-	if ((mytty = fopen(_PATH_TTY, "r")) == NULL)
+	do {
+		mytty = fopen(_PATH_TTY, "r");
+	} while ((mytty == NULL) && (errno == EINTR));
+	if (mytty == NULL)
 		quit("fopen on %s fails: %s\n", _PATH_TTY, strerror(errno));
 	attnmessage = question;
 	timeout = 0;
Index: tape.c
===================================================================
RCS file: /big/FreeBSD-CVS/src/sbin/dump/tape.c,v
retrieving revision 1.18
diff -u -r1.18 tape.c
--- tape.c	20 Mar 2002 22:49:39 -0000	1.18
+++ tape.c	4 Jun 2002 08:53:44 -0000
@@ -328,7 +328,7 @@
 				quit("or use no size estimate at all.\n");
 			}
 		}
-		(void) close(slaves[f].fd);
+		while ((close(slaves[f].fd) < 0) && (errno == EINTR)) /* nop */;
 	}
 	while (wait((int *)NULL) >= 0)	/* wait for any signals from slaves */
 		/* void */;
@@ -351,10 +351,10 @@
 		(void)close(tapefd);
 		return;
 	}
-	(void) close(tapefd);
+	while ((close(tapefd) < 0) && (errno == EINTR)) /* nop */;
 	while ((f = open(tape, 0)) < 0)
 		sleep (10);
-	(void) close(f);
+	while ((close(f) < 0) && (errno == EINTR)) /* nop */;
 }
 
 void
@@ -502,6 +502,7 @@
 	int	childpid;
 	int	status;
 	int	waitpid;
+	int	tmpfd;
 	char	*p;
 	sig_t	interrupt_save;
 
@@ -590,12 +591,16 @@
 				nexttape = NULL;
 			msg("Dumping volume %d on %s\n", tapeno, tape);
 		}
+
+		if (0 != pipeout)
+			do {
+				tmpfd = open(tape, O_WRONLY|O_CREAT, 0666);
+			} while ((tmpfd < 0) && (errno == EINTR));
 #ifdef RDUMP
 		while ((tapefd = (host ? rmtopen(tape, 2) :
-			pipeout ? 1 : open(tape, O_WRONLY|O_CREAT, 0666))) < 0)
+			pipeout ? 1 : tmpfd)) < 0)
 #else
-		while ((tapefd = (pipeout ? 1 :
-				  open(tape, O_WRONLY|O_CREAT, 0666))) < 0)
+		while ((tapefd = (pipeout ? 1 : tmpfd)) < 0)
 #endif
 		    {
 			msg("Cannot open output \"%s\".\n", tape);
@@ -696,7 +701,8 @@
 		slaves[i].sent = 0;
 		if (slaves[i].pid == 0) { 	    /* Slave starts up here */
 			for (j = 0; j <= i; j++)
-			        (void) close(slaves[j].fd);
+			        while ((close(slaves[j].fd) < 0)
+					&& (errno == EINTR)) /* nop */;
 			signal(SIGINT, SIG_IGN);    /* Master handles this */
 			doslave(cmd[0], i);
 			Exit(X_FINOK);
@@ -739,8 +745,11 @@
 	/*
 	 * Need our own seek pointer.
 	 */
-	(void) close(diskfd);
-	if ((diskfd = open(disk, O_RDONLY)) < 0)
+	while ((close(diskfd) < 0) && (errno == EINTR)) /* nop */;
+	do {
+		diskfd = open(disk, O_RDONLY);
+	} while ((diskfd < 0) && (errno == EINTR));
+	if (diskfd < 0)
 		quit("slave couldn't reopen disk: %s\n", strerror(errno));
 
 	/*
@@ -849,7 +858,13 @@
 {
 	int got, need = count;
 
-	while ((got = (*func)(fd, buf, need)) > 0 && (need -= got) > 0)
-		buf += got;
+	do {
+		do {
+			got = (*func)(fd, buf, need);
+		} while ((got == -1) && (errno == EINTR));
+
+		if ((got > 0) && ((need -= got) > 0))
+			buf += got;
+	} while (got > 0 && need > 0);
 	return (got < 0 ? got : count - need);
 }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.