Perché la mia partizione esattamente 100 MiB con 1 blocco KiB non ha i blocchi / spazio disponibili corrispondenti?


33

Ho un ambiente virtualizzato ad altissima densità con contenitori, quindi sto cercando di rendere ogni contenitore davvero piccolo. "Davvero piccolo" significa 87 MB sulla base Ubuntu 14.04 (Trusty Tahr) senza interrompere la compatibilità del gestore pacchetti.

Quindi uso LVM come supporto di archiviazione per i miei contenitori e recentemente ho trovato numeri molto strani. Eccoli.

Creiamo un volume logico di 100 MiB (sì, potenza di 2).

sudo lvcreate -L100M -n test1 /dev/purgatory

Vorrei controllare le dimensioni, quindi rilascio sudo lvs --units k

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

Dolce, questo è davvero 100 MiB.

Ora facciamo un filesystem ext4 . E, naturalmente, ricordiamo il -m 0parametro, che impedisce lo spreco di spazio.

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

Dolce e pulito. Ricorda la dimensione del blocco: il nostro volume logico è piccolo, quindi mkfs.ext4 ha deciso di creare un blocco di 1 KiB, non il solito 4 KiB.

Ora lo monteremo.

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

E chiamiamo dfsenza parametri (vorremmo vedere 1 blocco KiB)

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

Aspetta, oh shi ~

Abbiamo 95054 blocchi in totale. Ma il dispositivo stesso ha 102400 blocchi di 1 KiB. Abbiamo solo il 92,8% del nostro deposito. Dove sono i miei blocchi, amico?

Vediamolo su un dispositivo a blocchi reale. A hanno un disco virtuale da 16 GiB, 16777216 blocchi da 1K, ma solo 15396784 blocchi sono in output df. 91,7%, che cos'è?

Ora segue l'indagine (spoiler: nessun risultato)

  1. Il filesystem potrebbe iniziare non all'inizio del dispositivo. Questo è strano, ma possibile. Fortunatamente, ext4 ha byte magici, controlliamo la loro presenza.

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

Questo mostra superblock:

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

Hex 430 = Dec 1072, quindi da qualche parte dopo il primo kilobyte. Sembra ragionevole, ext4 salta i primi 1024 byte per stranezze come VBR, ecc.

  1. Questo è diario!

No non lo è. Il journal prende spazio da Disponibile se output df.

  1. Oh, abbiamo dump2fs e potremmo controllare le dimensioni lì!

... molte greps ...

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

Ahia.

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

E abbiamo un altro numero. 93504 blocchi gratuiti.

La domanda è: cosa sta succedendo?

  • Dispositivo a blocchi: 102400k (dice lvs)
  • Dimensione del filesystem: 95054k (dice df)
  • Blocchi liberi: 93504k (dice dumpe2fs)
  • Dimensione disponibile: 91456k (dice df)

Ecco perché lo uso ancora ext2per piccole partizioni.
frostschutz,

@frostschutz ext2sembra ragionevole qui, certo
maniaco il

Risposte:


32

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

Penso che questo ti faccia capire "cosa sta succedendo".

-N 104 (imposta il numero di iNode che il tuo filesystem dovrebbe avere)

  • ogni iNode "costa" lo spazio utilizzabile (128 byte)

-m 0(nessun blocco riservato)
-O ^has_journal,^resize_inode(disattivare le funzionalità has_journaleresize_inode

  • resize_inode"costa" spazio libero (la maggior parte dei 1550 blocchi 1K / 2% che vedi nel tuo df- 12K sono usati per la cartella "lost + found")
  • has_journal"costa" lo spazio utilizzabile (4096 blocchi 1K nel tuo caso)

Usciamo 102348da 102400altri 52 blocchi inutilizzabili (se abbiamo eliminato la cartella "lost + found"). Pertanto ci immergiamo in 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

e contare i blocchi utilizzati (per il superblocco di backup, i descrittori di gruppo, la bitmap di blocco, la bitmap di Inode e la tabella di Inode) oppure grepcontiamo:

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

che ci dà il conteggio delle linee che hanno un singolo blocco (nel nostro esempio) e

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

che ci dà il conteggio delle linee che hanno due blocchi (nel nostro esempio).

Quindi abbiamo (nel nostro esempio) 13linee con un blocco ciascuna e 19linee con due blocchi ciascuna.

13+19*2

che ci dà 51blocchi che sono in uso da ext4 stesso. Finalmente rimane solo un blocco. Il blocco 0, che sono i 1024byte ignorati all'inizio per cose come il settore di avvio.


E se il diario impiega solo 4096k, non ho questo numero (95054 - 4096)! = 91456?
maniaque,

Tutti i numeri qui sono in k, quindi un totale di 95054k - 4096k di giornale! = 91456k disponibili.
maniaque,

1
dfsu fs con journal: 95054k - dfsu fs senza jorunal 99150k - e non mescolare spazio "utilizzabile" e "libero".
xx4h,

Alcuni filesystem, ad esempio xfs, allocano dinamicamente lo spazio per gli inode secondo necessità. Potresti provare xfs e btrfs, se sei curioso. mkfs.xfs -l size=512 -d agcount=1produrrà un filesystem con la dimensione minima assoluta del registro (aka journal), ma le prestazioni di scrittura potrebbero risentirne. Non credo che il supporto del codice XFS funzioni senza un registro. Possibilmente di sola lettura, per supportare i casi in cui un dispositivo di registro esterno è rotto. (Inoltre, agcount=1è probabilmente un'altra terribile idea per le prestazioni di scrittura, in particolare parallelo. E anche le intestazioni del gruppo di allocazione sono probabilmente piccole.)
Peter Cordes,

Incuriosito e provato XFS. Se esiste una combinazione di opzioni per Linux XFS che consente di ridurre la dimensione minima del registro al minimo assoluto di 512 blocchi, IDK di cosa si tratta. mkfs.xfs -d agcount=1su una partizione da 100 Mii reso disponibile un FS di 95980 kB, con 5196 k usati, 90784 k disponibili. Il conteggio predefinito è 4 e la dimensione del registro predefinita è 1605 blocchi (anche il minimo). Quindi XFS usa un registro piccolo quanto è disposto a permetterti di specificare, per FS piccoli.
Peter Cordes,

19

La breve risposta:

Non tutto lo spazio sul dispositivo a blocchi diventa spazio disponibile per i tuoi dati: parte dello spazio grezzo è necessario per gli interni del file system, la contabilità dietro le quinte.

Tale contabilità comprende il superblocco, i descrittori dei gruppi di blocchi, le bitmap di blocco e inode e la tabella degli inode. Inoltre, vengono create copie del superblocco per scopi di backup / ripristino in diverse posizioni. Una lunga lettura degli interni del file system EXT4 è disponibile su ext4.wiki.kernel.org .

Poiché EXT4 è un file system con journaling che occupa anche un po 'di spazio.

Inoltre, parte dello spazio è riservato per future espansioni del file system.

La lunga risposta:

Ho ricreato il tuo scenario su uno dei miei sistemi di test:

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

Quindi prima ancora di montare il file system viene dumpe2fsmostrato:

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

e dopo il montaggio:

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

Quindi cosa dfci mostra? Dai 102400 blocchi della capacità del dispositivo di archiviazione raw, 99150 blocchi 1K sono visibili al file system, il che significa che 3250 blocchi da 1 Kilobyte di spazio di archiviazione raw sono diventati inutilizzabili per l'archiviazione effettiva dei dati.

Dove sono finiti quei blocchi? Scorrendo verso il basso dumpe2fsnell'output mostra esattamente dove:

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 (blocco # 0) I primi 1024 byte vengono ignorati per consentire l'installazione di settori di avvio x86 e altre stranezze.
1 block è occupato dal super blocco primario.
1 block contiene i descrittori di gruppo.
256 blockssono riservati per la Tabella descrittori di gruppo per consentire il futuro ridimensionamento del filesystem. 16 blocks sono assegnati per il bitmap del blocco.
16 blockssono assegnati per la bitmap inode.
246 blockssono assegnati per la tabella degli inode.

Ciò rappresenta già 537 dei 3250 blocchi mancanti. Un file system ext4 è suddiviso in una serie di gruppi di blocchi e lo scorrimento verso il basso mostra ulteriormente un'allocazione simile della capacità di archiviazione non elaborata agli interni del file system negli altri gruppi di blocchi:

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

Ora torniamo dfall'output:

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

Il motivo per cui su quel nuovo file system già il 7% della capacità è contrassegnato come in uso è:

99150 (la dimensione del file system) MINUS 5120 (il conteggio dei blocchi riservati) MINUS 5646 (blocchi usati, 4096 dei quali sono dal Journal (di nuovo parte dell'output di dumpe2fs))
= 88384

Il conteggio dei blocchi gratuiti in dumpe2fs è la dimensione disponibile del file system meno l'utilizzo effettivo (e non tiene conto dei blocchi riservati), quindi 99150 - 5646 = 93504.


0

Non una risposta alla domanda, ma mi sono incuriosito, quindi immagino che lo faranno gli altri. Dato che avevo già avviato un liveCD e avevo un disco rigido con cui potevo scherzare senza preoccuparmi che i refusi non danneggiassero nulla, sono andato avanti e ho provato.

Ho creato partizioni con tutti gli FS per i quali Ubuntu 14.10 spedisce un mkfs, su partizioni da 100 MiB. (tranne minix, che supporta solo 64 MiB e bfs, che è una cosa SCO di cui non ho mai sentito parlare.)

Per prima cosa ho guardato df -klo spazio a disposizione (con le impostazioni predefinite mkfs), allora io ddEd /dev/zeroin un file su ogni FS per assicurarsi che essi potrebbero essere colmate per tutta la strada fino. (vale a dire verificare che il reclamo available spacefosse davvero disponibile.)
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

Perché btrfs ha così tanto spazio inutilizzabile? Forse per i metadati? beh 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

Entrambi i file system basati su alberi non possono contenere un file vuoto da nessuna parte, ma tutti gli altri possono farlo.

Oppure guarda quanto è grande un file che puoi creare:

$ 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

(Ho chiamato la mia partizione ext4 "small-ext" perché non avevo intenzione di impazzire e rendere ogni filesystem. Così ext = ext4 qui. NON l'ext pre-ext2 originale.)

E df -koutput dopo averli rimossi di nuovo:

/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 è tornato all'1% utilizzato dopo che ho rimosso anche "toccato". O si è verificato un ritardo o ci è voluta un'altra scrittura per ottenere le dimensioni disponibili per l'aggiornamento.)

Comunque, penso che sia per la mia curiosità.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.