*BSD News Article 13901


Return to BSD News archive

Path: sserve!newshost.anu.edu.au!munnari.oz.au!news.Hawaii.Edu!ames!haven.umd.edu!umd5.umd.edu!roissy.umd.edu!mark
From: mark@roissy.umd.edu (Mark Sienkiewicz)
Newsgroups: comp.os.386bsd.development
Subject: Re: File Truncation Philosophy
Date: 1 Apr 1993 23:21:47 GMT
Organization: University of Maryland
Lines: 70
Message-ID: <1pfteb$ch5@umd5.umd.edu>
References: <C4tJ6C.C17@ns1.nodak.edu>
NNTP-Posting-Host: roissy.umd.edu

In article <C4tJ6C.C17@ns1.nodak.edu> tinguely@plains.NoDak.edu (Mark Tinguely) writes:
> As most of you know that with 386bsd installing a new copy of a running
> program causes the running program to crash and core.

> The philosophy question is should we change "cp" and "cat" to unlink (remove)
> the file before opening? Or even lower in the filesystem (as would need be in
> the restore example).

Since "cat" does not open files for writing, changing it won't help much.
I suppose you are thinking of "cat old > new", which is done by the shell.

This is an important distinction for this question.  You can't isolate the
problem to a particular user program.

The problem is really that the swap area for the text is not protected against
"random" (wrt. paging) changes.  Many older systems do this by refusing write
access to files that are being used as VM for executing programs.

I suspect the reason this doesn't happen any more is that you can't tell if
some _other_ machine is executing a file on a filesystem you export through
NFS.  Since NFS is stateless, you can't even know for sure if another machine
has a file open.  Therefore you can't know when to deny access.

There are things you could do about it though.

Idea 1:  When paging over NFS, the kernel could detect that the file
has changed and kill the program itself instead of waiting for the program to 
crash.  That way, you know that it doesn't do something random before it
crashes.

Idea 2: Have the UFS code cooperate with the VM code to prohibit writes to
files that are being used for paging.  This has worked well in the past.

Idea 3: Have the UFS code cooperate with the VM code to _move_ inodes that
are being used for paging.  It might work like this:
	- you execute a file from inode X
	- somebody tries to creat() inode X
		find a free inode Y
		copy the data from X to Y
		clear X and treat it as if it had just been allocated

This only works for a creat(), though.  It doesn't work for the case
	fd=open(file,1);
	lseek(fd,offset,0);
	write(fd,buffer,size);
which can crash a program just as effectively as a creat.

Idea 4: Copy the program text into the swap area
	4a- always.  This causes a performance penalty when you start a
		program.
	4b- when executing from a filesystem not known to be "reliable".
		NFS.  CDFS is unlikely to be a problem. various other
		ideas here (e.g. 1,4c) might make UFS reliable.  It would
		probably work best if you had the kernel be conservative
		about any "new" filesystem types.  e.g. you don't know if
		marksfs does what you need or not.
	4c- when the program file is opened for writing.  You would have
		to block the open until the copy was complete.

Idea 5: When writing to an executing file, remove the block you are writing
	to from the file.  (Give it to some other file, so it stays allocated.)
	allocate a new block to do the write in.  This is "copy-on-write" for
	file blocks.

Some combinations of these would produce a system like what you wanted.
(I caution that #3 and #5 look like they will cause more pain than they
prevent.)

Mark S.