* Alexander Skwar <[EMAIL PROTECTED]> wrote:

Hi,

> Well, depends on how you define "open files are overwritten". On
> Linux, it is like you say. But on Windows and HP-UX, you CANNOT
> replace a file, if it's still opened somewhere. Eg. you cannot
> replace /bin/sh. Instead, a new file will be created and after
> a reboot, the new file will be moved in place (that's how it
> works on HP-UX, on Windows you cannot overwrite opened files.).
> 
> What I mean: On Linux, you can replace /bin/sh even if it used.
> You cannot overwrite the used inodes/blocks, that's absolutely
> correct, but that's not what I meant.

ACK. 

I'll try to explain the logic behind a little bit more detailed:

On Linux (and probably other Unix'ish kernels), files are not 
identified by names, but inode-id's. The name is just an pointer
to the file, just like an DNS-name->IP-addr mapping ;-)
Many such pointers to some file may exist. Only when all pointers
are removed (open fd's also considered as an pointer) the file
gets actually removed. That's why the syscall used for removing
a file is called unlink(): it just removes the given name but
does not actually delete it.

When you intend to replace some file, you've got two choices:
(from the kernel's view)

a) open the existing file, probably truncate it and write new the 
   data. if someone has opened this file, he will see the changes 
   you made. If the file has been mmap'ed to some process, it will
   see the changes immediately in its address space. therefore files 
   should be locked (at least the used regions), so an accidental 
   overwrite (which may cause ugly crashes) can be prevented. AFAIK 
   on Linux, .TEXT segments are always locked when the get mapped in 
   (you you get "busy" when trying to write there)
  
b) create a new file under the old name. either by renaming or 
   unlink'ing the old file. here you've got no problem w/ other
   processes holding the file opened, since you actually have 
   two different files. the new file only gets accessed when 
   you (re)open the file and thus let the kernel do an new 
   name->inode lookup.
   
  
BTW: when coding installers for running systems (which in fact
is the case in >90%). Do not use cp (at least GNU coreutils), 
since it *overwrites* the existing file (case a). This will 
fail on used .TEXT (=executable code) files, since they're locked
and most likely produce problems with other open files. 
If writing the file does not run almost immediately you should 
first write to some temporary file (on the same filesystem!)
and then do a quick rename (unlink(..) ; rename(..)) so nobody 
tries to use unfinished files. 

And be very careful you reinstall you (running) installer !
Several years ago, glibc had a critical problem, which screwed up 
your system on install over the running system: it first removed 
the /lib/ld.so and /lib/libc* symlinks and then recreated them by 
separate calling /bin/rm and /bin/ln binaries. If they weren't
linked statically, it killed itself - /bin/ln coulnd'n be executed
since libc was unusable in this moment. Using -s flag to ln instead
of calling rm did the trick.

I have no idea how careful emerge is here ...


cu
-- 
---------------------------------------------------------------------
 Enrico Weigelt    ==   metux IT service - http://www.metux.de/
---------------------------------------------------------------------
 Please visit the OpenSource QM Taskforce:
        http://wiki.metux.de/public/OpenSource_QM_Taskforce
 Patches / Fixes for a lot dozens of packages in dozens of versions:
        http://patches.metux.de/
---------------------------------------------------------------------
-- 
gentoo-user@gentoo.org mailing list

Reply via email to