¿Por qué mi partición de 100 MiB exactamente en un tamaño de bloque de 1 KiB no tiene los bloques / espacio disponibles correspondientes?


33

Tengo un entorno virtualizado de muy alta densidad con contenedores, así que estoy tratando de hacer que cada contenedor sea realmente pequeño. "Realmente pequeño" significa 87 MB en Ubuntu 14.04 base (Trusty Tahr) sin romper la compatibilidad del administrador de paquetes.

Así que uso LVM como almacenamiento de respaldo para mis contenedores y recientemente encontré números muy extraños. Aquí están.

Creemos un volumen lógico de 100 MiB (sí, potencia de 2).

sudo lvcreate -L100M -n test1 /dev/purgatory

Me gustaría comprobar el tamaño, así que emito sudo lvs --units k

test1             purgatory  -wi-a----  102400.00k

Dulce, esto es realmente 100 MiB.

Ahora hagamos un sistema de archivos ext4 . Y, por supuesto, recordamos el -m 0parámetro, que evita el desperdicio de espacio.

sudo mkfs.ext4 -m 0 /dev/purgatory/test1

mke2fs 1.42.9 (4-Feb-2014)
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
Stride=0 blocks, Stripe width=0 blocks
25688 inodes, 102400 blocks
0 blocks (0.00%) reserved for the super user
First data block=1
Maximum filesystem blocks=67371008
13 block groups
8192 blocks per group, 8192 fragments per group
1976 inodes per group
Superblock backups stored on blocks:
        8193, 24577, 40961, 57345, 73729

Allocating group tables: done
Writing inode tables: done
Creating journal (4096 blocks): done
Writing superblocks and filesystem accounting information: done

Dulce y limpio. Tenga en cuenta el tamaño del bloque: nuestro volumen lógico es pequeño, por lo que mkfs.ext4 decidió hacer un bloque de 1 KiB, no los 4 KiB habituales.

Ahora lo montaremos.

sudo mount /dev/purgatory/test1 /mnt/test1

Y llamemos dfsin parámetros (nos gustaría ver 1 bloques KiB)

/dev/mapper/purgatory-test1     95054    1550     91456   2% /mnt/test1

Espera, oh shi ~

Tenemos 95054 bloques en total. Pero el dispositivo en sí tiene 102400 bloques de 1 KiB. Tenemos solo el 92.8% de nuestro almacenamiento. ¿Dónde están mis bloques, hombre?

Veámoslo en un dispositivo de bloque real. A tiene un disco virtual de 16 GiB, 16777216 bloques de 1K, pero solo 15396784 bloques están en salida df. 91.7%, ¿qué es?

Ahora sigue la investigación (spoiler: sin resultados)

  1. El sistema de archivos podría comenzar no al comienzo del dispositivo. Esto es extraño, pero posible. Afortunadamente, ext4 tiene bytes mágicos, verifiquemos su presencia.

    sudo hexdump -C / dev / purgatory / test1 | grep "53 ef"

Esto muestra superbloque:

00000430  a9 10 e7 54 01 00 ff ff  53 ef 01 00 01 00 00 00  |...T....S.......|

Hex 430 = Dec 1072, entonces en algún lugar después del primer kilobyte. Parece razonable, ext4 omite los primeros 1024 bytes para rarezas como VBR, etc.

  1. Esto es diario!

No, no es. El diario toma espacio de Disponible si la salida de df.

  1. ¡Oh, tenemos dump2fs y podríamos comprobar los tamaños allí!

... muchos greps ...

sudo dumpe2fs /dev/purgatory/test1 | grep "Free blocks"

Ay.

Free blocks:              93504
  Free blocks: 3510-8192
  Free blocks: 8451-16384
  Free blocks: 16385-24576
  Free blocks: 24835-32768
  Free blocks: 32769-40960
  Free blocks: 41219-49152
  Free blocks: 53249-57344
  Free blocks: 57603-65536
  Free blocks: 65537-73728
  Free blocks: 73987-81920
  Free blocks: 81921-90112
  Free blocks: 90113-98304
  Free blocks: 98305-102399

Y tenemos otro número. 93504 bloques libres.

La pregunta es: ¿qué está pasando?

  • Dispositivo de bloque: 102400k (dice lvs)
  • Tamaño del sistema de archivos: 95054k (df dice)
  • Bloques gratuitos: 93504k (dumpe2fs dice)
  • Tamaño disponible: 91456k (df dice)

Es por eso que todavía lo uso ext2para particiones pequeñas.
frostschutz

@frostschutz ext2parece razonable aquí, claro
maníaco

Respuestas:


32

Prueba esto: mkfs.ext4 -N 104 -m0 -O ^has_journal,^resize_inode /dev/purgatory/test1

Creo que esto te permite entender "lo que está pasando".

-N 104 (establezca el número de iNodes que debe tener su sistema de archivos)

  • cada iNode "cuesta" espacio utilizable (128 Byte)

-m 0(sin bloques reservados)
-O ^has_journal,^resize_inode(desactiva las funciones has_journalyresize_inode

  • resize_inode"costo" de espacio libre (la mayoría de los 1550 bloques 1K / 2% que ve en sudf - 12K se usan para la carpeta "perdido + encontrado")
  • has_journal"costos" de espacio utilizable (4096 1K-Blocks en su caso)

Obtenemos 102348de 102400, otros 52 bloques inutilizables (si hemos suprimido el "lost + found" carpeta). Por eso nos sumergimos en dumpe2fs:

Group 0: (Blocks 1-8192) [ITABLE_ZEROED]
  Checksum 0x5ee2, unused inodes 65533
  Primary superblock at 1, Group descriptors at 2-2
  Block bitmap at 3 (+2), Inode bitmap at 19 (+18)
  Inode table at 35-35 (+34)
  8150 free blocks, 0 free inodes, 1 directories, 65533 unused inodes
  Free blocks: 17-18, 32-34, 48-8192
  Free inodes: 
Group 1: (Blocks 8193-16384) [BLOCK_UNINIT, ITABLE_ZEROED]
  Checksum 0x56cf, unused inodes 5
  Backup superblock at 8193, Group descriptors at 8194-8194
  Block bitmap at 4 (+4294959107), Inode bitmap at 20 (+4294959123)
  Inode table at 36-36 (+4294959139)
  8190 free blocks, 6 free inodes, 0 directories, 5 unused inodes
  Free blocks: 8193-16384
  Free inodes: 11-16
Group 2: (Blocks 16385-24576) [INODE_UNINIT, BLOCK_UNINIT, ITABLE_ZEROED]
  Checksum 0x51eb, unused inodes 8
  Block bitmap at 5 (+4294950916), Inode bitmap at 21 (+4294950932)
  Inode table at 37-37 (+4294950948)
  8192 free blocks, 8 free inodes, 0 directories, 8 unused inodes
  Free blocks: 16385-24576
  Free inodes: 17-24
Group 3: (Blocks 24577-32768) [INODE_UNINIT, BLOCK_UNINIT, ITABLE_ZEROED]
  Checksum 0x3de1, unused inodes 8
  Backup superblock at 24577, Group descriptors at 24578-24578
  Block bitmap at 6 (+4294942725), Inode bitmap at 22 (+4294942741)
  Inode table at 38-38 (+4294942757)
  8190 free blocks, 8 free inodes, 0 directories, 8 unused inodes
  Free blocks: 24577-32768
  Free inodes: 25-32
Group 4: (Blocks 32769-40960) [INODE_UNINIT, BLOCK_UNINIT, ITABLE_ZEROED]
  Checksum 0x79b9, unused inodes 8
  Block bitmap at 7 (+4294934534), Inode bitmap at 23 (+4294934550)
  Inode table at 39-39 (+4294934566)
  8192 free blocks, 8 free inodes, 0 directories, 8 unused inodes
  Free blocks: 32769-40960
  Free inodes: 33-40
Group 5: (Blocks 40961-49152) [INODE_UNINIT, BLOCK_UNINIT, ITABLE_ZEROED]
  Checksum 0x0059, unused inodes 8
  Backup superblock at 40961, Group descriptors at 40962-40962
  Block bitmap at 8 (+4294926343), Inode bitmap at 24 (+4294926359)
  Inode table at 40-40 (+4294926375)
  8190 free blocks, 8 free inodes, 0 directories, 8 unused inodes
  Free blocks: 40961-49152
  Free inodes: 41-48
Group 6: (Blocks 49153-57344) [INODE_UNINIT, BLOCK_UNINIT, ITABLE_ZEROED]
  Checksum 0x3000, unused inodes 8
  Block bitmap at 9 (+4294918152), Inode bitmap at 25 (+4294918168)
  Inode table at 41-41 (+4294918184)
  8192 free blocks, 8 free inodes, 0 directories, 8 unused inodes
  Free blocks: 49153-57344
  Free inodes: 49-56
Group 7: (Blocks 57345-65536) [INODE_UNINIT, BLOCK_UNINIT, ITABLE_ZEROED]
  Checksum 0x5c0a, unused inodes 8
  Backup superblock at 57345, Group descriptors at 57346-57346
  Block bitmap at 10 (+4294909961), Inode bitmap at 26 (+4294909977)
  Inode table at 42-42 (+4294909993)
  8190 free blocks, 8 free inodes, 0 directories, 8 unused inodes
  Free blocks: 57345-65536
  Free inodes: 57-64
Group 8: (Blocks 65537-73728) [INODE_UNINIT, BLOCK_UNINIT, ITABLE_ZEROED]
  Checksum 0xf050, unused inodes 8
  Block bitmap at 11 (+4294901770), Inode bitmap at 27 (+4294901786)
  Inode table at 43-43 (+4294901802)
  8192 free blocks, 8 free inodes, 0 directories, 8 unused inodes
  Free blocks: 65537-73728
  Free inodes: 65-72
Group 9: (Blocks 73729-81920) [INODE_UNINIT, BLOCK_UNINIT, ITABLE_ZEROED]
  Checksum 0x50fd, unused inodes 8
  Backup superblock at 73729, Group descriptors at 73730-73730
  Block bitmap at 12 (+4294893579), Inode bitmap at 28 (+4294893595)
  Inode table at 44-44 (+4294893611)
  8190 free blocks, 8 free inodes, 0 directories, 8 unused inodes
  Free blocks: 73729-81920
  Free inodes: 73-80
Group 10: (Blocks 81921-90112) [INODE_UNINIT, BLOCK_UNINIT, ITABLE_ZEROED]
  Checksum 0x60a4, unused inodes 8
  Block bitmap at 13 (+4294885388), Inode bitmap at 29 (+4294885404)
  Inode table at 45-45 (+4294885420)
  8192 free blocks, 8 free inodes, 0 directories, 8 unused inodes
  Free blocks: 81921-90112
  Free inodes: 81-88
Group 11: (Blocks 90113-98304) [INODE_UNINIT, BLOCK_UNINIT, ITABLE_ZEROED]
  Checksum 0x28de, unused inodes 8
  Block bitmap at 14 (+4294877197), Inode bitmap at 30 (+4294877213)
  Inode table at 46-46 (+4294877229)
  8192 free blocks, 8 free inodes, 0 directories, 8 unused inodes
  Free blocks: 90113-98304
  Free inodes: 89-96
Group 12: (Blocks 98305-102399) [INODE_UNINIT, ITABLE_ZEROED]
  Checksum 0x9223, unused inodes 8
  Block bitmap at 15 (+4294869006), Inode bitmap at 31 (+4294869022)
  Inode table at 47-47 (+4294869038)
  4095 free blocks, 8 free inodes, 0 directories, 8 unused inodes
  Free blocks: 98305-102399
  Free inodes: 97-104

y cuente los bloques utilizados (para el superbloque de copia de seguridad, los descriptores de grupo, el mapa de bits de bloque, el mapa de bits de Inode y la tabla de Inode) o we grepand count:

LANG=C dumpe2fs /dev/mapper/vg_vms-test1 | grep ' at ' | grep -v ',' | wc -l

que nos da el recuento de líneas que tienen un solo bloque (en nuestro ejemplo) y

LANG=C dumpe2fs /dev/mapper/vg_vms-test1 | grep ' at ' | grep ',' | wc -l

lo que nos da el recuento de líneas que tienen dos bloques (en nuestro ejemplo).

Entonces tenemos (en nuestro ejemplo) 13líneas con un bloque cada una y 19líneas con dos bloques cada una.

13+19*2

lo que nos da 51bloques que están en uso por ext4. Finalmente solo queda un bloque. El bloque 0, que son los 1024bytes omitidos al principio para cosas como el sector de arranque.


Y si el diario solo toma 4096k, ¡no tengo este número (95054 - 4096)! = 91456?
maniaque

Todos los números aquí están en k, entonces 95054k total - 4096k de diario! = 91456k disponible.
maniaque

1
dfen fs con journal: 95054k - dfen fs sin jorunal 99150k - y no mezcle espacio "utilizable" y "libre".
xx4h

Algunos sistemas de archivos, por ejemplo xfs, asignan dinámicamente espacio para inodos según sea necesario. Es posible que desee probar xfs y btrfs, si tiene curiosidad. mkfs.xfs -l size=512 -d agcount=1creará un sistema de archivos con el tamaño de registro mínimo absoluto (también conocido como diario), pero el rendimiento de escritura podría verse afectado. No creo que el código XFS sea compatible sin un registro. Posiblemente de solo lectura, para admitir casos en los que un dispositivo de registro externo está roto. (también, agcount=1es probablemente otra idea terrible para el rendimiento de escritura, especialmente en paralelo. Y los encabezados de los grupos de asignación también son probablemente pequeños)
Peter Cordes

Tuve curiosidad y probé XFS. Si hay una combinación de opciones para Linux XFS que permitirá que el tamaño mínimo de registro baje al mínimo absoluto de 512 bloques, identifique cuál es. mkfs.xfs -d agcount=1en una partición de 100MiB se obtuvo un FS de 95980kiB, con 5196k usados, 90784k disponibles. La cuenta predeterminada es 4 y el tamaño de registro predeterminado es 1605 bloques (también el mínimo). Por lo tanto, XFS utiliza un registro tan pequeño como esté dispuesto a permitirle especificar, para FSes pequeños.
Peter Cordes

19

La respuesta corta:

No todo el espacio en el dispositivo de bloque se convierte en espacio disponible para sus datos: parte del espacio en bruto es necesario para las partes internas del sistema de archivos, la contabilidad detrás de escena.

Esa contabilidad incluye el superbloque, los descriptores de grupo de bloque, los mapas de bits de bloque e inodo y la tabla de inodo. Además, se crean copias del súper bloque con fines de respaldo / recuperación en varias ubicaciones. Una lectura larga sobre los componentes internos del sistema de archivos EXT4 se puede encontrar en ext4.wiki.kernel.org .

Dado que EXT4 es un sistema de archivos registrado que también ocupa algo de espacio.

Además, se reserva algo de espacio para futuras expansiones del sistema de archivos.

La respuesta larga:

He recreado su escenario en uno de mis sistemas de prueba:

lvcreate -L 100M -n test MyVG
mkfs.ext4 -b 1024 /dev/MyVG/test 

Luego, incluso antes de montar el sistema de archivos, se dumpe2fsmuestra:

Filesystem state:         clean
Errors behavior:          Continue
Filesystem OS type:       Linux
Inode count:              25688
Block count:              102400
Reserved block count:     5120
Free blocks:              93504
Free inodes:              25677
First block:              1
Block size:               1024
Fragment size:            1024
Reserved GDT blocks:      256
Blocks per group:         8192
Fragments per group:      8192
Inodes per group:         1976
Inode blocks per group:   247
Flex block group size:    16
Filesystem created:       Fri Feb 20 13:20:54 2015
Last mount time:          n/a
Last write time:          Fri Feb 20 13:20:55 2015
...
Journal size:             4096k  
...

y después del montaje:

df /tmp/test/
Filesystem              1K-blocks  Used Available Use% Mounted on
/dev/mapper/MyVG-test       99150  5646     88384   7% /tmp/test

Entonces, ¿qué dfnos muestra? De los 102400 bloques del dispositivo de almacenamiento sin procesar, 99150 bloques de 1K son visibles para el sistema de archivos, lo que significa que 3250 bloques de 1 kilobyte de espacio de almacenamiento sin procesar se han vuelto inutilizables para el almacenamiento de datos real.

¿A dónde fueron esos bloques? Desplazarse hacia abajo en la dumpe2fssalida muestra exactamente dónde:

Group 0: (Blocks 1-8192) [ITABLE_ZEROED]
  Checksum 0x0d67, unused inodes 1965
  Primary superblock at 1, Group descriptors at 2-2
  Reserved GDT blocks at 3-258
  Block bitmap at 259 (+258), Inode bitmap at 275 (+274)
  Inode table at 291-537 (+290)
  4683 free blocks, 1965 free inodes, 2 directories, 1965 unused inodes
  Free blocks: 3510-8192
  Free inodes: 12-1976

1 block (bloque # 0) Los primeros 1024 bytes se omiten para permitir la instalación de sectores de arranque x86 y otras rarezas.
1 block está ocupado por el superbloque primario.
1 block contiene los descriptores de grupo.
256 blocksestán reservados para la Tabla de descriptores de grupo para permitir el cambio de tamaño futuro del sistema de archivos. 16 blocks se asignan para el mapa de bits del bloque.
16 blocksse asignan para el mapa de bits de inodo.
246 blocksson asignados para la tabla de inodo.

Eso ya representa 537 de los 3250 bloques faltantes. Un sistema de archivos ext4 se divide en una serie de grupos de bloques y el desplazamiento hacia abajo muestra una asignación similar de la capacidad de almacenamiento sin procesar a los componentes internos del sistema de archivos en los otros grupos de bloques:

Group 1: (Blocks 8193-16384) [INODE_UNINIT, ITABLE_ZEROED]
  Checksum 0x0618, unused inodes 1976
  Backup superblock at 8193, Group descriptors at 8194-8194
  Reserved GDT blocks at 8195-8450
  Block bitmap at 260 (+4294959363), Inode bitmap at 276 (+4294959379)
  Inode table at 538-784 (+4294959641)
  7934 free blocks, 1976 free inodes, 0 directories, 1976 unused inodes
  Free blocks: 8451-16384
  Free inodes: 1977-3952
Group 2: (Blocks 16385-24576) [INODE_UNINIT, BLOCK_UNINIT, ITABLE_ZEROED]
  Checksum 0xcfd3, unused inodes 1976
  Block bitmap at 261 (+4294951172), Inode bitmap at 277 (+4294951188)
  Inode table at 785-1031 (+4294951696)
  8192 free blocks, 1976 free inodes, 0 directories, 1976 unused inodes
  Free blocks: 16385-24576
  Free inodes: 3953-5928 
Group ....

Ahora de vuelta a la dfsalida:

df /tmp/test/
Filesystem              1K-blocks  Used Available Use% Mounted on
/dev/mapper/MyVG-test       99150  5646     88384   7% /tmp/test

La razón por la que en ese nuevo sistema de archivos ya está marcado el 7% de la capacidad como en uso es:

99150 (el tamaño del sistema de archivos) MENOS 5120 (el recuento de bloques reservado) MENOS 5646 (bloques usados, 4096 de los cuales son del Diario (nuevamente parte de la salida de dumpe2fs))
= 88384

El recuento de bloques libres en dumpe2fs es el tamaño disponible del sistema de archivos menos el uso real (y no tiene en cuenta los bloques reservados), por lo que 99150 - 5646 = 93504.


0

No es una respuesta a la pregunta, pero tengo curiosidad, así que imagino que otras personas lo harán. Como ya tenía un liveCD arrancado y tenía un disco duro con el que podía meterme sin preocuparme de que los errores tipográficos dañaran nada, seguí adelante y probé.

Hice particiones con todos los FSes para los que Ubuntu 14.10 incluye un mkfs, en particiones de 100MiB. (excepto minix, que solo admite 64MiB, y bfs, que es algo de SCO del que nunca he oído hablar).

Primero miré df -kespacio disponible (con la configuración por defecto mkfs), entonces dded /dev/zeroa un archivo en cada FS para asegurarse de que se podrían llenar todo el camino hacia arriba. (es decir, compruebe que el reclamo available spaceestaba realmente disponible).
for i in /media/ubuntu/small-*;do sudo dd if=/dev/zero of="$i/fill" bs=16k;done

* FS: empty `df -k` : non-zero `df -k` when full (false bottom)
* jfs:  101020k
* fat32:100808k  : 4
* ntfs:  99896k
* btrfs: 98276k  : 4428
* ext2:  92480k
* xfs:   90652k  : 20
* ext4:  86336k
* ext3:  88367k
* reiserfs(v3): 69552k

¿Por qué btrfs tiene tanto espacio inutilizable? Tal vez para los metadatos? bueno no:

$ for i in /media/ubuntu/small-*;do sudo touch "$i/touched";done
touch: cannot touch ‘/media/ubuntu/small-btrfs/touched’: No space left on device
touch: cannot touch ‘/media/ubuntu/small-reiser/touched’: No space left on device

Ambos sistemas de archivos basados ​​en árboles no pueden empaquetar un archivo vacío en ninguna parte, pero todos los demás sí.

O simplemente mire qué tamaño puede crear un archivo:

$ ls -SdlG --block-size=1k /media/ubuntu/small-*/*
-rw-r--r-- 1 root   101020 Feb 21 11:55 /media/ubuntu/small-jfs/fill
-rw-r--r-- 1 ubuntu 100804 Feb 21 11:55 /media/ubuntu/small-fat/fill
-rw------- 1 ubuntu  99848 Feb 21 11:55 /media/ubuntu/small-ntfs/fill
-rw-r--r-- 1 root    97216 Feb 21 11:55 /media/ubuntu/small-ext2/fill
-rw-r--r-- 1 root    93705 Feb 21 11:27 /media/ubuntu/small-btrfs/foo
-rw-r--r-- 1 root    93120 Feb 21 11:55 /media/ubuntu/small-ext3/fill
-rw-r--r-- 1 root    91440 Feb 21 11:55 /media/ubuntu/small-ext/fill
-rw-r--r-- 1 root    90632 Feb 21 11:55 /media/ubuntu/small-xfs/fill
-rw-r--r-- 1 root    69480 Feb 21 11:55 /media/ubuntu/small-reiser/fill
drwx------ 2 root       12 Feb 21 11:33 /media/ubuntu/small-ext2/lost+found
drwx------ 2 root       12 Feb 21 11:43 /media/ubuntu/small-ext3/lost+found
drwx------ 2 root       12 Feb 21 11:29 /media/ubuntu/small-ext/lost+found

(Llamé a mi partición ext4 "small-ext" porque no estaba planeando volverme loco y hacer todos los sistemas de archivos. Así que ext = ext4 aquí. NO el original pre-ext2 ext.)

Y df -ksalida después de eliminarlos nuevamente:

/dev/sdd6          95980    5328     90652   6% /media/ubuntu/small-xfs
/dev/sdd7          95054    1550     86336   2% /media/ubuntu/small-ext
/dev/sdd5         102400   93880    101020  96% /media/ubuntu/small-btrfs
/dev/sdd8         101168  101168         0 100% /media/ubuntu/small-jfs
/dev/sdd9          99150    1550     92480   2% /media/ubuntu/small-ext2
/dev/sdd10        102392   32840     69552  33% /media/ubuntu/small-reiser
/dev/sdd11        100808       1    100808   1% /media/ubuntu/small-fat
/dev/sdd12        102396    2548     99848   3% /media/ubuntu/small-ntfs
/dev/sdd13         95054    1567     88367   2% /media/ubuntu/small-ext3

(jfs volvió al 1% usado después de que eliminé "tocado" también. O hubo un retraso de tiempo, o tomó otra escritura para obtener el tamaño disponible para actualizar).

De todos modos, creo que es por mi curiosidad.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.