Depois de passar pelo código pam_mount , acredito que sei o que é
indo. A situação surge principalmente de duas questões:
-
A abordagem pam_mount para detectar volumes já montados
é muito simplista.
-
O kernel irá alegremente empilhar montagens repetidas de bind no topo de
um ao outro, mesmo se o caminho de origem e o ponto de montagem forem os mesmos.
De mount.c
no repo pam_mount :
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;
É isso. Os valores para source e target são fornecidos por
libmount do util-linux. Infelizmente, libmount é capaz de
determinar o caminho de origem original de uma montagem de ligação apenas se
aparece em /run/mount/utab
. Pontos de montagem do PAM, não. Assim é
não é suficiente para estender a verificação acima.
No entanto, para a montagem de ligação
<volume
options="bind,nodev,exec,nosuid"
user="yourstruly"
mountpoint="/nix"
path="/mnt/local/nix"
/>
o kernel gera uma entrada em /proc/mounts
da seguinte forma:
/dev/mapper/VolGroup00-local /nix ext4 rw,relatime 0 0
onde a fonte obviamente não corresponde ao caminho especificado
a linha de comando mount (8). Em vez disso, dá a base
volume como a origem, fazendo com que a verificação pam_mount falhe.
As informações do caminho de origem são perdidas. Um pouco melhor é
/proc/self/mountinfo
:
934 654 253:6 /nix /nix rw,relatime shared:33 - ext4 /dev/mapper/VolGroup00-local rw
Ainda de acordo com o
fonte libmount
o primeiro /nix
(arg index 4) corresponde à “raiz do
o monte dentro do FS ”. (O segundo é o ponto de montagem
VFS.) Assim, o caminho original passado para mount (8) é
substituído pela localização dentro do volume. Com o volume
sendo montado em /mnt/local
, acabamos meramente com /nix
.
Esse valor pode ser consultado usando uma API ( mnt_table_get_fs_root()
)
mas é inútil para pam_mount porque o último não tira
o ponto de montagem do valor de origem ao executar a verificação.