*BSD News Article 14185


Return to BSD News archive

Newsgroups: comp.os.386bsd.development
Path: sserve!newshost.anu.edu.au!munnari.oz.au!spool.mu.edu!howland.reston.ans.net!zaphod.mps.ohio-state.edu!magnus.acs.ohio-state.edu!csn!hellgate.utah.edu!fcom.cc.utah.edu!cs.weber.edu!terry
From: terry@cs.weber.edu (A Wizard of Earth C)
Subject: Re: File Truncation Philosophy
Message-ID: <1993Apr7.234429.1714@fcom.cc.utah.edu>
Sender: news@fcom.cc.utah.edu
Organization: Weber State University  (Ogden, UT)
References: <C4tJ6C.C17@ns1.nodak.edu>
Date: Wed, 7 Apr 93 23:44:29 GMT
Lines: 86

In article <C4tJ6C.C17@ns1.nodak.edu> tinguely@plains.NoDak.edu (Mark Tinguely) writes:
>		******** Request for Comments ********
>
> As most of you know that with 386bsd installing a new copy of a running
> program causes the running program to crash and core. This happens due to
> couple of things. Fist, with the Mach VM used in 386bsd, executing
> instructions are paged directly from the executable in the filesystem
> (whereas old BSD VMs copy the executable to swap and page from there).
> Secondly, programs like "cp" TRUNCATES the existing file when copying in
> the new copy of the program. When the executing program does the next page
> fault the fault will fail and the program will crash/core.

How does Mach fix this?  After all, the problem is introduced by not having a
process local copy of the image in swap to page from, and Mach either has
the same behaviour or has fixed it.

My personal take on this would be to have the pages marked as in use but not
in core, and simply mark them copy on write.  In theory, this would cause
the O_TRUNC to work "correctly", but it's kind of iffy.  Any future reference
to the same file would be required to use the same PTDI's (the iffy part,
since direct page references for all pages in a file aren't made in itrunc).

Another alternative would be to return EBUSY from itrunc() in ufs_inode.c if
the file is being used as a swap store (sys/errno.h defines ETXTBSY, but for
some reason this is only if _POSIX_SOURCE isn't defined).  This is what
Xenix and SVR4 have traditionally done (I can't count how many times I've
gotten "text file busy" on Xenix systems when trying to overwrite an
executable).  An "rm" of the file wouldn't get rid of the blocks as long as
there was an open vp for the file.  The cp after the rm would work fine and
the currently executing image wouldn't fail.  This may mean we would need
an additional tag on the vnode (it may already be there; I haven't checked
it out and don't have time to right now) to tell that the file is opened
as a swap store by a process.

I *don't* advocate changing "cp", unless it's to take advantage of mmap()
to avoid data copies across the user/kernel boundry (an optimization used
in most modern implementations).

> The easy fix is to move or remove the file before installing the new
> program. The filesystem does work correctly and keep a copy of the executable
> and the VM still finds and uses this copy.

Right; a user action is required.  As long as we bring text pages from the
file instead of swap, I think this is the only method that should be allowed
(meaning we mod the fs to disallow truncation of "busy" files).  The big
issue is disallowing corruption of a text page swap store.  Whether this is
done by inhibiting the corruption at the point it would take place (itrunc)
or preempting it (marking the pages as file swap pages, ie: in use, and
copy on write), is irrelevant.

> It would be NICE to not have to worry about unlinking the file associated
> with running programs before making our copies. Nate and all the others
> working the patchkit are interested in this, also very important if the user
> is restoring from a backup (as I learned once).

Definitely!  The image replacement should be disallowed but non-fatal (ie:
the constant warnings about replacing "tar" on Xenix package installations).

> 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).
>
> I can think of several reasons to not do this:
>	1) won't have the same inode.
>	2) won't cover all cases -- using open(2) and O_TRUNC will still 
>	   cause the same problem.

So will a creat(), which is an open with O_TRUC|O_CREAT.  Definitely,
definitely, definitely don't "hack" a "fix" to cp, cat, and others which,
while it won't dork UFS, will dork other file systems.	The problem is in
the kernel and either needs a VM fix (inconvenient and expensive) or an
FS fix (inconvenient int that all FS's would be required to support it).
One of these two must be our answer.


					Terry Lambert
					terry@icarus.weber.edu
					terry_lambert@novell.com
---
Any opinions in this posting are my own and not those of my present
or previous employers.
-- 
-------------------------------------------------------------------------------
                                        "I have an 8 user poetic license" - me
 Get the 386bsd FAQ from agate.berkeley.edu:/pub/386BSD/386bsd-0.1/unofficial
-------------------------------------------------------------------------------