Pourquoi ma partition de 100 Mo exactement à une taille de bloc de 1 Ko n'a-t-elle pas les blocs / espaces disponibles correspondants?

33

J'ai un environnement virtualisé très haute densité avec des conteneurs, j'essaie donc de rendre chaque conteneur vraiment petit. "Vraiment petit" signifie 87 Mo sur la base Ubuntu 14.04 (Trusty Tahr) sans rompre la compatibilité du gestionnaire de paquets.

J'utilise donc LVM comme stockage de sauvegarde pour mes conteneurs et récemment, j'ai trouvé des nombres très étranges. Les voici.

Créons un volume logique de 100 Mio (ouais, puissance de 2).

sudo lvcreate -L100M -n test1 /dev/purgatory

Je voudrais vérifier la taille, alors je publie sudo lvs --units k

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

Doux, c'est vraiment 100 MiB.

Faisons maintenant un système de fichiers ext4 . Et bien sûr, nous nous souvenons du -m 0paramètre qui évite les pertes d’espace.

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

Doux et propre. Attention à la taille des blocs - notre volume logique est petit, donc mkfs.ext4 a décidé de créer un bloc de 1 Ko, et non les 4 Ko habituels.

Maintenant nous allons le monter.

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

Et appelons dfsans paramètres (nous aimerions voir 1 blocs KiB)

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

Attends, oh shi ~

Nous avons 95054 blocs au total. Mais l'appareil lui-même a 102400 blocs de 1 KiB. Nous n'avons que 92,8% de notre stockage. Où sont mes blocs, mec?

Regardons cela sur un vrai périphérique en mode bloc. A ont un disque virtuel de 16 Go, 16777216 blocs de 1K, mais seuls 15396784 blocs sont en sortie df. 91,7%, c'est quoi?

Suit maintenant l'enquête (spoiler: aucun résultat)

  1. Le système de fichiers pourrait ne pas commencer au début de l'appareil. C'est étrange, mais possible. Heureusement, ext4 a des octets magiques, vérifions leur présence.

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

Cela montre superbloc:

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

Hex 430 = Dec 1072, donc quelque part après le premier kilo-octet. Apparemment, ext4 saute les 1024 premiers octets pour les bizarreries comme VBR, etc.

  1. C'est un journal!

Non ce n'est pas. Le journal prend de l'espace de Disponible si sortie df.

  1. Oh, nous avons dump2fs et pourrions vérifier les tailles ici!

... beaucoup de greps ...

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

Aie.

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

Et nous avons un autre numéro. 93504 blocs gratuits.

La question est: que se passe-t-il?

  • Périphérique de blocage: 102400k (dit LVS)
  • Taille du système de fichiers: 95054k (df dit)
  • Blocs gratuits: 93504k (dumpe2fs dit)
  • Taille disponible: 91456k (df dit)
maniaque
la source
C'est pourquoi j'utilise toujours ext2pour les petites partitions.
frostschutz
@frostschutz ext2semble raisonnable ici, bien sûr
maniaque

Réponses:

32

Essaye ça: mkfs.ext4 -N 104 -m0 -O ^has_journal,^resize_inode /dev/purgatory/test1

Je pense que cela vous laisse comprendre "ce qui se passe".

-N 104 (définissez le nombre d'iNodes que votre système de fichiers devrait avoir)

  • chaque iNode "coûte" de l' espace utilisable (128 octets)

-m 0(pas de blocs réservés)
-O ^has_journal,^resize_inode(désactivez les fonctions has_journaletresize_inode

  • resize_inode"coûte" de l' espace libre (la plupart des 1550 blocs de 1K / 2% que vous voyez dans votre df- 12K sont utilisés pour le dossier "perdu + trouvé")
  • has_journal"coûte" l' espace utilisable (4096 1K-Blocks dans votre cas)

Nous 102348sortons de 102400, 52 autres blocs inutilisables (si nous avons supprimé le dossier "lost + found"). Nous plongeons donc dans 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

et comptez les blocs utilisés (pour le superbloc de sauvegarde, les descripteurs de groupe, le bitmap de bloc, le bitmap d’inode et le tableau Inode) ou bien nous grepcomptons:

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

qui nous donne le nombre de lignes qui ont un seul bloc (dans notre exemple) et

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

ce qui nous donne le nombre de lignes qui ont deux blocs (dans notre exemple).

Nous avons donc (dans notre exemple) des 13lignes avec un bloc chacune et des 19lignes avec deux blocs chacune.

13+19*2

ce qui nous donne des 51blocs qui sont utilisés par ext4 lui-même. Enfin, il ne reste qu'un bloc. Le bloc 0, qui sont les 1024octets ignorés au début pour des choses comme le secteur de démarrage.

xx4h
la source
Et si journal prend seulement 4096k, je n'ai pas ce numéro (95054 - 4096)! = 91456?
maniaque
Tous les nombres ici sont en k, donc 95054k au total - 4096k du journal! = 91456k disponible.
maniaque
1
dfsur fs avec journal: 95054k - dfsur fs sans jorunal 99150k - et ne mélangez pas les espaces "utilisable" et "libre".
xxh
Certains systèmes de fichiers, par exemple xfs, allouent dynamiquement de la place pour les inodes selon les besoins. Vous voudrez peut-être essayer xfs et btrfs, si vous êtes curieux. mkfs.xfs -l size=512 -d agcount=1créera un système de fichiers avec la taille minimale absolue du journal (journal), mais les performances en écriture pourraient en souffrir. Je ne pense pas que le code XFS supporte le fonctionnement sans journal. Peut-être en lecture seule, pour prendre en charge les cas où un périphérique de journalisation externe est endommagé. (Aussi, agcount=1est probablement une autre idée terrible pour la performance en écriture, en particulier parallèle. Et les en-têtes de groupe d'allocation sont probablement petits également.)
Peter Cordes
Je suis curieux et j'ai essayé XFS. S'il existe une combinaison d'options pour Linux XFS qui permettra à la taille minimale du journal de descendre à un minimum absolu de 512 blocs, IDK ce qu'elle est. mkfs.xfs -d agcount=1sur une partition de 100 Mo faite un FS de 95980kiB, avec 5196k utilisé, 90784k disponible. Le nombre d'agents par défaut est 4 et la taille de journal par défaut est de 1605 blocs (également le minimum). Donc, XFS utilise un journal aussi petit qu'il est prêt à vous laisser spécifier, pour les petits FS.
Peter Cordes
19

La réponse courte:

Tout l'espace sur le périphérique en bloc ne devient pas un espace disponible pour vos données: une partie de l'espace brut est nécessaire pour les internes du système de fichiers, la comptabilité en arrière-plan.

Cette comptabilité comprend le superbloc, les descripteurs de groupe de blocs, les bitmaps de blocs et d’inodes et la table inode. De plus, des copies du superbloc à des fins de sauvegarde / récupération sont créées à plusieurs endroits. Une longue lecture sur les composants internes du système de fichiers EXT4 se trouve sur ext4.wiki.kernel.org .

Depuis EXT4 est un système de fichiers journalisé qui prend également de la place.

De plus, de l'espace est réservé pour de futures extensions du système de fichiers.

La réponse longue:

J'ai recréé votre scénario sur l'un de mes systèmes de test:

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

Ensuite, avant même de monter le système de fichiers, a dumpe2fsmontre:

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

et après montage:

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

Alors qu'est-ce que dfnous montre? Sur les 102400 blocs de capacité de stockage brute, 99150 blocs sont visibles pour le système de fichiers, ce qui signifie que 3250 blocs d'espace mémoire brut de 1 kilo-octet sont devenus inutilisables pour le stockage de données.

Où sont allés ces blocs? Faire défiler vers le bas dans la dumpe2fssortie montre exactement où:

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 (bloc 0) Les 1024 premiers octets sont ignorés pour permettre l'installation de secteurs d'amorçage x86 et d'autres bizarreries.
1 block est occupé par le superbloc primaire.
1 block contient les descripteurs de groupe.
256 blockssont réservés pour la table de descripteur de groupe afin de permettre un redimensionnement ultérieur du système de fichiers. 16 blocks sont attribués pour le bitmap de bloc.
16 blockssont attribués pour le bitmap inode.
246 blockssont affectés à la table inode.

Cela représente déjà 537 des 3 250 blocs manquants. Un système de fichiers ext4 est divisé en une série de groupes de blocs et le défilement vers le bas montre également une allocation similaire de la capacité de stockage brute aux internes du système de fichiers des autres groupes de blocs:

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

Revenons maintenant à la dfsortie:

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

La raison pour laquelle 7% de la capacité déjà utilisée sur ce nouveau système de fichiers est marquée comme étant en cours d'utilisation est la suivante:

99150 (taille du système de fichiers) MOINS 5120 (nombre de blocs réservés) MOINS 5646 (blocs utilisés, dont 4096 extraits du Journal (faisant également partie de la sortie de dumpe2fs`))
= 88384

Le nombre de blocs libres dans dumpe2fs est la taille disponible du système de fichiers moins l'utilisation réelle (et ne prend pas en compte les blocs réservés), donc 99150 - 5646 = 93504.

HBruijn
la source
0

Pas une réponse à la question, mais je suis devenu curieux alors j'imagine que d'autres le feront. Comme j'avais déjà démarré un liveCD et que j'avais un disque dur avec lequel je pouvais jouer sans me soucier des fautes de frappe, je suis allé de l'avant et j'ai testé.

J'ai créé des partitions avec tous les systèmes de stockage pour lesquels Ubuntu 14.10 fournit un fichier mkfs, sur des partitions de 100 Mo. (sauf minix, qui ne supporte que 64MiB, et bfs, ce qui est quelque chose de SCO dont je n'ai jamais entendu parler.)

D' abord , je regardais l' df -kespace disponible (avec les paramètres de mkfs par défaut), alors ddj'ed /dev/zerodans un fichier sur chaque FS pour vous assurer qu'ils pourraient remplir toute la hauteur. (c.-à-d. vérifier que la réclamation available spaceétait vraiment 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

Pourquoi btrfs a-t-il autant d'espace inutilisable? Peut-être pour les métadonnées? bien nope:

$ 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

Les deux systèmes de fichiers basés sur des arbres ne peuvent pas compresser un fichier vide n'importe où, mais tous les autres peuvent.

Ou regardez simplement la taille d'un fichier que vous pouvez créer:

$ 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

(J'ai appelé ma partition ext4 "small-ext" parce que je n'avais pas l'intention de devenir dingue et de créer tous les systèmes de fichiers. So ext = ext4 ici. PAS l'original pré-ext2 ext.)

Et df -ksortie après les avoir à nouveau enlevés:

/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 est revenu à 1% utilisé après que j'ai supprimé "touché" également. Soit il y avait un délai, soit il a fallu une autre écriture pour obtenir la taille disponible à mettre à jour.)

Quoi qu'il en soit, je pense que c'est à peu près tout pour ma curiosité.

Peter Cordes
la source