Hello
As we are working on snap instances, where a single snap may be installed multiple times under different names, possibly tracking different channels and in general having different revisions active, we face an important issue in how many classically confined snaps are actually constructed.
Today a classically confined snap may use compiled C code and set the prefix to /snap/realname/current/usr
to effectively get many C programs to do the right thing and get their files from /snap/realname/current
(which is a symlink) /usr
.
If on a given system that is instantiated as instancename
it will appear as /snap/instancename/current/usr
but the hard-coded paths still refer to realname
.
The proposed solution is to put classically confined snaps in a new mount namespace and provide them with a recursive bind mount from /snap/instancename/
to /snap/realname
. That is, whatever the instance is will hide the real snap (non-instantiated) mount point but only from the point of view of that snap’s process.
How can we do this? I think we can do this as follows:
- unshare the mount namespace
- make
/snap
a mount point with slave event propagation (see below). - create a bind mount from
/snap/instancename
to/snap/realname
This mount namespace would not be preserved anywhere as it would not need any updates for individual processes. The slave event propagation refers to https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt where a given mount namespace receives mount events (that is mounts and unmounts) from another namespace when those mount events belong to a particular tree (a mount point and anything below that is not overridden by another mount point).
That’s the current proposal, I will prepare some exploratory PR for this shortly.