<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>lvm &amp;mdash; Cyberdyne Systems</title>
    <link>https://noblogo.org/aytin/tag:lvm</link>
    <description>&#34;Fare o non fare. Non c&#39;è provare!&#34;</description>
    <pubDate>Wed, 10 Jun 2026 00:13:42 +0000</pubDate>
    <item>
      <title>Cose molto notevoli su LVM</title>
      <link>https://noblogo.org/aytin/cose-molto-notevoli-su-lvm</link>
      <description>&lt;![CDATA[lvm plus&#xA;Oltre che alla grande flessibilità nella gestione dei volumi, LVM attraverso device mapper, aggiunge tutta una serie di ulteriori capacità che rendono questa tecnologia estremamente versatile.&#xA;&#xA;La possibilità di disporre di meccanismi per la gestione di snapshot, cache pool. thin provisioning e raid, rendono LVM qualcosa di più di un gestore di volumi. &#xA;!--more--&#xA;&#xA;1. Snapshot&#xA;   1.1. Attenzione: Dimensione della snapshot&#xA;   1.2. Esempio&#xA;2. Thin Pool&#xA;3. Thin Pool e snapshot&#xA;4. Cache Pool&#xA;   4.1. Caso 1: configurazione automatica del cache pool lv&#xA;   4.2. Caso 2: configurazione manuale del cache pool lv&#xA;   4.3. Switch della modalità&#xA;   4.4. Rimozione della cache&#xA;   4.5. Monitoraggio&#xA;5. LVM Stripe&#xA;6. LVM Mirror&#xA;7. LVM Raid&#xA;   7.1. Raid 0 (Stripe)&#xA;   7.2. Raid 1 (Mirroring)&#xA;   7.3. Raid 5 (Stripe con parità singola)&#xA;   7.4. Raid 6 (Stripe con parità doppia)&#xA;   7.5. Raid 10&#xA;   7.6. Come monitorare il raid&#xA;   7.7. Come intervenire in caso di guasto&#xA;&#xA;1. Snapshot&#xA;Le snapshot LVM usano la tecnica del Copy-on-Write (CoW) allo scopo di ridurre la duplicazione. &#xA;&#xA;La snapshot dovrà essre la fotografia del volume prima all&#39;origine.&#xA;&#xA;Ad ogni modifica / cancellazione, il file originale verrà portato sulla snapshot prima dell&#39;operazione.&#xA;Sul volume originale verranno scritti tutti i dati nuovi e quelli modificati.&#xA;&#xA;Per il ripristino, si effettua quello che si chiama merge, dove i dati vecchi vengono ripristinati dalla snapshot e quelli nuovi cancellati dal volume.&#xA;&#xA;Per il consolidamento delle modifiche, basterò rimuovere la snapshot,&#xA;&#xA;1.1. Attenzione: Dimensione della snapshot&#xA;&#xA;Se la snapshot ha la stessa dimensione del volume logico non ci sono problemi.&#xA;&#xA;Se è più piccola, occorre prestare attenzione a che la quantità dei dati modificati sul volume logico non superino la dimensione della snapshot.&#xA;&#xA;In questo caso infatti la snapshot risulterà inutilizzabile e non potrà più essere usata per il ripristino ma potrà essree solo rimossa.&#xA;&#xA;1.2. Esempio&#xA;Supponiamo di avere un gruppo di volumi, myvg, composto da 3 volumi logici:&#xA;&#xA;lvroot (30 GiB)&#xA;lvhome (200 GiB)&#xA;lvdati (500 GiB)&#xA;&#xA;e di voler creare una snapshot precauzionale sulla root (supponendo di avere spazio a sufficienza altrimenti dovrò fare bene i miei conti per non riempire oltremisura la snapshot rendendola inservibile).&#xA;&#xA;Creazione snapshot&#xA;lvcreate -s -L 30G -n  lvrootsnap myvg/snap&#xA;Ripristino&#xA;umount /dev/myvg/lvroot&#xA;lvconvert --merge myvg/snap&#xA;Consolidamento&#xA;lvremove snap&#xA;2. Thin Pool&#xA;Il thin provisioning di LVM è l&#39;alternativa dinamica alla classica gestione di volumi, thick, che prevede l&#39;assegnazione statica delle dimensioni dei volumi.&#xA;&#xA;Se è vero che il thick provisioning risulta comunque abbastastanza agevole per via della flessibilità intrinseca dei volumi in caso di riduzione o aumento della superficie allocabile, il thin provisioning può aumentare i vantaggi derivanti da LVM in alcuni scenari.&#xA;&#xA;Il thin provisioning si basa sul principio che lo spazio assegnato ai volumi non viene usato mai completamente e mai tutto in una volta.&#xA;&#xA;Ecco perché un&#39;allocazione dinamica ci permetterebbe di definire volumi che si riempiono solo man mano che lo spazio viene occupato.&#xA;&#xA;Se si opta per un thin provisioning sarebbe opportuno non usare tutto il gruppo di volumi ma lasciarne un 20% in previsione di future espansioni.&#xA;&#xA;Con i thin pool non solo abbiamo la stessa flessibilità della gestione thick, ma possiamo lavorare anche in over provisioning ossia creare pool di volumi la cui somma potenziale sia superiore allo spazio realmente allocabile.&#xA;&#xA;Es. Supponiamo avere un device da 100 GiB, /dev/sdb, su cui definisco un volume group e creare un thin pool di 50 GiB. Su questo thin pool creeremo 3 volumi &#34;virtuali&#34; da 20, 30 e 20 GiB.&#xA;creazione volume group di 100 GiB&#xA;vgcreate vglab /dev/sdb&#xA;&#xA;creazione thin pool da 50 GiB&#xA;lvcreate -L 50G --thinpool vglab/lvtp&#xA;&#xA;creazione dei 3 volumi virtuali in &#34;over provisioning&#34; &#xA;lvcreate -V 20G --thin -n vol1virt --thinpool vglab/lvtp&#xA;lvcreate -V 30G --thin -n vol2virt --thinpool vglab/lvtp&#xA;lvcreate -V 20G --thin -n vol3virt --thinpool vglab/lvtp&#xA;Una volta creati i volumi possono essere formattati e montati come di consueto.&#xA;&#xA;Lo spazio effettivamente occupato è quasi nullo, il sistema solleverà solo un warning per avvertirci che i volumi virtuali rischiano di saturare lo spazio disponibile.&#xA;&#xA;Ecco perché bisogna prestare attenzione al raggiungimento della soglia critica.&#xA;Bisognerà estendere subito il thin pool ed i volumi virtuali nel modo consueto.&#xA;&#xA;⚠️⚠️⚠️ ATTENZIONE ⚠️⚠️⚠️&#xA;L&#39;estensione di un volume virtuale non differisce molto da quello di un volume &#34;classico&#34;.&#xA;Se lo spazio per le fette si sta esaurendo, si estendono nell&#39;ordine:&#xA;&#xA;il gruppo di volumi (se necessario)&#xA;il thin pool (se nel volume group c&#39;è spazio a sufficienza)&#xA;i volumi virtuali&#xA;i filesystem&#xA;&#xA;Se non siamo con l&#39;acqua alla gola, i punti 3 e 4 sono sufficienti. L&#39;estensione del volume virtuale è più rapida di quella classica perché non viene allocato spazio.&#xA;L&#39;estensione di un volume logico classico corrisponde all&#39;estensione del thin pool.&#xA;&#xA;Nel caso di riduzione, la situazione cambia parecchio perché la riduzione di un volume virtuale non fa guadagnare spazio allocabile visto che l&#39;ampiezza del volume è solo teorica, ciò avviene solo con fstrim.&#xA;Inoltre accorciando il volume virtuale al di sotto dei dati effettivamente scritti, si rischia di corrompere l&#39;intero filesystem.&#xA;Consiglio spassionato: ESTENDI SEMPRE E NON RIDURRE MAI!!!&#xA;&#xA;Altra considerazione va fatta anche per i metadati.&#xA;&#xA;A differenza dell&#39;LVM classico dove la creazione di un volume logico necessitava di un extent per i metadati, il thin provisioning di LVM riserva un volume logico per i dati e un volume logico per i metadati.&#xA;&#xA;L&#39;estensione continua di piccole fette, può riempire il volume dei metadati col rischio di corrompere l&#39;intero thin pool e prima che succeda, anche il volume dei metadati può dover essere esteso.&#xA;lvextend --poolmetadatasize +1G vglab/lvtp&#xA;3. Thin Pool e snapshot&#xA;Un altro bel vantaggio della modalità thin pool è quello di facilitare l&#39;uso delle snapshot.&#xA;&#xA;Trattandosi di volumi virtuali, la dimensione della snapshot non ha bisogno di essere dichiarata. La creazione di snapshot è estremamente semplice.&#xA;creazione di una snapshot&#xA;lvcreate -s -n lvsnap vglab/volvirt&#xA;Come pure sia la creazione di snapshot annidate che il rollback risultano molto più semplici ed efficienti.&#xA;creazione di una snapshot&#xA;lvcreate -s -n lvsnap1 vglab/volvirt&#xA;&#xA;creazione di una snapshot annidata&#xA;lvcreate -s -n lvsnap2 vglab/lvsnap1&#xA;&#xA;rollback&#xA;umount vol1&#xA;lvconvert --merge vglab/lvsnap2&#xA;mount -t ext4 -o defaults /dev/vglab/volvirt vol1&#xA;E a proposito di snapshot, occorre fare qualche osservazione.&#xA;&#xA;Una serie di snapshot thin annidate, non è una catena di patch incrementali esposte al filesystem come si potrebbe pensare.&#xA;In virtù del CoW, la snapshot annidate fotograferanno sempre lo stesso istante: quello del file system all&#39;origine.&#xA;&#xA;Facciamo un esempio:&#xA;lvcreate -V 10g -T vgtest/thinpool -n vmroot&#xA;mkfs.ext4 /dev/vgtest/vmroot&#xA;mount /dev/vgtest/vmroot /mnt/test&#xA;echo ORIGINAL   /mnt/test/file.txt&#xA;umount test&#xA;&#xA;lvcreate -s -n snap1 vgtest/vmroot&#xA;&#xA;mount /dev/vgtest/vmroot /mnt/test&#xA;echo MOD1   /mnt/test/file.txt&#xA;umount /mnt/test&#xA;&#xA;lvcreate -s -n snap2 vgtest/snap1&#xA;&#xA;mount /dev/vgtest/vmroot /mnt/test&#xA;echo MOD2   /mnt/test/file.txt&#xA;umount /mnt/test&#xA;&#xA;lvcreate -s -n snap3 vgtest/snap2&#xA;&#xA;mount /dev/vgtest/vmroot /mnt/test&#xA;echo MOD3   /mnt/test/file.txt&#xA;umount /mnt/test&#xA;In questo esempio creo un volume virtuale, vmroot, e 3 snap annidate.&#xA;&#xA;Monto il volume virtuale.&#xA;La prima snapshot, snap1, fotografa il file system del volume virtuale che contiene il file con &#34;ORIGINAL&#34;.&#xA;Il volume virtuale viene montato e il file viene modificato.&#xA;La seconda snapshot, snap2, fotografa snap1 che a sua volta conteneva il file system del volume virtuale che contiene il file con &#34;ORIGINAL&#34;.&#xA;Il volume virtuale viene montato e il file viene modificato.&#xA;La terza snapshot, snap3, fotografa snap2 che a sua volta conteneva snap1.. ecc.&#xA;&#xA;Quindi snapshot siffatte non realizzano un versioning del file system come si potrebbe pensare, piuttosto possono essere utili per creare alberi di cloni/read-only, ambienti temporanei derivati da uno stato consistente, ecc.&#xA;&#xA;In sostanza tornano utili quando ho una base da cui faccio derivare n snapshot che condividono i blocchi comune e con CoW minimizzo lo spazio.&#xA;&#xA;Il merge di una qualunque snapshot ricondurrà il file system allo stato originario.&#xA;origin&#xA; ├── snap1&#xA; ├── snap2&#xA; ├── snap3&#xA;Per lavorare sul delta come immaginiamo, si dovranno montare via via le snapshop, non il volume virtuale, e modificare quelle.&#xA;lvcreate -V 10g -T vgtest/thinpool -n vmroot&#xA;mkfs.ext4 /dev/vgtest/vmroot&#xA;mount /dev/vgtest/vmroot /mnt/test&#xA;echo ORIGINAL   /mnt/test/file.txt&#xA;umount /mnt/test&#xA;&#xA;lvcreate -s -n snap1 vgtest/vmroot&#xA;&#xA;lvchange -ay -K vgtest/snap1&#xA;mount /dev/vgtest/snap1 /mnt/test&#xA;echo MOD1   /mnt/test/file.txt&#xA;umount /mnt/test&#xA;&#xA;lvcreate -s -n snap2 vgtest/snap1&#xA;&#xA;lvchange -ay -K vgtest/snap2&#xA;mount /dev/vgtest/snap2 /mnt/test&#xA;echo MOD2   /mnt/test/file.txt&#xA;umount /mnt/test&#xA;&#xA;lvcreate -s -n snap3 vgtest/snap2&#xA;&#xA;lvchange -ay -K vgtest/snap3&#xA;mount /dev/vgtest/snap3 /mnt/test&#xA;echo MOD3   /mnt/test/file.txt&#xA;umount /mnt/test&#xA;In questo modo si &#34;inverte&#34; la logica del merge che, prima riconduceva il file system allo stato inizale, ora invece consolida le modifiche delle snapshot&#xA;origin&#xA; └── snap1&#xA;      └── snap2&#xA;           └── snap3&#xA;Il merge va fatto in ordine se si vogliono acquisire correttamente i delta.&#xA;Tuttavia questo approccio&#xA;&#xA;è raro&#xA;è difficile da gestire&#xA;complica i merge&#xA;può creare dependency tree intricati&#xA;&#xA;Per questo quasi tutti:&#xA;&#xA;snapshot sempre dell’origin&#xA;mai snapshot di snapshot&#xA;rollback lineare&#xA;&#xA;4. Cache Pool&#xA;Il cache pool di LVM serve a migliorare l&#39;accesso a dispositivi tradizionalmente lenti e lo fa combinando dischi  HDD con SSD/NVMe.&#xA;&#xA;In sostanza avremo un gruppo di volumi costituito dai dischi HDD e un altro gruppo di volumi costituito dai dischi SDD/NVMe, la nostra cache.&#xA;&#xA;Il Logical Volume Cache sul disco veloce migliora l&#39;accesso ad uno specifico volume logico del disco lento e prevede il ricorso a tutta una serie di tipi di volumi logici abbastanza variegata:&#xA;&#xA;Origin LV: volume logico orignale costituito dai dischi lenti&#xA;Cache pool LV: volume logico composto  a sua volta da altri due voumi logici: dati della cache e metadati della cache&#xA;&#x9;Cache data LV: volume logico contenente i blocchi di dati per il Cache pool LV.&#xA;&#x9;Cache metadata LV: volume logico contenente i metadatati per il Cache pool LV.&#xA;Cache LV: volume logico contenente l&#39;Origin LV e Il Cache pool LV. È il volume realemente utilizzabile&#xA;Spare metadata LV: volume logico correlato ad una funzione di recovery data failure&#xA;&#xA;cacheLVM.jpg&#xA;&#xA;Quando si crea una cache ho due possibilità a seconda che si voglia massimizzare velocità o affidabilità:&#xA;&#xA;writethrough: Le operazioni di scrittura vengono inviate sia alla cache SSD che all&#39;Origin HDD. La lettura avviene preferibilmente dalla cache.&#xA;È la modalità più sicura. Se l&#39;SSD muore, nessun dato va perso ma è meno efficiente in scrittura perché Origin HDD diventa il collo di bottiglia,&#xA;writeback: più veloce ma meno sicuro. Le scritture vengono salvate immediatamente sulla cache veloce e sincronizzate sull&#39;HDD in background in un secondo momento. Se si dovesse rompere il disco di cache, c&#39;è il rischio di una perdita di dati.&#xA;&#xA;Il dimensionamento della cache è proporzionale alla dimensione del disco origin.&#xA;Di solito si aggira in un range del 2-10%&#xA;&#xA;2%: archiviazione sequenziale, file di grandi dimensioni;&#xA;5%: standard consigliato. File server generico, utilizzo desktop/workstation;&#xA;10%: carichi di lavoro intensivi e casuali come database SQL/NoSQL attivi, nodi di virtualizzazione densi (molte VM), ecc.&#xA;&#xA;Non è necessario prevedere da subito Il disco di cache (se c&#39;è stata la possibilità tanto meglio), ma si può aggiungere in un secondo momento estendendo il gruppo di volumi contenente l&#39;HDD e battezzando l&#39;LV di cache.&#xA;&#xA;Perpariamo il nostro laboratorio in cui abbiamo un HD lento con un unico volume logico a cui applichiamo una cache.&#xA;&#xA;disco lento: 2 GiB&#xA;disco veloce: 500 MiB&#xA;cache: 5% di 2 GiB (~100 MiB)&#xA;&#xA;creazione del device fisico per il laboratorio&#xA;fallocate -l 2GiB slowdisk.img&#xA;&#xA;attach del device e creazione del gruppo di volumi&#xA;vgcreate vglab $(losetup -Pf --show slowdisk.img)&#xA;&#xA;creazione e formattazione dell&#39;unico volume logico&#xA;lvcreate -n lvorigin vglab -l 100%FREE&#xA;mkfs.ext4 /dev/vglab/lvorigin&#xA;Ora aggiungiamo il disco che farà da cache estendendo il gruppo di volumi:&#xA;creazione del device fisico di cache per il laboratorio&#xA;fallocate -l 500MiB fastdisk.img&#xA;&#xA;attach del dispositivo e estensione del gruppo di volumi&#xA;DEVFAST=$(losetup -Pf --show fastdisk.img)&#xA;vgextend vglab &#34;${DEVFAST}&#34;&#xA;Il cache pool lv può essere configurato automaticamente oppure manualente.&#xA;4.1. Caso 1: configurazione automatica del cache pool lv&#xA;In un unico passaggio, convertiamo il volume logico attuale in un volume logico con cache.&#xA;lvcreate \&#xA;  --type cache \&#xA;  --cachemode writethrough \&#xA;  -l 5%FREE \&#xA;  -n cachepool vglab/lvorigin &#34;${DEVFAST}&#34;&#xA;Dopo questo comando vedremo che il volume logico lv\origin incapsula il cache pool (lv\origincache\cpool) e il volume logico dei dati (lv\origin\corig).&#xA;&#xA;Il cache pool è composto da due volumi logici per i dati (lv\origincache\cpool\cdata) e i metadati (lv\origincache\cpool\cmeta).&#xA;&#xA;Infine distinguiamo anche il volume logico di metadati spare da utilizzare per un eventuale data recovery failure (lvol0\pmspare).&#xA;lvs -a&#xA;  LV                           VG        Attr       LSize   Pool                   Origin            Data%  Meta%  Move Log Cpy%Sync Convert&#xA;  home                         vgfedora -wi-ao---- 409,81g                                                           &#xA;  root                         vgfedora -wi-ao----  50,00g                                                           &#xA;  swap                         vgfedora -wi-ao----  16,00g                                                           &#xA;  lvorigin                    vglab    Cwi-a-C---  &lt;2,00g [lvorigincachecpool] [lvorigincorig] 0,00   0,59            0,00&#xA;  [lvorigincorig]            vglab    owi-aoC---  &lt;2,00g                                                           &#xA;  [lvorigincachecpool]       vglab    Cwi---C---   8,00m                                          0,00   0,59            0,00&#xA;  [lvorigincachecpoolcdata] vglab    Cwi-ao----   8,00m                                                           &#xA;  [lvorigincachecpoolcmeta] vglab    ewi-ao----   8,00m                                                           &#xA;  [lvol0pmspare]              vglab    ewi-------   8,00m &#xA;&#xA;4.2. Caso 2: configurazione manuale del cache pool lv&#xA;Se invece vogliamo intervenire su ogni singolo passaggio della creazione del cache pool:&#xA;creazione dei volumi logici meta e dati per il cache pool&#xA;lvcreate -n cachepoolmeta -L 10M vglab &#34;${DEVFAST}&#34;&#xA;lvcreate -n cachepool -l 5%FREE vglab &#34;${DEVFAST}&#34;&#xA;&#xA;creazione del cache pool assemblando meta e data&#xA;lvconvert \&#xA;  --type cache-pool \&#xA;  --cachemode writethrough \&#xA;  --poolmetadata vglab/cachepoolmeta vglab/cachepool&#xA;&#xA;conversione del volume logico origin nel nuovo volume logico con cache&#xA;lvconvert \&#xA;  --type cache \&#xA;  --cachepool vglab/cachepool vglab/lvorigin&#xA;In realtà è meglio lasciare a LVM il compito di dimensionare correttamente il volume per i metadati.&#xA;creazione della cache pool&#xA;lvcreate --type cache-pool -l 5%FREE -n cachecpool vglab &#34;${DEVFAST}&#34;&#xA;&#xA;conversione del volume logico originale in un volume logico con cache&#xA;lvconvert \&#xA;  --type cache \&#xA;  --cachepool vglab/cachecpool vglab/lvorigin&#xA;4.3. Switch della modalità&#xA;Per cambiare modalità fra writetrough e writeback (se non specificato nella definizione della cache pool, il default è writethrough).&#xA;lvchange --cachemode writeback vglab/lvorigin&#xA;4.4. Rimozione della cache&#xA;Se volessi levare il disco di cache e ritornare al volume logico di partenza:&#xA;lvconvert --uncache vglab/lvorigin&#xA;  Logical volume &#34;lvorigincachecpool&#34; successfully removed.&#xA;  Logical volume vglab/lvorigin is not cached.&#xA;e lvs -a mostra il volume logico in queste condizioni:&#xA;lvs -a&#xA;  LV        VG        Attr       LSize   Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert&#xA;  lvorigin vglab    -wi-a-----  &lt;2,00g&#xA;4.5. Monitoraggio&#xA;lvs -a -o lvname,lvsize,cachemode,datapercent,metadatapercent vglab&#xA;5. LVM Stripe&#xA;Analogo a Raid 0, l&#39;uso diretto di stripe in lvm  attraverso il mappatore interno dm-stripe, permette di definire su quali e quanti dischi va frammentata l&#39;informazione da memorizzare allo scopo di aumentare le prestazioni.&#xA;&#xA;Considerazioni:&#xA;&#xA;Il gruppo di volumi deve contenere almeno due dischi fisici.&#xA;È preferibile che i dischi fisici abbiano tutti la stessa velocità altrimenti quello più lento diventerà il collo di bottiglia.&#xA;È possibile che i &lt; n, dove i è il numero di dischi per  lo stripe e n è il numero totale di dischi del gruppo di volumi&#xA;È anche possibile specificare i dischi va applicato lo stripe.&#xA;La dimensione dello stripe è di 64K come default. Ma per file molto grandi, video o database, la dimensione può essere anche di 128K o 256K&#xA;&#xA;creazione di un gruppo di volumi con 3 dischi&#xA;vgcreate vglab /dev/sdb /dev/sdc /dev/sdd&#xA;&#xA;stripe su due dischi a caso di vglab&#xA;lvcreate -i 2 -I 64k -L 10G -n lvstripe vglab&#xA;&#xA;stripe su tutti i dischi di vglab&#xA;lvcreate -i 3 -I 64k -L 10G -n lvstripe vglab&#xA;&#xA;stripe sui dischi sdc e sdd con uno stripe size di 128K&#xA;lvcreate -i 2 -I 128k -L 10G -n lvstripe vglab /dev/sdc /dev/sdd&#xA;Come ogni raid 0, massime prestazioni e sicurezza 0. Se un disco si rompe, addio ai dati.&#xA;6. LVM Mirror&#xA;Come per lvm stripe analogo a raid 0, il mirror in lvm tramite il mappatore interno dm-mirror, è assimiliabile a raid 1.&#xA;&#xA;Come ogni raid 1 che si rispetti, il chiaro vantaggio di questo approccio è proprio la ridondanza dei dati che, al costo del sacrificio di un disco, permette di correre ai ripari se uno dei dischi si danneggia.&#xA;creazione di un gruppo di volumi con 2 dischi&#xA;vgcreate vglab /dev/sdb /dev/sdc&#xA;&#xA;creazione del volume logico &#34;mirror&#34;&#xA;lvcreate -m 1 -L 10G -n lvmirror vglab&#xA;Il mirror diretto attraverso LVM in realtà è considerato legacy. Si consiglia di usare l&#39;approccio più moderno che prevede di specificare il tipo, raid x, nell&#39;invocazione di lvcreate perché userà il modulo specializzato del kernel per il raid software.&#xA;&#xA;LVM mirror infatti pur essendo funzionalmente equivalente ad un raid 1 non è altrettanto efficace perché si basa su un log di sincronizzazione dove lvm tiene traccia degli elementi allineati.&#xA;&#xA;Tale log deve stare su un altro disco (che diventa un altro punto di vulnerabilità) e quando c&#39;è bisogno di ricostruire l&#39;array in caso di rottura di un disco, l&#39;operazione è molto lenta.&#xA;7. LVM Raid&#xA;Il raid lvm è un modo per prendere il meglio dei due mondi.&#xA;&#xA;Non è che LVM abbia una sua implementazione del raid.&#xA;Il raid &#34;tradizionale&#34; si basa sul sottosistema Multiple Devices del kernel e lavora direttamente sui dispositivi a blocchi.&#xA;&#xA;LVM si interfaccia direttamente con il modulo md del kernel per attingere alle funzioni di raid così da offrire, attraverso device mapper, un&#39;interfaccia unica per la gestione dei volumi e del raid.&#xA;7.1. Raid 0 (Stripe)&#xA;lvcreate --type raid0 -i 2 -I 64k -L 10G -n lvraid0 vglab&#xA;A differenza del mirror, non ci sono gli stessi problemi per stripe. Il mappatore nativo di LVM, dm-stripe, fa bene il suo lavoro.&#xA;&#xA;Usare lvmraid in questo caso resta vantaggioso per ragioni di coerenza. L&#39;uso del modulo md rende possibile un&#39;eventuale evoluzione verso livelli superiori (come RAID 1 o RAID 5).&#xA;7.2. Raid 1 (Mirroring)&#xA;L&#39;alternativa moderna al vecchio lvm mirror che risolve i suoi problemi di efficienza usando il modulo md.&#xA;&#xA;Basandoci sull&#39;esempio di prima:&#xA;lvcreate --type raid1 -m 1 -L 10G -n lvraid1 vglab&#xA;7.3. Raid 5 (Stripe con parità singola)&#xA;Creiamo un volume logico con RAID 5 basato su 4 dischi (stripe su 3 dischi e uno per la parità):&#xA;creazione di un gruppo di volumi con 4 dischi&#xA;vgcreate vglab /dev/sdb /dev/sdc /dev/sdd /dev/sde&#xA;&#xA;creazione del volume logico con RAID 5&#xA;lvcreate --type raid5 -i 3 -L 10G -n lvraid5 vglab&#xA;7.4. Raid 6 (Stripe con parità doppia)&#xA;Se vogliamo una parità doppia su 4 dischi (2 stripe e due di parità);&#xA;creazione di un gruppo di volumi con 4 dischi&#xA;vgcreate vglab /dev/sdb /dev/sdc /dev/sdd /dev/sde&#xA;&#xA;creazione del volume logico con RAID 5&#xA;lvcreate --type raid6 -i 2 -L 10G -n lvraid6 vglab&#xA;7.5. Raid 10&#xA;E veniamo al RAID 1+0, uno stripe su n array in mirror per combinare l&#39;efficienza dello stripe con la sicurezza del mirror:&#xA;creazione di un gruppo di volumi con 4 dischi&#xA;vgcreate vglab /dev/sdb /dev/sdc /dev/sdd /dev/sde&#xA;&#xA;creazione del volume logico con RAID 5&#xA;lvcreate --type raid10 -i 2 -m 1 -L 10G -n lvraid10 vglab&#xA;7.6. Come monitorare il raid&#xA;Metodo rapido:&#xA;lvs -o name,vgname,copypercent,lvattr,raidhealthstatus,devices vglab&#xA;&#xA;Combinandolo con watch posso vedere per es. la percentuale &#xA;di completamento della copia in caso di sostituzione del disco&#xA;watch -n 1 lvs -o name,vgname,copypercent,lvattr,raidhealthstatus,devices vglab&#xA;Metodo dettagliato:&#xA;lvdisplay vglab/lvraid5&#xA;Monitoraggio a basso livello:&#xA;Balamente, visto che viene usato il modulo md:&#xA;cat /proc/mdstat&#xA;7.7. Come intervenire in caso di guasto&#xA;Con lvs vedremo che lo stato del volume è diventato degraded.&#xA;Con pvpdisplay possiamo individuare il device danneggiato che comparirà come unknown device o con un sacco di errori I/O .&#xA;&#xA;Dopo aver estratto il disco e messo quello nuovo, supponendo sia /dev/sdc, procediamo con la ricostruzione dell&#39;array:&#xA;inizializzazione nuovo disco&#xA;pvcreate /dev/sdc&#xA;&#xA;aggiunta del nuovo disco al gruppo&#xA;vgextend vglab /dev/sdc&#xA;&#xA;array rebuild&#xA;lvconvert --repair vglab/lvraid5&#xA;&#xA;rimozione disco danneggiato dal gruppo di volumi&#xA;vgreduce --removemissing vglab&#xA;#lvm #dm #devicemapper #md #multipledevices #snapshot #thinpool #thinprovisioning #cachepool #raid #lvmraid]]&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://pixelfed.uno/storage/m/_v2/489827599091373610/0d402c64b-2701fc/8LVsevJUK9RB/pIGAWHQBQQtrEFdtoftvYLD9uFIUaLRrpYrDYhz0.jpg" alt="lvm plus">
Oltre che alla grande flessibilità nella gestione dei volumi, LVM attraverso <strong>device mapper</strong>, aggiunge tutta una serie di ulteriori capacità che rendono questa tecnologia estremamente versatile.</p>

<p>La possibilità di disporre di meccanismi per la gestione di snapshot, cache pool. thin provisioning e raid, rendono LVM qualcosa di più di un gestore di volumi.
</p>
<ul><li><a href="#1-snapshot" rel="nofollow">1. Snapshot</a>
<ul><li><a href="#1-1-attenzione-dimensione-della-snapshot" rel="nofollow">1.1. Attenzione: Dimensione della snapshot</a></li>
<li><a href="#1-2-esempio" rel="nofollow">1.2. Esempio</a></li></ul></li>
<li><a href="#2-thin-pool" rel="nofollow">2. Thin Pool</a></li>
<li><a href="#3-thin-pool-e-snapshot" rel="nofollow">3. Thin Pool e snapshot</a></li>
<li><a href="#4-cache-pool" rel="nofollow">4. Cache Pool</a>
<ul><li><a href="#4-1-caso-1-configurazione-automatica-del-cache-pool-lv" rel="nofollow">4.1. Caso 1: configurazione automatica del cache pool lv</a></li>
<li><a href="#4-2-caso-2-configurazione-manuale-del-cache-pool-lv" rel="nofollow">4.2. Caso 2: configurazione manuale del cache pool lv</a></li>
<li><a href="#4-3-switch-della-modalit%C3%A0" rel="nofollow">4.3. Switch della modalità</a></li>
<li><a href="#4-4-rimozione-della-cache" rel="nofollow">4.4. Rimozione della cache</a></li>
<li><a href="#4-5-monitoraggio" rel="nofollow">4.5. Monitoraggio</a></li></ul></li>
<li><a href="#5-lvm-stripe" rel="nofollow">5. LVM Stripe</a></li>
<li><a href="#6-lvm-mirror" rel="nofollow">6. LVM Mirror</a></li>
<li><a href="#7-lvm-raid" rel="nofollow">7. LVM Raid</a>
<ul><li><a href="#7-1-raid-0-stripe" rel="nofollow">7.1. Raid 0 (Stripe)</a></li>
<li><a href="#7-2-raid-1-mirroring" rel="nofollow">7.2. Raid 1 (Mirroring)</a></li>
<li><a href="#7-3-raid-5-stripe-con-parit%C3%A0-singola" rel="nofollow">7.3. Raid 5 (Stripe con parità singola)</a></li>
<li><a href="#7-4-raid-6-stripe-con-parit%C3%A0-doppia" rel="nofollow">7.4. Raid 6 (Stripe con parità doppia)</a></li>
<li><a href="#7-5-raid-10" rel="nofollow">7.5. Raid 10</a></li>
<li><a href="#7-6-come-monitorare-il-raid" rel="nofollow">7.6. Come monitorare il raid</a></li>
<li><a href="#7-7-come-intervenire-in-caso-di-guasto" rel="nofollow">7.7. Come intervenire in caso di guasto</a></li></ul></li></ul>

<h2 id="1-snapshot">1. Snapshot</h2>

<p>Le snapshot LVM usano la tecnica del <strong>C</strong>opy-<strong>o</strong>n-<strong>W</strong>rite (<strong>CoW</strong>) allo scopo di ridurre la duplicazione.</p>

<p>La snapshot dovrà essre la fotografia del volume prima all&#39;origine.</p>

<p>Ad ogni modifica / cancellazione, il file originale verrà portato sulla snapshot prima dell&#39;operazione.
Sul volume originale verranno scritti tutti i dati nuovi e quelli modificati.</p>

<p>Per il <strong>ripristino</strong>, si effettua quello che si chiama <strong>merge</strong>, dove i dati vecchi vengono ripristinati dalla snapshot e quelli nuovi cancellati dal volume.</p>

<p>Per il consolidamento delle modifiche, basterò rimuovere la snapshot,</p>

<h3 id="1-1-attenzione-dimensione-della-snapshot">1.1. Attenzione: Dimensione della snapshot</h3>

<p>Se la snapshot ha la stessa dimensione del volume logico non ci sono problemi.</p>

<p>Se è più piccola, occorre prestare attenzione a che la quantità dei dati modificati sul volume logico non superino la dimensione della snapshot.</p>

<p>In questo caso infatti la snapshot risulterà inutilizzabile e non potrà più essere usata per il ripristino ma potrà essree solo rimossa.</p>

<h3 id="1-2-esempio">1.2. Esempio</h3>

<p>Supponiamo di avere un gruppo di volumi, <strong>my_vg</strong>, composto da 3 volumi logici:</p>
<ul><li><strong>lv_root</strong> (30 GiB)</li>
<li><strong>lv_home</strong> (200 GiB)</li>
<li><strong>lv_dati</strong> (500 GiB)</li></ul>

<p>e di voler creare una snapshot precauzionale sulla root (supponendo di avere spazio a sufficienza altrimenti dovrò fare bene i miei conti per non riempire oltremisura la snapshot rendendola inservibile).</p>

<p><strong>Creazione snapshot</strong></p>

<pre><code class="language-bash">lvcreate -s -L 30G -n  lv_root_snap my_vg/snap
</code></pre>

<p><strong>Ripristino</strong></p>

<pre><code class="language-bash">umount /dev/my_vg/lv_root
lvconvert --merge my_vg/snap
</code></pre>

<p><strong>Consolidamento</strong></p>

<pre><code class="language-bash">lvremove snap
</code></pre>

<h2 id="2-thin-pool">2. Thin Pool</h2>

<p>Il <strong>thin provisioning</strong> di LVM è l&#39;alternativa dinamica alla classica gestione di volumi, <strong>thick</strong>, che prevede l&#39;assegnazione statica delle dimensioni dei volumi.</p>

<p>Se è vero che il <strong>thick provisioning</strong> risulta comunque abbastastanza agevole per via della flessibilità intrinseca dei volumi in caso di riduzione o aumento della superficie allocabile, il <strong>thin provisioning</strong> può aumentare i vantaggi derivanti da LVM in alcuni scenari.</p>

<p>Il thin provisioning si basa sul principio che lo spazio assegnato ai volumi non viene usato mai completamente e mai tutto in una volta.</p>

<p>Ecco perché un&#39;allocazione dinamica ci permetterebbe di definire volumi che si riempiono <strong>solo</strong> man mano che lo spazio viene occupato.</p>

<p>Se si opta per un thin provisioning sarebbe opportuno non usare tutto il gruppo di volumi ma lasciarne un 20% in previsione di future espansioni.</p>

<p>Con i thin pool non solo abbiamo la stessa flessibilità della gestione thick, ma possiamo lavorare anche in <strong>over provisioning</strong> ossia creare pool di volumi la cui somma potenziale sia superiore allo spazio realmente allocabile.</p>

<p>Es. Supponiamo avere un device da 100 GiB, <code>/dev/sdb</code>, su cui definisco un volume group e creare un thin pool di 50 GiB. Su questo thin pool creeremo 3 volumi “virtuali” da 20, 30 e 20 GiB.</p>

<pre><code class="language-bash"># creazione volume group di 100 GiB
vgcreate vg_lab /dev/sdb

# creazione thin pool da 50 GiB
lvcreate -L 50G --thinpool vg_lab/lv_tp

# creazione dei 3 volumi virtuali in &#34;over provisioning&#34; 
lvcreate -V 20G --thin -n vol1_virt --thinpool vg_lab/lv_tp
lvcreate -V 30G --thin -n vol2_virt --thinpool vg_lab/lv_tp
lvcreate -V 20G --thin -n vol3_virt --thinpool vg_lab/lv_tp
</code></pre>

<p>Una volta creati i volumi possono essere formattati e montati come di consueto.</p>

<p>Lo spazio effettivamente occupato è quasi nullo, il sistema solleverà solo un warning per avvertirci che i volumi virtuali rischiano di saturare lo spazio disponibile.</p>

<p>Ecco perché bisogna prestare attenzione al raggiungimento della soglia critica.
Bisognerà estendere subito il thin pool ed i volumi virtuali nel <a href="https://cyberdynesystem.wordpress.com/2026/04/21/ridimensionare-volumi-lvm/#step-4-estendere-il-volume-logico" rel="nofollow">modo consueto</a>.</p>

<p>⚠️⚠️⚠️ <strong>ATTENZIONE</strong> ⚠️⚠️⚠️
L&#39;estensione di un volume virtuale non differisce molto da quello di un volume “classico”.
Se lo spazio per le fette si sta esaurendo, si estendono nell&#39;ordine:</p>
<ol><li>il gruppo di volumi (se necessario)</li>
<li>il thin pool (se nel volume group c&#39;è spazio a sufficienza)</li>
<li>i volumi virtuali</li>
<li>i filesystem</li></ol>

<p>Se non siamo con l&#39;acqua alla gola, i punti 3 e 4 sono sufficienti. L&#39;estensione del volume virtuale è più rapida di quella classica perché non viene allocato spazio.
L&#39;estensione di un volume logico classico corrisponde all&#39;estensione del thin pool.</p>

<p>Nel caso di riduzione, la situazione cambia parecchio perché la riduzione di un volume virtuale non fa guadagnare spazio allocabile visto che l&#39;ampiezza del volume è solo teorica, ciò avviene solo con <code>fstrim</code>.
Inoltre accorciando il volume virtuale al di sotto dei dati effettivamente scritti, si rischia di corrompere l&#39;intero filesystem.
<strong>Consiglio spassionato:</strong> ESTENDI SEMPRE E NON RIDURRE MAI!!!</p>

<p>Altra considerazione va fatta anche per i metadati.</p>

<p>A differenza dell&#39;LVM classico dove la creazione di un volume logico necessitava di un extent per i metadati, il thin provisioning di LVM riserva un volume logico per i dati e un volume logico per i metadati.</p>

<p>L&#39;estensione continua di piccole fette, può riempire il volume dei metadati col rischio di corrompere l&#39;intero thin pool e prima che succeda, anche il volume dei metadati può dover essere esteso.</p>

<pre><code class="language-bash">lvextend --poolmetadatasize +1G vg_lab/lv_tp
</code></pre>

<h2 id="3-thin-pool-e-snapshot">3. Thin Pool e snapshot</h2>

<p>Un altro bel vantaggio della modalità thin pool è quello di facilitare l&#39;uso delle snapshot.</p>

<p>Trattandosi di volumi virtuali, la dimensione della snapshot non ha bisogno di essere dichiarata. La creazione di snapshot è estremamente semplice.</p>

<pre><code class="language-bash"># creazione di una snapshot
lvcreate -s -n lv_snap vg_lab/vol_virt
</code></pre>

<p>Come pure sia la creazione di snapshot annidate che il rollback risultano molto più semplici ed efficienti.</p>

<pre><code class="language-bash"># creazione di una snapshot
lvcreate -s -n lv_snap1 vg_lab/vol_virt

# creazione di una snapshot annidata
lvcreate -s -n lv_snap2 vg_lab/lv_snap1

# rollback
umount vol_1
lvconvert --merge vg_lab/lv_snap2
mount -t ext4 -o defaults /dev/vg_lab/vol_virt vol_1
</code></pre>

<p>E a proposito di snapshot, occorre fare qualche osservazione.</p>

<p>Una serie di snapshot thin annidate, non è una catena di patch incrementali esposte al filesystem come si potrebbe pensare.
In virtù del CoW, la snapshot annidate fotograferanno sempre lo stesso istante: quello del file system all&#39;origine.</p>

<p>Facciamo un esempio:</p>

<pre><code class="language-bash">lvcreate -V 10g -T vgtest/thinpool -n vmroot
mkfs.ext4 /dev/vgtest/vmroot
mount /dev/vgtest/vmroot /mnt/test
echo ORIGINAL &gt; /mnt/test/file.txt
umount test

lvcreate -s -n snap1 vgtest/vmroot

mount /dev/vgtest/vmroot /mnt/test
echo MOD1 &gt; /mnt/test/file.txt
umount /mnt/test

lvcreate -s -n snap2 vgtest/snap1

mount /dev/vgtest/vmroot /mnt/test
echo MOD2 &gt; /mnt/test/file.txt
umount /mnt/test

lvcreate -s -n snap3 vgtest/snap2

mount /dev/vgtest/vmroot /mnt/test
echo MOD3 &gt; /mnt/test/file.txt
umount /mnt/test
</code></pre>

<p>In questo esempio creo un volume virtuale, <code>vmroot</code>, e 3 snap annidate.</p>
<ol><li>Monto il volume virtuale.</li>
<li>La prima snapshot, <code>snap1</code>, fotografa il file system del volume virtuale che contiene il file con “ORIGINAL”.</li>
<li>Il volume virtuale viene montato e il file viene modificato.</li>
<li>La seconda snapshot, <code>snap2</code>, fotografa <code>snap1</code> che <strong>a sua volta conteneva il file system del volume virtuale che contiene il file con “ORIGINAL”</strong>.</li>
<li>Il volume virtuale viene montato e il file viene modificato.</li>
<li>La terza snapshot, <code>snap3</code>, fotografa <code>snap2</code> che <strong>a sua volta conteneva snap1.. ecc.</strong></li></ol>

<p>Quindi snapshot siffatte non realizzano un versioning del file system come si potrebbe pensare, piuttosto possono essere utili per creare alberi di cloni/read-only, ambienti temporanei derivati da uno stato consistente, ecc.</p>

<p>In sostanza tornano utili quando ho una base da cui faccio derivare <em>n</em> snapshot che condividono i blocchi comune e con CoW minimizzo lo spazio.</p>

<p>Il merge di una qualunque snapshot ricondurrà il file system allo stato originario.</p>

<pre><code>origin
 ├── snap1
 ├── snap2
 ├── snap3
</code></pre>

<p>Per lavorare sul delta come immaginiamo, si dovranno montare via via le snapshop, non il volume virtuale, e modificare quelle.</p>

<pre><code class="language-bash">lvcreate -V 10g -T vgtest/thinpool -n vmroot
mkfs.ext4 /dev/vgtest/vmroot
mount /dev/vgtest/vmroot /mnt/test
echo ORIGINAL &gt; /mnt/test/file.txt
umount /mnt/test

lvcreate -s -n snap1 vgtest/vmroot

lvchange -ay -K vgtest/snap1
mount /dev/vgtest/snap1 /mnt/test
echo MOD1 &gt; /mnt/test/file.txt
umount /mnt/test

lvcreate -s -n snap2 vgtest/snap1

lvchange -ay -K vgtest/snap2
mount /dev/vgtest/snap2 /mnt/test
echo MOD2 &gt; /mnt/test/file.txt
umount /mnt/test

lvcreate -s -n snap3 vgtest/snap2

lvchange -ay -K vgtest/snap3
mount /dev/vgtest/snap3 /mnt/test
echo MOD3 &gt; /mnt/test/file.txt
umount /mnt/test
</code></pre>

<p>In questo modo si “inverte” la logica del merge che, prima riconduceva il file system allo stato inizale, ora invece consolida le modifiche delle snapshot</p>

<pre><code>origin
 └── snap1
      └── snap2
           └── snap3
</code></pre>

<p>Il merge va fatto in ordine se si vogliono acquisire correttamente i delta.
Tuttavia questo approccio</p>
<ul><li>è raro</li>
<li>è difficile da gestire</li>
<li>complica i merge</li>
<li>può creare dependency tree intricati</li></ul>

<p>Per questo quasi tutti:</p>
<ul><li>snapshot sempre dell’origin</li>
<li>mai snapshot di snapshot</li>
<li>rollback lineare</li></ul>

<h2 id="4-cache-pool">4. Cache Pool</h2>

<p>Il cache pool di LVM serve a migliorare l&#39;accesso a dispositivi tradizionalmente lenti e lo fa combinando dischi  HDD con SSD/NVMe.</p>

<p>In sostanza avremo un gruppo di volumi costituito dai dischi HDD e un altro gruppo di volumi costituito dai dischi SDD/NVMe, la nostra cache.</p>

<p>Il <strong>Logical Volume Cache</strong> sul disco veloce migliora l&#39;accesso ad uno specifico volume logico del disco lento e prevede il ricorso a tutta una serie di tipi di volumi logici abbastanza variegata:</p>
<ul><li><strong>Origin LV</strong>: volume logico orignale costituito dai dischi lenti</li>
<li><strong>Cache pool LV</strong>: volume logico composto  a sua volta da altri due voumi logici: dati della cache e metadati della cache
<ul><li><strong>Cache data LV</strong>: volume logico contenente i <strong>blocchi di dati</strong> per il <strong>Cache pool LV</strong>.</li>
<li><strong>Cache metadata LV</strong>: volume logico contenente i <strong>metadatati</strong> per il <strong>Cache pool LV</strong>.</li></ul></li>
<li><strong>Cache LV</strong>: volume logico contenente l&#39;<strong>Origin LV</strong> e Il <strong>Cache pool LV</strong>. È il volume realemente utilizzabile</li>
<li><strong>Spare metadata LV</strong>: volume logico correlato ad una funzione di recovery data failure</li></ul>

<p><img src="https://pixelfed.uno/storage/m/_v2/489827599091373610/0d402c64b-2701fc/ghjmK6oYuYls/Zt6F2X7EaV5JxGJ3ZsvML0XgUmFAPWjrC4BlHSAA.jpg" alt="cacheLVM.jpg"></p>

<p>Quando si crea una cache ho due possibilità a seconda che si voglia massimizzare velocità o affidabilità:</p>
<ul><li><strong>writethrough</strong>: Le operazioni di scrittura vengono inviate sia alla cache SSD che all&#39;Origin HDD. La lettura avviene preferibilmente dalla cache.
È la modalità più sicura. Se l&#39;SSD muore, nessun dato va perso ma è meno efficiente in scrittura perché Origin HDD diventa il collo di bottiglia,</li>
<li><strong>writeback</strong>: più veloce ma meno sicuro. Le scritture vengono salvate immediatamente sulla cache veloce e sincronizzate sull&#39;HDD in background in un secondo momento. Se si dovesse rompere il disco di cache, c&#39;è il rischio di una perdita di dati.</li></ul>

<p>Il dimensionamento della cache è proporzionale alla dimensione del disco origin.
Di solito si aggira in un range del 2-10%</p>
<ul><li>2%: archiviazione sequenziale, file di grandi dimensioni;</li>
<li>5%: <strong>standard consigliato</strong>. File server generico, utilizzo desktop/workstation;</li>
<li>10%: carichi di lavoro intensivi e casuali come database SQL/NoSQL attivi, nodi di virtualizzazione densi (molte VM), ecc.</li></ul>

<p>Non è necessario prevedere da subito Il disco di cache (se c&#39;è stata la possibilità tanto meglio), ma si può aggiungere in un secondo momento estendendo il gruppo di volumi contenente l&#39;HDD e battezzando l&#39;LV di cache.</p>

<p>Perpariamo il nostro laboratorio in cui abbiamo un HD lento con un unico volume logico a cui applichiamo una cache.</p>
<ul><li>disco lento: 2 GiB</li>
<li>disco veloce: 500 MiB</li>
<li>cache: 5% di 2 GiB (~100 MiB)</li></ul>

<pre><code class="language-bash"># creazione del device fisico per il laboratorio
fallocate -l 2GiB slow_disk.img

# attach del device e creazione del gruppo di volumi
vgcreate vg_lab $(losetup -Pf --show slow_disk.img)

# creazione e formattazione dell&#39;unico volume logico
lvcreate -n lv_origin vg_lab -l 100%FREE
mkfs.ext4 /dev/vg_lab/lv_origin
</code></pre>

<p>Ora aggiungiamo il disco che farà da cache estendendo il gruppo di volumi:</p>

<pre><code class="language-bash"># creazione del device fisico di cache per il laboratorio
fallocate -l 500MiB fast_disk.img

# attach del dispositivo e estensione del gruppo di volumi
DEV_FAST=$(losetup -Pf --show fast_disk.img)
vgextend vg_lab &#34;${DEV_FAST}&#34;
</code></pre>

<p>Il cache pool lv può essere configurato automaticamente oppure manualente.</p>

<h3 id="4-1-caso-1-configurazione-automatica-del-cache-pool-lv">4.1. Caso 1: configurazione automatica del cache pool lv</h3>

<p>In un unico passaggio, convertiamo il volume logico attuale in un volume logico con cache.</p>

<pre><code class="language-bash">lvcreate \
  --type cache \
  --cachemode writethrough \
  -l 5%FREE \
  -n cache_pool vg_lab/lv_origin &#34;${DEV_FAST}&#34;
</code></pre>

<p>Dopo questo comando vedremo che il volume logico <strong>lv_origin</strong> incapsula il cache pool (<strong>lv_origincache_cpool</strong>) e il volume logico dei dati (<strong>lv_origin_corig</strong>).</p>

<p>Il cache pool è composto da due volumi logici per i dati (<strong>lv_origincache_cpool_cdata</strong>) e i metadati (<strong>lv_origincache_cpool_cmeta</strong>).</p>

<p>Infine distinguiamo anche il volume logico di metadati spare da utilizzare per un eventuale data recovery failure (<strong>lvol0_pmspare</strong>).</p>

<pre><code class="language-bash">lvs -a
  LV                           VG        Attr       LSize   Pool                   Origin            Data%  Meta%  Move Log Cpy%Sync Convert
  home                         vg_fedora -wi-ao---- 409,81g                                                           
  root                         vg_fedora -wi-ao----  50,00g                                                           
  swap                         vg_fedora -wi-ao----  16,00g                                                           
  lv_origin                    vg_lab    Cwi-a-C---  &lt;2,00g [lv_origincache_cpool] [lv_origin_corig] 0,00   0,59            0,00
  [lv_origin_corig]            vg_lab    owi-aoC---  &lt;2,00g                                                           
  [lv_origincache_cpool]       vg_lab    Cwi---C---   8,00m                                          0,00   0,59            0,00
  [lv_origincache_cpool_cdata] vg_lab    Cwi-ao----   8,00m                                                           
  [lv_origincache_cpool_cmeta] vg_lab    ewi-ao----   8,00m                                                           
  [lvol0_pmspare]              vg_lab    ewi-------   8,00m 

</code></pre>

<h3 id="4-2-caso-2-configurazione-manuale-del-cache-pool-lv">4.2. Caso 2: configurazione manuale del cache pool lv</h3>

<p>Se invece vogliamo intervenire su ogni singolo passaggio della creazione del cache pool:</p>

<pre><code class="language-bash"># creazione dei volumi logici meta e dati per il cache pool
lvcreate -n cache_pool_meta -L 10M vg_lab &#34;${DEV_FAST}&#34;
lvcreate -n cache_pool -l 5%FREE vg_lab &#34;${DEV_FAST}&#34;

# creazione del cache pool assemblando meta e data
lvconvert \
  --type cache-pool \
  --cachemode writethrough \
  --poolmetadata vg_lab/cache_pool_meta vg_lab/cache_pool

# conversione del volume logico origin nel nuovo volume logico con cache
lvconvert \
  --type cache \
  --cachepool vg_lab/cache_pool vg_lab/lv_origin
</code></pre>

<p>In realtà è meglio lasciare a LVM il compito di dimensionare correttamente il volume per i metadati.</p>

<pre><code class="language-bash"># creazione della cache pool
lvcreate --type cache-pool -l 5%FREE -n cache_cpool vg_lab &#34;${DEV_FAST}&#34;

# conversione del volume logico originale in un volume logico con cache
lvconvert \
  --type cache \
  --cachepool vg_lab/cache_cpool vg_lab/lv_origin
</code></pre>

<h3 id="4-3-switch-della-modalità">4.3. Switch della modalità</h3>

<p>Per cambiare modalità fra <strong>writetrough</strong> e <strong>writeback</strong> (se non specificato nella definizione della cache pool, il default è <strong>writethrough</strong>).</p>

<pre><code class="language-bash">lvchange --cachemode writeback vg_lab/lv_origin
</code></pre>

<h3 id="4-4-rimozione-della-cache">4.4. Rimozione della cache</h3>

<p>Se volessi levare il disco di cache e ritornare al volume logico di partenza:</p>

<pre><code class="language-bash">lvconvert --uncache vg_lab/lv_origin
  Logical volume &#34;lv_origincache_cpool&#34; successfully removed.
  Logical volume vg_lab/lv_origin is not cached.
```https://noblogo.org/ebdpsbxxid/edit#publish
e `lvs -a` mostra il volume logico in queste condizioni:
```bash
lvs -a
  LV        VG        Attr       LSize   Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  lv_origin vg_lab    -wi-a-----  &lt;2,00g
</code></pre>

<h3 id="4-5-monitoraggio">4.5. Monitoraggio</h3>

<pre><code class="language-bash">lvs -a -o lv_name,lv_size,cache_mode,data_percent,metadata_percent vg_lab
</code></pre>

<h2 id="5-lvm-stripe">5. LVM Stripe</h2>

<p>Analogo a <strong>Raid 0</strong>, l&#39;uso diretto di stripe in lvm  attraverso il mappatore interno <strong>dm-stripe</strong>, permette di definire su quali e quanti dischi va frammentata l&#39;informazione da memorizzare allo scopo di aumentare le prestazioni.</p>

<p><strong>Considerazioni:</strong></p>
<ul><li>Il gruppo di volumi deve contenere almeno due dischi fisici.</li>
<li>È preferibile che i dischi fisici abbiano tutti la stessa velocità altrimenti quello più lento diventerà il collo di bottiglia.</li>
<li>È possibile che <em>i</em> &lt; <em>n</em>, dove <em>i</em> è il numero di dischi per  lo stripe e <em>n</em> è il numero totale di dischi del gruppo di volumi</li>
<li>È anche possibile specificare i dischi va applicato lo stripe.</li>
<li>La dimensione dello stripe è di 64K come default. Ma per file molto grandi, video o database, la dimensione può essere anche di 128K o 256K</li></ul>

<pre><code class="language-bash"># creazione di un gruppo di volumi con 3 dischi
vgcreate vg_lab /dev/sdb /dev/sdc /dev/sdd

# stripe su due dischi a caso di vg_lab
lvcreate -i 2 -I 64k -L 10G -n lv_stripe vg_lab

# stripe su tutti i dischi di vg_lab
lvcreate -i 3 -I 64k -L 10G -n lv_stripe vg_lab

# stripe sui dischi sdc e sdd con uno stripe size di 128K
lvcreate -i 2 -I 128k -L 10G -n lv_stripe vg_lab /dev/sdc /dev/sdd
</code></pre>

<p>Come ogni raid 0, massime prestazioni e sicurezza 0. Se un disco si rompe, addio ai dati.</p>

<h2 id="6-lvm-mirror">6. LVM Mirror</h2>

<p>Come per <strong>lvm stripe</strong> analogo a <strong>raid 0</strong>, il <strong>mirror</strong> in lvm tramite il mappatore interno <strong>dm-mirror</strong>, è assimiliabile a <strong>raid 1</strong>.</p>

<p>Come ogni raid 1 che si rispetti, il chiaro vantaggio di questo approccio è proprio la ridondanza dei dati che, al costo del sacrificio di un disco, permette di correre ai ripari se uno dei dischi si danneggia.</p>

<pre><code class="language-bash"># creazione di un gruppo di volumi con 2 dischi
vgcreate vg_lab /dev/sdb /dev/sdc

# creazione del volume logico &#34;mirror&#34;
lvcreate -m 1 -L 10G -n lv_mirror vg_lab
</code></pre>

<p>Il mirror diretto attraverso LVM in realtà è considerato legacy. Si consiglia di usare l&#39;approccio più moderno che prevede di specificare il tipo, raid <em>x</em>, nell&#39;invocazione di <strong>lvcreate</strong> perché userà il modulo specializzato del kernel per il raid software.</p>

<p>LVM mirror infatti pur essendo funzionalmente equivalente ad un raid 1 non è altrettanto efficace perché si basa su un log di sincronizzazione dove lvm tiene traccia degli elementi allineati.</p>

<p>Tale log deve stare su un altro disco (che diventa un altro punto di vulnerabilità) e quando c&#39;è bisogno di ricostruire l&#39;array in caso di rottura di un disco, l&#39;operazione è molto lenta.</p>

<h2 id="7-lvm-raid">7. LVM Raid</h2>

<p>Il raid lvm è un modo per prendere il meglio dei due mondi.</p>

<p>Non è che LVM abbia una sua implementazione del raid.
Il raid “tradizionale” si basa sul sottosistema <strong>Multiple Devices</strong> del kernel e lavora direttamente sui dispositivi a blocchi.</p>

<p>LVM si interfaccia direttamente con il modulo <strong>md</strong> del kernel per attingere alle funzioni di raid così da offrire, attraverso <strong>device mapper</strong>, un&#39;interfaccia unica per la gestione dei volumi e del raid.</p>

<h3 id="7-1-raid-0-stripe">7.1. Raid 0 (Stripe)</h3>

<pre><code class="language-bash">lvcreate --type raid0 -i 2 -I 64k -L 10G -n lv_raid0 vg_lab
</code></pre>

<p>A differenza del mirror, non ci sono gli stessi problemi per stripe. Il mappatore nativo di LVM, <strong>dm-stripe</strong>, fa bene il suo lavoro.</p>

<p>Usare lvmraid in questo caso resta vantaggioso per ragioni di coerenza. L&#39;uso del modulo <strong>md</strong> rende possibile un&#39;eventuale evoluzione verso livelli superiori (come RAID 1 o RAID 5).</p>

<h3 id="7-2-raid-1-mirroring">7.2. Raid 1 (Mirroring)</h3>

<p>L&#39;alternativa moderna al vecchio lvm mirror che risolve i suoi problemi di efficienza usando il modulo <strong>md</strong>.</p>

<p>Basandoci sull&#39;esempio di prima:</p>

<pre><code class="language-bash">lvcreate --type raid1 -m 1 -L 10G -n lv_raid1 vg_lab
</code></pre>

<h3 id="7-3-raid-5-stripe-con-parità-singola">7.3. Raid 5 (Stripe con parità singola)</h3>

<p>Creiamo un volume logico con RAID 5 basato su 4 dischi (stripe su 3 dischi e uno per la parità):</p>

<pre><code class="language-bash"># creazione di un gruppo di volumi con 4 dischi
vgcreate vg_lab /dev/sdb /dev/sdc /dev/sdd /dev/sde

# creazione del volume logico con RAID 5
lvcreate --type raid5 -i 3 -L 10G -n lv_raid5 vg_lab
</code></pre>

<h3 id="7-4-raid-6-stripe-con-parità-doppia">7.4. Raid 6 (Stripe con parità doppia)</h3>

<p>Se vogliamo una parità doppia su 4 dischi (2 stripe e due di parità);</p>

<pre><code class="language-bash"># creazione di un gruppo di volumi con 4 dischi
vgcreate vg_lab /dev/sdb /dev/sdc /dev/sdd /dev/sde

# creazione del volume logico con RAID 5
lvcreate --type raid6 -i 2 -L 10G -n lv_raid6 vg_lab
</code></pre>

<h3 id="7-5-raid-10">7.5. Raid 10</h3>

<p>E veniamo al RAID 1+0, uno stripe su <em>n</em> array in mirror per combinare l&#39;efficienza dello stripe con la sicurezza del mirror:</p>

<pre><code class="language-bash"># creazione di un gruppo di volumi con 4 dischi
vgcreate vg_lab /dev/sdb /dev/sdc /dev/sdd /dev/sde

# creazione del volume logico con RAID 5
lvcreate --type raid10 -i 2 -m 1 -L 10G -n lv_raid10 vg_lab
</code></pre>

<h3 id="7-6-come-monitorare-il-raid">7.6. Come monitorare il raid</h3>

<p><strong>Metodo rapido:</strong></p>

<pre><code class="language-bash">lvs -o name,vg_name,copy_percent,lv_attr,raid_health_status,devices vg_lab

# Combinandolo con watch posso vedere per es. la percentuale 
# di completamento della copia in caso di sostituzione del disco
watch -n 1 lvs -o name,vg_name,copy_percent,lv_attr,raid_health_status,devices vg_lab
</code></pre>

<p><strong>Metodo dettagliato:</strong></p>

<pre><code class="language-bash">lvdisplay vg_lab/lv_raid5
</code></pre>

<p><strong>Monitoraggio a basso livello:</strong>
Balamente, visto che viene usato il modulo <strong>md</strong>:</p>

<pre><code class="language-bash">cat /proc/mdstat
</code></pre>

<h3 id="7-7-come-intervenire-in-caso-di-guasto">7.7. Come intervenire in caso di guasto</h3>

<p>Con <code>lvs</code> vedremo che lo stato del volume è diventato <code>degraded</code>.
Con <code>pvpdisplay</code> possiamo individuare il device danneggiato che comparirà come <code>unknown device</code> o con un sacco di errori I/O .</p>

<p>Dopo aver estratto il disco e messo quello nuovo, supponendo sia <code>/dev/sdc</code>, procediamo con la ricostruzione dell&#39;array:</p>

<pre><code class="language-bash"># inizializzazione nuovo disco
pvcreate /dev/sdc

# aggiunta del nuovo disco al gruppo
vgextend vg_lab /dev/sdc

# array rebuild
lvconvert --repair vg_lab/lv_raid5

# rimozione disco danneggiato dal gruppo di volumi
vgreduce --removemissing vg_lab
</code></pre>

<p><a href="/aytin/tag:lvm" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">lvm</span></a> <a href="/aytin/tag:dm" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">dm</span></a> <a href="/aytin/tag:devicemapper" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">devicemapper</span></a> <a href="/aytin/tag:md" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">md</span></a> <a href="/aytin/tag:multipledevices" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">multipledevices</span></a> <a href="/aytin/tag:snapshot" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">snapshot</span></a> <a href="/aytin/tag:thinpool" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">thinpool</span></a> <a href="/aytin/tag:thinprovisioning" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">thinprovisioning</span></a> <a href="/aytin/tag:cachepool" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">cachepool</span></a> <a href="/aytin/tag:raid" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">raid</span></a> <a href="/aytin/tag:lvmraid" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">lvmraid</span></a></p>
]]></content:encoded>
      <guid>https://noblogo.org/aytin/cose-molto-notevoli-su-lvm</guid>
      <pubDate>Mon, 25 May 2026 06:08:02 +0000</pubDate>
    </item>
    <item>
      <title>Ridimensionare volumi LVM</title>
      <link>https://noblogo.org/aytin/ridimensionare-volumi-lvm</link>
      <description>&lt;![CDATA[lvm&#xA;Supponiamo di avere 3 volumi logici, ad es. vol1, vol2, vol3 e di voler aumentare il secondo a discapito degli altri due.&#xA;&#xA;Un’esigenza analoga, su un filesystem partizionato in 3 parti in maniera canonica, è un mezzo incubo perché il ridimensionamento della partizione centrale prevede un discreto numero di salti mortali per manenere la contiguità e per non rischiare di lasciare buchetti inutilizzabili fra una partizione e l’altra. &#xA;!--more--&#xA;&#xA;1. Cose che è bene ricordare quando si manipolano i volumi logici&#xA;2. Scenario 1: Estensione e riduzione di volumi logici&#xA;   2.1. Step 0: curiosità&#xA;   2.2. Step 1: Smontare i dischi&#xA;   2.3. Step 2: Riduzione del filesystem&#xA;   2.4. Step 3: Ridimensionare i volumi logici&#xA;   2.5. Step 4: Estendere il volume logico&#xA;   2.6. Step 5: Bonus&#xA;3. Scenario 2: Estensione e riduzione di gruppi di volume&#xA;4. Conclusione&#xA;&#xA;Provo a buttare giù due righe su quello che mi verrebbe di fare:&#xA;&#xA;riduco la prima partizione&#xA;riduco la terza partizione&#xA;sposto la terza partizione fino alla fine del disco&#xA;sposto la seconda partizione fino alla fine della prima partizione&#xA;estendo la seconda partizione fino alla fine della prima&#xA;&#xA;Tutto questo tenendo presente che l’unità minima allocabile è il blocco (512 bytes) e che l’operazione che mi fa più paura è il move della partizione. parted non ha un comando “move” diretto. La procedura richiede di calcolare i nuovi settori, spostare i dati e aggiornare la tabella delle partizioni.&#xA;&#xA;Senza una GUI come quella di gparted, bisogna farsi letteralmente i conti con carta e penna prima di agire e c’è il rischio, comunque molto alto, di commettere errori che sarebbero disastrosi.&#xA;&#xA;LVM, al confronto, è una boccata d’ossigeno.&#xA;&#xA;LVM dà la possibilità di ridimensionare volumi in maniera più semplice rispetto al partizionamento più tradizionale perché la dimensione della partizione è disaccoppiata da concetti di contiguità e dalla geometria del disco.&#xA;&#xA;Nel caso del partizionamento tradizionale infatti le partizioni sono dei blocchi di settori consecutivi in cui ogni partizione inizia in un settore finisce in un altro.&#xA;&#xA;Con LVM invece l’approccio è radicalmente diverso. La minima unità allocabile è l’extent (default 4 MiB) che serve per mappare un volume fisico in un volume logico.&#xA;&#xA;Se immaginiamo che il volume fisico possa essere spezzettato in altrettanti extents in una sorta di “paniere”, il volume group, il volume logico non è altro che un insieme di questi extents pescati dal volume group (senza alcuna pretesa d’ordinamento) a cui posso:&#xA;&#xA;aggiungere extents prelevandoli dal volume group&#xA;levare extents riponendoli nel volume group (o assegnandoli ad altri volumi logici).&#xA;&#xA;Queste proprietà conferiscono una grande flessibilità alle operazioni di riduzione ed estensione dei volumi.&#xA;&#xA;1. Cose che è bene ricordare quando si manipolano i volumi logici.&#xA;&#xA;Partizioni&#xA;Quando si riduce o aumenta un filesystem, è bene smontare le partizioni e volumi logici.&#xA;&#xA;Ridurre un volume logico&#xA;Quando si riduce un volume logico, si deve:&#xA;&#xA;fare un check del filesystem&#xA;ridurre il filesystem&#xA;ridurre il volume logico&#xA;&#xA;Estendere un volume logico&#xA;Quando si aumenta un volume logico, al contrario, si deve:&#xA;&#xA;estendere il volume logico&#xA;estendere il filesystem&#xA;fare un check del filesystem&#xA;&#xA;Calcolare lo spazio allocabile&#xA;Un volume logico è composto da un insieme di extents, blocchi grandi di default 4 MiB, che sono la minima unità allocabile. Un volume logico è quindi sempre corrispondente ad un multiplo di 4 MiB, n extents di cui n\-1 allocabili, il rimanente per i metadati. Ad es. un volume logico di 2 GiB è composta da 512 extents di cui 511 allocabili.&#xA;&#xA;La potenza di due&#xA;Si deve tenere sempre presente che, nella matematica del calcolo dello spazio, si considerano le potenze di 2. Non di 10. Quindi un GiB equivale a 1024 MiB, non a 1000. Di conseguenza, se dividessi un GiB in due parti uguali avrei 2 blocchi da 512 MiB non da 500.&#xA;&#xA;Estensione e riduzione&#xA;Nelle istruzioni di estensione (lvextend) e riduzione (lvreduce) possiamo scegliere ciò che va specificato fra 4 modalità:&#xA;&#xA;il numero totale di extents&#xA;il delta in aggiunta o in diminuzione degli extents (a seconde che l’operazione sia rispettivamente di estensione o di riduzione)&#xA;la dimensione totale espressa in KiB-MiB-GiB-TiB&#xA;come prima, il delta in aggiunta o in diminuzione della dimensione espresso in KiB-MiB-GiB-TiB&#xA;&#xA;2. Scenario 1: Estensione e riduzione di volumi logici&#xA;Supponiamo di avere un disco da 2 GiB (2048 MiB) diviso in 3 volumi logici da 550 MiB, 350 MiB e 1148 MiB di e di volerne ridurre due per ampliare il terzo.&#xA;&#xA;Vogliamo ridurre il primo di 150 MiB, il terzo di 330 MiB e aumentare corrispondentemente il secondo volume di 480 MiB.&#xA;&#xA;Prepariamo il laboratorio col solito file appiccicato ad un loop device. Su quello definirò il volume group, il mio “paniere” di extents.&#xA;creazione device&#xA;fallocate -l 2GiB disk1.img&#xA;&#xA;creazione device e volum group&#xA;vgcreate vglab $(losetup -Pf --show disk1.img)&#xA;&#xA;creazione volumi logici&#xA;lvcreate -n lvlab1 vglab -L 550M&#xA;lvcreate -n lvlab2 vglab -L 350M&#xA;lvcreate -n lvlab3 vglab -l 100%FREE&#xA;&#xA;formattazione volumi logici&#xA;mkfs.ext4 /dev/vglab/lvlab1&#xA;mkfs.ext4 /dev/vglab/lvlab2&#xA;mkfs.ext4 /dev/vglab/lvlab3&#xA;&#xA;mount dei volumi&#xA;mkdir vol1 vol2 vol3&#xA;mount -t ext4 -o defaults /dev/vglab/lvlab1 vol1&#xA;mount -t ext4 -o defaults /dev/vglab/lvlab2 vol2&#xA;mount -t ext4 -o defaults /dev/vglab/lvlab3 vol3&#xA;2.1. Step 0: curiosità&#xA;Prima di cominciare esaminiamo un po’ di dati, ad es. di quanti extents sono composti i nostri oggetti.&#xA;pvdisplay /dev/loop9&#xA;  --- Physical volume ---&#xA;  PV Name               /dev/loop9&#xA;  VG Name               vglab&#xA;  PV Size               2,00 GiB / not usable 4,00 MiB&#xA;  Allocatable           yes (but full)&#xA;  PE Size               4,00 MiB&#xA;  Total PE              511&#xA;  Free PE               0&#xA;  Allocated PE          511&#xA;  PV UUID               YmLOru-bIdL-iqGb-vJfI-RsTk-yhv7-vSJhkX&#xA;pvdisplay mi dà informazioni sul disco fisico che andrò ad aggiungere nel volume group. Fra queste:&#xA;&#xA;PV Name: il nome del device, /dev/loop9&#xA;VG Name: è il nome del gruppo di volume, vglab, visibile solo perché abbiamo creato il gruppo di volume direttamente sul dispositivo invece che passare prima da pvcreate.&#xA;PV Size: 2 GiB, la dimensione del nostro “disco”&#xA;PE Size: dove PE sta Physical Extent, è di 4 MiB&#xA;Total PE sono i PE totali e sono 511, come previsto.&#xA;&#xA;vgdisplay vglab&#xA;  --- Volume group ---&#xA;  VG Name               vglab&#xA;  System ID&#xA;  Format                lvm2&#xA;  Metadata Areas        1&#xA;  Metadata Sequence No  1&#xA;  VG Access             read/write&#xA;  VG Status             resizable&#xA;  MAX LV                0&#xA;  Cur LV                0&#xA;  Open LV               0&#xA;  Max PV                0&#xA;  Cur PV                1&#xA;  Act PV                1&#xA;  VG Size               &lt;2,00 GiB&#xA;  PE Size               4,00 MiB&#xA;  Total PE              511&#xA;  Alloc PE / Size       0 / 0&#xA;  Free  PE / Size       511 / &lt;2,00 GiB&#xA;  VG UUID               6D89ck-c2Ni-XlMN-5Was-rh5j-vi2t-5juCXt&#xA;vgdisplay mi dà informazioni sul gruppo di volumi. Fra queste, disitnguiamo&#xA;&#xA;VG Name: il nome del volume group, già visto in pvdisplay, vglab&#xA;VG Size: la dimensione del volume group, minore di 2 GiB perché ci sono i metadati da considerari&#xA;PE Size: la dimensione di un extent, 4 MiB&#xA;Total PE / Size: Il numero totale di extent allocabili, che conferma VG Size, pari a 511 invece che 512.&#xA;Alloc PE: il numero totale di extent allocati, momento della creazione del volume group è 0&#xA;Free PE / Size: il numero totale di extent liberi, prima della creazione dei volumi logici è 511&#xA;&#xA;Cosa succede quando creerò i volumi logici? Che cambia il numero di PE liberi e allocati. Siccome userò tutti gli extent disponibili, i valori per Alloc PE e Free PE si invertiranno rispetto a prima.&#xA;&#xA;Infatti dopo la creazione dei volumi logici, vgdisplay mi dirà:&#xA;vgdisplay vglab&#xA;  --- Volume group ---&#xA;  VG Name               vglab&#xA;  ...&#xA;  Alloc PE / Size       511 / &lt;2,00 GiB&#xA;  Free  PE / Size       0 / 0&#xA;  ...  &#xA;511 extents allocati come confermato dai dati desumibili dei 3 volumi logici&#xA;lvdisplay vglab&#xA; --- Logical volume ---&#xA;  LV Path                /dev/vglab/lvlab1&#xA;  LV Name                lvlab1&#xA;  VG Name                vglab&#xA;...&#xA;  LV Size                552,00 MiB&#xA;  Current LE             138&#xA;...&#xA; --- Logical volume ---&#xA;  LV Path                /dev/vglab/lvlab2&#xA;  LV Name                lvlab2&#xA;  VG Name                vglab&#xA;...&#xA;  LV Size                352,00 MiB&#xA;  Current LE             88&#xA;...&#xA; --- Logical volume ---&#xA;  LV Path                /dev/vglab/lvlab3&#xA;  LV Name                lvlab2&#xA;  VG Name                vglab&#xA;...&#xA;  LV Size                1,11 GiB&#xA;  Current LE             285&#xA;...&#xA;Per il primo, il secondo e il terzo volume logico abbiamo rispettivamente:&#xA;&#xA;138, 88, 285 extents corrispondenti a&#xA;552 MiB, 352 MiB e 1140 MiB (1,11 GiB)&#xA;per un totale di 2044 MiB, al netto dei metadati.&#xA;&#xA;Possiamo notare subito che le dimensioni non corrispondono a quanto indicato in lvcreate.&#xA;lvcreate -n lvlab1 vglab -L 550M&#xA;lvcreate -n lvlab2 vglab -L 350M&#xA;lvcreate -n lvlab3 vglab -l 100%FREE&#xA;Questo succede perché vengono sempre approssimate all’extent più vicino. Ecco perché il primo e il secondo volume sono diventati di 552 (138 extents) e 352 MiB (88 extents).&#xA;&#xA;Sempre ricordando la particolarità dei multipli di 4 MiB legati a LVM, anche la riduzione di 150 MiB e di 330 MiB dei due volumi saranno approssimate sempre all’extent più vicino (152 MiB=38 extents e 332=83 extents). Questo dettaglio si rivelerà fondamentale quando dovremo ridimensionare il filesystem.&#xA;&#xA;Con questa rinnovata consapevolezza cominciamo a ridimensionare.&#xA;2.2. Step 1: Smontare i dischi&#xA;umount /dev/vglab/lvlab1&#xA;umount /dev/vglab/lvlab2&#xA;umount /dev/vglab/lvlab3&#xA;2.3. Step 2: Riduzione del filesystem&#xA;Se dovessi ridimensionare solo il filesystem, sarebbe sufficiente considerare dimensioni che siano potenze di 2 e non di 10.&#xA;&#xA;Ma sapendo che sotto c’è un LVM, sappiamo che per mantenere l’allineamento fra filesystem e volumi logici, oltre che potenze di due le dimensioni devono essere anche multipli di 4MiB.&#xA;&#xA;Ecco perché anche nel resize reale del filesystem non dovrò levare 150 MiB e 330 MiB ma 148 MiB (37 PE) e 328 (82 PE) (è buona norma approssimare per difetto all’extent più vicino per maggior prudenza) per un totale effettivo di 476 MiB (119 PE)&#xA;&#xA;Il filesystem del primo volume sarà dunque di 552 MiB - 148 MiB = 404 MiB. Il filesystem del terzo volume sarà di 1140 MiB - 328 MiB = 812 MiB.&#xA;check dei filesystem&#xA;e2fsck -f /dev/vglab/lvlab1&#xA;e2fsck -f /dev/vglab/lvlab2&#xA;e2fsck -f /dev/vglab/lvlab3&#xA;&#xA;Riduco il primo filesystem di 148 MiB&#xA;resize2fs /dev/vglab/lvlab1 404M&#xA;&#xA;Riduco il terzo filesystem di 328 MiB&#xA;resize2fs /dev/vglab/lvlab3 812M&#xA;2.4. Step 3: Ridimensionare i volumi logici&#xA;La riduzione del volume logico può essere fatta in 4 modi come sappiamo, ad es. sul primo volume:&#xA;il numero totale di extents, 138 PE - 37 PE = 101 PE&#xA;lvreduce -l 101 /dev/vglab/lvlab1 #oppure&#xA;&#xA;il numero di exrtents da sottrarre, 38 PE&#xA;lvreduce -l -37 /dev/vglab/lvlab1 #oppure&#xA;&#xA;la dimensione totale da ottenere, 404 MiB&#xA;lvreduce -L 404M /dev/vglab/lvlab1 #oppure&#xA;&#xA;il numero di MiB da sottrarre, 148 MiB&#xA;lvreduce -L -148M /dev/vglab/lvlab1 #oppure&#xA;Per maggior chiarezza userò il size assoluto in modo da farlo corrispondere a resize2fs&#xA;Riduco il primo volume logico di 148 Mib&#xA;lvreduce -L 404M /dev/vglab/lvlab1&#xA;&#xA;Riduco il terzo volume logico di 328 Mib&#xA;lvreduce -L 812M /dev/vglab/lvlab3&#xA;Verifichiamo quanti siano i PE residui&#xA;vgdisplay vglab | grep &#34;Free  PE&#34;&#xA; Free  PE / Size       119 / 476,00 MiB&#xA;119 extents, come previsto.&#xA;2.5. Step 4: Estendere il volume logico&#xA;Dopo aver ridotto il primo e il terzo volume, non ci rimane che estendere il secondo in base alla scaletta indicata prima:&#xA;&#xA;si estende il secondo volume logico&#xA;si estende il filesystem&#xA;si esegue il check fnale del filesystem&#xA;&#xA;L’estensione del volume, come ormai ben sappiamo, non sarà di 480 MiB ma di 476 MiB (37 PE + 82 PE = 119 PE) per via degli arrotondamenti effettuati nella riduzione degli altri volumi logici.&#xA;specifico gli extent che so essere residui&#xA;lvextend -l +119 /dev/vglab/lvlab2&#xA;o, equivalentemente&#xA;lvextend -L +476M /dev/vglab/lvlab2&#xA;&#xA;estendo il filesystem&#xA;resize2fs /dev/vglab/lvlab2 828M&#xA;&#xA;check filesystem&#xA;e2fsck -f /dev/vglab/lvlab2&#xA;2.6. Step 5: Bonus&#xA;Come premio per essere arrivato in fondo, posso rivelare come fare in un colpo solo tutte le operazioni descritte sopra.&#xA;&#xA;È vero che c&#39;è poco da considerare, giusto tenere a mente che su LVM ogni oggetto è multiplo di 4 MiB e che bisogna ridimensionare filesystem e volumi logici in ugual modo per non generare pericolose anomalie, ma tutte le operazioni che ho descritto nei passi 2-4 possono essere fatte con un unico comando che provvederà ad eseguire nell&#39;ordine corretto e con le giuste approssimazioni:&#xA;&#xA;il check del filesystem&#xA;il ridimensionamento del filesystem&#xA;il ridimensionamento dei volumi logici&#xA;&#xA;Dunque, tutto il pippone atomico precedente può essere condensato in un unico, solido comando:&#xA;Riduce il primo volume logico e il filesystem&#xA;lvreduce -r -L -150M /dev/vglab/lvlab1&#xA;&#xA;Riduce il terzo volume logico e il filesystem&#xA;lvreduce -r -L -330M /dev/vglab/lvlab3&#xA;&#xA;Estende il secondo volume logico e il filesystem&#xA;lvextend -r -l +119 /dev/vglab/lvlab2&#xA;Ora spieghiamo il perché soprattutto dell&#39;extend, che è interessante.&#xA;&#xA;Diciamo che è tutto molto guidato e le eventuali correzioni da apportare, senza spaccarsi troppo il cervello, sono suggerite con estrema chiarezza, basta leggere.&#xA;lvreduce -r -L -150M /dev/vglab/lvlab1&#xA; Rounding size to boundary between physical extents: 148.00 MiB.&#xA;  File system ext4 found on vglab/lvlab1.&#xA;  File system size (552.00 MiB) is larger than the requested size (404.00 MiB).&#xA;  File system reduce is required using resize2fs.&#xA;...&#xA;  Size of logical volume vglab/lvlab1 changed from 552.00 MiB (138 extents) to 404.00 MiB (101 extents).&#xA;  Logical volume vglab/lvlab1 successfully resized.&#xA;Ci dice innanzitutto che:&#xA;&#xA;c&#39;è stato un arrotondamento a 148 MiB (37 extents);&#xA;il filesystem è più grande del volume richiesto pertanto va subito ridimensionato;&#xA;infine si ridimensiona il volume logico da 552 MiB (138 extents) a 404 MiB (101 extents).&#xA;&#xA;Anche il secondo lvreduce ha un risultato analogo&#xA;lvreduce -r -L -330M /dev/vglab/lvlab3&#xA;  Rounding size to boundary between physical extents: 328.00 MiB.&#xA;  File system ext4 found on vglab/lvlab3.&#xA;  File system size (1.11 GiB) is larger than the requested size (812.00 MiB).&#xA;  File system reduce is required using resize2fs.&#xA;...&#xA;  Size of logical volume vglab/lvlab3 changed from 1.11 GiB (285 extents) to 812.00 MiB (203 extents).&#xA;  Logical volume vglab/lvlab3 successfully resized.&#xA;&#xA;anche qui abbiamo un arrotondamento a 328 MiB (82 extents);&#xA;il filesystem è più grande del volume richiesto pertanto va subito ridimensionato;&#xA;infine si ridimensiona il volume logico da 1140 MiB (285 extents) a 812 MiB (203 extents).&#xA;&#xA;È facilissimo desumere che la massima dimensione dell&#39;estensione sia 148 MiB + 328 MiB = 476 MiB (119 extents), basta fare una somma.&#xA;&#xA;Ma supponiamo di essere particolarmente distratti e proviamo ad estendere considerando le quantità iniziali: 150 MiB + 330 MiB = 480 MiB&#xA;lvextend -r -L +480M /dev/vglab/lvlab2&#xA;  File system ext4 found on vglab/lvlab2.&#xA;  File system fsck will be run before extend.&#xA;  Insufficient free space: 120 extents needed, but only 119 available&#xA;Nonostante la mia distrazione, come si può vedere, non si producono danni perché l&#39;ouput è categorico: &#34;non faccio nulla. Se vuoi, puoi aumentare al max di 476 MiB (119 extents)&#34;.&#xA;Non ci sono danni e anzi c&#39;è pure il suggerimento risolutivo.&#xA;&#xA;Ed ecco spiegato il mio extend di prima.&#xA;3. Scenario 2: Estensione e riduzione di gruppi di volume&#xA;Esaminiamo le possibilità di aggiungere o rimuovere dispositivi ad un volume group esistente.&#xA;&#xA;Ricreiamo il laboratorio partendo da 3 dischi, poi aggiungeremo due nuovi dischi e ne rimuoveremo altrettanti, il tutto senza intaccare l&#39;integrità dei dati.&#xA;&#xA;creazione di 5 device&#xA;for i in {1..5}: do fallocate -l 1GiB disk${i}.img; done&#xA;&#xA;creazione del gruppo di volumi con 3 device&#xA;vgcreate vglab \&#xA;  $(losetup -Pf --show disk1.img) \&#xA;  $(losetup -Pf --show disk2.img) \&#xA;  $(losetup -Pf --show disk3.img)&#xA;&#xA;crezione di 3 volumi logici&#xA;lvcreate -n lvlab1 vglab -l 300&#xA;lvcreate -n lvlab2 vglab -l 250&#xA;lvcreate -n lvlab3 vglab -l 100%FREE&#xA;&#xA;formattazione dei 3 dispositivi&#xA;mkfs.ext4 /dev/vglab/lvlab1&#xA;mkfs.ext4 /dev/vglab/lvlab2&#xA;mkfs.ext4 /dev/vglab/lvlab3&#xA;Ecco come sono distribuiti i volumi logici all&#39;interno dei dischi fisici&#xA;lsblk -o NAME,FSTYPE,SIZE,TYPE&#xA;  NAME               FSTYPE        SIZE      TYPE&#xA;  loop9              LVM2member     1G      loop&#xA;  └─vglab-lvlab1                1,2G      lvm&#xA;  loop10             LVM2member     1G      loop&#xA;  ├─vglab-lvlab1                1,2G      lvm&#xA;  └─vglab-lvlab3                860M      lvm&#xA;  loop11             LVM2member     1G      loop&#xA;  ├─vglab-lvlab2               1000M      lvm&#xA;  └─vglab-lvlab3                860M      lvm&#xA;Il gruppo di volumi è composto da 3 volumi fisici tutti attivi&#xA;vgdisplay vglab |grep PV&#xA;  Max PV                0&#xA;  Cur PV                3&#xA;  Act PV                3&#xA;Andiamo ad estendere il nostro gurppo di volumi con altri due device&#xA;vgextend vglab $(losetup -Pf --show disk4.img) $(losetup -Pf --show disk5.img)&#xA;I nuovi dischi sono visibili in fondo, come si può vedere anche da  vgdisplay che mostra i 5 dischi tutti attivi. &#xA;lsblk -o NAME,FSTYPE,SIZE,TYPE&#xA;  NAME               FSTYPE        SIZE      TYPE&#xA;  loop9              LVM2member     1G      loop&#xA;  └─vglab-lvlab1                1,2G      lvm&#xA;  loop10             LVM2member     1G      loop&#xA;  ├─vglab-lvlab1                1,2G      lvm&#xA;  └─vglab-lvlab3                860M      lvm&#xA;  loop11             LVM2member     1G      loop&#xA;  ├─vglab-lvlab2               1000M      lvm&#xA;  └─vglab-lvlab3                860M      lvmchan&#xA;  loop12             LVM2member     1G      loop&#xA;  loop13             LVM2member     1G      loop&#xA;&#xA;vgdisplay vglab |grep PV&#xA;  Max PV                0&#xA;  Cur PV                5&#xA;  Act PV                5&#xA;Potremo usare i nuovi dischi per estendere i volumi logici esistenti ma li impiegheremo invece per rimpiazzare i primi due dischi. &#xA;&#xA;pvmove distribuisce tutti gli extents del disco fra tutti i volumi fisici che hanno spazio a sufficienza. Se non dovesse essercene, restituirà un messaggio d&#39;errore.&#xA;pvmove /dev/loop9&#xA;  /dev/loop9: Moved: 3,14%&#xA;  /dev/loop9: Moved: 100,00%&#xA;Alla fine dell&#39;operazione il disco s&#39;è liberato di tutti i suoi extents e può essere rimosso&#xA;lsblk -o NAME,FSTYPE,SIZE,TYPE&#xA;  NAME               FSTYPE        SIZE      TYPE&#xA;  loop9              LVM2member     1G      loop&#xA;  loop10             LVM2member     1G      loop&#xA;  ├─vglab-lvlab1                1,2G      lvm&#xA;  └─vglab-lvlab3                860M      lvm&#xA;  loop11             LVM2member     1G      loop&#xA;  ├─vglab-lvlab2               1000M      lvm&#xA;  └─vglab-lvlab3                860M      lvm&#xA;  loop12             LVM2member     1G      loop&#xA;  └─vglab-lvlab1                1,2G      lvm&#xA;  loop13             LVM2member     1G      loop&#xA;Prima si estrae il volume fisico dal gruppo di volumi e poi si rimuove il volume fisico e così può essere scollegato.&#xA;vgreduce vglab /dev/loop9&#xA;pvremove /dev/loop9&#xA;Verifichiamo che il volume fisico non sia più presente.&#xA;vgdisplay vglab |grep PV&#xA;  Max PV                0&#xA;  Cur PV                4&#xA;  Act PV                4&#xA;Procediamo allo stesso modo col secondo disco.&#xA;pvmove /dev/loop10&#xA;  /dev/loop10: Moved: 9,80%&#xA;  /dev/loop10: Moved: 17,65%&#xA;  /dev/loop10: Moved: 100,00%&#xA;&#xA;vgreduce vglab /dev/loop10&#xA;  Removed &#34;/dev/loop10&#34; from volume group &#34;vglab&#34;&#xA;&#xA;pvremove /dev/loop10&#xA;  Labels on physical volume &#34;/dev/loop10&#34; successfully wiped.&#xA;In conclusione possiamo vedere il gruppo di volumi con solo 3 dischi, gli altri due completamente disimpegnati col gruppo di volumi ricostituitosi attorno ai 3 dischi rimanenti. E tutto spostando semplicemente gli extents dove c&#39;era disponibilità in maniera totalmente trasparente per il filesystem.&#xA;vgdisplay vglab |grep PV&#xA;  Max PV                0&#xA;  Cur PV                3&#xA;  Act PV                3&#xA;&#xA;lsblk -o NAME,FSTYPE,SIZE,TYPE&#xA;  NAME               FSTYPE        SIZE      TYPE&#xA;  loop9                              1G      loop&#xA;  loop10                             1G      loop&#xA;  loop11             LVM2member     1G      loop&#xA;  ├─vglab-lvlab2               1000M      lvm&#xA;  └─vglab-lvlab3                860M      lvm&#xA;  loop12             LVM2member     1G      loop&#xA;  └─vglab-lvlab1                1,2G      lvm&#xA;  loop13             LVM2member     1G      loop&#xA;  ├─vglab-lvlab1                1,2G      lvm&#xA;  └─vglab-lvlab_3                860M      lvm&#xA;4. Conclusione&#xA;Ho solo sfiorato la complessità e le capacità offerte da LVM.&#xA;&#xA;L&#39;estensione e la riduzione di volumi logici e di gruppi di volumi sono scenari di base. Tuttavia sono sufficienti per mostrare come sia semplice, con i volumi logici, compiere operazioni che con un filesystem partizionato in maniera classica sarebbero complicatissime.&#xA;&#xA;#lvm #volumegroup #logicalvolume #filesystem #devicemapper]]&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://pixelfed.uno/storage/m/_v2/489827599091373610/31410d826-759a86/YynFD6sqFGzb/E2tgEVkaEtWT6Ucn0rqMrtk9qnJlr5p9nLl9m5pu.jpg" alt="lvm">
Supponiamo di avere 3 volumi logici, ad es. vol1, vol2, vol3 e di voler aumentare il secondo a discapito degli altri due.</p>

<p>Un’esigenza analoga, su un filesystem partizionato in 3 parti in maniera canonica, è un mezzo incubo perché il ridimensionamento della partizione centrale prevede un discreto numero di salti mortali per manenere la contiguità e per non rischiare di lasciare buchetti inutilizzabili fra una partizione e l’altra.
</p>
<ul><li><a href="#1-cose-che-%C3%A8-bene-ricordare-quando-si-manipolano-i-volumi-logici" rel="nofollow">1. Cose che è bene ricordare quando si manipolano i volumi logici</a></li>
<li><a href="#2-scenario-1-estensione-e-riduzione-di-volumi-logici" rel="nofollow">2. Scenario 1: Estensione e riduzione di volumi logici</a>
<ul><li><a href="#2-1-step-0-curiosit%C3%A0" rel="nofollow">2.1. Step 0: curiosità</a></li>
<li><a href="#2-2-step-1-smontare-i-dischi" rel="nofollow">2.2. Step 1: Smontare i dischi</a></li>
<li><a href="#2-3-step-2-riduzione-del-filesystem" rel="nofollow">2.3. Step 2: Riduzione del filesystem</a></li>
<li><a href="#2-4-step-3-ridimensionare-i-volumi-logici" rel="nofollow">2.4. Step 3: Ridimensionare i volumi logici</a></li>
<li><a href="#2-5-step-4-estendere-il-volume-logico" rel="nofollow">2.5. Step 4: Estendere il volume logico</a></li>
<li><a href="#2-6-step-5-bonus" rel="nofollow">2.6. Step 5: Bonus</a></li></ul></li>
<li><a href="#3-scenario-2-estensione-e-riduzione-di-gruppi-di-volume" rel="nofollow">3. Scenario 2: Estensione e riduzione di gruppi di volume</a></li>
<li><a href="#4-conclusione" rel="nofollow">4. Conclusione</a></li></ul>

<p>Provo a buttare giù due righe su quello che mi verrebbe di fare:</p>
<ol><li>riduco la prima partizione</li>
<li>riduco la terza partizione</li>
<li>sposto la terza partizione fino alla fine del disco</li>
<li>sposto la seconda partizione fino alla fine della prima partizione</li>
<li>estendo la seconda partizione fino alla fine della prima</li></ol>

<p>Tutto questo tenendo presente che l’unità minima allocabile è il blocco (512 bytes) e che l’operazione che mi fa più paura è il move della partizione. <code>parted</code> non ha un comando “move” diretto. La procedura richiede di calcolare i nuovi settori, spostare i dati e aggiornare la tabella delle partizioni.</p>

<p>Senza una GUI come quella di <strong>gparted</strong>, bisogna farsi letteralmente i conti con carta e penna prima di agire e c’è il rischio, comunque molto alto, di commettere errori che sarebbero disastrosi.</p>

<p>LVM, al confronto, è una boccata d’ossigeno.</p>

<p>LVM dà la possibilità di ridimensionare volumi in maniera più semplice rispetto al partizionamento più tradizionale perché la dimensione della partizione è disaccoppiata da concetti di contiguità e dalla geometria del disco.</p>

<p>Nel caso del partizionamento tradizionale infatti le partizioni sono dei blocchi di settori consecutivi in cui ogni partizione inizia in un settore finisce in un altro.</p>

<p>Con LVM invece l’approccio è radicalmente diverso. La minima unità allocabile è l’<strong>extent</strong> (default 4 MiB) che serve per mappare un volume fisico in un volume logico.</p>

<p>Se immaginiamo che il volume fisico possa essere spezzettato in altrettanti extents in una sorta di “paniere”, il <strong>volume group</strong>, il volume logico non è altro che un insieme di questi extents pescati dal volume group (senza alcuna pretesa d’ordinamento) a cui posso:</p>
<ul><li>aggiungere extents prelevandoli dal volume group</li>
<li>levare extents riponendoli nel volume group (o assegnandoli ad altri volumi logici).</li></ul>

<p>Queste proprietà conferiscono una grande flessibilità alle operazioni di riduzione ed estensione dei volumi.</p>

<h2 id="1-cose-che-è-bene-ricordare-quando-si-manipolano-i-volumi-logici">1. Cose che è bene ricordare quando si manipolano i volumi logici.</h2>

<p><strong>Partizioni</strong>
Quando si riduce o aumenta un filesystem, è bene smontare le partizioni e volumi logici.</p>

<p><strong>Ridurre un volume logico</strong>
Quando si riduce un volume logico, si deve:</p>
<ol><li>fare un check del filesystem</li>
<li>ridurre il filesystem</li>
<li>ridurre il volume logico</li></ol>

<p><strong>Estendere un volume logico</strong>
Quando si aumenta un volume logico, al contrario, si deve:</p>
<ol><li>estendere il volume logico</li>
<li>estendere il filesystem</li>
<li>fare un check del filesystem</li></ol>

<p><strong>Calcolare lo spazio allocabile</strong>
Un volume logico è composto da un <strong>insieme di extents</strong>, blocchi grandi di default 4 MiB, che sono la minima unità allocabile. Un volume logico è quindi <strong>sempre</strong> corrispondente ad un multiplo di 4 MiB, <em>n</em> extents di cui <em>n</em>-1 allocabili, il rimanente per i metadati. Ad es. un volume logico di 2 GiB è composta da 512 extents di cui <strong>511 allocabili</strong>.</p>

<p><strong>La potenza di due</strong>
Si deve tenere <strong>sempre</strong> presente che, nella matematica del calcolo dello spazio, si considerano le potenze di 2. Non di 10. Quindi un GiB equivale a 1024 MiB, non a 1000. Di conseguenza, se dividessi un GiB in due parti uguali avrei 2 blocchi da 512 MiB non da 500.</p>

<p><strong>Estensione e riduzione</strong>
Nelle istruzioni di estensione (<strong>lvextend</strong>) e riduzione (<strong>lvreduce</strong>) possiamo scegliere ciò che va specificato fra 4 modalità:</p>
<ol><li>il <strong>numero totale</strong> di extents</li>
<li>il <strong>delta</strong> in aggiunta o in diminuzione degli extents (a seconde che l’operazione sia rispettivamente di estensione o di riduzione)</li>
<li>la dimensione totale espressa in KiB-MiB-GiB-TiB</li>
<li>come prima, il delta in aggiunta o in diminuzione della dimensione espresso in KiB-MiB-GiB-TiB</li></ol>

<h2 id="2-scenario-1-estensione-e-riduzione-di-volumi-logici">2. Scenario 1: Estensione e riduzione di volumi logici</h2>

<p>Supponiamo di avere un disco da 2 GiB (2048 MiB) diviso in 3 volumi logici da <strong>550 MiB</strong>, <strong>350 MiB</strong> e <strong>1148 MiB</strong> di e di volerne ridurre due per ampliare il terzo.</p>

<p>Vogliamo ridurre il primo di <strong>150 MiB</strong>, il terzo di <strong>330 MiB</strong> e aumentare corrispondentemente il secondo volume di <strong>480 MiB</strong>.</p>

<p>Prepariamo il laboratorio col solito file appiccicato ad un loop device. Su quello definirò il volume group, il mio “paniere” di extents.</p>

<pre><code class="language-bash"># creazione device
fallocate -l 2GiB disk_1.img

# creazione device e volum group
vgcreate vg_lab $(losetup -Pf --show disk_1.img)

# creazione volumi logici
lvcreate -n lv_lab_1 vg_lab -L 550M
lvcreate -n lv_lab_2 vg_lab -L 350M
lvcreate -n lv_lab_3 vg_lab -l 100%FREE

# formattazione volumi logici
mkfs.ext4 /dev/vg_lab/lv_lab_1
mkfs.ext4 /dev/vg_lab/lv_lab_2
mkfs.ext4 /dev/vg_lab/lv_lab_3

# mount dei volumi
mkdir vol_1 vol_2 vol_3
mount -t ext4 -o defaults /dev/vg_lab/lv_lab_1 vol_1
mount -t ext4 -o defaults /dev/vg_lab/lv_lab_2 vol_2
mount -t ext4 -o defaults /dev/vg_lab/lv_lab_3 vol_3
</code></pre>

<h3 id="2-1-step-0-curiosità">2.1. Step 0: curiosità</h3>

<p>Prima di cominciare esaminiamo un po’ di dati, ad es. di quanti extents sono composti i nostri oggetti.</p>

<pre><code class="language-bash">pvdisplay /dev/loop9
  --- Physical volume ---
  PV Name               /dev/loop9
  VG Name               vg_lab
  PV Size               2,00 GiB / not usable 4,00 MiB
  Allocatable           yes (but full)
  PE Size               4,00 MiB
  Total PE              511
  Free PE               0
  Allocated PE          511
  PV UUID               YmLOru-bIdL-iqGb-vJfI-RsTk-yhv7-vSJhkX
</code></pre>

<p><code>pvdisplay</code> mi dà informazioni sul disco fisico che andrò ad aggiungere nel volume group. Fra queste:</p>
<ul><li><strong>PV Name</strong>: il nome del device, <strong>/dev/loop9</strong></li>
<li><strong>VG Name</strong>: è il nome del gruppo di volume, <strong>vg_lab</strong>, visibile solo perché abbiamo creato il gruppo di volume direttamente sul dispositivo invece che passare prima da <strong>pvcreate</strong>.</li>
<li><strong>PV Size</strong>: 2 GiB, la dimensione del nostro “disco”</li>
<li><strong>PE Size</strong>: dove <strong>PE</strong> sta <strong>P</strong>hysical <strong>E</strong>xtent, è di 4 MiB</li>
<li><strong>Total PE</strong> sono i PE totali e sono <strong>511</strong>, come previsto.</li></ul>

<pre><code class="language-bash">vgdisplay vg_lab
  --- Volume group ---
  VG Name               vg_lab
  System ID
  Format                lvm2
  Metadata Areas        1
  Metadata Sequence No  1
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                0
  Open LV               0
  Max PV                0
  Cur PV                1
  Act PV                1
  VG Size               &lt;2,00 GiB
  PE Size               4,00 MiB
  Total PE              511
  Alloc PE / Size       0 / 0
  Free  PE / Size       511 / &lt;2,00 GiB
  VG UUID               6D89ck-c2Ni-XlMN-5Was-rh5j-vi2t-5juCXt
</code></pre>

<p><code>vgdisplay</code> mi dà informazioni sul gruppo di volumi. Fra queste, disitnguiamo</p>
<ul><li><strong>VG Name</strong>: il nome del volume group, già visto in <code>pvdisplay</code>, <strong>vg_lab</strong></li>
<li><strong>VG Size</strong>: la dimensione del volume group, minore di 2 GiB perché ci sono i metadati da considerari</li>
<li><strong>PE Size</strong>: la dimensione di un extent, 4 MiB</li>
<li><strong>Total PE / Size</strong>: Il numero totale di extent allocabili, che conferma <strong>VG Size</strong>, pari a <strong>511</strong> invece che <strong>512</strong>.</li>
<li><strong>Alloc PE</strong>: il numero totale di extent allocati, momento della creazione del volume group è <strong>0</strong></li>
<li><strong>Free PE / Size</strong>: il numero totale di extent liberi, prima della creazione dei volumi logici è <strong>511</strong></li></ul>

<p>Cosa succede quando creerò i volumi logici? Che cambia il numero di PE liberi e allocati. Siccome userò tutti gli extent disponibili, i valori per <code>Alloc PE</code> e <code>Free PE</code> si invertiranno rispetto a prima.</p>

<p>Infatti dopo la creazione dei volumi logici, <code>vgdisplay</code> mi dirà:</p>

<pre><code class="language-bash">vgdisplay vg_lab
  --- Volume group ---
  VG Name               vg_lab
  ...
  Alloc PE / Size       511 / &lt;2,00 GiB
  Free  PE / Size       0 / 0
  ...  
</code></pre>

<p><strong>511 extents</strong> allocati come confermato dai dati desumibili dei 3 volumi logici</p>

<pre><code class="language-bash">lvdisplay vg_lab
 --- Logical volume ---
  LV Path                /dev/vg_lab/lv_lab_1
  LV Name                lv_lab_1
  VG Name                vg_lab
...
  LV Size                552,00 MiB
  Current LE             138
...
 --- Logical volume ---
  LV Path                /dev/vg_lab/lv_lab_2
  LV Name                lv_lab_2
  VG Name                vg_lab
...
  LV Size                352,00 MiB
  Current LE             88
...
 --- Logical volume ---
  LV Path                /dev/vg_lab/lv_lab_3
  LV Name                lv_lab_2
  VG Name                vg_lab
...
  LV Size                1,11 GiB
  Current LE             285
...
</code></pre>

<p>Per il primo, il secondo e il terzo volume logico abbiamo rispettivamente:</p>
<ul><li><strong>138, 88, 285 extents</strong> corrispondenti a</li>
<li><strong>552 MiB, 352 MiB e 1140 MiB (1,11 GiB)</strong></li>
<li>per un totale di <strong>2044 MiB</strong>, al netto dei metadati.</li></ul>

<p>Possiamo notare subito che le dimensioni non corrispondono a quanto indicato in <code>lvcreate</code>.</p>

<pre><code class="language-bash">lvcreate -n lv_lab_1 vg_lab -L 550M
lvcreate -n lv_lab_2 vg_lab -L 350M
lvcreate -n lv_lab_3 vg_lab -l 100%FREE
</code></pre>

<p>Questo succede perché vengono <strong>sempre</strong> approssimate all’extent più vicino. Ecco perché il primo e il secondo volume sono diventati di <strong>552</strong> (138 extents) e <strong>352 MiB</strong> (88 extents).</p>

<p>Sempre ricordando la particolarità dei multipli di 4 MiB legati a LVM, anche la riduzione di 150 MiB e di 330 MiB dei due volumi saranno approssimate sempre all’extent più vicino (<strong>152 MiB=38 extents</strong> e <strong>332=83 extents</strong>). Questo dettaglio si rivelerà fondamentale quando dovremo ridimensionare il filesystem.</p>

<p>Con questa rinnovata consapevolezza cominciamo a ridimensionare.</p>

<h3 id="2-2-step-1-smontare-i-dischi">2.2. Step 1: Smontare i dischi</h3>

<pre><code class="language-bash">umount /dev/vg_lab/lv_lab_1
umount /dev/vg_lab/lv_lab_2
umount /dev/vg_lab/lv_lab_3
</code></pre>

<h3 id="2-3-step-2-riduzione-del-filesystem">2.3. Step 2: Riduzione del filesystem</h3>

<p>Se dovessi ridimensionare solo il filesystem, sarebbe sufficiente considerare dimensioni che siano potenze di 2 e non di 10.</p>

<p>Ma sapendo che sotto c’è un LVM, sappiamo che per mantenere l’allineamento fra filesystem e volumi logici, oltre che potenze di due le dimensioni devono essere anche multipli di 4MiB.</p>

<p>Ecco perché <strong>anche</strong> nel resize reale del filesystem non dovrò levare <strong>150 MiB</strong> e <strong>330 MiB</strong> ma <strong>148 MiB (37 PE)</strong> e <strong>328 (82 PE)</strong> (è buona norma approssimare per difetto all’extent più vicino per maggior prudenza) per un totale effettivo di <strong>476 MiB (119 PE)</strong></p>

<p>Il filesystem del primo volume sarà dunque di <em>552 MiB – 148 MiB = 404 MiB</em>. Il filesystem del terzo volume sarà di <em>1140 MiB – 328 MiB = 812 MiB</em>.</p>

<pre><code class="language-bash"># check dei filesystem
e2fsck -f /dev/vg_lab/lv_lab_1
e2fsck -f /dev/vg_lab/lv_lab_2
e2fsck -f /dev/vg_lab/lv_lab_3

# Riduco il primo filesystem di 148 MiB
resize2fs /dev/vg_lab/lv_lab_1 404M

# Riduco il terzo filesystem di 328 MiB
resize2fs /dev/vg_lab/lv_lab_3 812M
</code></pre>

<h3 id="2-4-step-3-ridimensionare-i-volumi-logici">2.4. Step 3: Ridimensionare i volumi logici</h3>

<p>La riduzione del volume logico può essere fatta in 4 modi come sappiamo, ad es. sul primo volume:</p>

<pre><code class="language-bash"># il numero totale di extents, 138 PE - 37 PE = 101 PE
lvreduce -l 101 /dev/vg_lab/lv_lab_1 #oppure

# il numero di exrtents da sottrarre, 38 PE
lvreduce -l -37 /dev/vg_lab/lv_lab_1 #oppure

# la dimensione totale da ottenere, 404 MiB
lvreduce -L 404M /dev/vg_lab/lv_lab_1 #oppure

# il numero di MiB da sottrarre, 148 MiB
lvreduce -L -148M /dev/vg_lab/lv_lab_1 #oppure
</code></pre>

<p>Per maggior chiarezza userò il size assoluto in modo da farlo corrispondere a <code>resize2fs</code></p>

<pre><code class="language-bash"># Riduco il primo volume logico di 148 Mib
lvreduce -L 404M /dev/vg_lab/lv_lab_1

# Riduco il terzo volume logico di 328 Mib
lvreduce -L 812M /dev/vg_lab/lv_lab_3
</code></pre>

<p>Verifichiamo quanti siano i PE residui</p>

<pre><code class="language-bash">vgdisplay vg_lab | grep &#34;Free  PE&#34;
 Free  PE / Size       119 / 476,00 MiB
</code></pre>

<p>119 extents, come previsto.</p>

<h3 id="2-5-step-4-estendere-il-volume-logico">2.5. Step 4: Estendere il volume logico</h3>

<p>Dopo aver ridotto il primo e il terzo volume, non ci rimane che estendere il secondo in base alla scaletta indicata prima:</p>
<ol><li>si estende il secondo volume logico</li>
<li>si estende il filesystem</li>
<li>si esegue il check fnale del filesystem</li></ol>

<p>L’estensione del volume, come ormai ben sappiamo, non sarà di <strong>480 MiB</strong> ma di <strong>476 MiB (37 PE + 82 PE = 119 PE)</strong> per via degli arrotondamenti effettuati nella riduzione degli altri volumi logici.</p>

<pre><code class="language-bash"># specifico gli extent che so essere residui
lvextend -l +119 /dev/vg_lab/lv_lab_2
# o, equivalentemente
# lvextend -L +476M /dev/vg_lab/lv_lab_2

# estendo il filesystem
resize2fs /dev/vg_lab/lv_lab_2 828M

# check filesystem
e2fsck -f /dev/vg_lab/lv_lab_2
</code></pre>

<h3 id="2-6-step-5-bonus">2.6. Step 5: Bonus</h3>

<p>Come premio per essere arrivato in fondo, posso rivelare come fare in un colpo solo tutte le operazioni descritte sopra.</p>

<p>È vero che c&#39;è poco da considerare, giusto tenere a mente che su LVM ogni oggetto è multiplo di 4 MiB e che bisogna ridimensionare filesystem e volumi logici in ugual modo per non generare pericolose anomalie, ma tutte le operazioni che ho descritto nei passi 2-4 possono essere fatte con un unico comando che provvederà ad eseguire nell&#39;ordine corretto e con le giuste approssimazioni:</p>
<ul><li>il check del filesystem</li>
<li>il ridimensionamento del filesystem</li>
<li>il ridimensionamento dei volumi logici</li></ul>

<p>Dunque, tutto il pippone atomico precedente può essere condensato in un unico, solido comando:</p>

<pre><code class="language-bash"># Riduce il primo volume logico e il filesystem
lvreduce -r -L -150M /dev/vg_lab/lv_lab_1

# Riduce il terzo volume logico e il filesystem
lvreduce -r -L -330M /dev/vg_lab/lv_lab_3

# Estende il secondo volume logico e il filesystem
lvextend -r -l +119 /dev/vg_lab/lv_lab_2
</code></pre>

<p>Ora spieghiamo il perché soprattutto dell&#39;extend, che è interessante.</p>

<p>Diciamo che è tutto molto guidato e le eventuali correzioni da apportare, senza spaccarsi troppo il cervello, sono suggerite con estrema chiarezza, basta leggere.</p>

<pre><code class="language-bash">lvreduce -r -L -150M /dev/vg_lab/lv_lab_1
 Rounding size to boundary between physical extents: 148.00 MiB.
  File system ext4 found on vg_lab/lv_lab_1.
  File system size (552.00 MiB) is larger than the requested size (404.00 MiB).
  File system reduce is required using resize2fs.
...
  Size of logical volume vg_lab/lv_lab_1 changed from 552.00 MiB (138 extents) to 404.00 MiB (101 extents).
  Logical volume vg_lab/lv_lab_1 successfully resized.
</code></pre>

<p>Ci dice innanzitutto che:</p>
<ul><li>c&#39;è stato un arrotondamento a <strong>148 MiB (37 extents)</strong>;</li>
<li>il filesystem è più grande del volume richiesto pertanto va subito ridimensionato;</li>
<li>infine si ridimensiona il volume logico da <strong>552 MiB (138 extents)</strong> a <strong>404 MiB (101 extents)</strong>.</li></ul>

<p>Anche il secondo <code>lvreduce</code> ha un risultato analogo</p>

<pre><code class="language-bash">lvreduce -r -L -330M /dev/vg_lab/lv_lab_3
  Rounding size to boundary between physical extents: 328.00 MiB.
  File system ext4 found on vg_lab/lv_lab_3.
  File system size (1.11 GiB) is larger than the requested size (812.00 MiB).
  File system reduce is required using resize2fs.
...
  Size of logical volume vg_lab/lv_lab_3 changed from 1.11 GiB (285 extents) to 812.00 MiB (203 extents).
  Logical volume vg_lab/lv_lab_3 successfully resized.
</code></pre>
<ul><li>anche qui abbiamo un arrotondamento a <strong>328 MiB (82 extents)</strong>;</li>
<li>il filesystem è più grande del volume richiesto pertanto va subito ridimensionato;</li>
<li>infine si ridimensiona il volume logico da <strong>1140 MiB (285 extents)</strong> a <strong>812 MiB (203 extents)</strong>.</li></ul>

<p>È facilissimo desumere che la massima dimensione dell&#39;estensione sia <strong>148 MiB + 328 MiB = 476 MiB (119 extents)</strong>, basta fare una somma.</p>

<p>Ma supponiamo di essere particolarmente distratti e proviamo ad estendere considerando le quantità iniziali: 150 MiB + 330 MiB = <strong>480 MiB</strong></p>

<pre><code class="language-bash">lvextend -r -L +480M /dev/vg_lab/lv_lab_2
  File system ext4 found on vg_lab/lv_lab_2.
  File system fsck will be run before extend.
  Insufficient free space: 120 extents needed, but only 119 available
</code></pre>

<p>Nonostante la mia distrazione, come si può vedere, non si producono danni perché l&#39;ouput è categorico: “non faccio nulla. Se vuoi, puoi aumentare al max di 476 MiB (119 extents)”.
Non ci sono danni e anzi c&#39;è pure il suggerimento risolutivo.</p>

<p>Ed ecco spiegato il mio extend di prima.</p>

<h2 id="3-scenario-2-estensione-e-riduzione-di-gruppi-di-volume">3. Scenario 2: Estensione e riduzione di gruppi di volume</h2>

<p>Esaminiamo le possibilità di aggiungere o rimuovere dispositivi ad un volume group esistente.</p>

<p>Ricreiamo il laboratorio partendo da 3 dischi, poi aggiungeremo due nuovi dischi e ne rimuoveremo altrettanti, il tutto senza intaccare l&#39;integrità dei dati.</p>

<pre><code class="language-bash"># creazione di 5 device
for i in {1..5}: do fallocate -l 1GiB disk_${i}.img; done

# creazione del gruppo di volumi con 3 device
vgcreate vg_lab \
  $(losetup -Pf --show disk_1.img) \
  $(losetup -Pf --show disk_2.img) \
  $(losetup -Pf --show disk_3.img)

# crezione di 3 volumi logici
lvcreate -n lv_lab_1 vg_lab -l 300
lvcreate -n lv_lab_2 vg_lab -l 250
lvcreate -n lv_lab_3 vg_lab -l 100%FREE

# formattazione dei 3 dispositivi
mkfs.ext4 /dev/vg_lab/lv_lab_1
mkfs.ext4 /dev/vg_lab/lv_lab_2
mkfs.ext4 /dev/vg_lab/lv_lab_3
</code></pre>

<p>Ecco come sono distribuiti i volumi logici all&#39;interno dei dischi fisici</p>

<pre><code class="language-bash">lsblk -o NAME,FSTYPE,SIZE,TYPE
  NAME               FSTYPE        SIZE      TYPE
  loop9              LVM2_member     1G      loop
  └─vg_lab-lv_lab_1                1,2G      lvm
  loop10             LVM2_member     1G      loop
  ├─vg_lab-lv_lab_1                1,2G      lvm
  └─vg_lab-lv_lab_3                860M      lvm
  loop11             LVM2_member     1G      loop
  ├─vg_lab-lv_lab_2               1000M      lvm
  └─vg_lab-lv_lab_3                860M      lvm
</code></pre>

<p>Il gruppo di volumi è composto da 3 volumi fisici tutti attivi</p>

<pre><code class="language-bash">vgdisplay vg_lab |grep PV
  Max PV                0
  Cur PV                3
  Act PV                3
</code></pre>

<p>Andiamo ad estendere il nostro gurppo di volumi con altri due device</p>

<pre><code class="language-bash">vgextend vg_lab $(losetup -Pf --show disk_4.img) $(losetup -Pf --show disk_5.img)
</code></pre>

<p>I nuovi dischi sono visibili in fondo, come si può vedere anche da  <code>vgdisplay</code> che mostra i 5 dischi tutti attivi.</p>

<pre><code class="language-bash">lsblk -o NAME,FSTYPE,SIZE,TYPE
  NAME               FSTYPE        SIZE      TYPE
  loop9              LVM2_member     1G      loop
  └─vg_lab-lv_lab_1                1,2G      lvm
  loop10             LVM2_member     1G      loop
  ├─vg_lab-lv_lab_1                1,2G      lvm
  └─vg_lab-lv_lab_3                860M      lvm
  loop11             LVM2_member     1G      loop
  ├─vg_lab-lv_lab_2               1000M      lvm
  └─vg_lab-lv_lab_3                860M      lvmchan
  loop12             LVM2_member     1G      loop
  loop13             LVM2_member     1G      loop

vgdisplay vg_lab |grep PV
  Max PV                0
  Cur PV                5
  Act PV                5
</code></pre>

<p>Potremo usare i nuovi dischi per estendere i volumi logici esistenti ma li impiegheremo invece per rimpiazzare i primi due dischi.</p>

<p><code>pvmove</code> distribuisce tutti gli extents del disco fra tutti i volumi fisici che hanno spazio a sufficienza. Se non dovesse essercene, restituirà un messaggio d&#39;errore.</p>

<pre><code class="language-bash">pvmove /dev/loop9
  /dev/loop9: Moved: 3,14%
  /dev/loop9: Moved: 100,00%
</code></pre>

<p>Alla fine dell&#39;operazione il disco s&#39;è liberato di tutti i suoi extents e può essere rimosso</p>

<pre><code class="language-bash">lsblk -o NAME,FSTYPE,SIZE,TYPE
  NAME               FSTYPE        SIZE      TYPE
  loop9              LVM2_member     1G      loop
  loop10             LVM2_member     1G      loop
  ├─vg_lab-lv_lab_1                1,2G      lvm
  └─vg_lab-lv_lab_3                860M      lvm
  loop11             LVM2_member     1G      loop
  ├─vg_lab-lv_lab_2               1000M      lvm
  └─vg_lab-lv_lab_3                860M      lvm
  loop12             LVM2_member     1G      loop
  └─vg_lab-lv_lab_1                1,2G      lvm
  loop13             LVM2_member     1G      loop
</code></pre>

<p>Prima si estrae il volume fisico dal gruppo di volumi e poi si rimuove il volume fisico e così può essere scollegato.</p>

<pre><code class="language-bash">vgreduce vg_lab /dev/loop9
pvremove /dev/loop9
</code></pre>

<p>Verifichiamo che il volume fisico non sia più presente.</p>

<pre><code class="language-bash">vgdisplay vg_lab |grep PV
  Max PV                0
  Cur PV                4
  Act PV                4
</code></pre>

<p>Procediamo allo stesso modo col secondo disco.</p>

<pre><code class="language-bash">pvmove /dev/loop10
  /dev/loop10: Moved: 9,80%
  /dev/loop10: Moved: 17,65%
  /dev/loop10: Moved: 100,00%

vgreduce vg_lab /dev/loop10
  Removed &#34;/dev/loop10&#34; from volume group &#34;vg_lab&#34;

pvremove /dev/loop10
  Labels on physical volume &#34;/dev/loop10&#34; successfully wiped.
</code></pre>

<p>In conclusione possiamo vedere il gruppo di volumi con solo 3 dischi, gli altri due completamente disimpegnati col gruppo di volumi ricostituitosi attorno ai 3 dischi rimanenti. E tutto spostando semplicemente gli extents dove c&#39;era disponibilità in maniera totalmente trasparente per il filesystem.</p>

<pre><code class="language-bash">vgdisplay vg_lab |grep PV
  Max PV                0
  Cur PV                3
  Act PV                3


lsblk -o NAME,FSTYPE,SIZE,TYPE
  NAME               FSTYPE        SIZE      TYPE
  loop9                              1G      loop
  loop10                             1G      loop
  loop11             LVM2_member     1G      loop
  ├─vg_lab-lv_lab_2               1000M      lvm
  └─vg_lab-lv_lab_3                860M      lvm
  loop12             LVM2_member     1G      loop
  └─vg_lab-lv_lab_1                1,2G      lvm
  loop13             LVM2_member     1G      loop
  ├─vg_lab-lv_lab_1                1,2G      lvm
  └─vg_lab-lv_lab_3                860M      lvm
</code></pre>

<h2 id="4-conclusione">4. Conclusione</h2>

<p>Ho solo sfiorato la complessità e le capacità offerte da LVM.</p>

<p>L&#39;estensione e la riduzione di volumi logici e di gruppi di volumi sono scenari di base. Tuttavia sono sufficienti per mostrare come sia semplice, con i volumi logici, compiere operazioni che con un filesystem partizionato in maniera classica sarebbero complicatissime.</p>

<p><a href="/aytin/tag:lvm" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">lvm</span></a> <a href="/aytin/tag:volumegroup" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">volumegroup</span></a> <a href="/aytin/tag:logicalvolume" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">logicalvolume</span></a> <a href="/aytin/tag:filesystem" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">filesystem</span></a> <a href="/aytin/tag:devicemapper" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">devicemapper</span></a></p>
]]></content:encoded>
      <guid>https://noblogo.org/aytin/ridimensionare-volumi-lvm</guid>
      <pubDate>Mon, 20 Apr 2026 21:13:18 +0000</pubDate>
    </item>
    <item>
      <title>Device Mapper: LUKS + LVM</title>
      <link>https://noblogo.org/aytin/device-mapper-luks-lvm</link>
      <description>&lt;![CDATA[luks-lvm&#xA;(segue da &#34;Cenni sulla creazione di pool di storage con LVM&#34;)&#xA;...anche se è la base per una serie di sviluppi interessanti. &#xA;&#xA;Come ormai sappiamo, device mapper è il framework del kernel Linux col quale mappare dispositivi a blocchi fisici su dispositivi a blocchi logici, che costituisce la base per fornire funzionalità ulteriori quali:&#xA;!--more--&#xA;&#xA;volumi logici&#xA;raid&#xA;cifratura (Full Disk Encryption)&#xA;snapshot di volumi&#xA;&#xA;Scenario 1&#xA;È molto comune per es. cifrare l&#39;intero disco e &#34;affettarlo&#34; con volumi logici in base alle proprie esigenze di partizionamento .&#xA;&#xA;Il doppio vantaggio è dato da:&#xA;&#xA;offuscamento totale dello schema di partizionamento&#xA;estrema versatilità / flessibilità del partizionamento grazie ai volumi logici &#xA;&#xA;Come si agisce?&#xA;&#xA;si cifra il dispositivo fisico&#xA;si crea un gruppo di volumi avente come volume fisico il volume cifrato&#xA;si creano i volumi logici in base allo schema di partizionamento desiderato.&#xA;&#xA;luks-lvm&#xA;Passo 1 - Inizializzazione&#xA;Simulo il mio dispositivo fisico ricorrendo ai loop device.&#xA;&#xA;Il &#34;disco&#34; avrà una grandezza simbolica di 2 GiB, non avrà header detachable. L&#39;algoritmo di hash sarà sha512 e la chiave sarà da 512 bit. Il resto è il default di luks2 (argon2id come pbkdf, per maggiori dettagli vedi cryptsetup --help)&#xA;1. Preparazione disco &#34;fisico&#34;&#xA;fallocate -l 2g cipherdisk.img&#xA;&#xA;2. loop device che simula l&#39;attach del dispositivo&#xA;DEV=$(losetup -Pf --show cipherdisk.img)&#xA;&#xA;3. Inizializzazione cifratura&#xA;cryptsetup luksFormat  \&#xA;    --type luks2 \&#xA;    --hash sha512 \&#xA;    --key-size 512 \&#xA;    $DEV&#xA;Passo 2&#xA;Il passo successivo consiste nell&#39;apertura del dispositivo cifrato e nella definizione dello schema di partizionamento in volumi logici&#xA;1. apertura del disco cifrato&#xA;cryptsetup open \&#xA;    --type luks2 \&#xA;    $DEV cipherdisk&#xA;Nell&#39;apertura, device mapper fa la sua prima magia.&#xA;&#xA;Infatti, se osserviamo lo stato dei dispositivi, vedremo una situazione simile:&#xA;lsblk&#xA;...&#xA;loop9                7:9    Kib0     2G  0 loop  &#xA;└─cipherdisk      252:3    0     2G  0 crypt &#xA;...&#xA;Cio vuol dire che sopra il dispositivo fisico, /dev/loop9 in questo caso, device mapper ha &#34;poggiato&#34; cipherdisk (/dev/mapper/cipherdisk).&#xA;&#xA;Questo sarà il nostro volume fisico per definire gruppi di volume e, conseguentemente, i volumi logici.&#xA;2. creazione gruppo di volumi&#xA;vgcreate vglab /dev/mapper/cipherdisk&#xA;&#xA;3. creazione volumi logici&#xA;lvcreate -n lvlab1 vglab -L 700M&#xA;lvcreate -n lvlab2 vglab -L 600M&#xA;lvcreate -n lvlab3 vglab -l 100%FREE&#xA;La situazione dei dispositivi è ora questa:&#xA;lsblk&#xA;...&#xA;loop9                7:9    0     2G  0 loop  &#xA;└─cipherdisk      252:3    0     2G  0 crypt&#xA;  ├─vglab-lvlab1 252:4    0   700M  0 lvm&#xA;  ├─vglab-lvlab2 252:5    0   600M  0 lvm&#xA;  └─vglab-lvlab3 252:6    0   728M  0 lvm&#xA;...&#xA;Sopra /dev/loop9 c&#39;è cipherdisk (/dev/mapper/cipherdisk) e sopra di esso, i 3 volumi logici&#xA;&#xA;lvlab1 (/dev/mapper/vglab-lvlab1)&#xA;lvlab2 (/dev/mapper/vglab-lvlab2)&#xA;lvlab3 (/dev/mapper/vglab-lvlab3)&#xA;&#xA;Formatto e monto i volumi logici&#xA;4. formattazione dei 3 volumi logici&#xA;mkfs.ext4 /dev/mapper/vglab-lvlab1&#xA;mkfs.ext4 /dev/mapper/vglab-lvlab2&#xA;mkfs.ext4 /dev/mapper/vglab-lvlab3&#xA;&#xA;5. creo e preparo i punti di mmontaggio&#xA;mkdir disk1 disk2 disk3&#xA;mount -t ext4 -o user,noauto,rw  /dev/mapper/vglab-lvlab1 disk1&#xA;mount -t ext4 -o user,noauto,rw  /dev/mapper/vglab-lvlab2 disk2&#xA;mount -t ext4 -o user,noauto,rw  /dev/mapper/vglab-lvlab3 disk3&#xA;chown $USER disk1 disk2 disk3&#xA;&#xA;6. unmount di tutti i dispositivi&#xA;umount disk1 disk2 disk3&#xA;vgchange -an vglab&#xA;cryptsetup close cipherdisk&#xA;losetup -d $DEV&#xA;Passo 3&#xA;Infine, per completezza, gli script di mount e unmount del dispositivo.&#xA;mount&#xA;1. attach del dispositivo&#xA;DEV=$(losetup -Pf --show cipherdisk.img)&#xA;&#xA;2. Apre il disco cifrato &#xA;cryptsetup open \&#xA;    --type luks2 \&#xA;    $DEV cipherdisk&#xA;&#xA;3. monta il gruppo di volume&#xA;(opzionale. L&#39;apertura del disco cifrato dovrebbe montare &#xA;automaticamente il gruppo di volumi)&#xA;vgchange -ay vglab&#xA;&#xA;4. monta i volumi logici&#xA;mount -t ext4 -o user,noauto,rw  /dev/mapper/vglab-lvlab1 disk1&#xA;mount -t ext4 -o user,noauto,rw  /dev/mapper/vglab-lvlab2 disk2&#xA;mount -t ext4 -o user,noauto,rw  /dev/mapper/vglab-lvlab3 disk3&#xA;unmount&#xA;1. smonta i 3 dischi&#xA;umount disk1 disk2 disk3&#xA;&#xA;2. smonta il gruppo di volumi&#xA;vgchange -an vglab&#xA;&#xA;3. chiude il disco cifrato&#xA;cryptsetup close cipherdisk&#xA;&#xA;4. &#34;stacca&#34; il dispositivo fisico&#xA;losetup -d $DEV&#xA;&#xA;Questo è ciò che si farebbe normalmente quando si vuole il full disk encryption sul proprio pc. Ma con una piccola eccezione.&#xA;&#xA;In realtà ciò che viene cifrata è una partizione quasi completa del disco, perché almeno una piccola partizione, quella contenente il boot, /BOOT, deve essere in chiaro per consentire:&#xA;&#xA;a UEFI di avviare GRUB che conosce le partizioni,&#xA;GRUB provvederà all&#39;avvio del kernel,&#xA;l&#39;avvio del kernel con initramfs chiederà la password per sbloccare la partizione cifrata.&#xA;&#xA;La cifratura totale (che proprio totale non sarà perché /boot/efi deve rimanere in chiaro) eleva di molto la complessità del setup iniziale.&#xA;&#xA;Affidare a GRUB la gestione della cifratura potrebbe voler dire, oltre alla complessità della configurazione iniziale che dovrà far ricorso a moduli come cryptodisk, che bisognerà rinunciare ad Argon2 perché GRUB ancora non lo supporta pienamente e, a differenza del kernel, non ha sufficiente potenza per farlo lavorare come si deve.&#xA;&#xA;Un buon compromesso potrebbe essere il ricorso ad un dispositivo esterno, es. una pendrive, che contenga tutta la partizione /boot in chiaro, anche  l&#39;header del disco cifrato.&#xA;GRUB dovrà solo sapere dove si trovi il boot, il resto dell&#39;avvio viene affidato come di consueto al kernel.&#xA;Scenario 2&#xA;Rimanendo nell&#39;ambito dell&#39;esplorazione di device mapper e della cifratura di dispositivi esterni non avviabili, immaginiamo qualcosa di più estremo.&#xA;&#xA;Supponiamo di dover custodire un segreto in qualcosa che non sia un semplice vault cifrato.&#xA;&#xA;Per diminuire il rischio di compromettere un unico vault, decido di dividerlo in varie parti, come gli horcrux ma con 0 malignità. Ogni parte sarà cifrata con una sua chiave che affiderò ad una persona diversa, di mia fiducia. Solo io, titolare ultimo del segreto, avrò accesso ai dati e solo la mia chiave (come l&#39;Anello che li domina tutti) aprirà il vault.&#xA;&#xA;Supponiamo di avere 3 dispositivi fisici (che nel laboratoro saranno simulati da loop device come al solito) per altrettanti &#34;custodi&#34;, ognuno dei quali verrà cifrato con la chiave e con dei parametri da consegnare al &#34;custode&#34; specifico.&#xA;&#xA;I 3 dispositivi cifrati costituiranno un gruppo di volumi con un volume logico (dai requisiti posti non c&#39;è necessità di sfruttare la flessibilità di partizionamento dei volumi logici) che verrà cifrato con la mia chiave master.&#xA;&#xA;luks-lvm-luks&#xA;&#x9;&#xA;Ogni dispositivo, volume logico finale compreso, prima della cifratura, verrà inizializzato con del rumore casuale. Questo per impedire ad un&#39;analisi forense di risalire ad un qualunque pattern sul dispositivo raw.&#xA;&#xA;Caratteristiche di ogni cifratura:&#xA;&#xA;dispositivi inizializzati con rumore casuale&#xA;header detachable&#xA;offset custom&#xA;key-file&#xA;default di argon2id (controlla il tuo default con cryptsetup benchmark)&#xA;&#xA;Quando vorrò aprire il vault, sarà necessario che i 3 &#34;custodi&#34; aprano il loro &#34;pezzo&#34; e solo io potrò ricostruire e decifrare il volume con la mia chiave.&#xA;&#xA;L&#39;inzializzazione con rumore casuale dei dispositivo, tralasciando l&#39;uso di dd su /dev/urandom che sappiamo essere CPU-intensive, può essere fatta ricorrendo:&#xA;&#xA;ad openssl rand, come sappiamo da &#34;Come generare una password o un keyfile sicuri (Trilogia Della Password – 1 di 3&#34;&#xA;oppure usando furbescamente cryptsetup, con cui apriamo il dispositivo in modalità plain, senza header, e riempiendolo di zeri (da /dev/zero con dd) che, attraversando il motore di cifratura, verranno scritti sul dispositivo come dati casuali ad alta velocità.&#xA;&#xA;################################&#xA;Emulazione dei device fisici &#xA;################################&#xA;fallocate -l 512M cipherdisk1.img&#xA;fallocate -l 512M cipherdisk2.img&#xA;fallocate -l 512M cipherdisk3.img&#xA;&#xA;###########################&#xA;creazione dei 3 keyfile &#xA;###########################&#xA;keyfile del custode n° 1&#xA;dd if=/dev/urandom bs=1024 count=4 | \&#xA;    gpg --yes -o cipherdisk1.key.gpg -c \&#xA;        --s2k-mode 3 \&#xA;        --s2k-count 32505856 \&#xA;        --s2k-cipher-algo aes256 \&#xA;        --s2k-digest-algo sha512 \&#xA;        --force-mdc -&#xA;&#xA;keyfile del custode n° 2&#xA;dd if=/dev/urandom bs=1024 count=4 | \&#xA;    gpg --yes -o cipherdisk2.key.gpg -c \&#xA;        --s2k-mode 3 \&#xA;        --s2k-count 32505856 \&#xA;        --s2k-cipher-algo aes256 \&#xA;        --s2k-digest-algo sha512 \&#xA;        --force-mdc -&#xA;&#xA;keyfile del custode n° 3&#xA;dd if=/dev/urandom bs=1024 count=4 | \&#xA;    gpg --yes -o cipherdisk3.key.gpg -c \&#xA;        --s2k-mode 3 \&#xA;        --s2k-count 32505856 \&#xA;        --s2k-cipher-algo aes256 \&#xA;        --s2k-digest-algo sha512 \&#xA;        --force-mdc -&#xA;&#xA;keyfile master&#xA;dd if=/dev/urandom bs=1024 count=4 | \&#xA;    gpg --yes -o master.key.gpg -c \&#xA;        --s2k-mode 3 \&#xA;        --s2k-count 32505856 \&#xA;        --s2k-cipher-algo aes256 \&#xA;        --s2k-digest-algo sha512 \&#xA;        --force-mdc -&#xA;&#xA;##########################&#xA;cifratura dei 3 device &#xA;##########################&#xA;attach dispositivo&#xA;DEV1=$(losetup -Pf --show cipherdisk1.img)&#xA;&#xA;inizializzazione dev1 con rumore casuale&#xA;cryptsetup open --type plain ${DEV1} container --key-file /dev/urandom&#xA;dd if=/dev/zero of=/dev/mapper/container status=progress&#xA;cryptsetup close container&#xA;&#xA;cifratura dispositivo n° 1&#xA;gpg -d cipherdisk1.key.gpg | \&#xA;    cryptsetup luksFormat  \&#xA;        --type luks2 \&#xA;        --key-file - \&#xA;        --header header1.img \&#xA;        --offset 32768 \&#xA;        --hash sha512 \&#xA;        --key-size 512 \&#xA;        --cipher aes-xts-plain64 \&#xA;        ${DEV1}&#xA;&#xA;attach dispositivo&#xA;DEV2=$(losetup -Pf --show cipherdisk2.img)&#xA;&#xA;inizializzazione dev2 con rumore casuale&#xA;cryptsetup open --type plain ${DEV2} container --key-file /dev/urandom&#xA;dd if=/dev/zero of=/dev/mapper/container status=progress&#xA;cryptsetup close container&#xA;&#xA;cifratura dispositivo n° 2&#xA;gpg -d cipherdisk2.key.gpg | \&#xA;    cryptsetup luksFormat  \&#xA;        --type luks2 \&#xA;        --key-file - \&#xA;        --header header2.img \&#xA;        --offset 36864 \&#xA;        --hash sha512 \&#xA;        --key-size 512 \&#xA;        --cipher aes-xts-plain64 \&#xA;        ${DEV2}&#xA;&#xA;attach dispositivo&#xA;DEV3=$(losetup -Pf --show cipherdisk3.img)&#xA;&#xA;inizializzazione dev3 con rumore casuale&#xA;cryptsetup open --type plain ${DEV3} container --key-file /dev/urandom&#xA;dd if=/dev/zero of=/dev/mapper/container status=progress&#xA;cryptsetup close container&#xA;&#xA;cifratura dispositivo n° 3&#xA;gpg -d cipherdisk3.key.gpg | \&#xA;    cryptsetup luksFormat  \&#xA;        --type luks2 \&#xA;        --key-file - \&#xA;        --header header3.img \&#xA;        --offset 40960 \&#xA;        --hash sha512 \&#xA;        --key-size 512 \&#xA;        --cipher aes-xts-plain64 \&#xA;        ${DEV3}&#xA;&#xA;##############################&#xA;Creazione gruppo di volumi &#xA;##############################&#xA;&#34;apro&#34; il volume 1&#xA;gpg -d cipherdisk1.key.gpg | \&#xA;    cryptsetup open \&#xA;         --type luks2 \&#xA;         --header header1.img \&#xA;         --key-file - \&#xA;         ${DEV1} cipherdisk1&#xA;&#xA;&#34;apro&#34; il volume 2&#xA;gpg -d cipherdisk2.key.gpg | \&#xA;    cryptsetup open \&#xA;         --type luks2 \&#xA;         --header header2.img \&#xA;         --key-file - \&#xA;         ${DEV2} cipherdisk2&#xA;&#xA;&#34;apro&#34; il volume 3&#xA;gpg -d cipherdisk3.key.gpg | \&#xA;    cryptsetup open \&#xA;         --type luks2 \&#xA;         --header header3.img \&#xA;         --key-file - \&#xA;         ${DEV3} cipherdisk3&#xA;&#xA;Creo il mio gruppo di volumi con i 3 volumi &#34;fisici&#34;:&#xA;1. /dev/mapper/cipherdisk1&#xA;2. /dev/mapper/cipherdisk2&#xA;3. /dev/mapper/cipherdisk3&#xA;vgcreate vgmaster /dev/mapper/cipherdisk1  /dev/mapper/cipherdisk2  /dev/mapper/cipherdisk3&#xA;&#xA;creazione dell&#39;unico volume logico&#xA;lvcreate -n lvmaster vgmaster -l 100%FREE&#xA;&#xA;################################&#xA;cifratura e mount del master &#xA;################################&#xA;cifratura dispositivo master&#xA;dd if=/dev/urandom of=/dev/mapper/vgmaster-lvmaster bs=1M count=32 status=progress&#xA;gpg -d master.key.gpg | \&#xA;    cryptsetup luksFormat  \&#xA;        --type luks2 \&#xA;        --key-file - \&#xA;        --header headermaster.img \&#xA;&#x9;&#x9;--offset 65536 \&#xA;        --hash sha512 \&#xA;        --key-size 512 \&#xA;        --cipher aes-xts-plain64 \&#xA;        /dev/mapper/vgmaster-lvmaster&#xA;&#xA;apriamo il dispositivo master&#xA;gpg -d master.key.gpg | \&#xA;    cryptsetup open \&#xA;         --type luks2 \&#xA;         --header headermaster.img \&#xA;         --key-file - \&#xA;         /dev/mapper/vgmaster-lvmaster cipherdiskmaster&#xA;&#xA;e finalmente lo formattiamo&#xA;mkfs.ext4 /dev/mapper/cipherdiskmaster&#xA;&#xA;Test: montiamo il disco&#xA;mkdir -p /run/media/master/diskmaster&#xA;chown -R ${USER}:${USER} /run/media/master/diskmaster&#xA;mount -t auto /dev/mapper/cipherdiskmaster /run/media/master/diskmaster&#xA;&#xA;Infine chiudiamo tutto&#xA;umount /run/media/master/diskmaster&#xA;cryptsetup close cipherdiskmaster&#xA;vgchange -an vgmaster&#xA;cryptsetup close cipherdisk1&#xA;cryptsetup close cipherdisk2&#xA;cryptsetup close cipherdisk3&#xA;losetup -d ${DEV1} ${DEV2} ${DEV3}&#xA;Dopo aver appurato che tutto funzioni, consegno ad ogni &#34;custode&#34; dispositivo, keyfile e header.&#xA;&#xA;Se un attaccante dovesse entrare in possesso di uno o più dispositivi, troverebbe solo un mucchio di dati incomprensibili.&#xA;&#xA;Posto che riuscisse a decifrare il dispositivo, troverebbe un pezzo di un gruppo di volumi, cifrato e inutilizzabile.&#xA;&#xA;Il master a questo punto non dovrà fare altro che aprire e chiudere il vault, dopo aver riunito tutti i pezzi, come segue:&#xA;&#xA;Apertura del vault&#xA;Attach dei dispositivi&#xA;DEV1=$(losetup -Pf --show cipherdisk1.img)&#xA;DEV2=$(losetup -Pf --show cipherdisk2.img)&#xA;DEV3=$(losetup -Pf --show cipherdisk3.img)&#xA;&#xA;&#34;apro&#34; il volume 1&#xA;gpg -d cipherdisk1.key.gpg | \&#xA;    cryptsetup open \&#xA;         --type luks2 \&#xA;         --header header1.img \&#xA;         --key-file - \&#xA;         ${DEV1} cipherdisk1&#xA;&#xA;&#34;apro&#34; il volume 2&#xA;gpg -d cipherdisk2.key.gpg | \&#xA;    cryptsetup open \&#xA;         --type luks2 \&#xA;         --header header2.img \&#xA;         --key-file - \&#xA;         ${DEV2} cipherdisk2&#xA;&#xA;&#34;apro&#34; il volume 3&#xA;gpg -d cipherdisk3.key.gpg | \&#xA;    cryptsetup open \&#xA;         --type luks2 \&#xA;         --header header3.img \&#xA;         --key-file - \&#xA;         ${DEV3} cipherdisk3&#xA;&#xA;(facoltativo) apre il gruppo di volumi&#xA;vgchange -ay vgmaster&#xA;&#xA;&#34;apre&#34; il master volume&#xA;gpg -d master.key.gpg | \&#xA;    cryptsetup open \&#xA;         --type luks2 \&#xA;         --header headermaster.img \&#xA;         --key-file - \&#xA;         /dev/mapper/vgmaster-lvmaster cipherdiskmaster&#xA;&#xA;Monta il volume&#xA;mount -t auto /dev/mapper/cipherdiskmaster /run/media/master/diskmaster&#xA;Chiusura del vault&#xA;smonta il volume cifrato&#xA;umount /run/media/master/diskmaster&#xA;&#xA;chiusura del vault master&#xA;cryptsetup close cipherdiskmaster&#xA;&#xA;chiusura del gruppo di volumi&#xA;vgchange -an vgmaster&#xA;&#xA;chiusura dei singoli vault cifrati&#xA;cryptsetup close cipherdisk1&#xA;cryptsetup close cipherdisk2&#xA;cryptsetup close cipherdisk3&#xA;&#xA;deattach dei dispositivi&#xA;losetup -d ${DEV1} ${DEV2} ${DEV3}&#xA;&#xA;#cryptsetup #devicemapper #dmcrypt #gpg #loseup #luks #lvm #loopdevice #storage]]&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://pixelfed.uno/storage/m/_v2/489827599091373610/fbedcc803-0ec729/JqVu1t3agiao/CSE9exMSdTVlv9adGCHXwSbkxvn9EPD0SPJNIsQo.jpg" alt="luks-lvm">
<em>(segue da <a href="https://noblogo.org/aytin/cenni-sulla-creazione-di-pool-di-storage-con-lvm/" rel="nofollow">“<strong>Cenni sulla creazione di pool di storage con LVM</strong>“</a>)</em>
...anche se è la base per una serie di sviluppi interessanti.</p>

<p>Come ormai sappiamo, <strong>device mapper</strong> è il framework del kernel Linux col quale mappare dispositivi a blocchi fisici su dispositivi a blocchi logici, che costituisce la base per fornire funzionalità ulteriori quali:
</p>
<ul><li>volumi logici</li>
<li>raid</li>
<li>cifratura (<strong>F</strong>ull <strong>D</strong>isk <strong>E</strong>ncryption)</li>
<li>snapshot di volumi</li></ul>

<h2 id="scenario-1">Scenario 1</h2>

<p>È molto comune per es. cifrare l&#39;intero disco e “affettarlo” con volumi logici in base alle proprie esigenze di partizionamento .</p>

<p>Il doppio vantaggio è dato da:</p>
<ol><li>offuscamento totale dello schema di partizionamento</li>
<li>estrema versatilità / flessibilità del partizionamento grazie ai volumi logici</li></ol>

<p>Come si agisce?</p>
<ol><li>si cifra il dispositivo fisico</li>
<li>si crea un gruppo di volumi avente come volume fisico il volume cifrato</li>
<li>si creano i volumi logici in base allo <strong>schema di partizionamento</strong> desiderato.</li></ol>

<p><img src="https://pixelfed.uno/storage/m/_v2/489827599091373610/fbedcc803-0ec729/e9tSS2DIxi6F/Bc8zWpFAR2KxQSK92F6I3Z6ocbA5E67bT3ziz1Ke.jpg" alt="luks-lvm"></p>

<h3 id="passo-1-inizializzazione">Passo 1 – Inizializzazione</h3>

<p>Simulo il mio dispositivo fisico ricorrendo ai <strong>loop device</strong>.</p>

<p>Il “disco” avrà una grandezza simbolica di 2 GiB, non avrà header detachable. L&#39;algoritmo di hash sarà sha512 e la chiave sarà da 512 bit. Il resto è il default di luks2 (argon2id come pbkdf, per maggiori dettagli vedi <code>cryptsetup --help</code>)</p>

<pre><code class="language-bash"># 1. Preparazione disco &#34;fisico&#34;
fallocate -l 2g cipher_disk.img

# 2. loop device che simula l&#39;attach del dispositivo
DEV=$(losetup -Pf --show cipher_disk.img)

# 3. Inizializzazione cifratura
cryptsetup luksFormat  \
    --type luks2 \
    --hash sha512 \
    --key-size 512 \
    $DEV
</code></pre>

<h3 id="passo-2">Passo 2</h3>

<p>Il passo successivo consiste nell&#39;apertura del dispositivo cifrato e nella definizione dello schema di partizionamento in volumi logici</p>

<pre><code class="language-bash"># 1. apertura del disco cifrato
cryptsetup open \
    --type luks2 \
    $DEV cipher_disk
</code></pre>

<p>Nell&#39;apertura, device mapper fa la sua prima magia.</p>

<p>Infatti, se osserviamo lo stato dei dispositivi, vedremo una situazione simile:</p>

<pre><code>lsblk
...
loop9                7:9    Kib0     2G  0 loop  
└─cipher_disk      252:3    0     2G  0 crypt 
...
</code></pre>

<p>Cio vuol dire che sopra il dispositivo fisico, <code>/dev/loop9</code>in questo caso, device mapper ha “poggiato” <strong>cipher_disk</strong> (<code>/dev/mapper/cipher_disk</code>).</p>

<p>Questo sarà il nostro volume fisico per definire gruppi di volume e, conseguentemente, i volumi logici.</p>

<pre><code class="language-bash"># 2. creazione gruppo di volumi
vgcreate vg_lab /dev/mapper/cipher_disk

# 3. creazione volumi logici
lvcreate -n lv_lab_1 vg_lab -L 700M
lvcreate -n lv_lab_2 vg_lab -L 600M
lvcreate -n lv_lab_3 vg_lab -l 100%FREE
</code></pre>

<p>La situazione dei dispositivi è ora questa:</p>

<pre><code>lsblk
...
loop9                7:9    0     2G  0 loop  
└─cipher_disk      252:3    0     2G  0 crypt
  ├─vg_lab-lv_lab_1 252:4    0   700M  0 lvm
  ├─vg_lab-lv_lab_2 252:5    0   600M  0 lvm
  └─vg_lab-lv_lab_3 252:6    0   728M  0 lvm
...
</code></pre>

<p>Sopra <code>/dev/loop9</code> c&#39;è <code>cipher_disk</code> (<code>/dev/mapper/cipher_disk</code>) e sopra di esso, i 3 volumi logici</p>
<ul><li><code>lv_lab_1</code> (<code>/dev/mapper/vg_lab-lv_lab_1</code>)</li>
<li><code>lv_lab_2</code> (<code>/dev/mapper/vg_lab-lv_lab_2</code>)</li>
<li><code>lv_lab_3</code> (<code>/dev/mapper/vg_lab-lv_lab_3</code>)</li></ul>

<p>Formatto e monto i volumi logici</p>

<pre><code class="language-bash"># 4. formattazione dei 3 volumi logici
mkfs.ext4 /dev/mapper/vg_lab-lv_lab_1
mkfs.ext4 /dev/mapper/vg_lab-lv_lab_2
mkfs.ext4 /dev/mapper/vg_lab-lv_lab_3

# 5. creo e preparo i punti di mmontaggio
mkdir disk_1 disk_2 disk_3
mount -t ext4 -o user,noauto,rw  /dev/mapper/vg_lab-lv_lab_1 disk_1
mount -t ext4 -o user,noauto,rw  /dev/mapper/vg_lab-lv_lab_2 disk_2
mount -t ext4 -o user,noauto,rw  /dev/mapper/vg_lab-lv_lab_3 disk_3
chown $USER disk_1 disk_2 disk_3

# 6. unmount di tutti i dispositivi
umount disk_1 disk_2 disk_3
vgchange -an vg_lab
cryptsetup close cipher_disk
losetup -d $DEV
</code></pre>

<h3 id="passo-3">Passo 3</h3>

<p>Infine, per completezza, gli script di mount e unmount del dispositivo.
<strong>mount</strong></p>

<pre><code class="language-bash"># 1. attach del dispositivo
DEV=$(losetup -Pf --show cipher_disk.img)

# 2. Apre il disco cifrato 
cryptsetup open \
    --type luks2 \
    $DEV cipher_disk

# 3. monta il gruppo di volume
# (opzionale. L&#39;apertura del disco cifrato dovrebbe montare 
# automaticamente il gruppo di volumi)
vgchange -ay vg_lab

# 4. monta i volumi logici
mount -t ext4 -o user,noauto,rw  /dev/mapper/vg_lab-lv_lab_1 disk_1
mount -t ext4 -o user,noauto,rw  /dev/mapper/vg_lab-lv_lab_2 disk_2
mount -t ext4 -o user,noauto,rw  /dev/mapper/vg_lab-lv_lab_3 disk_3
</code></pre>

<p><strong>unmount</strong></p>

<pre><code class="language-bash"># 1. smonta i 3 dischi
umount disk_1 disk_2 disk_3

# 2. smonta il gruppo di volumi
vgchange -an vg_lab

# 3. chiude il disco cifrato
cryptsetup close cipher_disk

# 4. &#34;stacca&#34; il dispositivo fisico
losetup -d $DEV
</code></pre>

<p>Questo è ciò che si farebbe normalmente quando si vuole il full disk encryption sul proprio pc. Ma con una piccola eccezione.</p>

<p>In realtà ciò che viene cifrata è una partizione quasi completa del disco, perché almeno una piccola partizione, quella contenente il boot, <code>/BOOT</code>, deve essere in chiaro per consentire:</p>
<ul><li>a UEFI di avviare GRUB che conosce le partizioni,</li>
<li>GRUB provvederà all&#39;avvio del kernel,</li>
<li>l&#39;avvio del kernel con initramfs chiederà la password per sbloccare la partizione cifrata.</li></ul>

<p>La cifratura totale (che proprio totale non sarà perché <code>/boot/efi</code> deve rimanere in chiaro) eleva di molto la complessità del setup iniziale.</p>

<p>Affidare a GRUB la gestione della cifratura potrebbe voler dire, oltre alla complessità della configurazione iniziale che dovrà far ricorso a moduli come <code>cryptodisk</code>, che bisognerà rinunciare ad Argon2 perché GRUB ancora non lo supporta pienamente e, a differenza del kernel, non ha sufficiente potenza per farlo lavorare come si deve.</p>

<p>Un buon compromesso potrebbe essere il ricorso ad un dispositivo esterno, es. una pendrive, che contenga tutta la partizione <code>/boot</code> in chiaro, anche  l&#39;header del disco cifrato.
GRUB dovrà solo sapere dove si trovi il boot, il resto dell&#39;avvio viene affidato come di consueto al kernel.</p>

<h2 id="scenario-2">Scenario 2</h2>

<p>Rimanendo nell&#39;ambito dell&#39;esplorazione di device mapper e della cifratura di dispositivi esterni non avviabili, immaginiamo qualcosa di più estremo.</p>

<p>Supponiamo di dover custodire un segreto in qualcosa che non sia un semplice vault cifrato.</p>

<p>Per diminuire il rischio di compromettere un unico vault, decido di dividerlo in varie parti, come gli horcrux ma con 0 malignità. Ogni parte sarà cifrata con una sua chiave che affiderò ad una persona diversa, di mia fiducia. Solo io, titolare ultimo del segreto, avrò accesso ai dati e solo la mia chiave (come l&#39;Anello che li domina tutti) aprirà il vault.</p>

<p>Supponiamo di avere 3 dispositivi fisici (che nel laboratoro saranno simulati da loop device come al solito) per altrettanti “custodi”, ognuno dei quali verrà cifrato con la chiave e con dei parametri da consegnare al “custode” specifico.</p>

<p>I 3 dispositivi cifrati costituiranno un gruppo di volumi con un volume logico (dai requisiti posti non c&#39;è necessità di sfruttare la flessibilità di partizionamento dei volumi logici) che verrà cifrato con la mia chiave master.</p>

<p><img src="https://pixelfed.uno/storage/m/_v2/489827599091373610/fbedcc803-0ec729/pnRafhfUlqts/Wl6xNlvrbnZJIjRVRbAIM0fmo6KZAnYoy1Wga0C2.jpg" alt="luks-lvm-luks"></p>

<p>Ogni dispositivo, volume logico finale compreso, prima della cifratura, verrà inizializzato con del rumore casuale. Questo per impedire ad un&#39;analisi forense di risalire ad un qualunque pattern sul dispositivo raw.</p>

<p>Caratteristiche di ogni cifratura:</p>
<ul><li>dispositivi inizializzati con rumore casuale</li>
<li>header detachable</li>
<li>offset custom</li>
<li>key-file</li>
<li>default di argon2id (controlla il tuo default con <code>cryptsetup benchmark</code>)</li></ul>

<p>Quando vorrò aprire il vault, sarà necessario che i 3 “custodi” aprano il loro “pezzo” e solo io potrò ricostruire e decifrare il volume con la mia chiave.</p>

<p>L&#39;inzializzazione con rumore casuale dei dispositivo, tralasciando l&#39;uso di <code>dd</code> su <code>/dev/urandom</code> che sappiamo essere CPU-intensive, può essere fatta ricorrendo:</p>
<ul><li>ad <code>openssl rand</code>, come sappiamo da <em><a href="https://noblogo.org/aytin/come-generare-una-password-o-un-keyfile-sicuri-trilogia-della-password-1-di/" rel="nofollow">“<strong>Come generare una password o un keyfile sicuri (Trilogia Della Password – 1 di 3</strong>“</a></em></li>
<li>oppure usando furbescamente <strong>cryptsetup</strong>, con cui apriamo il dispositivo in modalità plain, senza header, e riempiendolo di zeri (da <code>/dev/zero</code> con <code>dd</code>) che, attraversando il motore di cifratura, verranno scritti sul dispositivo come dati casuali ad alta velocità.</li></ul>

<pre><code class="language-bash">################################
# Emulazione dei device fisici #
################################
fallocate -l 512M cipher_disk_1.img
fallocate -l 512M cipher_disk_2.img
fallocate -l 512M cipher_disk_3.img



###########################
# creazione dei 3 keyfile #
###########################
# keyfile del custode n° 1
dd if=/dev/urandom bs=1024 count=4 | \
    gpg --yes -o cipher_disk_1.key.gpg -c \
        --s2k-mode 3 \
        --s2k-count 32505856 \
        --s2k-cipher-algo aes256 \
        --s2k-digest-algo sha512 \
        --force-mdc -

# keyfile del custode n° 2
dd if=/dev/urandom bs=1024 count=4 | \
    gpg --yes -o cipher_disk_2.key.gpg -c \
        --s2k-mode 3 \
        --s2k-count 32505856 \
        --s2k-cipher-algo aes256 \
        --s2k-digest-algo sha512 \
        --force-mdc -

# keyfile del custode n° 3
dd if=/dev/urandom bs=1024 count=4 | \
    gpg --yes -o cipher_disk_3.key.gpg -c \
        --s2k-mode 3 \
        --s2k-count 32505856 \
        --s2k-cipher-algo aes256 \
        --s2k-digest-algo sha512 \
        --force-mdc -

# keyfile master
dd if=/dev/urandom bs=1024 count=4 | \
    gpg --yes -o master.key.gpg -c \
        --s2k-mode 3 \
        --s2k-count 32505856 \
        --s2k-cipher-algo aes256 \
        --s2k-digest-algo sha512 \
        --force-mdc -



##########################
# cifratura dei 3 device #
##########################
# attach dispositivo
DEV_1=$(losetup -Pf --show cipher_disk_1.img)

# inizializzazione dev_1 con rumore casuale
cryptsetup open --type plain ${DEV_1} container --key-file /dev/urandom
dd if=/dev/zero of=/dev/mapper/container status=progress
cryptsetup close container

# cifratura dispositivo n° 1
gpg -d cipher_disk_1.key.gpg | \
    cryptsetup luksFormat  \
        --type luks2 \
        --key-file - \
        --header header_1.img \
        --offset 32768 \
        --hash sha512 \
        --key-size 512 \
        --cipher aes-xts-plain64 \
        ${DEV_1}

# attach dispositivo
DEV_2=$(losetup -Pf --show cipher_disk_2.img)

# inizializzazione dev_2 con rumore casuale
cryptsetup open --type plain ${DEV_2} container --key-file /dev/urandom
dd if=/dev/zero of=/dev/mapper/container status=progress
cryptsetup close container

# cifratura dispositivo n° 2
gpg -d cipher_disk_2.key.gpg | \
    cryptsetup luksFormat  \
        --type luks2 \
        --key-file - \
        --header header_2.img \
        --offset 36864 \
        --hash sha512 \
        --key-size 512 \
        --cipher aes-xts-plain64 \
        ${DEV_2}

# attach dispositivo
DEV_3=$(losetup -Pf --show cipher_disk_3.img)

# inizializzazione dev_3 con rumore casuale
cryptsetup open --type plain ${DEV_3} container --key-file /dev/urandom
dd if=/dev/zero of=/dev/mapper/container status=progress
cryptsetup close container

# cifratura dispositivo n° 3
gpg -d cipher_disk_3.key.gpg | \
    cryptsetup luksFormat  \
        --type luks2 \
        --key-file - \
        --header header_3.img \
        --offset 40960 \
        --hash sha512 \
        --key-size 512 \
        --cipher aes-xts-plain64 \
        ${DEV_3}



##############################
# Creazione gruppo di volumi #
##############################
# &#34;apro&#34; il volume 1
gpg -d cipher_disk_1.key.gpg | \
    cryptsetup open \
         --type luks2 \
         --header header_1.img \
         --key-file - \
         ${DEV_1} cipher_disk_1

# &#34;apro&#34; il volume 2
gpg -d cipher_disk_2.key.gpg | \
    cryptsetup open \
         --type luks2 \
         --header header_2.img \
         --key-file - \
         ${DEV_2} cipher_disk_2

# &#34;apro&#34; il volume 3
gpg -d cipher_disk_3.key.gpg | \
    cryptsetup open \
         --type luks2 \
         --header header_3.img \
         --key-file - \
         ${DEV_3} cipher_disk_3

# Creo il mio gruppo di volumi con i 3 volumi &#34;fisici&#34;:
# 1. /dev/mapper/cipher_disk_1
# 2. /dev/mapper/cipher_disk_2
# 3. /dev/mapper/cipher_disk_3
vgcreate vg_master /dev/mapper/cipher_disk_1  /dev/mapper/cipher_disk_2  /dev/mapper/cipher_disk_3

# creazione dell&#39;unico volume logico
lvcreate -n lv_master vg_master -l 100%FREE



################################
# cifratura e mount del master #
################################
# cifratura dispositivo master
dd if=/dev/urandom of=/dev/mapper/vg_master-lv_master bs=1M count=32 status=progress
gpg -d master.key.gpg | \
    cryptsetup luksFormat  \
        --type luks2 \
        --key-file - \
        --header header_master.img \
		--offset 65536 \
        --hash sha512 \
        --key-size 512 \
        --cipher aes-xts-plain64 \
        /dev/mapper/vg_master-lv_master

# apriamo il dispositivo master
gpg -d master.key.gpg | \
    cryptsetup open \
         --type luks2 \
         --header header_master.img \
         --key-file - \
         /dev/mapper/vg_master-lv_master cipher_disk_master

# e finalmente lo formattiamo
mkfs.ext4 /dev/mapper/cipher_disk_master

# Test: montiamo il disco
mkdir -p /run/media/master/disk_master
chown -R ${USER}:${USER} /run/media/master/disk_master
mount -t auto /dev/mapper/cipher_disk_master /run/media/master/disk_master

# Infine chiudiamo tutto
umount /run/media/master/disk_master
cryptsetup close cipher_disk_master
vgchange -an vg_master
cryptsetup close cipher_disk_1
cryptsetup close cipher_disk_2
cryptsetup close cipher_disk_3
losetup -d ${DEV_1} ${DEV_2} ${DEV_3}
</code></pre>

<p>Dopo aver appurato che tutto funzioni, consegno ad ogni “custode” dispositivo, keyfile e header.</p>

<p>Se un attaccante dovesse entrare in possesso di uno o più dispositivi, troverebbe solo un mucchio di dati incomprensibili.</p>

<p>Posto che riuscisse a decifrare il dispositivo, troverebbe un pezzo di un gruppo di volumi, cifrato e inutilizzabile.</p>

<p>Il master a questo punto non dovrà fare altro che aprire e chiudere il vault, dopo aver riunito tutti i pezzi, come segue:</p>

<p><strong>Apertura del vault</strong></p>

<pre><code class="language-bash"># Attach dei dispositivi
DEV_1=$(losetup -Pf --show cipher_disk_1.img)
DEV_2=$(losetup -Pf --show cipher_disk_2.img)
DEV_3=$(losetup -Pf --show cipher_disk_3.img)

# &#34;apro&#34; il volume 1
gpg -d cipher_disk_1.key.gpg | \
    cryptsetup open \
         --type luks2 \
         --header header_1.img \
         --key-file - \
         ${DEV_1} cipher_disk_1

# &#34;apro&#34; il volume 2
gpg -d cipher_disk_2.key.gpg | \
    cryptsetup open \
         --type luks2 \
         --header header_2.img \
         --key-file - \
         ${DEV_2} cipher_disk_2

# &#34;apro&#34; il volume 3
gpg -d cipher_disk_3.key.gpg | \
    cryptsetup open \
         --type luks2 \
         --header header_3.img \
         --key-file - \
         ${DEV_3} cipher_disk_3

# (facoltativo) apre il gruppo di volumi
vgchange -ay vg_master

# &#34;apre&#34; il master volume
gpg -d master.key.gpg | \
    cryptsetup open \
         --type luks2 \
         --header header_master.img \
         --key-file - \
         /dev/mapper/vg_master-lv_master cipher_disk_master

# Monta il volume
mount -t auto /dev/mapper/cipher_disk_master /run/media/master/disk_master
</code></pre>

<p><strong>Chiusura del vault</strong></p>

<pre><code class="language-bash"># smonta il volume cifrato
umount /run/media/master/disk_master

# chiusura del vault master
cryptsetup close cipher_disk_master

# chiusura del gruppo di volumi
vgchange -an vg_master

# chiusura dei singoli vault cifrati
cryptsetup close cipher_disk_1
cryptsetup close cipher_disk_2
cryptsetup close cipher_disk_3

# deattach dei dispositivi
losetup -d ${DEV_1} ${DEV_2} ${DEV_3}
</code></pre>

<p><a href="/aytin/tag:cryptsetup" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">cryptsetup</span></a> <a href="/aytin/tag:devicemapper" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">devicemapper</span></a> <a href="/aytin/tag:dmcrypt" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">dmcrypt</span></a> <a href="/aytin/tag:gpg" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">gpg</span></a> <a href="/aytin/tag:loseup" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">loseup</span></a> <a href="/aytin/tag:luks" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">luks</span></a> <a href="/aytin/tag:lvm" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">lvm</span></a> <a href="/aytin/tag:loopdevice" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">loopdevice</span></a> <a href="/aytin/tag:storage" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">storage</span></a></p>
]]></content:encoded>
      <guid>https://noblogo.org/aytin/device-mapper-luks-lvm</guid>
      <pubDate>Mon, 23 Feb 2026 10:58:17 +0000</pubDate>
    </item>
    <item>
      <title>Cenni sulla creazione di pool di storage con LVM</title>
      <link>https://noblogo.org/aytin/cenni-sulla-creazione-di-pool-di-storage-con-lvm</link>
      <description>&lt;![CDATA[lvm&#xA;&#xA;Premessa&#xA;Supponiamo di voler aggregare dei dispositivi in un unico storage. Potrebbero essere 3 hd nella propria workstation. O un pool di pendrive.&#xA;&#xA;Ognuno di essi avrà dimensioni differenti e se le usassi singolarmente, quasi certamente la loro dimensione condizionerebbe il loro utilizzo.&#xA;&#xA;Visto che la volta scorsa ho accennato a device mapper, vale la pena spendere due parole sui volumi logici e sulla loro utilità.&#xA;!--more--&#xA;Il fatto di poter aggregare dispositivi fisici diversi in un unico (o più) volume virtuale che si può affettare a piacimento, è un&#39;innegabile flessibilità. Inoltre, ogni operazione di estensione o riduzione sarà eseguita sui volumi logici che rappresentano l&#39;astrazione dei dispositivi fisici sottostanti.&#xA;&#xA;Si deve tenere conto però che aggregare dispositivi di natura molto  differente (ad es. dischi ssd e dischi a rotazione) può comportare un&#39;imprevedibilità non trascurabile in termini di prestazioni.&#xA;&#xA;Tutto ciò avviene attraverso dei tool disponibili nella userland grazie ai quali:&#xA;&#xA;si fa il mapping fra dispositivi fisici e volumi fisici&#xA;si aggregano i   volumi fisici in gruppi di volumi&#xA;si &#34;affettano&#34; i gruppi di volume in volumi logici&#xA;&#xA;Oltre a poter rimuovere/aggiungere/ridimensionare volumi fisici, gruppi di volume e volumi logici.&#xA;Prova sul campo&#xA;Nel nostro laboratorio supporremo di avere 3 dischi di dimensioni differenti che vogliamo usare come un unico volume da partizionare in base ad una necessità che non sia legata alla dimensione del dispositivo fisico.&#xA;&#xA;Per simulare tutto ciò, farò uso di file associati dinamicamente a dei loop device attraverso losetup&#xA;Emulazione - Fase 1 di 2&#xA;Si inizia con la creazione di 3 file container di dimensioni differenti che emuleranno i &#34;device fisici&#34;&#xA;fallocate -l 800M disco1.img&#xA;fallocate -l 500M disco2.img&#xA;fallocate -l 300M disco3.img&#xA;Emulazione - Fase 2 di 2&#xA;I block device, solitamente originati  nel momento in cui avviene la connessione fisica all&#39;host, in questo caso saranno ottenuti associando  i file container ai loop device con losetup&#xA;losetup -Pf --show disco1.img&#xA;  /dev/loop12&#xA;losetup -Pf --show disco2.img&#xA;  /dev/loop13&#xA;losetup -Pf --show disco3.img&#xA;  /dev/loop14&#xA;Tutto ciò che è stato fatto finora, serve solo ai fini dell&#39;emulazione. Con dispositivi fisici si può cominciare direttamente dal passo 1&#xA;Passo 1&#xA;Prendiamo nota dell&#39;ip dei loop device( 12,13,14 in questo esempio) e cominciamo a creare i physical volume.&#xA;pvcreate /dev/loop12&#xA;pvcreate /dev/loop13&#xA;pvcreate /dev/loop14 &#xA;Passo 2&#xA;Dopo aver mappato i volumi fisici con i dispositivi, si farà l&#39;aggregazione in un unico volume group. &#xA;vgcreate vglab /dev/loop12 /dev/loop13 /dev/loop14&#xA;Passo 3&#xA;Infine, la creazione dei logical volume.&#xA;I volumi logici saranno di 100 MiB, 700 MiB, 788 MiB. Non ne fanno parte i 12 MiB dell&#39;header LVM (4 MiB per ogni disco fisico):&#xA;lvcreate -n lvlab1 vglab -L 100M&#xA;lvcreate -n lvlab2 vglab -L 700M&#xA;lvcreate -n lvlab3 vglab -l 100%FREE&#xA;Questa definizione va bene per la didattica.&#xA;&#xA;Dilingentemente abbiamo fatto ogni singolo passaggio come bravi scolaretti, ma siccome siamo bravi e c&#39;è un modo più compatto per eseguire alcuni passaggi, vale la pena scoprire quali.&#xA;&#xA;Tralasciando la fase di inizializzazione, mi riferisco ai primi 3 passi, che possono collassare in un unico passaggio perché la creazione di un volume group nel passo 3, noto il dispositivo a blocchi del passo 1, può creare implicitamente i physical volume del passo 2. &#xA;&#xA;In realtà i passi 1 e 2 possono collassare in unico passaggio perché la creazione di un volume group crea contestualmente anche i physical volume.&#xA;&#xA;E quindi, emulazione a parte, sintetizzando:&#xA;Passo 1bis (passi 1, 2, 3 e 4):&#xA;vgcreate vglab /dev/loop12 /dev/loop13 /dev/loop14 &#xA;&#xA;lvcreate -n lvlab1 vglab -L 100M&#xA;lvcreate -n lvlab2 vglab -L 700M&#xA;lvcreate -n lvlab3 vglab -l 100%FREE&#xA;Questo è il minimo indispensabile per creare dei volumi logici.&#xA;&#xA;Dopo aver creato i volumi logici, bisognerà utilizzarli.&#xA;&#xA;I volumi logici sono volumi a cui device mapper fa corrispondere dei block device virtuali sui quali si creeranno dei file system con la formattazione (un exfat e due ext4), come avviene con qualunque altro volume fisico attraverso il corrispondente block device, e si creeranno i punti di montaggio. &#xA;creazione punti di mount&#xA;mkdir  disco1 disco2 disco3&#xA;&#xA;formattazione volumi logici&#xA;mkfs.exfat -L &#34;Disco 1&#34; /dev/mapper/vglab-lvlab1 &#xA;mkfs.ext4 -L &#34;Disco 2&#34; /dev/mapper/vglab-lvlab2&#xA;mkfs.ext4 -L &#34;Disco 3&#34; /dev/mapper/vglab-lvlab3&#xA;lvm&#xA;&#xA;Mount LVM&#xA;Ogni volta che dovremo usare i volumi logici faremo così:&#xA;vgchange -ay vglab&#xA;mount -t exfat -o defaults /dev/mapper/vglab-lvlab1 disco1&#xA;mount -t ext4 -o defaults /dev/mapper/vglab-lvlab2 disco2&#xA;mount -t ext4 -o defaults /dev/mapper/vglab-lvlab3 disco3&#xA;Umount LVM&#xA;Per smontarli invece basterà:&#xA;umount disco1 disco2 disco3&#xA;vgchange -an vglab&#xA;Tutto quello che s&#39;è visto finora, risponde all&#39;esigenza iniziale: come posso aggregare più volumi in unico volume?&#xA;&#xA;Ma riprendendiamo il passo 1bis, per vedere qualcosa di completamente inutile (all&#39;apparenza) ma non per questo meno interessante.&#xA;&#xA;Passo 1bis&#xA;Fin qua nulla di nuovo.&#xA;vgcreate vglab $(losetup -Pf --show disco1.img) $(losetup -Pf --show disco2.img) $(losetup -Pf --show disco3.img) &#xA;&#xA;lvcreate -n lvlab1 vglab -L 100M&#xA;lvcreate -n lvlab2 vglab -L 700M&#xA;lvcreate -n lvlab3 vglab -l 100%FREE&#xA;&#xA;Passo 2&#xA;vgcreate vglab2 $(losetup -Pf --show /dev/vglab/lvlab3)&#xA;lvcreate -n lvlab4 vglab2 -l 100%FREE&#xA;La particolarità del passo 2, completamente inutile, ha il solo scopo di mostrare come device mapper mi permetta di stratificare i volumi virtuali attraverso i corrispondenti dispositivi a blocchi virtuali per creare delle vere e proprie matrioske di volumi virtuali.&#xA;&#xA;nested lvm&#xA;&#xA;In questo caso,  /dev/mapper/vglab-lv\lab\3 diventa un dispositivo a blocchi su un loop device ed è un attimo che quel dispositivo a blocchi diventi a sua volte un gruppo di volumi su cui creare un ulteriore  volume logico.&#xA;&#xA;Un discreto nonsense anche se... (to be continued)_&#xA;&#xA;#lvm #devicemapper #logicalvolume #volumegroup #loopdevice]]&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://pixelfed.uno/storage/m/_v2/489827599091373610/7321b8e85-c3df53/9yUu94KMzjel/9mhHuMxvnEmlvApYNEa2mIFVsU2393xMvfrpyNqp.png" alt="lvm"></p>

<h2 id="premessa">Premessa</h2>

<p>Supponiamo di voler aggregare dei dispositivi in un unico storage. Potrebbero essere 3 hd nella propria workstation. O un pool di pendrive.</p>

<p>Ognuno di essi avrà dimensioni differenti e se le usassi singolarmente, quasi certamente la loro dimensione condizionerebbe il loro utilizzo.</p>

<p>Visto che <a href="https://noblogo.org/aytin/come-creare-un-file-container" rel="nofollow">la volta scorsa</a> ho accennato a <strong>device mapper</strong>, vale la pena spendere due parole sui volumi logici e sulla loro utilità.

Il fatto di poter aggregare dispositivi fisici diversi in un unico (o più) volume virtuale che si può affettare a piacimento, è un&#39;innegabile flessibilità. Inoltre, ogni operazione di estensione o riduzione sarà eseguita sui <strong>volumi logici</strong> che rappresentano l&#39;astrazione dei dispositivi fisici sottostanti.</p>

<p>Si deve tenere conto però che aggregare dispositivi di natura molto  differente (ad es. dischi ssd e dischi a rotazione) può comportare un&#39;imprevedibilità non trascurabile in termini di prestazioni.</p>

<p>Tutto ciò avviene attraverso dei tool disponibili nella userland grazie ai quali:</p>
<ol><li>si fa il mapping fra dispositivi fisici e <strong>volumi fisici</strong></li>
<li>si aggregano i   volumi fisici in <strong>gruppi di volumi</strong></li>
<li>si “affettano” i gruppi di volume in <strong>volumi logici</strong></li></ol>

<p>Oltre a poter rimuovere/aggiungere/ridimensionare volumi fisici, gruppi di volume e volumi logici.</p>

<h2 id="prova-sul-campo">Prova sul campo</h2>

<p>Nel nostro laboratorio supporremo di avere 3 dischi di dimensioni differenti che vogliamo usare come un unico volume da partizionare in base ad una necessità che non sia legata alla dimensione del dispositivo fisico.</p>

<p>Per simulare tutto ciò, farò uso di file associati dinamicamente a dei loop device attraverso <code>losetup</code></p>

<h3 id="emulazione-fase-1-di-2">Emulazione – Fase 1 di 2</h3>

<p>Si inizia con la creazione di 3 file container di dimensioni differenti che emuleranno i “device fisici”</p>

<pre><code class="language-bash">fallocate -l 800M disco1.img
fallocate -l 500M disco2.img
fallocate -l 300M disco3.img
</code></pre>

<h3 id="emulazione-fase-2-di-2">Emulazione – Fase 2 di 2</h3>

<p>I block device, solitamente originati  nel momento in cui avviene la connessione fisica all&#39;host, in questo caso saranno ottenuti associando  i file container ai loop device con <code>losetup</code></p>

<pre><code class="language-bash">losetup -Pf --show disco1.img
  /dev/loop12
losetup -Pf --show disco2.img
  /dev/loop13
losetup -Pf --show disco3.img
  /dev/loop14
</code></pre>

<p>Tutto ciò che è stato fatto finora, serve solo ai fini dell&#39;emulazione. Con dispositivi fisici si può cominciare direttamente dal <strong>passo 1</strong></p>

<h3 id="passo-1">Passo 1</h3>

<p>Prendiamo nota dell&#39;ip dei loop device( 12,13,14 in questo esempio) e cominciamo a creare i <strong>physical volume</strong>.</p>

<pre><code class="language-bash">pvcreate /dev/loop12
pvcreate /dev/loop13
pvcreate /dev/loop14 
</code></pre>

<h3 id="passo-2">Passo 2</h3>

<p>Dopo aver mappato i volumi fisici con i dispositivi, si farà l&#39;aggregazione in un unico <strong>volume group</strong>.</p>

<pre><code class="language-bash">vgcreate vg_lab /dev/loop12 /dev/loop13 /dev/loop14
</code></pre>

<h3 id="passo-3">Passo 3</h3>

<p>Infine, la creazione dei <strong>logical volume</strong>.
I volumi logici saranno di 100 MiB, 700 MiB, 788 MiB. Non ne fanno parte i 12 MiB dell&#39;header LVM (4 MiB per ogni disco fisico):</p>

<pre><code class="language-bash">lvcreate -n lv_lab_1 vg_lab -L 100M
lvcreate -n lv_lab_2 vg_lab -L 700M
lvcreate -n lv_lab_3 vg_lab -l 100%FREE
</code></pre>

<p>Questa definizione va bene per la didattica.</p>

<p>Dilingentemente abbiamo fatto ogni singolo passaggio come bravi scolaretti, ma siccome siamo bravi e c&#39;è un modo più compatto per eseguire alcuni passaggi, vale la pena scoprire quali.</p>

<p>Tralasciando la fase di inizializzazione, mi riferisco ai primi 3 passi, che possono collassare in un unico passaggio perché la creazione di un volume group nel passo 3, noto il dispositivo a blocchi del passo 1, può creare implicitamente i physical volume del passo 2.</p>

<p>In realtà i passi 1 e 2 possono collassare in unico passaggio perché la creazione di un volume group crea contestualmente anche i physical volume.</p>

<p>E quindi, emulazione a parte, sintetizzando:</p>

<h3 id="passo-1bis-passi-1-2-3-e-4">Passo 1bis (passi 1, 2, 3 e 4):</h3>

<pre><code class="language-bash">vgcreate vg_lab /dev/loop12 /dev/loop13 /dev/loop14 

lvcreate -n lv_lab_1 vg_lab -L 100M
lvcreate -n lv_lab_2 vg_lab -L 700M
lvcreate -n lv_lab_3 vg_lab -l 100%FREE
</code></pre>

<p>Questo è il minimo indispensabile per creare dei volumi logici.</p>

<p>Dopo aver creato i volumi logici, bisognerà utilizzarli.</p>

<p>I volumi logici sono volumi a cui device mapper fa corrispondere dei block device virtuali sui quali si creeranno dei file system con la formattazione (un exfat e due ext4), come avviene con qualunque altro volume fisico attraverso il corrispondente block device, e si creeranno i punti di montaggio.</p>

<pre><code class="language-bash"># creazione punti di mount
mkdir  disco1 disco2 disco3

# formattazione volumi logici
mkfs.exfat -L &#34;Disco 1&#34; /dev/mapper/vg_lab-lv_lab_1 
mkfs.ext4 -L &#34;Disco 2&#34; /dev/mapper/vg_lab-lv_lab_2
mkfs.ext4 -L &#34;Disco 3&#34; /dev/mapper/vg_lab-lv_lab_3
</code></pre>

<p><img src="https://pixelfed.uno/storage/m/_v2/489827599091373610/7321b8e85-c3df53/9FVjnpWgalop/O43bT2aJFAkN4O5rvjsryOLd3eTsCM9wJeAVvRxx.png" alt="lvm"></p>

<p><strong>Mount LVM</strong>
Ogni volta che dovremo usare i volumi logici faremo così:</p>

<pre><code class="language-bash">vgchange -ay vg_lab
mount -t exfat -o defaults /dev/mapper/vg_lab-lv_lab_1 disco1
mount -t ext4 -o defaults /dev/mapper/vg_lab-lv_lab_2 disco2
mount -t ext4 -o defaults /dev/mapper/vg_lab-lv_lab_3 disco3
</code></pre>

<p><strong>Umount LVM</strong>
Per smontarli invece basterà:</p>

<pre><code class="language-bash">umount disco1 disco2 disco3
vgchange -an vg_lab
</code></pre>

<p>Tutto quello che s&#39;è visto finora, risponde all&#39;esigenza iniziale: come posso aggregare più volumi in unico volume?</p>

<p>Ma riprendendiamo il passo 1bis, per vedere qualcosa di completamente inutile (all&#39;apparenza) ma non per questo meno interessante.</p>

<pre><code class="language-bash"># Passo 1bis
# Fin qua nulla di nuovo.
vgcreate vg_lab $(losetup -Pf --show disco1.img) $(losetup -Pf --show disco2.img) $(losetup -Pf --show disco3.img) 

lvcreate -n lv_lab_1 vg_lab -L 100M
lvcreate -n lv_lab_2 vg_lab -L 700M
lvcreate -n lv_lab_3 vg_lab -l 100%FREE

# Passo 2
vgcreate vg_lab_2 $(losetup -Pf --show /dev/vg_lab/lv_lab_3)
lvcreate -n lv_lab_4 vg_lab_2 -l 100%FREE
</code></pre>

<p>La particolarità del passo 2, completamente inutile, ha il solo scopo di mostrare come device mapper mi permetta di stratificare i volumi virtuali attraverso i corrispondenti dispositivi a blocchi virtuali per creare delle vere e proprie matrioske di volumi virtuali.</p>

<p><img src="https://pixelfed.uno/storage/m/_v2/489827599091373610/7321b8e85-c3df53/c05WUg43a3VK/cZHXiaUMAn51naNCasIoy3hSc61iyLOqsCT45eTG.png" alt="nested lvm"></p>

<p>In questo caso,  /dev/mapper/vg_lab-lv_lab_3 diventa un <strong>dispositivo a blocchi su un loop device</strong> ed è un attimo che quel dispositivo a blocchi diventi a sua volte <strong>un gruppo di volumi su cui creare un ulteriore  volume logico</strong>.</p>

<p>Un discreto nonsense anche se... <em>(to be continued)</em></p>

<p><a href="/aytin/tag:lvm" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">lvm</span></a> <a href="/aytin/tag:devicemapper" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">devicemapper</span></a> <a href="/aytin/tag:logicalvolume" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">logicalvolume</span></a> <a href="/aytin/tag:volumegroup" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">volumegroup</span></a> <a href="/aytin/tag:loopdevice" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">loopdevice</span></a></p>
]]></content:encoded>
      <guid>https://noblogo.org/aytin/cenni-sulla-creazione-di-pool-di-storage-con-lvm</guid>
      <pubDate>Tue, 14 May 2024 16:34:11 +0000</pubDate>
    </item>
    <item>
      <title>Come creare un file container cifrato</title>
      <link>https://noblogo.org/aytin/come-creare-un-file-container</link>
      <description>&lt;![CDATA[cartella con lucchetto&#xA;smallia href=&#34;https://www.freepik.com/free-photo/yellow-folder-with-security-key954598.htm#query=file%20lock&amp;position=1&amp;fromview=keyword&amp;track=ais&amp;uuid=7a92782d-c3bf-42db-ac2c-6c63c46f9edd&#34;Image by d3images/a/i on Freepik/small&#xA;&#xA;Introduzione a cryptsetup + LUKS&#xA;Supponiamo di voler creare una piccola cassaforte digitale come faremmo con Veracrypt. Ma senza Veracrypt.&#xA;&#xA;Ciò sarà possibile grazie a dm-crypt.&#xA;dm-crypt è un modulo del kernel che usa il framework device mapper per fornire funzionalità trasparenti di crittografia per dispositivi a blocchi usando le crypto api del kernel. L’uso di device mapper consente, tra l’altro, di &#34;poggiare&#34; dm-crypt sopra ogni possibile mapping dei dispositivi e quindi può cifrare partizioni, volumi raid o volumi logici.&#xA;!--more--&#xA;Introduzione a cryptsetup + LUKS&#xA;  Inizializzazione&#xA;  Apertura&#xA;  Chiusura&#xA;Come creare il file vault&#xA;Header detachable e keyfile&#xA;Partizionare un &#34;volume&#34; cifrato&#xA;&#xA;\EDIT 02/03/2026\]: Riscrittura del par. 3 - &#34;Header detachable e keyfile&#34;, alla luce degli approfondimenti fatti con &#34;[Device Mapper: Luks + LVM&#34; e la &#34;Trilogia delle password - Vol. 1,2 e 3&#34;&#xA;&#xA;Poi, essendo a tutti gli effetti anche un dispositivo a blocchi (virtuale), può essere utilizzabile a sua volta come volume nel file system, come swap o come disco fisico per lvm.&#xA;&#xA;La configurazione della cifratura avviene di solito (non è l’unico modo ma è lo standard de facto) con l’utility cryptsetup + LUKS&#xA;&#xA;Come avviene di base la cifratura di un dispositivo?&#xA;&#xA;Le operazioni principali di cryptsetup (con estensioni LUKS) sono:&#xA;&#xA;luksFormat: stabilisce le modalità di cifratura (consigliato il default)&#xA;luksOpen: (deprecato. Si usa open \-\-type luks2) attiva la cifratura sul device associandolo (grazie a device mapper) ad un dispositivo a blocchi virtuale&#xA;luksClose (deprecato. Si usa close \-\-type luks2): disattiva la cifratura&#xA;&#xA;Inizializzazione&#xA;&#xA;attacco il dispositivo fisico, viene creata la entry per /dev/\id\dispositivo\a\blocchi\fisico\&#xA;cifratura del dispositivo a blocchi /dev/\id\dispositivo\a\blocchi\fisico\ con LUKS (cryptsetup luksFormat)&#xA;al di sopra del dispositivo a blocchi fisico, viene creato un dispositivo a blocchi virtuale, che troverò sotto /dev/mapper/\nome\fittizio\, che eroga le funzionalità di cifratura (cryptsetup open) al dispositivo a blocchi fisico sottostante.&#xA;Infine, partiziono e/o formatto nella maniera canonica il dispositivo a blocchi virtuale (cifrato) /dev/mapper/\nome\fittizio\.&#xA;&#xA;Apertura&#xA;&#xA;attacco il dispositivo, viene creata la entry per /dev/\id\dispositivo\a\blocchi\fisico\&#xA;attivo il dispositivo a blocchi virtuale che eroga le funzionalità di cifratura (cryptsetup open) e che creerà l’occorrenza sotto /dev/mapper/\nome\fittizio\&#xA;faccio il mount del dispositivo a blocchi virtuale /dev/mapper/ su un punto di montaggio che è una cartella che creerò per l’occasione&#xA;&#xA;Chiusura&#xA;&#xA;faccio l’unmount del punto di montaggio&#xA;chiudo il dispositivo a blocchi virtuale (cryptsetup close) /dev/mapper/\nome\fittizio\&#xA;stacco il dispositivo fisico&#xA;&#xA;Fermo restando che questi restano i passaggi generali per qualunque dispositivo fisico, per creare un file container cifrato come farebbe Veracrypt, basta che cryptsetup formatti un file invece che un dispositivo a blocchi e automaticamente assocerà il file al primo loop device disponibile.&#xA;È veramente semplicesmalla id=&#34;linknota1&#34; title=&#34;vai alla nota 1&#34; href=&#34;#nota1&#34;supstrong [1] /strong/sup/a/small.&#xA;&#xA;Come creare il file vault&#xA;Divido le operazioni in 3 fasi:&#xA;&#xA;Init: fase di inizializzazione del &#34;dispositivo&#34; (il file). Andrà fatta solo la prima volta.&#xA;Open e Close: sono le operazioni che farò ogniqualvolta dovrò usare il container.&#xA;&#xA;Gli oggetti su cui andrà a lavorare sono:&#xA;&#xA;discocifrato.img: il file container cifrato.&#xA;discocifrato: il nome con cui discocifrato.img (o meglio, la sua rappresentazione come loop device visibile con losetup) viene mappato da device mapper.&#xA;disco\in\chiaro: il punto di montaggio.&#xA;&#xA;Init&#xA;creazione di una cartella che sarà il nostro punto di mount&#xA;mkdir discoinchiaro&#xA; &#xA;creazione di un file vuoto di 2 GiB&#xA;sudo fallocate -l 2g discocifrato.img&#xA; &#xA;preparazione cifratura LUKS &#xA;sudo cryptsetup luksFormat \&#xA;     --type luks2 \&#xA;     --hash=sha512 \&#xA;     --key-size=512 \&#xA;     discocifrato.img&#xA; &#xA;creazione dispositivo a blocchi virtuale che eroga le funzionalità di cifratura&#xA;sudo cryptsetup open \&#xA;     --type luks2 \&#xA;     discocifrato.img discocifrato&#xA; &#xA;formattazione&#xA;sudo mkfs.ext4 /dev/mapper/discocifrato&#xA;Open&#xA;creazione dispositivo a blocchi virtuale&#xA;sudo cryptsetup open \&#xA;     --type luks2 &#xA;     discocifrato.img discocifrato&#xA; &#xA;monta il dispositivo nel punto di montaggio&#xA;sudo mount -t ext4 -o defaults /dev/mapper/discocifrato discoinchiaro&#xA;Close&#xA;smonta il dispositivo&#xA;sudo umount discoinchiaro&#xA; &#xA;chiudo il dispositivo a blocchi virtuale staccandolo dai loop device&#xA;sudo cryptsetup close discocifrato&#xA;Header detachable e keyfile&#xA;Alziamo il livello di paranoia aggiungendo una complessità ulteriore. Creeremo il file vault nel seguente modo:&#xA;&#xA;il vault sarà inizializzato con rumore casuale&#xA;header detachable&#xA;offset custom&#xA;keyfile invece che password&#xA;default di argon2id (controlla il tuo default con cryptsetup benchmark)&#xA;&#xA;L’apertura del volume cifrato sarà così vincolata alla disponibiltà sia del keyfile che dell’header, senza il quale il volume cifrato sarebbe comunque inservibile.&#xA;&#xA;La presenza di rumore casuale su tutto il vault nella fase di inizializzazione impedirà qualunque tentativo di risalire alla tipologia di informazioni memorizzate, l&#39;assenza di zeri impedirà di capire quanti sono i dati (cifrati) memorizzati.&#xA;&#xA;L&#39;offset custom aggiunge un ulteriore tassello perchè nasconde il punto in cui inizia il payload.&#xA;&#xA;Un keyfile di dati binari casuali è infinitamente più robusto di una password  e può esser conservato separatamente insieme all&#39;header. La cifratura simmetrica del keyfile aggiunge ulteriore protezione, fatta magari usando una passphrase ottenuta col metodo Diceware.&#xA;&#xA;Infine la cifratura di default di luks2, argon2id, che è notoriamente sia CPU bound che GPU bound.&#xA;&#xA;Creo il keyfile protetto da una cifratura simmetrica di gpgsmalla id=&#34;linknota2&#34; title=&#34;vai alla nota 2&#34; href=&#34;#nota2&#34;supstrong [2] /strong/sup/small/a:&#xA;Creazione di un keyfile di 4KiB basata sulla pseudocasualità di /dev/urandom&#xA;creazione del keyfile&#xA;dd if=/dev/urandom bs=1024 count=4 | \&#xA;    gpg --yes -o discocifrato.key.gpg -c \&#xA;        --s2k-mode 3 \&#xA;        --s2k-count 32505856 \&#xA;        --s2k-cipher-algo aes256 \&#xA;        --s2k-digest-algo sha512 \&#xA;        --force-mdc -&#xA;Inizializzo il vault con dati casuali e poi lo formatto creando l&#39;header detachable del volume cifrato fornendo il keyfile invece della passphrase classica:&#xA;inizializzazione vault con dati casuali&#xA;Apro il vault in modalità &#39;plain&#39; senza header&#xA;sudo cryptsetup open \&#xA;    --type plain \&#xA;    --key-file /dev/urandom \&#xA;    --cipher aes-xts-plain64 \&#xA;    --key-size 512 \ &#xA;    discocifrato.img container&#xA;&#xA;scrivo degli zeri a cui, attraverso il motore di cifratura,&#xA;corrisponderanno dati casuali sul vault.&#xA;dd if=/dev/zero of=/dev/mapper/container status=progress&#xA;cryptsetup close container&#xA;&#xA;Formattazione vault&#xA;gpg -d discocifrato.key.gpg | \&#xA;    sudo cryptsetup luksFormat \&#xA;        --type luks2 \&#xA;        --key-file - \&#xA;        --header header.img \&#xA;        --offset 32768 \&#xA;        --hash sha512 \&#xA;        --key-size 512 \&#xA;        --cipher aes-xts-plain64 \&#xA;        discocifrato.img&#xA;Ed è così che l’apertura del volume cifrato è ora vincolata al possesso dell’header e del keyfile:&#xA;attivazione dispositivo a blocchi virtuale passando header e keyfile protetto da gpg&#xA;gpg -d discocifrato.key.gpg | \&#xA;    sudo cryptsetup open \&#xA;        --type luks2 \&#xA;&#x9;--header header.img \&#xA;&#x9;--key-file - \&#xA;&#x9;discocifrato.img discocifrato&#xA;Provando ad aprire container cifrato senza fornire l’header (non tanto il keyfile che è una passphrase evoluta) succede questo:&#xA;sudo cryptsetup open \&#xA;    --type luks2 \&#xA;    discocifrato.img discocifrato&#xA;Il dispositivo discocifrato.img non è un dispositivo LUKS valido.&#xA;Infine, un&#39;annotazione doverosa.&#xA;&#xA;Visto che il livello di paranoia abbiamo detto essere elevato, sarebbe consigliabile prestare una certa attenzione alla scelta dei nomi.&#xA;&#xA;Quelli usati finora avevano uno scopo &#34;didattico&#34;, che chiarisse il loro scopo  con un nome parlante.&#xA;&#xA;i nomi dei file relativi a header e keyfile sarebbe bene non fossero qualcosa del tpo &#34;header.img&#34; o &#34;discocifratokey.gpg&#34; che rivelano troppo esplicitamente la presenza di un disco cifrato o addirittura dello stesso LUKS. Meglio usare nomi più decontestualizzati, che so... &#34;sys-module-virtio.bin&#34; per l&#39;header e &#34;boot-vmlinuz-06.blob&#34; per il keyfile e via dicendo.&#xA;Partizionare un &#34;volume&#34; cifrato&#xA;Per concludere, visto che prima ho accennato al fatto che dm-crypt, grazie al sottosistema device mapper, fa in modo che i dispositivi a blocchi (virtuali) mascherino i dispositivo a blocchi sottostanti (un file montato su un loop device, nel nostro caso), i dispositivi a blocchi mappati possono anche essere partizionati invece che sempicemente formattati. O potrebbe essere volumi fisici di un gruppo di volumi LVM, and so on…&#xA;&#xA;Difficilmente avremo bisogno di partizionare un file container cifrato, è solo l’occasione per speculare un po’ su quello che potrebbe succedere su un device fisico.&#xA;Init&#xA;mkdir discoinchiaro&#xA;sudo fallocate -l 2g discocifrato.img&#xA;sudo cryptsetup luksFormat --hash=sha512 --key-size=512 discocifrato.img&#xA;sudo cryptsetup open --type luks2 discocifrato.img discocifrato&#xA; &#xA;Creo 1 partizione primaria da 600 MiB, una estesa da 1400 MiB&#xA;contenente 2 partizioni logiche da 600 MiB e 829 MiB (mancano i&#xA;16 MiB dell&#39;intestazione luks e i 3 MiB delle intestazioni delle&#xA;partizioni primarie ed estese per un totale di 2GiB tondi tondi)&#xA;sudo fdisk /dev/mapper/discocifrato&#xA;n,,,,+600M,n,e,,,,n,,+600M,n,,,w&#xA; &#xA;il partizionamento potrebbe richiedere l&#39;esecuzione di partprobe&#xA;affinché il kernel carichi la tabella delle partizioni aggiornata&#xA;sudo partprobe /dev/mapper/discocifrato&#xA;&#xA;stato delle partizioni&#xA;sudo fdisk -l /dev/mapper/discocifrato&#xA;Disk /dev/mapper/discocifrato: 1,98 GiB, 2130706432 bytes, 520192 sectors&#xA;Units: sectors of 1 * 4096 = 4096 bytes&#xA;Sector size (logical/physical): 4096 bytes / 4096 bytes&#xA;I/O size (minimum/optimal): 4096 bytes / 4096 bytes&#xA;Disklabel type: dos&#xA;Disk identifier: 0x6d65a06f&#xA;&#xA;Device                     Boot  Start    End Sectors  Size Id Type&#xA;/dev/mapper/discocifrato1         256 153855  153600  600M 83 Linux&#xA;/dev/mapper/discocifrato2      153856 520191  366336  1,4G  5 Extended&#xA;/dev/mapper/discocifrato5      154112 307711  153600  600M 83 Linux&#xA;/dev/mapper/discocifrato6      307968 520191  212224  829M 83 Linux&#xA;&#xA;procedo con la formattazione&#xA;sudo mkfs.ext4 /dev/mapper/discocifrato1 #formatto la partizione&#xA;sudo mkfs.ext4 /dev/mapper/discocifrato5 #formatto la partizione&#xA;sudo mkfs.ext4 /dev/mapper/discocifrato6 #formatto la partizione&#xA;Rispetto all’init di prima, invece che formattare subito il device &#34;fisico&#34;, l’ho partizionato. Esattamente come avrei fatto con un dispositivo realmente fisico.&#xA;Open&#xA;sudo cryptsetup open --type luks2 discocifrato.img discocifrato&#xA; &#xA;di nuovo, potrebbe essere necessario a meno di non riavviare&#xA;sudo partprobe /dev/mapper/discocifrato&#xA; &#xA;mount delle partizioni&#xA;sudo mount -t ext4 -o defaults /dev/mapper/discocifrato1 discoinchiaro1&#xA;sudo mount -t ext4 -o defaults /dev/mapper/discocifrato5 discoinchiaro2&#xA;sudo mount -t ext4 -o defaults /dev/mapper/discocifrato6 discoinchiaro3&#xA;Close&#xA;sudo umount discoinchiaro1&#xA;sudo umount discoinchiaro2&#xA;sudo umount discoinchiaro3&#xA;sudo cryptsetup close discocifrato1&#xA;sudo cryptsetup close discocifrato2&#xA;sudo cryptsetup close discocifrato5&#xA;sudo cryptsetup close discocifrato6&#xA;sudo cryptsetup close discocifrato&#xA;&#xA;Note:&#xA;small&#xA;&#xA;cryptsetup --open luks2 e cryptsetup --close luks2, a id=&#34;nota1&#34;/aquando applicate direttamente al file container, includono implicitamente la parte di accoppiamento al loop device.&#xA;    In altre parole,&#xA;    &#xA;        cryptsetup open --type luks2 discocifrato.img discocifrato&#xA;        equivale a &#xA;        cryptsetup open --type luks2 $(losetup -Pf --show discocifrato.img) discocifrato&#xA;        e&#xA;        cryptsetup close --type luks2 discocifrato&#xA;        equivale aa href=&#34;#linknota1&#34; title=&#34;torna su&#34;supb [↵] /b/sup/a&#xA;        cryptsetup close --type luks2 discocifrato&#xA;    losetup -D&#xA;    a id=&#34;nota2&#34;/aSe si incorre in questo errore usando gpg:&#xA;&#xA;        gpg: cancelled by user&#xA;    gpg: error creating passphrase: Operation cancelled&#xA;    gpg: symmetric encryption of &#39;[stdin]&#39; failed: Operation cancelled&#xA;        vuol dire che la variabile d’ambiente GPGTTY non ha lo stesso valore del comando tty. Per ovviare basta settare correttamente la variabile:&#xA;        GPGTTY=$(tty)&#xA;    export GPGTTY&#xA;        come suggerito dalla documentazione GnuPG a href=&#34;#linknota2&#34; title=&#34;torna su&#34;supb [↵] /b/sup/a&#xA;&#xA;/small&#xA;&#xA;#cryptsetup #devicemapper #dmcrypt #gpg #loseup #luks #lvm #loopdevice #storage]]&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://cyberdynesystem.files.wordpress.com/2024/05/yellow-folder-with-security-key.png" alt="cartella con lucchetto">
<small><i><a href="https://www.freepik.com/free-photo/yellow-folder-with-security-key_954598.htm#query=file%20lock&amp;position=1&amp;from_view=keyword&amp;track=ais&amp;uuid=7a92782d-c3bf-42db-ac2c-6c63c46f9edd" rel="nofollow">Image by d3images</a></i> on Freepik</small></p>

<h2 id="introduzione-a-cryptsetup-luks">Introduzione a cryptsetup + LUKS</h2>

<p>Supponiamo di voler creare una piccola cassaforte digitale come faremmo con Veracrypt. Ma senza Veracrypt.</p>

<p>Ciò sarà possibile grazie a <strong>dm-crypt</strong>.
dm-crypt è un modulo del kernel che usa il framework <strong>device mapper</strong> per fornire funzionalità trasparenti di crittografia per dispositivi a blocchi usando le crypto api del kernel. L’uso di device mapper consente, tra l’altro, di “poggiare” dm-crypt sopra ogni possibile mapping dei dispositivi e quindi può cifrare partizioni, volumi raid o volumi logici.

1. <a href="#introduzione-a-cryptsetup-luks" rel="nofollow">Introduzione a cryptsetup + LUKS</a>
  2. <a href="#inizializzazione" rel="nofollow">Inizializzazione</a>
  2. <a href="#apertura" rel="nofollow">Apertura</a>
  2. <a href="#chiusura" rel="nofollow">Chiusura</a>
1. <a href="#come-creare-il-file-vault" rel="nofollow">Come creare il file vault</a>
1. <a href="#header-detachable-e-keyfile" rel="nofollow">Header detachable e keyfile</a>
1. <a href="#partizionare-un-volume-cifrato" rel="nofollow">Partizionare un “volume” cifrato</a></p>

<p><strong>[EDIT 02/03/2026]: Riscrittura del par. 3 – “Header detachable e keyfile”, alla luce degli approfondimenti fatti con “<a href="https://noblogo.org/aytin/device-mapper-luks-lvm" rel="nofollow">Device Mapper: Luks + LVM</a>” e la “Trilogia delle password – Vol. <a href="https://noblogo.org/aytin/come-generare-una-password-o-un-keyfile-sicuri-trilogia-della-password-1-di" rel="nofollow">1</a>,<a href="https://noblogo.org/aytin/come-valutare-la-resistenza-di-una-password-trilogia-della-password-2-di-3" rel="nofollow">2</a> e <a href="https://noblogo.org/aytin/archiviare-le-password-in-sicurezza-con-kdf-password-hashing-trilogia-della" rel="nofollow">3</a>“</strong></p>

<p>Poi, essendo a tutti gli effetti anche un dispositivo a blocchi (virtuale), può essere utilizzabile a sua volta come volume nel file system, come swap o come disco fisico per lvm.</p>

<p>La configurazione della cifratura avviene di solito (non è l’unico modo ma è lo standard de facto) con l’utility <strong>cryptsetup + LUKS</strong></p>

<p>Come avviene di base la cifratura di un dispositivo?</p>

<p>Le operazioni principali di cryptsetup (con estensioni LUKS) sono:</p>
<ul><li><strong>luksFormat</strong>: stabilisce le modalità di cifratura (consigliato il default)</li>
<li><strong>luksOpen</strong>: (deprecato. Si usa <strong>open --type luks2</strong>) attiva la cifratura sul device associandolo (grazie a device mapper) ad un dispositivo a blocchi virtuale</li>
<li><strong>luksClose</strong> (deprecato. Si usa <strong>close --type luks2</strong>): disattiva la cifratura</li></ul>

<h3 id="inizializzazione">Inizializzazione</h3>
<ul><li>attacco il dispositivo fisico, viene creata la entry per <em>/dev/&lt;id_dispositivo_a_blocchi_fisico&gt;</em></li>
<li>cifratura del dispositivo a blocchi <em>/dev/&lt;id_dispositivo_a_blocchi_fisico&gt;</em> con LUKS (<strong>cryptsetup luksFormat</strong>)</li>
<li>al di sopra del dispositivo a blocchi fisico, viene creato un dispositivo a blocchi virtuale, che troverò sotto <em>/dev/mapper/&lt;nome_fittizio&gt;</em>, che eroga le funzionalità di cifratura (<strong>cryptsetup open</strong>) al dispositivo a blocchi fisico sottostante.</li>
<li>Infine, partiziono e/o formatto nella maniera canonica il dispositivo a blocchi virtuale (cifrato) <em>/dev/mapper/&lt;nome_fittizio&gt;</em>.</li></ul>

<h3 id="apertura">Apertura</h3>
<ul><li>attacco il dispositivo, viene creata la entry per <em>/dev/&lt;id_dispositivo_a_blocchi_fisico&gt;</em></li>
<li>attivo il dispositivo a blocchi virtuale che eroga le funzionalità di cifratura (<strong>cryptsetup open</strong>) e che creerà l’occorrenza sotto <em>/dev/mapper/&lt;nome_fittizio&gt;</em></li>
<li>faccio il mount del dispositivo a blocchi virtuale <em>/dev/mapper/</em> su un punto di montaggio che è una cartella che creerò per l’occasione</li></ul>

<h3 id="chiusura">Chiusura</h3>
<ul><li>faccio l’unmount del punto di montaggio</li>
<li>chiudo il dispositivo a blocchi virtuale (<strong>cryptsetup close</strong>) <em>/dev/mapper/&lt;nome_fittizio&gt;</em></li>
<li>stacco il dispositivo fisico</li></ul>

<p>Fermo restando che questi restano i passaggi generali per qualunque dispositivo fisico, per creare un <strong>file container cifrato</strong> come farebbe Veracrypt, basta che cryptsetup <strong>formatti un file</strong> invece che un dispositivo a blocchi e automaticamente assocerà il file al primo loop device disponibile.
È veramente semplice<small><a id="link_nota_1" title="vai alla nota 1" href="#nota_1" rel="nofollow"><sup><strong> [1] </strong></sup></a></small>.</p>

<h2 id="come-creare-il-file-vault">Come creare il file vault</h2>

<p>Divido le operazioni in 3 fasi:</p>
<ul><li><strong>Init</strong>: fase di inizializzazione del “dispositivo” (il file). Andrà fatta solo la prima volta.</li>
<li><strong>Open</strong> e <strong>Close</strong>: sono le operazioni che farò ogniqualvolta dovrò usare il container.</li></ul>

<p>Gli oggetti su cui andrà a lavorare sono:</p>
<ul><li><strong>disco_cifrato.img</strong>: il file container cifrato.</li>
<li><strong>disco_cifrato</strong>: il nome con cui disco_cifrato.img (o meglio, la sua rappresentazione come loop device visibile con <strong>losetup</strong>) viene mappato da device mapper.</li>
<li><strong>disco_in_chiaro</strong>: il punto di montaggio.</li></ul>

<pre><code class="language-bash">## Init
# creazione di una cartella che sarà il nostro punto di mount
mkdir disco_in_chiaro
 
# creazione di un file vuoto di 2 GiB
sudo fallocate -l 2g disco_cifrato.img
 
# preparazione cifratura LUKS 
sudo cryptsetup luksFormat \
     --type luks2 \
     --hash=sha512 \
     --key-size=512 \
     disco_cifrato.img
 
# creazione dispositivo a blocchi virtuale che eroga le funzionalità di cifratura
sudo cryptsetup open \
     --type luks2 \
     disco_cifrato.img disco_cifrato
 
# formattazione
sudo mkfs.ext4 /dev/mapper/disco_cifrato
</code></pre>

<pre><code class="language-bash">## Open
# creazione dispositivo a blocchi virtuale
sudo cryptsetup open \
     --type luks2 
     disco_cifrato.img disco_cifrato
 
# monta il dispositivo nel punto di montaggio
sudo mount -t ext4 -o defaults /dev/mapper/disco_cifrato disco_in_chiaro
</code></pre>

<pre><code class="language-bash">## Close
# smonta il dispositivo
sudo umount disco_in_chiaro
 
# chiudo il dispositivo a blocchi virtuale staccandolo dai loop device
sudo cryptsetup close disco_cifrato
</code></pre>

<h2 id="header-detachable-e-keyfile">Header detachable e keyfile</h2>

<p>Alziamo il livello di paranoia aggiungendo una complessità ulteriore. Creeremo il file vault nel seguente modo:</p>
<ol><li>il vault sarà inizializzato con rumore casuale</li>
<li>header detachable</li>
<li>offset custom</li>
<li>keyfile invece che password</li>
<li>default di argon2id (controlla il tuo default con cryptsetup benchmark)</li></ol>

<p>L’apertura del volume cifrato sarà così vincolata alla disponibiltà sia del keyfile che dell’header, senza il quale il volume cifrato sarebbe comunque inservibile.</p>

<p>La presenza di rumore casuale su tutto il vault nella fase di inizializzazione impedirà qualunque tentativo di risalire alla tipologia di informazioni memorizzate, l&#39;assenza di zeri impedirà di capire quanti sono i dati (cifrati) memorizzati.</p>

<p>L&#39;offset custom aggiunge un ulteriore tassello perchè nasconde il punto in cui inizia il payload.</p>

<p>Un keyfile di dati binari casuali è infinitamente più robusto di una password  e può esser conservato separatamente insieme all&#39;header. La cifratura simmetrica del keyfile aggiunge ulteriore protezione, fatta magari usando una passphrase ottenuta col <strong><a href="https://noblogo.org/aytin/come-valutare-la-resistenza-di-una-password-trilogia-della-password-2-di-3#metodo-diceware" rel="nofollow">metodo Diceware</a>.</strong></p>

<p>Infine la cifratura di default di luks2, argon2id, che è notoriamente sia CPU bound che GPU bound.</p>

<p>Creo il keyfile protetto da una cifratura simmetrica di gpg<small><a id="link_nota_2" title="vai alla nota 2" href="#nota_2" rel="nofollow"><sup><strong> [2] </strong></sup></small></a>:</p>

<pre><code class="language-bash">## Creazione di un keyfile di 4KiB basata sulla pseudocasualità di /dev/urandom
# creazione del keyfile
dd if=/dev/urandom bs=1024 count=4 | \
    gpg --yes -o disco_cifrato.key.gpg -c \
        --s2k-mode 3 \
        --s2k-count 32505856 \
        --s2k-cipher-algo aes256 \
        --s2k-digest-algo sha512 \
        --force-mdc -
</code></pre>

<p>Inizializzo il vault con dati casuali e poi lo formatto creando l&#39;header detachable del volume cifrato fornendo il keyfile invece della passphrase classica:</p>

<pre><code class="language-bash"># inizializzazione vault con dati casuali
# Apro il vault in modalità &#39;plain&#39; senza header
sudo cryptsetup open \
    --type plain \
    --key-file /dev/urandom \
    --cipher aes-xts-plain64 \
    --key-size 512 \ 
    disco_cifrato.img container

# scrivo degli zeri a cui, attraverso il motore di cifratura,
# corrisponderanno dati casuali sul vault.
dd if=/dev/zero of=/dev/mapper/container status=progress
cryptsetup close container

# Formattazione vault
gpg -d disco_cifrato.key.gpg | \
    sudo cryptsetup luksFormat \
        --type luks2 \
        --key-file - \
        --header header.img \
        --offset 32768 \
        --hash sha512 \
        --key-size 512 \
        --cipher aes-xts-plain64 \
        disco_cifrato.img
</code></pre>

<p>Ed è così che l’apertura del volume cifrato è ora <strong>vincolata al possesso dell’header e del keyfile</strong>:</p>

<pre><code class="language-bash"># attivazione dispositivo a blocchi virtuale passando header e keyfile protetto da gpg
gpg -d disco_cifrato.key.gpg | \
    sudo cryptsetup open \
        --type luks2 \
	--header header.img \
	--key-file - \
	disco_cifrato.img disco_cifrato
</code></pre>

<p>Provando ad aprire container cifrato <strong>senza fornire l’header</strong> (non tanto il keyfile che è una passphrase evoluta) succede questo:</p>

<pre><code class="language-bash">sudo cryptsetup open \
    --type luks2 \
    disco_cifrato.img disco_cifrato
Il dispositivo disco_cifrato.img non è un dispositivo LUKS valido.
</code></pre>

<p>Infine, un&#39;annotazione doverosa.</p>

<p>Visto che il livello di paranoia abbiamo detto essere elevato, sarebbe consigliabile prestare una certa attenzione alla scelta dei nomi.</p>

<p>Quelli usati finora avevano uno scopo “didattico”, che chiarisse il loro scopo  con un nome parlante.</p>

<p>i nomi dei file relativi a header e keyfile sarebbe bene non fossero qualcosa del tpo “header.img” o “discocifrato_key.gpg” che rivelano troppo esplicitamente la presenza di un disco cifrato o addirittura dello stesso LUKS. Meglio usare nomi più decontestualizzati, che so... “<code>sys-module-virtio.bin</code>” per l&#39;header e “<code>boot-vmlinuz-06.blob</code>” per il keyfile e via dicendo.</p>

<h2 id="partizionare-un-volume-cifrato">Partizionare un “volume” cifrato</h2>

<p>Per concludere, visto che prima ho accennato al fatto che dm-crypt, grazie al sottosistema device mapper, fa in modo che i dispositivi a blocchi (virtuali) mascherino i dispositivo a blocchi sottostanti (un file montato su un loop device, nel nostro caso), i dispositivi a blocchi mappati possono anche essere partizionati invece che sempicemente formattati. O potrebbe essere volumi fisici di un gruppo di volumi LVM, and so on…</p>

<p>Difficilmente avremo bisogno di partizionare un file container cifrato, è solo l’occasione per speculare un po’ su quello che potrebbe succedere su un device fisico.</p>

<pre><code class="language-bash">## Init
mkdir disco_in_chiaro
sudo fallocate -l 2g disco_cifrato.img
sudo cryptsetup luksFormat --hash=sha512 --key-size=512 disco_cifrato.img
sudo cryptsetup open --type luks2 disco_cifrato.img disco_cifrato
 
# Creo 1 partizione primaria da 600 MiB, una estesa da 1400 MiB
# contenente 2 partizioni logiche da 600 MiB e 829 MiB (mancano i
# 16 MiB dell&#39;intestazione luks e i 3 MiB delle intestazioni delle
# partizioni primarie ed estese per un totale di 2GiB tondi tondi)
sudo fdisk /dev/mapper/disco_cifrato
n,,,,+600M,n,e,,,,n,,+600M,n,,,w
 
# il partizionamento potrebbe richiedere l&#39;esecuzione di partprobe
# affinché il kernel carichi la tabella delle partizioni aggiornata
sudo partprobe /dev/mapper/disco_cifrato

# stato delle partizioni
sudo fdisk -l /dev/mapper/disco_cifrato
Disk /dev/mapper/disco_cifrato: 1,98 GiB, 2130706432 bytes, 520192 sectors
Units: sectors of 1 * 4096 = 4096 bytes
Sector size (logical/physical): 4096 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: dos
Disk identifier: 0x6d65a06f

Device                     Boot  Start    End Sectors  Size Id Type
/dev/mapper/disco_cifrato1         256 153855  153600  600M 83 Linux
/dev/mapper/disco_cifrato2      153856 520191  366336  1,4G  5 Extended
/dev/mapper/disco_cifrato5      154112 307711  153600  600M 83 Linux
/dev/mapper/disco_cifrato6      307968 520191  212224  829M 83 Linux

#procedo con la formattazione
sudo mkfs.ext4 /dev/mapper/disco_cifrato1 #formatto la partizione
sudo mkfs.ext4 /dev/mapper/disco_cifrato5 #formatto la partizione
sudo mkfs.ext4 /dev/mapper/disco_cifrato6 #formatto la partizione
</code></pre>

<p>Rispetto all’init di prima, invece che formattare subito il device “fisico”, l’ho partizionato. Esattamente come avrei fatto con un dispositivo realmente fisico.</p>

<pre><code class="language-bash">## Open
sudo cryptsetup open --type luks2 disco_cifrato.img disco_cifrato
 
# di nuovo, potrebbe essere necessario a meno di non riavviare
sudo partprobe /dev/mapper/disco_cifrato
 
# mount delle partizioni
sudo mount -t ext4 -o defaults /dev/mapper/disco_cifrato1 disco_in_chiaro_1
sudo mount -t ext4 -o defaults /dev/mapper/disco_cifrato5 disco_in_chiaro_2
sudo mount -t ext4 -o defaults /dev/mapper/disco_cifrato6 disco_in_chiaro_3
</code></pre>

<pre><code class="language-bash">## Close
sudo umount disco_in_chiaro_1
sudo umount disco_in_chiaro_2
sudo umount disco_in_chiaro_3
sudo cryptsetup close disco_cifrato1
sudo cryptsetup close disco_cifrato2
sudo cryptsetup close disco_cifrato5
sudo cryptsetup close disco_cifrato6
sudo cryptsetup close disco_cifrato
</code></pre>

<p><strong>Note:</strong>
<small></p>
<ol><li><p><code>cryptsetup --open luks2</code> e <code>cryptsetup --close luks2</code>, <a id="nota_1"></a>quando applicate direttamente al file container, includono implicitamente la parte di accoppiamento al loop device.
In altre parole,</p>

<pre><code class="language-bash">cryptsetup open --type luks2 disco_cifrato.img disco_cifrato
</code></pre>

<p>equivale a</p>

<pre><code class="language-bash">cryptsetup open --type luks2 $(losetup -Pf --show disco_cifrato.img) disco_cifrato
</code></pre>

<p>e</p>

<pre><code class="language-bash">cryptsetup close --type luks2 disco_cifrato
</code></pre>

<p>equivale a<a href="#link_nota_1" title="torna su" rel="nofollow"><sup><b> [↵] </b></sup></a></p>

<pre><code class="language-bash">cryptsetup close --type luks2 disco_cifrato
losetup -D
</code></pre></li>

<li><p><a id="nota_2"></a>Se si incorre in questo errore usando gpg:</p>

<pre><code class="language-bash">gpg: cancelled by user
gpg: error creating passphrase: Operation cancelled
gpg: symmetric encryption of &#39;[stdin]&#39; failed: Operation cancelled
</code></pre>

<p>vuol dire che la variabile d’ambiente <code>GPG_TTY</code> non ha lo stesso valore del comando tty. Per ovviare basta settare correttamente la variabile:</p>

<pre><code class="language-bash">GPG_TTY=$(tty)
export GPG_TTY
</code></pre>

<p>come suggerito dalla <a href="https://www.gnupg.org/documentation/manuals/gnupg/Invoking-GPG_002dAGENT.html#Invoking-GPG_002dAGENT" rel="nofollow">documentazione GnuPG</a> <a href="#link_nota_2" title="torna su" rel="nofollow"><sup><b> [↵] </b></sup></a></p></li></ol>

<p></small></p>

<p><a href="/aytin/tag:cryptsetup" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">cryptsetup</span></a> <a href="/aytin/tag:devicemapper" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">devicemapper</span></a> <a href="/aytin/tag:dmcrypt" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">dmcrypt</span></a> <a href="/aytin/tag:gpg" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">gpg</span></a> <a href="/aytin/tag:loseup" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">loseup</span></a> <a href="/aytin/tag:luks" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">luks</span></a> <a href="/aytin/tag:lvm" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">lvm</span></a> <a href="/aytin/tag:loopdevice" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">loopdevice</span></a> <a href="/aytin/tag:storage" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">storage</span></a></p>
]]></content:encoded>
      <guid>https://noblogo.org/aytin/come-creare-un-file-container</guid>
      <pubDate>Fri, 10 May 2024 21:32:57 +0000</pubDate>
    </item>
  </channel>
</rss>