Pourquoi ne puis-je pas créer un «lien dur» vers un fichier à partir d'un répertoire «mount --bind» sur le même système de fichiers?

9

Problème d'origine

J'ai un fichier sur un système de fichiers: /data/src/file

et je veux le lier à: /home/user/proj/src/file

mais /homeest sur un disque et /datasur un autre donc j'obtiens une erreur:

$ cd /home/user/proj/src
$ ln /data/src/file .
ln: failed to create hard link './file' => '/data/src/file': Invalid cross-device link

D'accord, j'ai donc appris que je ne peux pas établir de lien dur entre les appareils. Logique.

Problème à portée de main

J'ai donc pensé que j'aurais envie de créer un srcdossier sur /datale système de fichiers de:

$ mkdir -p /data/other/src
$ cd /home/user/proj
$ sudo mount --bind /data/other/src src/
$ cd src
$ # (now we're technically on `/data`'s file system, right?)
$ ln /data/src/file .
ln: failed to create hard link './file' => '/data/src/file': Invalid cross-device link

Pourquoi cela ne fonctionne toujours pas?

solution de contournement

Je sais que cette configuration est correcte car je peux créer le lien dur tant que je suis dans le "vrai" /datarépertoire au lieu du lien lié.

$ cd /data/other/src
$ ln /data/src/file .
$ # OK
$ cd /home/user/proj/src
$ ls -lh
total 35M
-rw------- 2 user user 35M Jul 17 22:22 file

$

Quelques informations système

$ uname -a
Linux <host> 4.10.0-24-generic #28-Ubuntu SMP Wed Jun 14 08:14:34 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

$ findmnt
.
.
.
├─/home                               /dev/sdb8   ext4       rw,relatime,data=ordered
│ └─/home/usr/proj/src             /dev/sda2[/other/src]
│                                                 ext4       rw,relatime,data=ordered
└─/data                               /dev/sda2   ext4       rw,relatime,data=ordered

$ mountpoint -d /data
8:2

$ mountpoint -d /home/usr/proj/src/
8:2

Remarque : J'ai modifié manuellement les noms de fichier et de répertoire pour rendre la situation plus claire, il peut donc y avoir une faute de frappe ou deux dans les affichages de commande.

jdk1.0
la source
2
Peu importe où vous montez le dossier. Ils sont physicall sur différentes partitions. Chaque partition a sa propre table de fichiers et le lien physique est simplement enregistré dans cette table.
user996142
2
Le point ici est que les fichiers ne sont PAS sur des partitions physiquement différentes. C'est le même système de fichiers de la même partition. La différence est le montage de liaison.
roaima
La monture de liaison n'est qu'une fiction. Il ne modifie pas les structures de données sur les disques. Les systèmes de fichiers sont encore physiquement séparés.
Bob Eager
Mais lorsque je crée le lien dur sur, /dataje peux accéder à l'inode à partir du répertoire de montage de liaison, donc soit le montage de liaison doit être sur la même partition que /data, soit le lien dur fonctionne sur plusieurs appareils, ce qui devrait être illégal, mais fonctionne quand même. Qu'est-ce que je rate?
jdk1.0

Réponses:

6

Il y a un manque décevant de commentaires dans le code . C'est comme si personne ne l'avait jamais jugé utile, car les montures de liaison temporelle ont été implémentées dans la version 2.4. Assurément, tout ce que vous auriez à faire serait de remplacer .mnt->mnt_sboù il est dit .mnt...

Parce que cela vous donne une limite de sécurité autour d'un sous-arbre.

PS: cela a été discuté plusieurs fois, mais pour éviter les recherches: pensez par exemple à mount --bind / tmp / tmp; vous avez maintenant une situation où les utilisateurs ne peuvent pas créer de liens vers ailleurs sans racine fs, même s'ils ont / tmp accessible en écriture. Des techniques similaires fonctionnent pour d'autres besoins d'isolement - en gros, vous pouvez limiter le changement de nom / lien à un sous-arbre donné. IOW, c'est une fonctionnalité délibérée. Notez que vous pouvez lier un tas d'arbres en chroot et obtenir des restrictions prévisibles quelle que soit la façon dont les éléments peuvent être réorganisés un an plus tard dans l'arbre principal, etc.

- Al Viro

Il y a un exemple concret plus loin dans le fil

Chaque fois que nous obtenons que mount -r --bind fonctionne correctement (que j'utilise pour placer des copies des bibliothèques partagées nécessaires dans les prisons chroot tout en autorisant le partage de cache de page), cette fonctionnalité rompait la sécurité.

mkdir /usr/lib/libs.jail
for i in $LIST_OF_LIBRARIES; do
ln /usr/lib/$i /usr/lib/libs.jail/$i
done
mount -r /usr/lib/libs.jail /jail/lib
chown prisoner /usr/log/jail
mount /usr/log/jail /jail/usr/log
chrootuid /jail prisoner /bin/untrusted &

Bien que les protections devraient être suffisantes, je préfère éviter d'avoir le lien prisonnier /jail/lib/libfoo.so (l'écriture renvoie EROFS) vers / jail / usr / log où il est potentiellement accessible en écriture.

sourcejedi
la source
-1

La raison pour laquelle vous ne pouvez pas effectuer de liaison entre appareils est que vous introduisez des ambiguïtés. L'entrée de répertoire du fichier contient (dans les systèmes simples) le numéro i-node du fichier concerné. Un lien dur (juste une autre entrée de répertoire) doit également contenir le même numéro i-node. C'est bien, mais les numéros i-node ne sont uniques que dans un seul système de fichiers (ils sont généralement un ensemble dense commençant à 1).

Votre monture de liaison ne résout pas ce problème. Oui, il construit une sorte de «fiction» de la structure, mais ce qu'il ne fait pas, c'est renuméroter tous les i-nœuds sur un système de fichiers pour s'assurer qu'ils sont tous uniques sur les deux systèmes de fichiers concernés! Ce serait idiot.

Cette restriction a toujours existé sur les systèmes UNIX. Le lien symbolique a été inventé en partie pour résoudre ce problème. Je sais qu'ils ne sont pas fonctionnellement tout à fait les mêmes, mais ils sont généralement OK.

Essayez un lien symbolique? ( ln -s)

Bob Eager
la source
Il n'y aurait pas de nom pour une renumérotation des inodes ici. Il n'y a qu'un seul système de fichiers sous-jacent, avec deux vues.
Gilles 'SO- arrête d'être méchant'
L'une des raisons pour lesquelles je ne voulais pas d'un lien symbolique était parce que mes chemins étaient longs et que c'était difficile de faire un ls -l. Un raisonnement un peu idiot au début, mais ensuite cela a conduit à un trou de lapin et je suis devenu curieux de savoir ce qui se passait avec les liens durs ...
jdk1.0
@Gilles, c'est ce que je disais. Le point que je faisais était que la renumérotation des inodes serait ridicule. Aucune idée de la raison pour laquelle une réponse correcte a été rejetée.
Bob Eager
Vous obtenez la bonne conclusion, mais votre explication est erronée à tellement d'endroits que votre réponse dans son ensemble est très trompeuse. Voir la réponse de sourcejedi pour une bonne explication.
Gilles 'SO- arrête d'être méchant'
Je ne vois aucune erreur, même si j'avoue que j'aurais pu être plus clair.
Bob Eager