Today, I added a second drive to a virtual machine. My plan was to use this second drive for the /home folder. To do so, I first tried to rename the existing /home folder:

# mv -vi home home_old
mv: cannot move "/home" to "/home-old": Device or resource busy

Oops. No, /home is not busy. Nobody is doing anything in /home. In any case, just because someone has a file open does not, under normal circumstances, prevent the folder that contains the file from being renamed. And no, /home is not mounted already to another file system.

This is how I ended up learning about mount namespaces, which are used by the systemd demon in Linux. Thing is, the same mount point may mean entirely different things in different namespaces. This is used extensively, for instance, when systemd assigns different folders to different programs, all mapped to /tmp, so that these programs do not get to "see" each others' temporary files.

And it so happens that one particular system process in my case, chronyd, was assigned a different namespace, where it "hogged" /home.

How to find out? For instance, ls -al /proc/*/task/*/ns/mnt lists all process mount points. It is easy to find out from this which one is the root namespace and then filter it out with grep -v. A more sophisticated way to list all namespaces is through

readlink /proc/*/task/*/ns/mnt | sort -u

whereas the root namespace can be found using

readlink /proc/1/ns/mnt

And the namespace of a given process can be inspected in detail using

cat /proc/1/task/1/mountinfo

These commands should be sufficient to identify the offending process. Shutting it down, at least temporarily, should enable renaming /home. Worked for me.

Yet another problem that I would not have been able to solve near as quickly, were it not for a relevant, very useful answer on StackExchange.