| Summary: | restore(8) can loop if tty goes away or with -y option | ||
|---|---|---|---|
| Product: | Base System | Reporter: | iedowse <iedowse> |
| Component: | bin | Assignee: | iedowse |
| Status: | Closed FIXED | ||
| Severity: | Affects Only Me | ||
| Priority: | Normal | ||
| Version: | 3.3-STABLE | ||
| Hardware: | Any | ||
| OS: | Any | ||
I am running into the second problem outlined. I run an automated dump over ssh. Sometimes if things do not finish just right, I get the infinite loop. The messages, Changing volumes on pipe input? Changing volumes on pipe input? Changing volumes on pipe input? Keep coming until they fill up the disk, # ls -l /var/spool/mqueue total 741960 -rw------- 1 root daemon 759382016 May 31 04:12 dfWAA01445 -rw------- 1 root daemon 0 May 30 22:30 qfWAA01445 -rw------- 1 root daemon 0 May 30 22:30 xfWAA01445 # df /var Filesystem 1K-blocks Used Avail Capacity Mounted on /dev/ad0s1e 916639 912239 -68931 108% /usr Why have these patches not been commited? -- Crist J. Clark cjc@scitec.com SciTec, Inc (609)921-3892 x252 Responsible Changed From-To: freebsd-bugs->dwmalone Local PR Responsible Changed From-To: dwmalone->iedowse My PR, so I'll deal with it now that I can. State Changed From-To: open->closed Fixed in -current and -stable. |
restore(8) can get stuck in a loop under certain conditions: - If run in the background, and the user logs out while it is still running, restore may start looping at the point where it asks if the permissions on "." should be set. It does check for tty EOF conditions with feof(3), but some types of tty errors generate an EIO error rather than an end-of-file condition. As well as looping, restore also fails to set permissions on most of the directories it has extracted. - If the '-y' option is specified, or an end-of-file or error condition occurs on the tty, a truncated pipe input will result in an infinite loop of 'Changing volumes on pipe input?' messages. This problem is related to that in PR bin/4176. Fix: Apply the following patches in src/sbin/restore: --- tape.c 1999/08/28 00:14:08 1.16 +++ tape.c 1999/10/10 18:36:34 @@ -305,8 +305,12 @@ gettingfile = 0; } if (pipein) { - if (nextvol != 1) + if (nextvol != 1) { panic("Changing volumes on pipe input?\n"); + /* Avoid looping if we weren't asking a tty */ + if (yflag || ferror(terminal) || feof(terminal)) + done(1); + } if (volno == 1) return; goto gethdr; @@ -343,10 +347,9 @@ do { fprintf(stderr, "Specify next volume #: "); (void) fflush(stderr); - (void) fgets(buf, BUFSIZ, terminal); - } while (!feof(terminal) && buf[0] == '\n'); - if (feof(terminal)) - done(1); + if (fgets(buf, BUFSIZ, terminal) == NULL) + done(1); + } while (buf[0] == '\n'); newvol = atoi(buf); if (newvol <= 0) { fprintf(stderr, @@ -362,8 +365,7 @@ fprintf(stderr, "Enter ``none'' if there are no more tapes\n"); fprintf(stderr, "otherwise enter tape name (default: %s) ", magtape); (void) fflush(stderr); - (void) fgets(buf, BUFSIZ, terminal); - if (feof(terminal)) + if (fgets(buf, BUFSIZ, terminal) == NULL) done(1); if (!strcmp(buf, "none\n")) { terminateinput(); --- utilities.c 1999/08/28 00:14:09 1.8 +++ utilities.c 1999/10/10 18:06:01 @@ -405,14 +405,14 @@ reply(question) char *question; { - char c; + int c; do { fprintf(stderr, "%s? [yn] ", question); (void) fflush(stderr); c = getc(terminal); while (c != '\n' && getc(terminal) != '\n') - if (feof(terminal)) + if (c == EOF) return (FAIL); } while (c != 'y' && c != 'n'); if (c == 'y') --- interactive.c 1999/08/28 00:14:05 1.8 +++ interactive.c 1999/10/10 18:34:29 @@ -325,12 +325,11 @@ do { fprintf(stderr, "restore > "); (void) fflush(stderr); - (void) fgets(input, BUFSIZ, terminal); - } while (!feof(terminal) && input[0] == '\n'); - if (feof(terminal)) { - (void) strcpy(cmd, "quit"); - return; - } + if (fgets(input, BUFSIZ, terminal) == NULL) { + (void) strcpy(cmd, "quit"); + return; + } + } while (input[0] == '\n'); for (cp = &input[strlen(input) - 2]; *cp == ' ' || *cp == '\t'; cp--) /* trim off trailing white space and newline */; *++cp = '\0'; How-To-Repeat: - Run the command: cat dumpfile | restore xf - & and then log out (I used tcsh - but this may not be important). The restore process will loop when it gets to the end, and not set all permissions correctly. - Truncate a dump file, and run the command: cat dumpfile | restore xyf -