GNU/Linux >> Tutoriels Linux >  >> Linux

Répertorier uniquement les montages liés

Les montages liés ne sont pas un type de système de fichiers, ni un paramètre d'un système de fichiers monté ; ce sont des paramètres d'une opération de montage . 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

Ainsi, la seule façon de se rappeler quels montages étaient des montages liés est le journal de mount commandes laissées dans /etc/mtab . Une opération de montage lié est indiquée par le bind option de montage (ce qui fait que le type de système de fichiers est ignoré). Mais mount n'a pas la possibilité de lister uniquement les systèmes de fichiers montés avec un ensemble particulier d'ensembles d'options. Vous devez donc faire votre propre filtrage.

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

Notez que /etc/mtab n'est utile ici que s'il s'agit d'un fichier texte maintenu par mount . Certaines distributions configurent /etc/mtab sous forme de lien symbolique vers /proc/mounts Au lieu; /proc/mounts est principalement équivalent à /etc/mtab mais présente quelques différences, dont l'une n'est pas le suivi des montages liés.

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

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

En /proc/mounts , les entrées pour /mnt/one et /mnt/partial ont le même périphérique, le même type de système de fichiers et les mêmes options. Les informations que /mnt/partial affiche uniquement la partie du système de fichiers qui est enracinée à /sub est visible 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

Peut-être que ceci 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

Le noyau ne gère pas les montages liés différents de normal monte après coup. La seule différence dans ce qui se passe alors que mount s'exécute.

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 -t ou utilisez -t auto mount devine 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 majeur :mineur.
  3. Le système de fichiers est lié à un chemin (le point de montage). Le noyau utilise également certaines des options de montage ici. (nodev par exemple est une option sur le point de montage, pas sur le système de fichiers. Vous pouvez avoir un montage lié avec nodev et une sans)

Si vous effectuez un montage lié (par exemple avec mount --bind /a /b ) voici ce qui se passe :

  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 relatif.

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

Cela ressemble assez à 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 physique, voici ce qui se passe :

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

Comme vous pouvez le voir, le fichier créé et le lien physique 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 nombres majeur/mineur de montages.

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

Le script Python suivant répertorie tous les montages liés. 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))

Linux
  1. Une monture liée ?

  2. Monter un système de fichiers Cifs directement ou via Fstab ?

  3. Comment faire monter un système de fichiers lors de la connexion de l'utilisateur ?

  4. Lister tous les montages sous Linux

  5. Liaison en lecture seule ?

Comment lister uniquement les répertoires sous Linux

Lier les montages sous Linux

Comment monter et démonter un système de fichiers/partition sous Linux (exemples de commandes Mount/Umount)

Monter le fichier zip en tant que système de fichiers en lecture seule

Le montage d'un nouveau système de fichiers affecte les montages liés non récursifs ?

Débogage des problèmes de fstab au redémarrage