Liste uniquement les montures de liaison

24

Plutôt que d'utiliser mount | grep, j'aimerais utiliser mount -l -t bind, mais cela ne fonctionne pas et -t nonemontre toutes les montures.

l0b0
la source

Réponses:

28

Les montages de liaison ne sont pas un type de système de fichiers, ni un paramètre d'un système de fichiers monté; ce sont les paramètres d'une opération de montage . Pour autant que je sache, les séquences de commandes suivantes conduisent à des états système essentiellement identiques en ce qui concerne le noyau:

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

Donc, la seule façon de se souvenir des montures qui étaient des montures de liaison est le journal des mountcommandes restantes /etc/mtab. Une opération de montage de liaison est indiquée par l' option debind montage (ce qui entraîne l'ignorance du type de système de fichiers). Mais n'a pas la possibilité de répertorier uniquement les systèmes de fichiers montés avec un ensemble particulier d'ensembles d'options. Par conséquent, vous devez effectuer votre propre filtrage.mount

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

Notez que cela /etc/mtabn'est utile ici que s'il s'agit d'un fichier texte géré par mount. Certaines distributions configurées à la place /etc/mtabcomme un lien symbolique /proc/mounts; /proc/mountsest principalement équivalent à, /etc/mtabmais présente quelques différences, dont l'une ne suit pas les montages de liaison.

Une information qui est conservée par le noyau, mais non représentée dans /proc/mounts, est lorsqu'un point de montage n'affiche qu'une partie de l'arborescence de répertoires sur le système de fichiers monté. En pratique, cela se produit principalement avec les montures de liaison:

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

Dans /proc/mounts, les entrées pour /mnt/oneet /mnt/partialont le même périphérique, le même type de système de fichiers et les mêmes options. Les informations qui /mnt/partialne montrent que la partie du système de fichiers enracinée /subsont visibles dans les informations de point de montage par processus dans /proc/$pid/mountinfo(colonne 4). Les entrées ressemblent à ceci:

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
Gilles 'SO- arrête d'être méchant'
la source
1
@Gilles En fait, vous pouvez le faire simplement en utilisant findmnt | fgrep [comme expliqué ici .
aculich
@Gilles Dans quoi mount --versionutilisez-vous pour enregistrer des bindinformations /etc/mtab? J'utilise la version 2.20.1 et j'ai regardé les dernières sources et dans aucun cas je ne vois des informations de liaison enregistrées n'importe où qui vous permettraient de rechercher bind. D'un autre côté, ce que j'ai suggéré dans ma réponse consiste en fait à lister les montages créés avec --bindet en utilisant l' bind option .
aculich
@aculich </etc/mtab awk …est compatible POSIX (j'oublie s'il est pris en charge dans Bourne). Veuillez vérifier vos faits. Je peux confirmer qu'il /etc/mtaba l' bindoption pour un système de fichiers monté avec mount --bind /source /targetsur Debian stable (montage depuis util-linux-ng 2.17.2).
Gilles 'SO- arrête d'être méchant'
@ Gilles J'ai supprimé mon commentaire errant pour éliminer toute confusion. Vous avez raison, il est en effet conforme à POSIX. De plus, je comprends maintenant la raison pour laquelle nous constatons un comportement différent de mountet /etc/mtab. Vous utilisez Debian stable qui a l'ancienne version d'util-linux-ng; J'utilise Debian testing qui a une version plus récente qui ne semble plus avoir le même /etc/mtabcomportement, ce qui est peut - être pourquoi @rozcietrzewiacz n'a pas vu binddans dans /etc/mtabsi sa distribution utilise également une version plus récente?
aculich
1
@aculich Vous devez poster findmntcomme réponse. Cela ne fonctionne que si le répertoire cible n'est pas un autre point de montage, soit dit en passant. Essayez par exemplesudo mount --bind / foo && findmnt | grep foo
l0b0
21

Peut-être que cela pourrait faire l'affaire:

findmnt | grep  "\["

Exemple:

$ mkdir /tmp/foo
$ sudo mount --bind /media/ /tmp/foo
$ findmnt | grep  "\["
│ └─/tmp/foo                     /dev/sda2[/media] ext4            rw,relatime,data=ordered
olopopo
la source
1
Apparemment, cela ne fonctionne que lorsqu'un sous-répertoire d'un point de montage est monté en liaison. Si /lui-même est monté en bind, par exemple, la sortie n'a pas de [...].
muru
8

Le noyau ne gère pas les montages de liaison différents des montages normaux après coup. Les seuls diffèrent dans ce qui se passe pendant les mountcourses.

Lorsque vous montez un système de fichiers (par exemple avec mount -t ext4 /dev/sda1 /mnt), le noyau (un peu simplifié) effectue trois étapes:

  1. Le noyau recherche un pilote de système de fichiers pour le type de système de fichiers spécifié (si vous omettez -tou utilisez -t auto mountdevine le type pour vous et fournit le type deviné au noyau)
  2. Le noyau demande au pilote du système de fichiers d'accéder au système de fichiers en utilisant le chemin source et toutes les options fournies. À ce stade, le système de fichiers n'est identifié que par une paire de nombres majeurs: mineurs.
  3. Le système de fichiers est lié à un chemin (le point de montage). Le noyau utilise également certaines des options de montage ici. ( nodevpar exemple, est une option sur le point de montage, pas sur le système de fichiers. Vous pouvez avoir un montage de liaison avec nodevet un sans)

Si vous effectuez un montage de liaison (par exemple avec mount --bind /a /b), les événements suivants se produisent:

  1. Le noyau détermine quel système de fichiers contient le chemin source et le chemin relatif du point de montage au répertoire.
  2. Le système de fichiers est lié au nouveau point de montage à l'aide des options et du chemin d'accès relatif.

(Je vais sauter mount --move, car ce n'est pas pertinent pour la question.)

Cela ressemble beaucoup à la façon dont les fichiers sont créés sous Linux:

  1. Le noyau détermine quel système de fichiers est responsable du répertoire dans lequel le fichier doit être créé.
  2. Un nouveau fichier dans le système de fichiers est créé. À ce stade, le fichier n'a qu'un numéro d'inode.
  3. Le nouveau fichier est lié à un nom de fichier dans le répertoire.

Si vous créez un lien dur, les événements suivants se produisent:

  1. Le noyau résout le numéro d'inode du fichier source.
  2. Le fichier est lié au nom de fichier de destination.

Comme vous pouvez le voir, le fichier créé et le lien dur sont indiscernables:

$ 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

Mais , comme vous pouvez identifier tous les liens physiques vers un fichier en comparant les numéros d'inode, vous pouvez identifier tous les montages sur un système de fichiers en comparant les principaux: les nombres mineurs de montages.

Vous pouvez le faire avec findmnt -o TARGET,MAJ:MINou en consultant directement /proc/self/mountinfo( voir la documentation du noyau Linux pour plus d'informations ).

Le script Python suivant répertorie tous les montages de liaison. Il suppose que le point de montage le plus ancien avec le chemin relatif le plus court vers la racine du système de fichiers monté est le montage d'origine.

#!/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))
cg909
la source
0
unset DONE1FSES
FSES=$(findmnt -vUPno SOURCE,FSROOT,TARGET,MAJ:MIN)
FSES=${FSES//MAJ:MIN/MAJ_MIN}
while read SEARCH1FS
do
  unset DONE2FSES
  eval "$SEARCH1FS"
  SEARCH1SOURCE=$SOURCE
  SEARCH1FSROOT=$FSROOT
  SEARCH1TARGET=$TARGET
  SEARCH1MAJMIN=$MAJ_MIN

  FS1WASHANDLED=0
  while read DONE1FS 
  do
    if [[ $DONE1FS == $MAJ_MIN ]]
    then
      FS1WASHANDLED=1
      break
    fi
  done < <(echo "$DONE1FSES")


  if [[ ($SEARCH1FSROOT == /) && ($FS1WASHANDLED == 0) ]]
  then
  DONE1FSES+=$MAJ_MIN$'\n'
  while read SEARCH2FS
  do
    eval "$SEARCH2FS"
    SEARCH2SOURCE=$SOURCE
    SEARCH2FSROOT=$FSROOT
    SEARCH2TARGET=$TARGET
    SEARCH2MAJMIN=$MAJ_MIN

    FS2WASHANDLED=0
    while read DONE2FS 
    do
      if [[ $DONE2FS == $SEARCH2FS ]]
      then
        FS2WASHANDLED=1
        break
      fi
    done < <(echo "$DONE2FSES")

    if [[ ($SEARCH1MAJMIN == $SEARCH2MAJMIN)  && ($SEARCH1TARGET != $SEARCH2TARGET )  && ($FS2WASHANDLED == 0 ) ]]
    then
      DONE2FSES+=$SEARCH2FS$'\n'
      echo "$SEARCH1TARGET$SEARCH2FSROOT   --> $SEARCH2TARGET"
    fi

  done < <(echo "$FSES")


  fi
done   < <(echo "$FSES")
n3rdopolis
la source
0

Ceci est similaire à l'autre réponse findmnt, mais évite le problème de formatage.

Pour afficher tous les sous-montages:

findmnt --kernel -n --list | grep '\['

Pour afficher tous les sous-systèmes de fichiers de type ext4:

findmnt --kernel -t ext4 -n --list | grep '\['

Pour afficher tous les montages à l'exception des sous-montages:

findmnt --kernel -n --list | grep -v '\['

Pour afficher tous les montages de systèmes de fichiers de type ext4 hors sous-montages:

findmnt --kernel -t ext4 -n --list | grep -v '\['

Le "-n" supprime les en-têtes et le "--list" supprime les lignes du format "arborescence".

Testé sur l'étirement Debian.

sg23
la source