# What happens to a running binary after a portmaster upgrade?



## Buck (Dec 17, 2019)

I've seen a thread on this matter but the underlying mechanisms are still not clear. Suppose I've done a minor upgrade to dovecot using portmaster while dovecot was running in the background. What happens then? Does it care if its binary had been modified and if yes, why exactly? Or does it load itself completely into memory upon startup and whether or not I modify a binary after that just doesn't matter? I know folks recommend restarting the service or the server itself after such upgrades, but I'd also like to understand what's happening on an OS level when binaries are modified.

Second, I've seen dovecot and postfix misbehaving after upgrades performed in such fashion, even minor ones, so there's some potential for data loss, but I have never seen an official recommendation to stop a daemon before performing its upgrade.


----------



## SirDice (Dec 17, 2019)

Buck said:


> What happens then?


Nothing.



> Does it care if its binary had been modified and if yes, why exactly?


It's not going to notice, it's already loaded into memory and running from there.



Buck said:


> I know folks recommend restarting the service or the server itself after such upgrades


You're going to need to restart that service in order to get the new version running. Or else the binary, on disk, would be new but the running process would still be old.


----------



## Buck (Dec 17, 2019)

Thanks. So apart from config files that may be changed by an upgrade (that may be accessed from time to time), no lib upgrades are going to affect the binary if it's already in memory?


----------



## piggy (Dec 17, 2019)

Buck said:


> Thanks. So apart from config files that may be changed by an upgrade (that may be accessed from time to time), no lib upgrades are going to affect the binary if it's already in memory?


Some programs have routines to discover system binary are modified and they tell the user to restart the program. In my experience it happened many times with Firefox browser, then I do not remember if it was under FreeBSD or some Linux (Ubuntu that's for sure).


----------



## xtaz (Dec 18, 2019)

Not totally true about nothing happening. Most software won't notice. But Dovecot specifically does. It complains that the authentication process which is spawned on a new login does not match the same version as the master process that spawned it and then rejects the login. Best practice is to restart something as soon as it's upgraded, and if you don't want to do that then don't upgrade it until you are ready to restart it.


----------



## PMc (Dec 19, 2019)

What happens exactly is that the upgrade process deletes the old file and installs the new one. 
But, for a running program, the executable file (and the shared libs) are open for execution. And on unix, when we delete an opened file, it will get invisible, but it will not be deleted until after the last close.
This means: 

your disk-space will not be freed immediately.
the running program can continue to run, it can also page in further pages per demand load.
if the application, for whatever reason, decides to newly open files of it's installation during runtime, it will grab the new ones. The results may be more or less undefined.


----------



## SirDice (Dec 20, 2019)

PMc said:


> But, for a running program, the executable file (and the shared libs) are open for execution.


The process is loaded into memory and it runs from there. The files themselves are not locked or open after they've been loaded into memory.


----------



## PMc (Dec 20, 2019)

I'm very certain the executable is open. Because on memory shortage these pages are not paged out but just dropped; they will be fetched again from disk when page-fault occurs.

We can also watch this:

```
$ cp /bin/sleep .
$ ls -i sleep
135017 sleep
$ ./sleep 60 &
[1] 14925
$ lsof -p 14925
COMMAND   PID  USER   FD   TYPE       DEVICE  SIZE/OFF   NODE NAME
sleep   14925 admin  txt   VREG 42,890372273      7888 135017 /home/admin/sleep
$ rm sleep ; cp /bin/sleep .
$ ls -i sleep
135021 sleep
$ lsof -p 14925
COMMAND   PID  USER   FD   TYPE       DEVICE  SIZE/OFF   NODE NAME
sleep   14925 admin  txt   VREG 42,890372273      7888 135017 /home (zdesk/home)
$
```

Copy the `/bin/sleep` to the homedir and run it. It has got inode #135017, and lsof shows the file opened as "txt" (that is, executable code). Now delete it while running, and copy a new one. This one gets inode #135021. And lsof still reports the old inode #135017 as opened, but cannot see a filename and only reports the filesystem instead - because the directory entry with the filename has been removed, but not yet the inode. If one does a fsck (or a filesystem structure dump or some ZFS equivalent) at this point, it will report the filespace as used and the inode lacking a directory entry.


----------



## Buck (Dec 21, 2019)

Thanks PMc for the great technical explanation and xtaz on reminding that dovecot is not a single binary. I saw that dovecot behavior myself but didn't have time to look into it in detail, was faster to just restart it.


----------

