Risposte:
Un mount bind è una vista alternativa di un albero di directory. Classicamente, il montaggio crea una vista di un dispositivo di archiviazione come un albero di directory. Un mount bind prende invece un albero di directory esistente e lo replica in un punto diverso. Le directory e i file nel mount del bind sono gli stessi dell'originale. Qualsiasi modifica su un lato si riflette immediatamente sull'altro lato, poiché le due viste mostrano gli stessi dati.
Ad esempio, dopo aver emesso il comando Linux
mount --bind /some/where /else/where
le directory /some/where
e /else/where
hanno lo stesso contenuto.
A differenza di un collegamento reale o simbolico, un mount bind non influisce su ciò che è memorizzato nel filesystem. È una proprietà del sistema live.
Il bindfs
filesystem è un filesystem FUSE che crea una vista di un albero di directory. Ad esempio, il comando
bindfs /some/where /else/where
crea /else/where
un mount point sotto il quale /some/where
sono visibili i contenuti di .
Poiché bindfs è un filesystem separato, i file /some/where/foo
e /else/where/foo
appaiono come file diversi per le applicazioni (il filesystem bindfs ha il suo st_dev
valore). Qualsiasi modifica da un lato si riflette "magicamente" sull'altro lato, ma il fatto che i file siano gli stessi è evidente solo quando si sa come funziona il bindfs.
Bindfs non ha conoscenza dei punti di mount, quindi se c'è un mount point sotto /some/where
, appare come un'altra directory sotto /else/where
. Il montaggio o lo smontaggio di un filesystem al di sotto /some/where
appare sotto /else/where
forma di modifica della directory corrispondente.
I bindfs possono alterare alcuni dei metadati dei file: possono mostrare permessi e proprietà falsi per i file. Vedere il manuale per i dettagli e vedere sotto per gli esempi.
Un filesystem bindfs può essere montato come utente non root, hai solo il privilegio di montare filesystem FUSE. A seconda della distribuzione, questo potrebbe richiedere di essere nel fuse
gruppo o essere autorizzato a tutti gli utenti. Per smontare un filesystem FUSE, utilizzare fusermount -u
invece di umount
, ad es
fusermount -u /else/where
FreeBSD fornisce il nullfs
filesystem che crea una vista alternativa di un filesystem. I seguenti due comandi sono equivalenti:
mount -t nullfs /some/where /else/where
mount_nullfs /some/where /else/where
Dopo aver emesso uno dei due comandi, /else/where
diventa un punto di montaggio in cui /some/where
sono visibili i contenuti di .
Poiché nullfs è un filesystem separato, i file /some/where/foo
e /else/where/foo
appaiono come file diversi per le applicazioni (il filesystem nullfs ha il suo st_dev
valore). Qualsiasi modifica su un lato si riflette "magicamente" sull'altro lato, ma il fatto che i file siano gli stessi è evidente solo quando si sa come funziona nullfs.
A differenza dei bindfs di FUSE, che agiscono a livello dell'albero delle directory, i nullfs di FreeBSD agiscono più in profondità nel kernel, quindi i punti di mount sotto /else/where
non sono visibili: solo l'albero che fa parte dello stesso punto di mount in cui /some/where
si riflette /else/where
.
Il filesystem nullfs può essere utilizzabile con altre varianti di BSD (OS X, OpenBSD, NetBSD) ma non è compilato come parte del sistema predefinito.
Sotto Linux, i mount bind sono disponibili come funzionalità kernel. Puoi crearne uno con il mount
comando, passando l' --bind
opzione della riga di comando o l' bind
opzione mount. I seguenti due comandi sono equivalenti:
mount --bind /some/where /else/where
mount -o bind /some/where /else/where
Qui, il "dispositivo" /some/where
non è una partizione del disco come nel caso di un filesystem su disco, ma una directory esistente. Il punto di montaggio /else/where
deve essere una directory esistente come al solito. Si noti che nessun tipo di filesystem è specificato in entrambi i modi: fare un mount di bind non implica un driver di filesystem, copia le strutture di dati del kernel dal mount originale.
mount --bind
supporta anche il montaggio di una non directory su una non directory: /some/where
può essere un file normale (nel qual caso /else/where
deve essere anche un file normale).
Un mount bind Linux è per lo più indistinguibile dall'originale. Il comando df -T /else/where
mostra lo stesso dispositivo e lo stesso tipo di filesystem di df -T /some/where
. I file /some/where/foo
e /else/where/foo
sono indistinguibili, come se fossero collegamenti reali. È possibile smontare /some/where
, nel qual caso /else/where
rimane montato.
Con i kernel più vecchi (non so esattamente quando, penso fino a circa 3.x), i supporti di collegamento erano veramente indistinguibili dall'originale. I kernel recenti tengono traccia dei montaggi di bind ed espongono le informazioni tramite PID / mountinfo, che consente findmnt
di indicare il bind mount in quanto tale .
È possibile inserire voci di bind mount /etc/fstab
. Includi bind
(o rbind
ecc.) Nelle opzioni, insieme a tutte le altre opzioni che desideri. Il "dispositivo" è l'albero esistente. La colonna del filesystem può contenere none
o bind
(viene ignorata, ma l'uso di un nome di filesystem sarebbe confuso). Per esempio:
/some/where /readonly/view none bind,ro
Se ci sono punti di mount sotto /some/where
, il loro contenuto non è visibile sotto /else/where
. Invece di bind
, è possibile utilizzare rbind
, replicare anche i punti di montaggio sottostanti /some/where
. Ad esempio, se /some/where/mnt
è un mount point allora
mount --rbind /some/where /else/where
è equivalente a
mount --bind /some/where /else/where
mount --bind /some/where/mnt /else/where/mnt
Inoltre, Linux consente di dichiarare i mount come condivisi , slave , privati o non vincolanti . Ciò influisce sul fatto che tale operazione di montaggio si rifletta in un montaggio di bind che replica il punto di montaggio. Per maggiori dettagli, consultare la documentazione del kernel .
Linux fornisce anche un modo per spostare i mount: dove --bind
copia, --move
sposta un mount point.
È possibile avere diverse opzioni di montaggio in due directory montate su bind. C'è una stranezza, tuttavia: fare il mount del bind e impostare le opzioni di mount non può essere fatto atomicamente, devono essere due operazioni successive. (I kernel precedenti non lo consentivano.) Ad esempio, i seguenti comandi creano una vista di sola lettura, ma durante il quale /else/where
è presente una piccola finestra di lettura:
mount --bind /some/where /else/where
mount -o remount,ro,bind /else/where
Se il tuo sistema non supporta FUSE, un trucco classico per ottenere lo stesso effetto è eseguire un server NFS, farlo esportare i file che vuoi esporre (consentendo l'accesso localhost
) e montarli sullo stesso computer. Questo ha un notevole sovraccarico in termini di memoria e prestazioni, quindi i mount bind hanno un netto vantaggio ove disponibili (che è sulla maggior parte delle varianti Unix grazie a FUSE).
Può essere utile creare una vista di sola lettura di un filesystem, sia per motivi di sicurezza o semplicemente come un livello di sicurezza per garantire che non lo modifichi accidentalmente.
Con bindfs:
bindfs -r /some/where /mnt/readonly
Con Linux, in modo semplice:
mount --bind /some/where /mnt/readonly
mount -o remount,ro,bind /mnt/readonly
Questo lascia un breve intervallo di tempo durante il quale /mnt/readonly
viene letto / scrivi. Se questo è un problema di sicurezza, prima crea il mount bind in una directory a cui solo root può accedere, rendilo di sola lettura, quindi spostalo in un mount point pubblico. Nel frammento di seguito, nota che è importante che /root/private
(la directory sopra il punto di montaggio) sia privata; le autorizzazioni originali su /root/private/mnt
sono irrilevanti poiché sono nascoste dietro il punto di montaggio.
mkdir -p /root/private/mnt
chmod 700 /root/private
mount --bind /some/where /root/private/mnt
mount -o remount,ro,bind /root/private/mnt
mount --move /root/private/mnt /mnt/readonly
I filesystem registrano utenti e gruppi in base al loro ID numerico. A volte si finisce con più sistemi che assegnano ID utente diversi alla stessa persona. Questo non è un problema con l'accesso alla rete, ma rende gli ID utente privi di significato quando si trasportano dati da un sistema all'altro su un disco. Supponiamo di avere un disco creato con un filesystem multiutente (ad esempio ext4, btrfs, zfs, UFS, ...) su un sistema in cui Alice ha l'ID utente 1000 e Bob ha l'ID utente 1001 e si desidera rendere tale disco accessibile su un sistema in cui Alice ha l'ID utente 1001 e Bob ha l'ID utente 1000. Se si monta direttamente il disco, i file di Alice appariranno di proprietà di Bob (perché l'ID utente è 1001) e i file di Bob appariranno di proprietà di Alice (perché il l'ID utente è 1000).
È possibile utilizzare bindfs per rimappare gli ID utente. Innanzitutto montare la partizione del disco in una directory privata, dove solo root può accedervi. Quindi crea una vista bindfs in un'area pubblica, con ID utente e ID gruppo rimappando che scambiano gli ID utente e gli ID gruppo di Alice e Bob.
mkdir -p /root/private/alice_disk /media/alice_disk
chmod 700 /root/private
mount /dev/sdb1 /root/private/alice_disk
bindfs --map=1000/1001:1001/1000:@1000/1001:@1001/1000 /root/private/alice_disk /media/alice_disk
Vedi Come si può accedere ai file nella cartella principale dell'utente del sistema non avviato? e mount - bind altro utente come me stesso un altro esempio.
Una jail o un container chroot esegue un processo in una sottostruttura dell'albero delle directory del sistema. Questo può essere utile per eseguire un programma con accesso limitato, ad es. Eseguire un server di rete con accesso solo ai propri file e ai file che serve, ma non ad altri dati memorizzati sullo stesso computer). Una limitazione di chroot è che il programma è limitato a una sottostruttura: non può accedere a sottotitoli indipendenti. I supporti di collegamento consentono di innestare altri sottotetti su quell'albero principale. Questo li rende fondamentali per l'utilizzo più pratico dei container sotto Linux.
Ad esempio, supponiamo che una macchina esegua un servizio /usr/sbin/somethingd
che dovrebbe avere accesso solo ai dati in /var/lib/something
. L'albero di directory più piccolo che contiene entrambi questi file è il root. Come può essere limitato il servizio? Una possibilità è quella di creare collegamenti reali a tutti i file necessari al servizio (almeno /usr/sbin/somethingd
e a diverse librerie condivise) /var/lib/something
. Ma questo è ingombrante (i collegamenti fisici devono essere aggiornati ogni volta che viene aggiornato un file) e non funziona se /var/lib/something
e si /usr
trovano su file system diversi. Una soluzione migliore è quella di creare una radice ad hoc e popolarla usando i mount:
mkdir /run/something
cd /run/something
mkdir -p etc/something lib usr/lib usr/sbin var/lib/something
mount --bind /etc/something etc/something
mount --bind /lib lib
mount --bind /usr/lib usr/lib
mount --bind /usr/sbin usr/sbin
mount --bind /var/lib/something var/lib/something
mount -o remount,ro,bind etc/something
mount -o remount,ro,bind lib
mount -o remount,ro,bind usr/lib
mount -o remount,ro,bind usr/sbin
chroot . /usr/sbin/somethingd &
Gli spazi dei nomi di mount di Linux generalizzano chroot. I mount di bind sono il modo in cui gli spazi dei nomi possono essere popolati in modo flessibile. Vedere Come fare un processo per leggere un file diverso per lo stesso nome file per un esempio.
Un altro uso di chroot è installare una diversa distribuzione in una directory ed eseguire programmi da essa, anche quando richiedono file su percorsi hardcoded che non sono presenti o hanno contenuti diversi sul sistema di base. Questo può essere utile, ad esempio, per installare una distribuzione a 32 bit su un sistema a 64 bit che non supporta pacchetti misti, per installare versioni precedenti di una distribuzione o altre distribuzioni per testare la compatibilità, per installare una versione più recente per testare le ultime funzionalità mantenendo un sistema base stabile, ecc. Vedi Come posso eseguire programmi a 32 bit su Debian / Ubuntu a 64 bit? per un esempio su Debian / Ubuntu.
Supponi di avere un'installazione degli ultimi pacchetti della tua distribuzione nella directory /f/unstable
, dove esegui i programmi passando a quella directory con chroot /f/unstable
. Per rendere disponibili le home directory da queste installazioni, bind montale nel chroot:
mount --bind /home /f/unstable/home
Il programma schroot lo fa automaticamente.
Quando monti un filesystem su una directory, questo nasconde ciò che si trova dietro la directory. I file in quella directory diventano inaccessibili fino a quando la directory non viene smontata. Poiché i nullfs BSD e i montaggi di bind Linux operano a un livello inferiore rispetto all'infrastruttura di mount, un mount nullfs o un mount bind di un filesystem espone directory nascoste dietro i submount nell'originale.
Ad esempio, supponiamo di avere un filesystem tmpfs montato su /tmp
. Se al /tmp
momento della creazione del filesystem tmpfs erano presenti dei file, questi file potrebbero rimanere, effettivamente inaccessibili ma occupando spazio su disco. Correre
mount --bind / /mnt
(Linux) o
mount -t nullfs / /mnt
(FreeBSD) per creare una vista del filesystem di root su /mnt
. La directory /mnt/tmp
è quella del filesystem di root.
Alcuni server NFS (come il server NFS del kernel Linux prima di NFSv4) pubblicizzano sempre l'ubicazione effettiva della directory quando esportano una directory. Cioè, quando un client richiede server:/requested/location
, il server serve l'albero nella posizione /requested/location
. A volte è desiderabile consentire ai client di richiedere /request/location
ma effettivamente servire i file in /actual/location
. Se il tuo server NFS non supporta la pubblicazione di una posizione alternativa, puoi creare un mount bind per la richiesta prevista, ad es
/requested/location *.localdomain(rw,async)
in /etc/exports
e quanto segue in /etc/fstab
:
/actual/location /requested/location bind bind
A volte ti piacerebbe creare un link simbolico per far /some/where/is/my/file
apparire un file sotto /else/where
, ma l'applicazione che utilizza file
espande i link simbolici e li rifiuta /some/where/is/my/file
. Un bind mount può aggirare questo: bind-mount /some/where/is/my
a /else/where/is/my
, e quindi realpath
riferirà /else/where/is/my/file
di essere sotto /else/where
, non sotto /some/where
.
Se usi i bind mount, devi occuparti delle applicazioni che attraversano ricorsivamente l'albero del filesystem, come i backup e l'indicizzazione (ad esempio per creare un database di individuazione ).
Di solito, i montaggi di bind devono essere esclusi dagli attraversamenti ricorsivi di directory, in modo che ogni albero di directory venga attraversato una sola volta, nella posizione originale. Con bindfs e nullfs, configura lo strumento traversal per ignorare questi tipi di filesystem, se possibile. I montaggi di bind Linux non possono essere riconosciuti come tali: la nuova posizione è equivalente all'originale. Con i montaggi di bind Linux o con strumenti che possono escludere solo percorsi e non tipi di filesystem, è necessario escludere i punti di montaggio per i montaggi di bind.
Attraversamenti che si fermano ai confini del file system (ad esempio find -xdev
, rsync -x
, du -x
, ...) si fermerà automaticamente quando incontrano un bindfs o nullfs mount point, perché questo punto di montaggio è un file system diverso. Con i bind mount di Linux, la situazione è un po 'più complicata: esiste un limite del filesystem solo se il mount del bind sta innestando un filesystem diverso, non se sta innestando un'altra parte dello stesso filesystem.
I montaggi di bind forniscono una vista di un albero di directory in una posizione diversa. Espongono gli stessi file, possibilmente con opzioni di montaggio diverse e (con bindfs) proprietà e autorizzazioni diverse. I filesystem che presentano una vista alterata di un albero di directory sono chiamati filesystem sovrapposti o filesystem sovrapponibili . Esistono molti altri filesystem overlay che eseguono trasformazioni più avanzate. Eccone alcuni comuni. Se il caso d'uso desiderato non è coperto qui, controllare il repository dei filesystem FUSE .
bindfs -r
, solo un po 'più leggero.Montaggi unione : presentano più filesystem (chiamati rami ) in un'unica directory: se tree1
contiene foo
e tree2
contiene, la bar
loro vista unione contiene sia foo
e bar
. I nuovi file vengono scritti in un ramo specifico o in un ramo scelto in base a regole più complesse. Esistono diverse implementazioni di questo concetto, tra cui:
mount --bind /dir1 /dir1
? In che modo differisce dal caso in cui l'origine e l'obiettivo del montaggio sono diversi?
/proc/self/mountinfo
. Per quanto riguarda chroot, può essere utilizzato per l'isolamento, ma non da solo. Non hai bisogno di mount dei namespace: chroot è sufficiente per la parte dello spazio dei nomi del filesystem. È necessario assicurarsi che nessun processo nel chroot venga eseguito come lo stesso utente di un processo esterno al chroot.
Semplice, quando si utilizza bind mount, un file o una directory sul computer host viene montato in un contenitore in modo che qualsiasi modifica apportata all'interno della directory dei file sul computer host sia automaticamente disponibile all'interno del contenitore nella directory.