Determine em qual dispositivo um diretório está localizado

Determine em qual dispositivo um diretório está localizado

Se eu fizer

# cd /
# ln -s /home test
# cd test
# mount --bind $PWD /mnt

a entrada /proc/mountsé

/dev/sda2 /mnt ext4 rw,noatime,data=ordered 0 0

qual é o dispositivo que está montado /homee não é facilmente dedutível de $PWDqual é /test. Como posso determinar qual dispositivo (ou seja,/dev/sda2) aparecerá em /proc/mountsgeral, visto que a montagem de ligação pode ser para um diretório/arquivo que é potencialmente "obscurecido" por links simbólicos, outras montagens de ligação, etc.?

Responder1

Se entendi sua pergunta, você quer saber qual dispositivo foi usado para uma determinada montagem. Para isso você pode usar o dfcomando:

$ df -h 
Filesystem                         Size  Used Avail Use% Mounted on
/dev/mapper/fedora_greeneggs-root   50G   21G   27G  44% /
devtmpfs                           3.8G     0  3.8G   0% /dev
tmpfs                              3.8G   14M  3.8G   1% /dev/shm
tmpfs                              3.8G  984K  3.8G   1% /run
tmpfs                              3.8G     0  3.8G   0% /sys/fs/cgroup
tmpfs                              3.8G  3.4M  3.8G   1% /tmp
/dev/sda1                          477M   99M  349M  23% /boot
/dev/mapper/fedora_greeneggs-home  402G  184G  198G  49% /home

Para descobrir em qual dispositivo um arquivo/diretório específico foi encontrado, forneça o arquivo como argumento para df. Usando seu exemplo:

$ df -h /mnt
Filesystem                         Size  Used Avail Use% Mounted on
/dev/sda1                          477M   99M  349M  23% /

Você também pode usar o mountcomando:

$ mount | grep '^/dev'
/dev/mapper/fedora_greeneggs-root on / type ext4 (rw,relatime,seclabel,data=ordered)
/dev/sda1 on /boot type ext4 (rw,relatime,seclabel,data=ordered)
/dev/mapper/fedora_greeneggs-home on /home type ext4 (rw,relatime,seclabel,data=ordered)

O diretório montado para cada dispositivo é o terceiro argumento na saída acima. Então, para dispositivo /dev/sda1seria /boot. Os outros dispositivos estão fazendo uso de LVM (Logical Volume Management) e precisariam ser consultados posteriormente para saber qual dispositivo real está sendo usado pelo LVM.

Responder2

No Linux fizemos findmntexatamente util-linuxpara isso

findmnt -n -o SOURCE --target /path/to/FILE

A vantagem de outras soluções é que elas ainda funcionam se os caminhos estiverem obscurecidos por links simbólicos ou montagens de ligação duplicadas.

Responder3

O método mais preciso que conheço é usar a saída da chamada de sistema lstat(). Especificamente, o campo st_dev. Existe um utilitário de linha de comando, stat(1) que pode ser usado para ver essas informações. Por exemplo, a saída de "stat /etc/issue" no meu laptop:

File: ‘/etc/issue’
  Size: 65          Blocks: 8          IO Block: 4096   regular file
Device: 801h/2049d  Inode: 1610916043  Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)

Observe a terceira linha, primeiro campo, “Dispositivo”. Aqui lista 801h. Esse valor pode ser separado em dois bytes, 8 e 1. O primeiro byte é conhecido como número maior, o segundo byte é o número menor. Portanto, a próxima etapa é descobrir qual é o dispositivo maior 8, menor 1.

Acho que consultar /proc/partitions é o mais rápido. No meu caso, /proc/partitions tem o conteúdo:

major minor  #blocks  name

   8       16  234431064 sdb
   8       17   33554432 sdb1
   8       18  200875608 sdb2
   8        0  500107608 sda
   8        1  500106584 sda1

Fica bastante claro a partir dessa saída que o maior 8, o menor 1 é sda1. Podemos confirmar isso com um ls -l /dev/sda1

brw-rw---- 1 root disk 8, 1 May  8 05:33 /dev/sda1

Observe o 8, 1 antes do carimbo de data.

É importante entender/lembrar que o nome de um arquivo de dispositivo como /dev/sda1 é apenas um rótulo. Os números maiores e menores são os valores significativos e importantes do arquivo do dispositivo. Se você ficar curioso, confira o utilitário mknod(1) usado para criar arquivos de dispositivos. Eu poderia criar uma nova entrada /dev chamada aardvark com maior 8, menor 18 com a seguinte sintaxe:

mknod /dev/aardvark b 8 18

Então, eu poderia montá-lo facilmente:

mount /dev/aardvark /mnt

e, se olharmos a saída do comando mount ou o conteúdo de /proc/mounts e vemos:

/dev/aardvark on /mnt type xfs (rw,relatime,attr2,inode64,noquota)

df -h mostra:

/dev/aardvark   192G  154G   38G  81% /mnt

... De qualquer forma, o objetivo de tudo isso é ilustrar que os detalhes importantes para identificar um dispositivo de bloco são os números maiores e menores - não o rótulo do arquivo do dispositivo - e que usar a chamada de sistema lstat() é a melhor maneira de consulte esses valores.

Como último comentário, acabei de reler sua pergunta para ter certeza de que estava respondendo e percebi que você estava perguntando qual rótulo do dispositivo de origem apareceria em /proc/mounts para uma montagem de ligação. Esse seria o mesmo rótulo do dispositivo de origem usado na chamada mount(2) original para a origem do ponto de montagem do sistema de arquivos para a montagem de ligação. Talvez um exemplo ajude:

Eu tenho /dev/sdb2 e /dev/aardvark (o mesmo que acima). Ambos são maiores 8 e menores 18. Observe que montarei o mesmo sistema de arquivos duas vezes. Eu faço o seguinte:

mkdir /mnt1 /mnt2 /foo

mount /dev/aardvark /mnt1
mount /dev/sdb2 /mnt2

Observe que eu crio o diretório somedir em /mnt1. Mas como /mnt1 e /mnt2 têm o mesmo sistema de arquivos montado, somedir também poderá ser acessado por meio de /mnt2.

mkdir /mnt1/somedir

mkdir /foo/left /foo/right

mount -o bind /mnt1/somedir /foo/left
mount -o bind /mnt2/somedir /foo/right

Agora, se verificarmos /proc/mounts, veremos:

/dev/aardvark /mnt1 xfs rw,relatime,attr2,inode64,noquota 0 0
/dev/sdb2 /mnt2 xfs rw,relatime,attr2,inode64,noquota 0 0
/dev/aardvark /foo/left xfs rw,relatime,attr2,inode64,noquota 0 0
/dev/sdb2 /foo/right xfs rw,relatime,attr2,inode64,noquota 0 0

O rótulo do dispositivo de origem nas montagens de ligação /foo/... é o mesmo que o valor fornecido originalmente na chamada mount(2) do sistema de arquivos. Lembre-se, /dev/aardvark e /dev/sdb2 no meu exemplo são o mesmo dispositivo.

Sei que acabei de digitar um romance e a primeira metade não responde à sua pergunta, mas pareceu um desperdício excluí-lo. Talvez ajude outra pessoa.

Boa sorte.

PS Tenha em mente que alguns sistemas de arquivos são baseados em rede - como NFS ou CIFS - ou são virtuais - como procfs ou sysfs e não possuem um dispositivo de bloco de origem. Não sei o que será retornado como dispositivo na saída estatística, apenas pelo que vale.

Responder4

O ducomando pode ser chamado com uma -xopção para ignorar o conteúdo de outros sistemas de arquivos montados.

O -kswitch exibe tamanhos de diretório em KB.

Para exibir diretórios com tamanho >~ 1 MB.

du -xk / | awk ' $1 > 1000000 { print } '

informação relacionada