Qual comando eu uso para ver o bloco inicial e final de um arquivo no sistema de arquivos?

10

Existe algum comando que produzirá os blocos inicial e final de qualquer arquivo?

preciso
fonte
1
qual tipo de sistema de arquivos: ext2,3,4; btrfs; xfs; zfs, etc ...?
BeowulfNode42
@ BeowulfNode42: ext4, ntfs, fat32 são os com os quais eu lido frequentemente ... então, de preferência para esses três ...
precisa
A pergunta deve ser melhorada (seja mais preciso): minha primeira resposta teria sido um programa que abre o arquivo, lê o primeiro bloco, depois procura o último bloco e lê também. Então, o que é "saída" de um bloco? O conteúdo do bloco, o endereço lógico do bloco (dentro do arquivo, dentro do sistema de arquivos, dentro da partição ou dentro do dispositivo do bloco) ou o endereço físico do bloco (fica interessante se o disco fizer parte de algum RAID ou LVM). As respostas parecem muito melhores que a pergunta.
U. Windl

Respostas:

16

hdparm

Não tenho 100% de certeza de que é isso que você está procurando, mas acredito que você pode fazer isso usando o comando hdparm, especificamente com sua --fibmapopção.

excerto

   --fibmap
          When  used,  this  must  be the only option given.  It requires a 
          file path as a parameter, and will print out a list of the block 
          extents (sector ranges) occupied by that file on disk.  Sector 
          numbers are  given as absolute LBA numbers, referenced from sector 
          0 of the physical device rather than from the partition or 
          filesystem.  This information can then be used for a variety of 
          purposes,  such  as examining the degree of fragmenation of larger 
          files, or determining appropriate sectors to deliberately corrupt 
          during fault-injection testing procedures.

          This option uses the new FIEMAP (file extent map) ioctl() when 
          available,  and  falls  back  to  the older  FIBMAP (file block 
          map) ioctl() otherwise.  Note that FIBMAP suffers from a 32-bit 
          block-number interface, and thus not work beyond 8TB or 16TB.  
          FIBMAP is also very slow, and  does  not  deal well  with  
          preallocated uncommitted extents in ext4/xfs filesystems, unless a 
          sync() is done before using this option.

Exemplo

Digamos que temos um arquivo de amostra.

$ echo "this is a test file" > afile

Agora quando corremos hdparm.

$ sudo hdparm --fibmap afile 

afile:
 filesystem blocksize 4096, begins at LBA 0; assuming 512 byte sectors.
 byte_offset  begin_LBA    end_LBA    sectors
           0  282439184  282439191          8

filefrag

Outro método interessante para descobrir os blocos inicial e final de um arquivo é filefrag. Você precisará usar as opções apropriadas para obter a saída desejada. Uma vantagem dessa ferramenta hdparmé que qualquer usuário pode executá-la, portanto não sudoé necessário. Você precisará usar o -b512comutador para que as saídas sejam exibidas em blocos de 512 bytes. Também precisamos dizer filefragpara ser detalhado.

Exemplo

$ filefrag -b512 -v afile
Filesystem type is: ef53
File size of afile is 20 (8 block of 512 bytes)
 ext:     logical_offset:        physical_offset: length:   expected: flags:
   0:        0..       7:  282439184.. 282439191:      8:             eof
afile: 1 extent found

debugfs

Um terceiro método para obter os LBAs de um arquivo é fazer uso debugfs. Esse método exigirá um pouco de matemática, mas achei importante mostrar como se pode converter do valor de extensões relatado pelos debugfsLBAs para aqueles que possam estar curiosos.

Então, vamos começar com o inode do arquivo.

$ ls -i afile
6560281 afile

NOTA: Também podemos usar o nome do arquivo, debugfsmas, para esta demonstração, utilizarei o inode.

Agora vamos obter as statinformações debugfssobre o nosso inode.

$ sudo debugfs -R "stat <6560281>" /dev/mapper/fedora_greeneggs-home
debugfs 1.42.7 (21-Jan-2013)
Inode: 6560281   Type: regular    Mode:  0664   Flags: 0x80000
Generation: 1999478298    Version: 0x00000000:00000001
User:  1000   Group:  1000   Size: 20
File ACL: 0    Directory ACL: 0
Links: 1   Blockcount: 8
Fragment:  Address: 0    Number: 0    Size: 0
 ctime: 0x52be10c3:a640e994 -- Fri Dec 27 18:44:03 2013
 atime: 0x52bff8a1:a9f08020 -- Sun Dec 29 05:25:37 2013
 mtime: 0x52be0fe7:18a2f344 -- Fri Dec 27 18:40:23 2013
crtime: 0x52be0dd8:64394b00 -- Fri Dec 27 18:31:36 2013
Size of extra inode fields: 28
Extended attributes stored in inode body: 
  selinux = "unconfined_u:object_r:user_home_t:s0\000" (37)
EXTENTS:
(0):35304898

As informações importantes estão na seção de extensões. Na verdade, esses são os blocos do sistema de arquivos que estão sendo usados ​​por este inode. Nós apenas precisamos convertê-los para o LBA. Podemos fazer isso através da seguinte equação.

NOTA: Supondo que o nosso sistema de arquivos use tamanhos de bloco de 4k e que o hardware subjacente use unidades de 512 bytes, precisamos multiplicar as existentes por 8.

beginning LBA = (BEGIN EXTENT) * 8
ending LBA    = (((ENDING EXTENT) + 1) * 8) - 1

Exemplo

Portanto, em nosso exemplo, nossa extensão inicial e final é a mesma, pois nosso arquivo se encaixa em uma única extensão.

beginning LBA = 35304898 * 8             = 282439184
ending LBA    = ((35304898 + 1) * 8) - 1 = 282439191

Portanto, nossos LBAs são 282439184..282439191.

Referências

slm
fonte
estes são alguns links ... obrigado pela resposta e links ...
precisa
2
@hash - eles são os restos de mim tentando encontrar dois outros métodos para determinar os LBAs. 8-). Estou escrevendo agora como meu próprio Q no site.
slm
@hash - eu adicionei outra técnica usando filefrag.
slm
@hash - eu adicionei outra técnica usando debugfs.
slm
Eu tentei filefragcom os tamanhos de bloco disponíveis de 1024 e 2048 .. debugfscom extensões de arquivo maiores : 0 - 12187 .. vou levar um tempo e entender .. isso é uma grande ajuda, obrigado ...
precisa
4

Número do setor relativo ao dispositivo de bloco que contém o FS (não o disco inteiro)

(Observe que hdparm --fibmapé relativo ao disco inteiro, não à partição ou a qualquer outro bloco que detém o FS. Também requer raiz.)

filefrag -efunciona bem e usa o ioctl genérico e eficienteFIEMAP , por isso deve funcionar em praticamente qualquer sistema de arquivos (incluindo o BTRFS geralmente estranho, mesmo para arquivos compactados por BTRFS). Ele retornará ao FIBMAP para sistemas de arquivos / kernels sem suporte ao FIEMAP.

$ filefrag xpsp3.vdi          # some old sparse disk image I had lying around
xpsp3.vdi: 110 extents found
$ filefrag -e xpsp3.vdi
Filesystem type is: 58465342
File size of xpsp3.vdi is 5368730112 (1310726 blocks of 4096 bytes)
 ext:     logical_offset:        physical_offset: length:   expected: flags:
   0:        0..       5: 1322629241..1322629246:      6:            
   1:       13..      13: 1322620799..1322620799:      1: 1322629247:
   2:       15..      47: 1323459271..1323459303:     33: 1322620800:
...
 160:   899498..  915839: 1325792977..1325809318:  16342: 1325725438:
 161:  1307294.. 1307391: 1323938199..1323938296:     98: 1325809319: last
xpsp3.vdi: 110 extents found

Somente XFS

Se você estiver usando xfs, terá uma xfs_bmapsaída melhor: mostra onde existem buracos, enquanto filefragapenas a próxima extensão começa em um setor posterior. Ele usa blocos de 512B, não importa o tamanho real do sistema de arquivos. (normalmente 4k no Linux). Ele mostra em qual grupo de alocação cada extensão está e como está alinhado nos limites da faixa RAID.

$ xfs_bmap -vvpl xpsp3.vdi   # the extra -v prints a key to the flags
xpsp3.vdi:
 EXT: FILE-OFFSET           BLOCK-RANGE              AG AG-OFFSET              TOTAL FLAGS
   0: [0..47]:              10581033928..10581033975 13 (83912..83959)            48 01111
   1: [48..103]:            hole                                                  56
   2: [104..111]:           10580966392..10580966399 13 (16376..16383)             8 01010
   3: [112..119]:           hole                                                   8
 ...
 322: [10458352..10459135]: 10591505592..10591506375 13 (10555576..10556359)     784 01111
 323: [10459136..10485807]: hole                                               26672
FLAG Values:   # this part is only here with -vv
    010000 Unwritten preallocated extent
    001000 Doesn't begin on stripe unit
    000100 Doesn't end   on stripe unit
    000010 Doesn't begin on stripe width
    000001 Doesn't end   on stripe width

-lé redundante quando -vusado, mas por algum motivo eu sempre digito -vpl. -plé uma saída mais compacta.


Ambos filefrage xfs_bmapmostram extensões pré-alocadas.

$ fallocate --length $((1024*1024*8)) prealloced_file
$ filefrag -e prealloced_file
Filesystem type is: 58465342
File size of prealloced_file is 8388608 (2048 blocks of 4096 bytes)
 ext:     logical_offset:        physical_offset: length:   expected: flags:
   0:        0..    2047: 1325371648..1325373695:   2048:             last,unwritten,eof
prealloced_file: 1 extent found
$ xfs_bmap -vvpl prealloced_file 
prealloced_file:
 EXT: FILE-OFFSET      BLOCK-RANGE              AG AG-OFFSET            TOTAL FLAGS
   0: [0..16383]:      10602973184..10602989567 13 (22023168..22039551) 16384 10010
 FLAG Values:
    010000 Unwritten preallocated extent
    001000 Doesn't begin on stripe unit
    000100 Doesn't end   on stripe unit
    000010 Doesn't begin on stripe width
    000001 Doesn't end   on stripe width
$ dd if=/dev/zero of=prealloced_file conv=notrunc bs=4k count=10 seek=10000
40960 bytes (41 kB) copied, 0.000335111 s, 122 MB/s
$ xfs_bmap -vpl prealloced_file                                           
prealloced_file:
 EXT: FILE-OFFSET      BLOCK-RANGE              AG AG-OFFSET            TOTAL FLAGS
   0: [0..16383]:      10602973184..10602989567 13 (22023168..22039551) 16384 10010
   1: [16384..79999]:  hole                                             63616
   2: [80000..80895]:  10603013120..10603014015 13 (22063104..22063999)   896 00111
 # oops, wrote past EOF and extended the file, instead of in the middle of the preallocated extent
$ dd if=/dev/zero of=prealloced_file conv=notrunc bs=4k count=10 seek=100
40960 bytes (41 kB) copied, 0.000212986 s, 192 MB/s
$ xfs_bmap -vpl prealloced_file 
prealloced_file:
 EXT: FILE-OFFSET      BLOCK-RANGE              AG AG-OFFSET            TOTAL FLAGS
   0: [0..16383]:      10602973184..10602989567 13 (22023168..22039551) 16384 10010
   1: [16384..79999]:  hole                                             63616
   2: [80000..80895]:  10603013120..10603014015 13 (22063104..22063999)   896 00111
# If you check *right away*, XFS's delayed allocation hasn't happened yet.
# FIEMAP on xfs only reflects allocations, which lag behind completed writes.  fsync first if you need it, IIRC.
$ xfs_bmap -vpl prealloced_file 
prealloced_file:
 EXT: FILE-OFFSET      BLOCK-RANGE              AG AG-OFFSET            TOTAL FLAGS
   0: [0..799]:        10602973184..10602973983 13 (22023168..22023967)   800 10111
   1: [800..879]:      10602973984..10602974063 13 (22023968..22024047)    80 01111
   2: [880..16383]:    10602974064..10602989567 13 (22024048..22039551) 15504 11010
   3: [16384..79999]:  hole                                             63616
   4: [80000..80895]:  10603013120..10603014015 13 (22063104..22063999)   896 00111
$ filefrag -e prealloced_file 
Filesystem type is: 58465342
File size of prealloced_file is 41000960 (10010 blocks of 4096 bytes)
 ext:     logical_offset:        physical_offset: length:   expected: flags:
   0:        0..      99: 1325371648..1325371747:    100:             unwritten
   1:      100..     109: 1325371748..1325371757:     10:            
   2:      110..    2047: 1325371758..1325373695:   1938:             unwritten
   3:    10000..   10111: 1325376640..1325376751:    112: 1325373696: last,eof
prealloced_file: 2 extents found

hdparm --fibmapsó é útil se você quiser um número de setor relativo a todo o disco rígido , não dentro da partição em que o sistema de arquivos está. Ele não funciona sobre o RAID de software (ou provavelmente qualquer outra coisa entre o sistema de arquivos e o disco rígido). Também requer raiz. Apesar do nome da opção, ele realmente usa FIEMAPquando disponível (o novo mapa de extensão ioctl, não o antigo mapa de bloco lento ioctl).

# hdparm --fibmap ..../xpsp3.vdi
Unable to determine start offset LBA for device, aborting.
Peter Cordes
fonte
0

Portanto, para um determinado arquivo, você deseja saber quais números de bloco de disco contêm o início e o final desse arquivo.

debugfs (8) parece promissor para FSes ext2 / 3/4

stat (1), ls -i, lsof (8) fornece o número do inode, mas não muito mais sobre blocos de disco.

head / tail --bytes = 1024 é útil para o conteúdo do arquivo, mas não para os blocos de disco.

dd (1) será o que você deseja inspecionar o conteúdo do bloco - esteja alerta para a diferença entre os parâmetros seek = e skip = e evite = / dev / ... a menos que você realmente queira que o arquivo de saída seja um dispositivo .

D McKeon
fonte
não, não foi isso que eu quis dizer ... é com os números de bloco do disco que estou preocupado.
precisa
0

hdparm --fibmaplistará os blocos que um arquivo ocupa. Observe que eles podem não ser contíguos; portanto, "início e fim" não faz sentido.

psusi
fonte
Eu acho que a mudança a que você está se referindo é --fibmap. Além disso, você precisa especificar um nome de arquivo com ele. Exemplo: hdparm --fibmap afile.
slm
@ slm, oops, sim, erro de digitação ... e achei óbvio que você tinha que nomear o arquivo em questão.
Psd #
Não foi para mim até que eu tentei executá-lo. Até hoje, minha experiência anterior hdparmera em todo o nível da unidade, nunca a usei para arquivos antes.
slm