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
[-- Attachment #1 --]
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
[-- Attachment #2 --]
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);
}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200206040907.g54975wE003913>
