Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 4 Jun 2002 11:07:05 +0200 (CEST)
From:      Alexander Leidinger <netchild@FreeBSD.org>
To:        audit@freebsd.org
Cc:        Benjamin Lewis <bhlewis@wossname.net>
Subject:   [PATCH] making dump EINTR resistant
Message-ID:  <200206040907.g54975wE003913@Magelan.Leidinger.net>

next in thread | raw e-mail | index | archive | help
--0-1804289383-1023181632=:572
Content-Type: TEXT/plain; charset=us-ascii

Hi,

Benjamin Lewis <bhlewis@wossname.net> 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

--0-1804289383-1023181632=:572
Content-Type: TEXT/plain; name="dump.diff"
Content-Disposition: attachment; filename="dump.diff"

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);
 }

--0-1804289383-1023181632=:572--

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-audit" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200206040907.g54975wE003913>