| Scott Lurndal 2005-05-14, 1:23 pm |
| Paul Colquhoun <postmaster@andor.dropbear.id.au> writes:
>On Thu, 12 May 2005 04:30:31 GMT, Scott Lurndal <scott@slp53.sl.home> wrote:
>| Izo <I@siol.net> writes:
>|>Kernel 2.4.x, 2.6.x
>|>
>|
>|>The behaviour seems slightly confusing for me. Why ? The file system /
>|>kernel allows the shared object rewrite / replace without complaint and
>|>it harms the program run-time behaviour while it blocks the program's
>|>binary replacement while such action (in contrary to shared object
>|>replacement) does not harm the program's operation.
>|>
>|>What is the reason for such behaviour (program crash etc.) anyway ?
>|
>| When the kernel pages out a code page, it just discards it, since it
>| can always reload it directly from the object itself (e.g. executable
>| or shared object). So, while some of the code pages will be
>| in memory when you overwrite the .so, not all will be. When the next
>| code page is paged in from the new shared object, the function calls
>| from the old code pages will call incorrect addresses in the new
>| code pages and will cause arbitrary random code to be executed which
>| will quickly cause a system fault.
>
>
>Unfortunatly it doeszn't work quite that way. When the library is opened,
>it gets a file handle attached. This file handle acts just like a directory
>entry. The file will not be deleted from the disk until all directory entries
>and file handles are removed/closed.
Actually, it does work the way I described. When you copy over a file,
the contents are replaced, not the directory entry. SVR3.2 was the
last release of unix which supported ETXTBUSY, since SVR4 (and linux
follows this), it is possible to overwrite the _contents_ of both an
a.out and a .so (shared object) while it is executing.
I never said anything about the file being deleted. It isn't. cp
or mv will replace the contents of the file without creating a new
inode.
If you want to keep the original content of the file around, you must
explicity unlink (man rm) the file first, then copy the new library
or a.out into place. If you do this, then your comments about
"File Handles" (which is a windows-ism) are correct. File handles don't act like
directory entries in unix. However, there are reference counts on
on-disk inodes and reference counts on in-core inodes. The on-disk
reference counts count all hard links (i.e. directory entries) that
refer to the inode. The in-core inode count includes all references
from open file descriptors and mmapped memory regions (man mmap), the
in-core inode won't be released until it is no longer referenced. That
doesn't prevent cp from replacing the content of the file in toto without
replacing the inode.
>
>When the library is updated, the new library gets its own disk blocks, and
>a new directory entry, but the old library is still on disk and the file
>handle pointer to it is still valid.
This is where you are incorrect. A directory entry in unix is simply a
name-value pair where the name is the leaf file name and the value is
the inode number. And when the new library is copied _over_ the old
library by cp, it doesn't change the directory entry, nor does it change
the inode number. It simply replaces the allocated blocks with newly
allocated blocks.
>
>When the OS needs to page in from teh library, it uses the file handle
>it already has, not the (new) directory entry.
There is no new directory entry. The soi disant file handle (the
inode number) hasn't changed, but the data contained in the file
referred to by the inode number has.
scott
(linux/unix kernel engineer for 20+ years)
|