Perché non posso creare un `hardlink` a un file da una directory“ mount --bind ”sullo stesso filesystem?


9

Problema originale

Ho un file su un filesystem: /data/src/file

e voglio collegarlo a: /home/user/proj/src/file

ma si /hometrova su un disco e /datasu un altro, quindi viene visualizzato un errore:

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

Ok, quindi ho imparato che non riesco a collegarmi duramente tra i dispositivi. Ha senso.

Problema a portata di mano

Quindi ho pensato che avrei avuto voglia di legare e montare una srccartella che si trova sul /datafile system:

$ 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

Perché questo non funziona ancora?

Soluzione

So di avere questa configurazione giusta perché posso creare il collegamento reale purché sia ​​nella /datadirectory "reale" anziché in quella associata.

$ 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

$

Alcune informazioni di sistema

$ 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

Nota : ho modificato manualmente i nomi di file e directory per rendere più chiara la situazione, quindi potrebbero esserci un errore di battitura o due nelle letture dei comandi.


2
Non importa dove si monta la cartella. Sono fisici su diverse partizioni. Ogni partizione ha una propria tabella di file e il collegamento fisico è appena registrato in questa tabella.
user996142,

2
Il punto qui è che i file NON sono su partizioni fisicamente diverse. È lo stesso filesystem dalla stessa partizione. La differenza è il bind mount.
roaima,

Il bind mount è semplicemente una finzione. Non modifica le strutture dei dati sui dischi. I file system sono ancora fisicamente separati.
Bob Eager,

Ma quando creo il collegamento reale su /dataposso accedere all'inode dalla directory di bind mount, quindi o il bind mount deve trovarsi sulla stessa partizione /dataoppure il collegamento reale funziona su tutti i dispositivi, il che dovrebbe essere illegale, ma funziona comunque. Cosa mi sto perdendo?
jdk1.0,

Risposte:


6

C'è una deludente mancanza di commenti nel codice . È come se nessuno lo avesse mai ritenuto utile, dal momento che i montaggi dei vincoli temporali sono stati implementati in v2.4. Sicuramente tutto ciò che dovresti fare è sostituire .mnt->mnt_sbdove dice .mnt...

Perché ti dà un limite di sicurezza attorno a una sottostruttura.

PS: che è stato discusso parecchie volte, ma per evitare ricerche: si consideri ad esempio mount --bind / tmp / tmp; ora hai una situazione in cui gli utenti non possono creare collegamenti a nessun altro root fs, anche se hanno / tmp scrivibili a loro. Tecniche simili funzionano per altre esigenze di isolamento: in sostanza, è possibile limitare la ridenominazione / collegamento a una sottostruttura specifica. IOW, è una caratteristica deliberata. Nota che puoi legare un gruppo di alberi in chroot e ottenere restrizioni prevedibili indipendentemente da come le cose potrebbero essere riorganizzate un anno dopo nell'albero principale, ecc.

- Al Viro

C'è un esempio concreto più in basso

Ogni volta che mount -r --bind funziona correttamente (che uso per posizionare copie delle librerie condivise necessarie all'interno delle jail chroot consentendo la condivisione della cache delle pagine), questa funzionalità interrompe la sicurezza.

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 &

Sebbene le protezioni dovrebbero essere sufficienti, ma preferirei evitare di avere il collegamento prigioniero /jail/lib/libfoo.so (write restituisce EROFS) a / jail / usr / log dove è potenzialmente scrivibile.


-1

Il motivo per cui non è possibile eseguire collegamenti tra dispositivi è perché si introducono ambiguità. La voce della directory per il file contiene (in sistemi semplici) il numero i-node per il file in questione. Un hard link (solo un'altra voce della directory) deve contenere lo stesso numero di i-node. Questo va bene, ma i numeri i-node sono univoci all'interno di un singolo file system (di solito sono un set denso che inizia da 1).

Il tuo bind mount non risolve questo problema. Sì, costruisce una sorta di "finzione" della struttura, ma ciò che non fa è ri-numerare tutti gli i-nodi su un file system per assicurarsi che siano tutti unici in entrambi i file system interessati! Sarebbe sciocco.

Questa restrizione è sempre stata presente sui sistemi UNIX. Il collegamento simbolico è stato inventato in parte per risolvere questo problema. So che non sono funzionalmente abbastanza uguali, ma di solito sono OK.

Prova un link simbolico? ( ln -s)


Non ci sarebbe alcun nome per qualsiasi rinumerazione di inode qui. C'è solo un filesystem sottostante, con due viste.
Gilles 'SO- smetti di essere malvagio' il

Uno dei motivi per cui non volevo un collegamento simbolico era perché i miei percorsi erano lunghi ed era disordinato farlo ls -l. All'inizio un ragionamento piuttosto sciocco, ma poi ha portato a una
tana di

@Gilles, questo è quello che stavo dicendo. Il punto che stavo sollevando era che la rinumerazione degli inode sarebbe ridicola. Non ho idea del perché sia ​​stata annullata la votazione di una risposta corretta.
Bob Eager,

Ottieni le conclusioni giuste, ma la tua spiegazione è sbagliata in così tanti punti che la tua risposta nel suo insieme è molto fuorviante. Vedi la risposta di sourcejedi per una buona spiegazione.
Gilles 'SO- smetti di essere malvagio' il

Non vedo alcun errore, anche se ammetto che avrei potuto essere più chiaro.
Bob Eager,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.