diff options
author | Kenneth R Westerback <krw@cvs.openbsd.org> | 2006-05-30 20:09:54 +0000 |
---|---|---|
committer | Kenneth R Westerback <krw@cvs.openbsd.org> | 2006-05-30 20:09:54 +0000 |
commit | e079c63011a676925530233d7493d35976af917c (patch) | |
tree | 7944c09456fcaffe2629bfc4d0b2e2015a24b6b0 | |
parent | 72b8721e359661b263429be415a6b75a0a8d013b (diff) |
Don't double-eject tapes. Once is enough. Closes PR#1282.
ok miod@ beck@, functionally equivalent diff ok deraadt@ a while ago
-rw-r--r-- | sbin/dump/tape.c | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/sbin/dump/tape.c b/sbin/dump/tape.c index a2391e49359..0e4336b0a73 100644 --- a/sbin/dump/tape.c +++ b/sbin/dump/tape.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tape.c,v 1.25 2006/04/13 00:48:48 deraadt Exp $ */ +/* $OpenBSD: tape.c,v 1.26 2006/05/30 20:09:53 krw Exp $ */ /* $NetBSD: tape.c,v 1.11 1997/06/05 11:13:26 lukem Exp $ */ /*- @@ -34,14 +34,16 @@ #if 0 static char sccsid[] = "@(#)tape.c 8.2 (Berkeley) 3/17/94"; #else -static const char rcsid[] = "$OpenBSD: tape.c,v 1.25 2006/04/13 00:48:48 deraadt Exp $"; +static const char rcsid[] = "$OpenBSD: tape.c,v 1.26 2006/05/30 20:09:53 krw Exp $"; #endif #endif /* not lint */ +#include <sys/types.h> #include <sys/param.h> #include <sys/socket.h> #include <sys/time.h> #include <sys/wait.h> +#include <sys/stat.h> #ifdef sunos #include <sys/vnode.h> @@ -361,8 +363,8 @@ flushtape(void) void trewind(void) { - int f; - int got; + struct stat sb; + int f, got; for (f = 0; f < SLAVES; f++) { /* @@ -405,6 +407,23 @@ trewind(void) return; } #endif + /* + * st(4) says: "... bits 0 and 1 of the minor number are interpreted as + * `sub-modes'. The sub-modes differ in the action taken when the + * device is closed ...". In short, if bit 1 is set the tape will be + * ejected on close. + * + * If the tape has been ejected, looping on open() will generate 'Media + * not present' errors until a tape is loaded. Once loaded the tape + * will be immediately ejected as a result of the second close(). + * + * So if the tape will be ejected, just close and return. + */ + if ((fstat(tapefd, &sb) == 0) && (minor(sb.st_rdev) & 0x02)) { + (void) close(tapefd); + return; + } + (void) close(tapefd); while ((f = open(tape, 0)) < 0) sleep (10); |