Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Here it says that you can rewrite an executable file and the process will run just fine - it will be re-read when a process restarts.

However, when I try to replace a binary file while the process is running (with scp, from dev to test server) it says 'file busy'. And if I replace a shared library file (*.so), all the processes that link it crash.

Why so? Am I missing something? How can I replace the binary files without stopping/crashing a process?

share|improve this question
    
You can check .so file using ldd filename.so to check dependencies –  Rahul Patil Apr 30 '13 at 9:39
    
I know the dependencies. I want a way to replace those files without affecting the running processes. As the linked question implies –  sammy Apr 30 '13 at 9:55
    
downtime is required.. or you can do like stop app && create symlink of .so && start app –  Rahul Patil Apr 30 '13 at 10:00

2 Answers 2

up vote 6 down vote accepted

As mentioned in Why does a software package run just fine even when it is being upgraded?, the lock is placed on inode not on filename. When you load and execute a binary, the the file is marked as busy - which is why you get ETXTBSY (file busy) error when you try to write to it.

Now, for shared libraries it is slightly different: the libraries get memory mapped into the process' address space with mmap(). Although MAP_DENYWRITE may be specified, at least Glibc on Linux silently ignores it (according to the man page, feel free to check the sources) - check this thread. Hence you actually are allowed to write the file and, as it is memory mapped, any changes are visible almost immediately - which means that if you try hard enough you can manage to brick your machine by overwriting the library.

The correct way to update therefore is:

  1. removing the file, which removes reference to the data from the file system, so that it isn't accessible for any newly spawned applications that might want to use it, while keeping the data accessible for anyone who already has it open (or mapped);

  2. creating a new file with updated contents.

Newly created processes will use the updated contents, running applications will access the old version. This is what any sane package management utility does. Note that it's not completely without any danger though - for example applications dynamically loading code (using dlsym() and friends) will experience troubles if the library's API changes silently.

If you want to be on the really, really safe side, shut down the system, mount the file system from another operating system instance, update and bring up the updated system again.

share|improve this answer

A rpm upgrade does the same - with running binaries and libraries while nothing crashes.

So what is the difference:

  1. unlink file
  2. write new file with the same name

This will NOT replace the file inplace: The inode referring to the in-use-binary is still "busy" until the last object holding it open finishes. The new file will be created with a new inode-number.

Now scp or cp will try to replace the file inplace - which would change the content the inode is referring to. This does not work - as you described.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.