[comp.unix.questions] SunOS 4.0.3 SCSI tape close error: EPERM

poage@sunny.ucdavis.edu (Tom Poage) (08/03/89)

Has anyone running SunOS 4.0.3 observed that closing a 1/4"
SCSI tape after read/write returns EPERM?  This happens on
a 3/150 with /dev/rst[08].  It may have happened under
4.0.1 too, but I don't specifically remember.

If you're root or you own the device, no problem.  If you
don't write or read the tape, no error.

Is this a known problem?  Any fixes/work-arounds?

Repeat with the following program and a scratch tape.

Tom.
==============================================================

/*
 * Write and read a dummy block on /dev/rst8 (SCSI tape).
 *
 * If you do not own the tape device (or not root)
 * you will get an EPERM error on calling close().
 * You won't get the error unless you call read()
 * or write().  Sun 3/150, SunOS 4.0.3.
 *
 * Tom Poage (poage@sunny.ucdavis.edu)
 */
#include <fcntl.h>
#include <errno.h>
main()
{
	int fd;
	char buf[512];	/* Tape read/write has to be modulo-512. */
	if ((fd = open("/dev/rst8", O_WRONLY)) < 0) {
		perror("tape open #1"); return(1);
	}
	if (write(fd, buf, sizeof buf) < 0) {
		perror("write to tape"); return(1);
	}
	if (close(fd) < 0) {	/* Fails here. */
		perror("tape close #1");
	}
	/* rst8 rewinds on close. */
	if ((fd = open("/dev/rst8", O_RDONLY)) < 0) {
		perror("tape open #2"); return(1);
	}
	if (read(fd, buf, sizeof buf) != sizeof buf) {
		perror("read from tape");
	}
	if (close(fd) < 0) {	/* Fails here, too. */
		perror("tape close #2");
	}
	return(0);
}
-- 
Tom Poage, Clinical Engineering
Universiy of California, Davis, Medical Center, Sacramento, CA
poage@sunny.ucdavis.edu  {...,ucbvax,uunet}!ucdavis!sunny!poage

fnf@estinc.UUCP (Fred Fish) (08/04/89)

In article <419@sunny.ucdavis.edu> poage@sunny.ucdavis.edu (Tom Poage) writes:
>Has anyone running SunOS 4.0.3 observed that closing a 1/4"
>SCSI tape after read/write returns EPERM?  This happens on
>a 3/150 with /dev/rst[08].  It may have happened under
>4.0.1 too, but I don't specifically remember.

Yes, I noticed and reported this bug last November, when I first tried
some code on a Sun-4 under 4.0.1 that bothered to check the status of
the close() call.  Looks like it's still there...

On an unrelated note, has anyone else noticed that the system does
not prevent you from overwriting an executable that is currently
executing?  For example, make a copy of tar in /tmp/tar, create a
tar archive in /tmp/tar.out that contains tar, and then try to
extract tar over itself.  You usually get a core dump.  On any other
UNIX I've tried, you get an errno for "text busy".

-Fred
-- 
# Fred Fish, 1835 E. Belmont Drive, Tempe, AZ 85284,  USA
# 1-602-491-0048           asuvax!{nud,mcdphx}!estinc!fnf

guy@auspex.auspex.com (Guy Harris) (08/06/89)

>>Has anyone running SunOS 4.0.3 observed that closing a 1/4"
>>SCSI tape after read/write returns EPERM?  This happens on
>>a 3/150 with /dev/rst[08].  It may have happened under
>>4.0.1 too, but I don't specifically remember.
>
>Yes, I noticed and reported this bug last November, when I first tried
>some code on a Sun-4 under 4.0.1 that bothered to check the status of
>the close() call.  Looks like it's still there...

Oh, this one again.  The problem is due to the way special files are
handled in SunOS (and other systems that have picked up recent versions
of the VFS mechanism).  The problem is that, as long as the device is
open, the vnode for the device on the underlying file system is
"shadowed" by a vnode for the "specfs" file system.  Updates to the
accessed and modified times go to that "shadow" vnode and not the native
vnode.  When the device is closed, the "specfs" code uses a VOP_SETATTR
to push the times back to the native vnode; unfortunately, UNIX tends to
require that you either be the super-user or the owner of a file in
order to set the accessed or modified times of a file.

"specfs" could try to forge sufficiently-powerful credentials when it
performs the VOP_SETATTR operation; it doesn't, however.  I think the
fix for this is straightforward; it may appear in a future SunOS
release, and possibly in a future NFS source release as well.  (I
certainly hope it at least gets into S5R4, unless the fix *isn't*
straightforward....)

>On an unrelated note, has anyone else noticed that the system does
>not prevent you from overwriting an executable that is currently
>executing?  For example, make a copy of tar in /tmp/tar, create a
>tar archive in /tmp/tar.out that contains tar, and then try to
>extract tar over itself.  You usually get a core dump.  On any other
>UNIX I've tried, you get an errno for "text busy".

Yup.  SunOS 4.x doesn't support shared texts; it supports copy-on-write
private mappings.  SunOS 4.x doesn't protect against attempts to write
to files mapped in that fashion; I don't know what the pros and cons of
having attempts to write to files of that sort copy the pages written to
would be.  Basically, the file system "write" code establishes a shared,
writable mapping to the relevant region of the file, and copies data
from user space into the mapped region.  The VM code might be able to
detect that somebody has part or all of the same region mapped
copy-on-write, and cause the other mappings to be remapped to a copy of
the page; however, 1) I don't know if this is possible with the current
VM system, 2) I don't know how difficult it is, or what the performance
impact would be, and 3) I don't know if this change in semantics would
cause other problems.

Given that said extraction operation doesn't work *regardless* of
whether such writes are detected or not, the correct way to extract a
"tar" file that would overwrite "tar" itself is to *move* "tar" off to
"tar.save" or something like that, and use "tar.save" to extract the
file.

(The subtle distinction between "shared texts" and "shared copy-on-write
mappings" lets SunOS permit you to remove the last link to an active
"shared-text" program without violating a rather stupid clause in the
SVID that requires the last unlink of a file whose text is active to
fail with ETXTBSY. 

Somebody claimed that said "feature" was put into V7 to reduce the
probability of an orphaned file from a crash - any file that had been
unlinked while the text was still active would still be around on disk,
but with no links, until the last reference to the text disappeared, so
if the machine crashed before said reference disappeared, you would have
an orphaned file - but 1) the same happens with files that were unlinked
while still open, and you can't forbid *that* without breaking many
programs and 2) "fsck" can fix that problem, anyway. 

Berkeley saw the bogosity in that - said restriction makes it a royal
pain to install new versions of programs that are currently being used,
since you have to leave one link around until the old version is no
longer being used - and removed the restriction.  The S5 folks didn't do
so, alas, and somebody working on the SVID didn't realize that the
restriction was pointless and didn't belong there, so they stuck it in.)