ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
#uname -a
Linux myserver 2.6.18-128.el5PAE #1 SMP Wed Dec 17 12:02:33 EST 2008 i686 i686 i386 GNU/Linux
I create a socket server program never exit, then I create a soft link to link it.
Code:
ln -sf realprogram linkname1
and then start linkname1 at background.
Code:
linkname1 &
Now I modify the code of realprogram and recompile and overwrite realprogram(which succeeded), at the same time I never exit or restart "linkname1".
And I found linkname1 not update to the modified code.
Can someone tell me the detail internal mechanism of it? Thanks in advance.
The linker does not write directly to the existing realprogram file but writes to a temporary file name and then renames the temp file to "realprogram", leaving the running process executing a now unnamed file. If you were to run
Code:
ls -l /proc/$(pidof linkname1)/exe
you would see the link marked as "(deleted)".
linkname1 will still point to the same name as before (realprogram), but following that link should get the new content. Are you doing this on a locally mounted filesystem, or is it remote via NFS? There might be some NFS caching weirdness going on. I'm by no means an expert on that.
The linker does not write directly to the existing realprogram file but writes to a temporary file name and then renames the temp file to "realprogram", leaving the running process executing a now unnamed file.
Thanks for your reply. But Sorry I don't understand what this mean.
In small words: you cannot change the program under a running process, even if you delete and recreate the binary executable (that's what linker does).
On the other hand, overwriting the executable (or a shared lib it uses) will lead to unpredictable errors, most likely abnormal termination. Symbolic (or other) links don't matter. So you have to restart your server-program, whenever you recreate it.
you can imagine the following: when you start a program it will be copied into the memory (from the filesystem) and will be executed from memory. Modifying the file afterward will not affect that copy and the execution.
you can imagine the following: when you start a program it will be copied into the memory (from the filesystem) and will be executed from memory. Modifying the file afterward will not affect that copy and the execution.
I am just wondering. How hard in OP's case to change the memory so the execution of the program will be updated accordingly?
Overwriting the program's memory will cause unpredictable errors and abnormal termination (overwriting the binary file may cause this, as it is still used when pages of the code are swapped out and needed to be reloaded).
If you want something like that, periodically check from the program the date of the executable (with stat(2)), and use exec* to replace the current process when necessary. (A more sophisticated approach is using a minimal core and a shared lib which can be replaced with dlcose+dlopen)
I think the key concept is that there are two distinct things involved. One is a file, and I don't think it matters that the file is open or has any kind of links to it. The other is a process. Nothing can modify the properties of a process (except killing the process by sending an uncatchable signal), except the process itself. Modifying the file does not affect the process, even though the process was started by loading object code that came from the file.
What happens, when a memory-page of the code gets swapped out? Well, as it is read-only, it won't be actually written to the swap-file, instead when it is needed again it will be reloaded from the binary executable file. If the file has been changed that will lead to random errors.
What happens, when a memory-page of the code gets swapped out? Well, as it is read-only, it won't be actually written to the swap-file, instead when it is needed again it will be reloaded from the binary executable file. If the file has been changed that will lead to random errors.
And that is why the kernel will not allow you to write to the file of an executable or library that is in use by a running process. If you try, you get an ETXTBSY (Text busy) error.
Yes, that's true. On the other hand, once I could somehow overwrite a shared library while it was used by a running program, which then crashed because of that.
Modifying the file does not affect the process, even though the process was started by loading object code that came from the file.
I think NevemTeve has already explained why your statement would be incorrect if you actually do modify that file (not a new file of the same name).
The process remains tied to the file. Pages can be read from that file long after the process is "started".
In the common situation, one can delete and recreate the file with different contents, so the filename in the directory is now associated with a different file. But the original file is not actually deleted as long as it is held open by that process.
The OP seems to be asking about a more complicated case in which there is also a soft link to the file. The OP seems to be saying the soft link remains connected to the old file (that only still exists because the process has it open) and does not connect to the new file.
I find that surprising, but I don't recall enough about soft links to be sure, nor do I have time now to test this behavior myself.
Quote:
Originally Posted by fantasy1215
Thanks for your reply. But Sorry I don't understand what this mean.
It is rare for programs to open existing files and incrementally overwrite their entire content. Writing part of an existing file is usually done only in cases where you really need to write part of an existing file.
When a program wants to replace all of an existing file, it typically deletes the existing file and creates a new file of the same name as the previous file.
That approach enables the Linux feature of not really deleting a file if some other process has that file open during the delete request. The file only loses its name when you try to delete it. Once no process has the file open, it actually gets deleted.
rknichols described the concept of delete and replace plus the common extra safety feature of starting with a temporary file. That allows the program to delay deleting the original until it is done writing the new one, so in case of error during the write, the old version is safe. That extra level of safety was not really relevant to the basic topic of your question: At whatever moment a file is deleted, if that file is still open by some process it isn't really deleted; It just loses its connection from its name in the directory. The true delete is delayed until the file is no longer open.
Quote:
Originally Posted by pan64
you can imagine the following: when you start a program it will be copied into the memory (from the filesystem) and will be executed from memory. Modifying the file afterward will not affect that copy and the execution.
But imagining it that way leads to misunderstanding. When you start a program, it will map (not copy) parts of that file onto parts of your virtual address space. Whenever the process happens to use mapped pages, the kernel may read or reread those pages from the mapped file.
Perhaps it might help to describe briefly how files and links are implemented.
A physical file is in three parts:
a directory entry (aka hard link) consisting of the file name and a pointer to:
an i-node (file descriptor) which contains a description of the file (type, dates, permissions, etc) and
if a directory, directory entries,
if a soft link, the complete path to the directory entry of the linked file,
otherwise, pointers to blocks containing the data of the file (such as text or code).
Normally, if a file is edited, the last two are replaced by new ones to which the old directory entry is redirected: a new directory entry is created to point to the old file descriptor as a back-up file. consequently, any soft link to this file is still valid, i.e. points to the original directory entry. However, when compiling and loading a file, the old directory entry cannot be used, since as rknichols points out, the new executable file has originally a different temporary name, and so different directory entry, whose name is subsequently replaced. However, the soft link points to an absolute address, which is the old, superseded, directory entry.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.