0

At login, a bind mount is created. In ~/.pam_mount.conf.xml:

  <volume options="bind" user="phg" mountpoint="/nix" path="/store/nix" />

This needs to be done only once per boot. Note that I do not have access to the fstab or systemd mounts.

The bind mount itself works. However, it is being executed on every login. Since I can have dozens, hundreds of logins to the box via SSH, this fills up the mount table rather quickly. Just minutes ago the box was rendered unusable due to resource exhaustion because of it.

Detecting an existing bind mount is easy but with pam_mount.so I don’t see a means to make the mount depend on the result of, say a script.

Hence my question:

  • How can I prevent the bind mount from being executed more than once, or
  • how can I make repeated bind mounts a no-op so as to prevent mounts from accumulating?

See also: https://github.com/karelzak/util-linux/issues/448

2
  • 1
    pam_exec could do it, but it sounds like you can't change the PAM configuration either.
    – sourcejedi
    Commented Jul 11, 2018 at 16:11
  • Thanks for the pointer. Sadly, pam_exec is not available on this system.
    – phg
    Commented Jul 12, 2018 at 6:34

2 Answers 2

2

I wonder if you are using systemd (mount propagation by default). It seems to more than double the number of bind mounts each time. Maybe it behaves better with private in the mount options... Ah. I see you can write unbindable as an option to mount. If it accepts that, then it could answer your question. So long as pam_mount allows a mount to fail and does not abort the login.


I notice that for some reason, your pam_mount does not seem to be working as it is designed.

pam_mount keeps a "reference count" of your mounts. For example, if you have two active logins at once, the filesystem should only be mounted once. It is unmounted after both sessions log out.

If you are stopping the filesystem from being unmounted at logout time, you are abusing pam_mount. Be aware that it might change in future in some way which breaks your setup.

3
  • So long as pam_mount allows a mount to fail and does not abort the login – this should be possible with the nofail option, shouldn’t it?
    – phg
    Commented Jul 12, 2018 at 6:35
  • pam_mount keeps a "reference count" of your mounts. For example, if you have two active logins at once, the filesystem should only be mounted once. It is unmounted after both sessions log out. – the first part does not agree with my observation; the latter is trivial to explain: over a work day, tons of SSH sessions accumulate to that system, I rarely close them (working with a master connection is too fragile in my experience).
    – phg
    Commented Jul 12, 2018 at 6:39
  • @phg I think nofail only applies to mount -a (or systemd equivalent).
    – sourcejedi
    Commented Jul 12, 2018 at 9:06
1

After going through the pam_mount code I believe I know what is going on. The situation arises mainly from two issues:

  • The pam_mount approach to detecting already mounted volumes is too simplistic.

  • The kernel will happily stack repeated bind mounts on top of one another even if source path and mountpoint are the same.

From mount.c in the pam_mount repo:

128         xcmp = fstype2_icase(vpt->type) ? strcasecmp : strcmp;
129         if (source != NULL)
130                 result = xcmp(vpt->volume, source) == 0;
131         if (target != NULL)
132                 result &= strcmp(vpt->mountpoint, target) == 0;

That’s it. The values for source and target are supplied by libmount from util-linux. Unfortunately, libmount is able to determine the original source path of a bind mount only if it appears in /run/mount/utab. PAM mountpoints don’t. Thus it’s not sufficient for extending the above check.

However, for the bind mount

<volume
  options="bind,nodev,exec,nosuid"
  user="yourstruly"
  mountpoint="/nix"
  path="/mnt/local/nix"
  />

the kernel generates an entry in /proc/mounts as follows:

/dev/mapper/VolGroup00-local /nix ext4 rw,relatime 0 0

where the source obviously doesn’t match the path we specified in the mount(8) command line. Instead, it gives the underlying volume as the source, causing the check by pam_mount to fail.

The source path information is lost. A bit better is /proc/self/mountinfo:

934 654 253:6 /nix /nix rw,relatime shared:33 - ext4 /dev/mapper/VolGroup00-local rw

Also according to the libmount source the first /nix (arg index 4) corresponds to the “root of the mount within the FS”. (The second one is the mountpoint in VFS.) Thus, the original path passed to mount(8) is substituted by the location inside the volume. With the volume being mounted at /mnt/local we end up with merely /nix. This value can be queried using an API (mnt_table_get_fs_root()) but it’s useless for pam_mount because the latter doesn’t strip the mountpoint from the source value when performing the check.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .