GNU/Linux >> Linux Esercitazione >  >> Linux

Elenca solo i supporti bind

I bind mount non sono un tipo di filesystem, né un parametro di un filesystem montato; sono i parametri di un'operazione di montaggio . Per quanto ne so, le seguenti sequenze di comandi portano a stati di sistema essenzialmente identici per quanto riguarda il kernel:

mount /dev/foo /mnt/one; mount --bind /mnt/one /mnt/two
mount /dev/foo /mnt/two; mount --bind /mnt/two /mnt/one

Quindi l'unico modo per ricordare quali mount erano bind mount è il log di mount comandi lasciati in /etc/mtab . Un'operazione di bind mount è indicata da bind mount opzione (che fa sì che il tipo di filesystem venga ignorato). Ma mount non ha alcuna opzione per elencare solo i filesystem montati con un particolare set di set di opzioni. Pertanto è necessario eseguire il proprio filtraggio.

mount | grep -E '[,(]bind[,)]'
</etc/mtab awk '$4 ~ /(^|,)bind(,|$)/'

Nota che /etc/mtab è utile qui solo se è un file di testo gestito da mount . Alcune distribuzioni impostano /etc/mtab come collegamento simbolico a /proc/mounts invece; /proc/mounts è per lo più equivalente a /etc/mtab ma presenta alcune differenze, una delle quali non è il monitoraggio dei montaggi dei bind.

Una parte di informazione conservata dal kernel, ma non mostrata in /proc/mounts , è quando un punto di montaggio mostra solo una parte dell'albero delle directory sul filesystem montato. In pratica questo accade principalmente con i bind mount:

mount --bind /mnt/one/sub /mnt/partial

In /proc/mounts , le voci per /mnt/one e /mnt/partial avere lo stesso dispositivo, lo stesso tipo di filesystem e le stesse opzioni. Le informazioni che /mnt/partial mostra solo la parte del filesystem che è radicata in /sub è visibile nelle informazioni del punto di montaggio per processo in /proc/$pid/mountinfo (colonna 4). Le voci hanno questo aspetto:

12 34 56:78 / /mnt/one rw,relatime - ext3 /dev/foo rw,errors=remount-ro,data=ordered
12 34 56:78 /sub /mnt/partial rw,relatime - ext3 /dev/foo rw,errors=remount-ro,data=ordered

Forse questo potrebbe fare al caso tuo:

findmnt | grep  "\["

Esempio:

$ mkdir /tmp/foo
$ sudo mount --bind /media/ /tmp/foo
$ findmnt | grep  "\["
│ └─/tmp/foo                     /dev/sda2[/media] ext4            rw,relatime,data=ordered

Il kernel non gestisce bind mount diversi dal normale monta dopo il fatto. L'unica differenza riguarda ciò che accade mentre mount corre.

Quando monti un filesystem (ad es. con mount -t ext4 /dev/sda1 /mnt ) il kernel (un po' semplificato) esegue tre passaggi:

  1. Il kernel cerca un driver di filesystem per il tipo di filesystem specificato (se si omette -t o usa -t auto mount indovina il tipo per te e fornisce il tipo indovinato al kernel)
  2. Il kernel istruisce il driver del filesystem per accedere al filesystem usando il percorso di origine e qualsiasi opzione fornita. A questo punto il filesystem è identificato solo da una coppia di numeri maggiore:minore.
  3. Il filesystem è associato a un percorso (il punto di montaggio). Il kernel utilizza anche alcune delle opzioni di montaggio qui. (nodev per esempio è un'opzione sul punto di montaggio, non sul filesystem. Puoi avere un bind mount con nodev e uno senza)

Se esegui un bind mount (es. con mount --bind /a /b ) accade quanto segue:

  1. Il kernel risolve quale filesystem contiene il percorso di origine e il percorso relativo dal punto di montaggio alla directory.
  2. Il filesystem è legato al nuovo punto di montaggio utilizzando le opzioni e il relativo percorso.

(Salto mount --move , perché non è rilevante per la domanda.)

Questo è abbastanza simile al modo in cui i file vengono creati su Linux:

  1. Il kernel risolve quale filesystem è responsabile della directory in cui deve essere creato il file.
  2. Viene creato un nuovo file nel filesystem. A questo punto il file ha solo un numero di inode.
  3. Il nuovo file è collegato a un nome file nella directory.

Se crei un hard link accade quanto segue:

  1. Il kernel risolve il numero di inode del file sorgente.
  2. Il file è collegato al nome del file di destinazione.

Come puoi vedere, il file creato e l'hard link sono indistinguibili:

$ touch first
$ ln first second
$ ls -li
1184243 -rw-rw-r-- 2 cg909 cg909 0 Feb 20 23:56 /tmp/first
1184243 -rw-rw-r-- 2 cg909 cg909 0 Feb 20 23:56 /tmp/second

Ma , poiché puoi identificare tutti i collegamenti fisici a un file confrontando i numeri di inode, puoi identificare tutti i montaggi su un filesystem confrontando i numeri major:minor dei montaggi.

Puoi farlo con findmnt -o TARGET,MAJ:MIN o guardando direttamente /proc/self/mountinfo (vedi la documentazione del kernel Linux per maggiori informazioni).

Il seguente script Python elenca tutti i bind mount. Presuppone che il punto di montaggio più vecchio con il percorso relativo più breve alla radice del file system montato sia il punto di montaggio originale.

#!/usr/bin/python3

import os.path, re
from collections import namedtuple

MountInfo = namedtuple('MountInfo', ['mountid', 'parentid', 'devid', 'root', 'mountpoint', 'mountoptions', 'extra', 'fstype', 'source', 'fsoptions'])

mounts = {}

def unescape(string):
    return re.sub(r'\\([0-7]{3})', (lambda m: chr(int(m.group(1), 8))), string)

with open('/proc/self/mountinfo', 'r') as f:
    for line in f:
        # Parse line
        mid, pid, devid, root, mp, mopt, *tail = line.rstrip().split(' ')
        extra = []
        for item in tail:
            if item != '-':
                extra.append(item)
            else:
                break
        fstype, src, fsopt = tail[len(extra)+1:]
        # Save mount info
        mount = MountInfo(int(mid), int(pid), devid, unescape(root), unescape(mp), mopt, extra, fstype, unescape(src), fsopt)
        mounts.setdefault(devid, []).append(mount)

for devid, mnts in mounts.items():
    # Skip single mounts
    if len(mnts) <= 1:
        continue
    # Sort list to get the first mount of the device's root dir (if still mounted)
    mnts.sort(key=lambda x: x.root)
    src, *binds = mnts
    # Print bind mounts
    for bindmount in binds:
        if src.root == bindmount.root:
            srcstring = src.mountpoint
        else:
            srcstring = src.mountpoint+':/'+os.path.relpath(bindmount.root, src.root)
        print('{0} -> {1.mountpoint} ({1.mountoptions})'.format(srcstring, bindmount))

Linux
  1. Come montare un filesystem, mappare gli ID utente?

  2. Montare un filesystem Cifs direttamente o tramite Fstab?

  3. Solo Root può montare, perché?

  4. Come montare e smontare filesystem/partizione in Linux (esempi di comando di montaggio/smontaggio)

  5. Elenca tutti i montaggi in Linux

Come elencare solo le directory in Linux

Sola lettura bind-mount?

Come consentire ai non superutenti di montare qualsiasi filesystem?

Perché mount non rispetta l'opzione di sola lettura per i bind mount?

Monta il file zip come filesystem di sola lettura

Debug dei problemi di fstab al riavvio