Przejdź to tekstu

Zmiana rozmiaru LUKS i LVM

Kategoria: Artykuły, etykiety: szyfrowanie, partycja, lvm, luks, dysk

Dodany przez: morfik, 2014-01-17 00:48 (zmodyfikowany: 2014-01-19 18:04)

Wyświetleń: 12701

Wszyscy wiedzą, że zabawa z dyskiem zwykle kończy się tragicznie dla zawartych na nim danych. Czasami jednak trafia się ktoś kto o tym nie wie i po takich eksperymentach zawartość dysku pozostaje niezmieniona. Poniżej będzie zaprezentowany sposób na to jak bez większego stresu można bawić się rozmiarami zaszyfrowanych partycji LUKS, oraz, w zależności od setupu, będą też omówione voluminy LVM. Nie da się jednak za to zabrać nie mają pojęcia jak dokonać powiększania i kurczenia zwykłych partycji i, o ile w przypadku ntfs, fat czy ext można zaprzęgnąć gparted do pracy, to jeśli chodzi o zabawę przy LVM i/lub LUKS, niestety trzeba się nieco bardziej postarać.

Na sam początek musimy się nauczyć obracać zwykłymi partycjami. LVM i LUKS mają w sobie systemy plików, takie same jak w przypadku normalnych partycji, z tym, że dostęp do nich odbywa się na nieco innej zasadzie.

1. Zmiana rozmiaru partycji ntfs

Mamy przykładowy dysk, znajdują się na nim dwie partycje i w tym też jest partycja ntfs. Tak to wygląda:

# parted /dev/sdb
GNU Parted 2.3
Using /dev/sdb
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) unit
Unit?  [compact]? s
(parted) print free
Model: WDC WD80 0JB-00JJA0 (scsi)
Disk /dev/sdb: 156299375s
Sector size (logical/physical): 512B/512B
Partition Table: msdos

Number  Start       End         Size       Type     File system  Flags
        63s         2047s       1985s               Free Space
 1      2048s       61442047s   61440000s  primary  ntfs
 2      61442048s   156299263s  94857216s  primary  ext4
        156299264s  156299374s  111s                Free Space

Obsługa systemu plików ntfs w parted nie jest zaimplementowana i przy próbie zmiany rozmiaru na takiej partycji dostaniemy poniższy komunikat:

No Implementation: Support for opening ntfs file systems is not implemented yet.

Istnieje co prawda automat, który umożliwia zmianę rozmiaru wszystkich partycji -- gparted -- ale my z niego nie będziemy korzystać, mimo (albo zwłaszcza dlatego), że on może sobie z tym zadaniem poradzić bez większego problemu. Skoro w przypadku ntfs odpadają nam już parted i gparted, to co nam pozostaje? W pakiecie ntfs-3g mamy dostępne narzędzie ntfsresize i to przy jego pomocy będziemy zmieniać rozmiar partycji ntfs.

1.1. Zmniejszanie rozmiaru partycji ntfs

Przed przystąpieniem do zmiany rozmiaru jakiejkolwiek partycji, nie tylko ntfs, trzeba ją pierw przeskanować w poszukiwaniu ewentualnych błędów w systemie plików. Poniżej przykładowa linijka (jeśli ktoś ma problemy ze zrozumieniem opcji niech skorzysta z --help):

# ntfsresize -i -f -v /dev/sdb1
ntfsresize v2013.1.13AR.1 (libntfs-3g)
Device name        : /dev/sdb1
NTFS volume version: 3.1
Cluster size       : 4096 bytes
Current volume size: 31457276416 bytes (31458 MB)
Current device size: 31457280000 bytes (31458 MB)
Checking for bad sectors ...
Checking filesystem consistency ...
100.00 percent completed
Accounting clusters ...
Space in use       : 538 MB (1.7%)
Collecting resizing constraints ...
Estimating smallest shrunken size supported ...
File feature         Last used at      By inode
$MFTMirr           :      7204 MB             1
Ordinary           :     14403 MB          3380
You might resize at 537702400 bytes or 538 MB (freeing 30920 MB).
Please make a test run using both the -n and -s options before real resizing!

Jak widać powyżej, jest nawet informacja na temat tego jak bardzo można zjechać z rozmiarem partycji. Jako, że jest tam na niej około 500MiB danych, minimalny rozmiar partycji nie może przekroczyć 538MB. Jest też również informacja by przed rzeczywistą zmianą rozmiaru przeprowadzić test używając opcji -n i -s. Sprawdźmy zatem co taki test nam powie:

# ntfsresize -f -s 10G -n /dev/sdb1
ntfsresize v2013.1.13AR.1 (libntfs-3g)
Device name        : /dev/sdb1
NTFS volume version: 3.1
Cluster size       : 4096 bytes
Current volume size: 31457276416 bytes (31458 MB)
Current device size: 31457280000 bytes (31458 MB)
New volume size    : 9999995392 bytes (10000 MB)
Checking filesystem consistency ...
100.00 percent completed
Accounting clusters ...
Space in use       : 538 MB (1.7%)
Collecting resizing constraints ...
Needed relocations : 23717 (98 MB)
Schedule chkdsk for NTFS consistency check at Windows boot time ...
Resetting $LogFile ... (this might take a while)
Relocating needed data ...
100.00 percent completed
Updating $BadClust file ...
Updating $Bitmap file ...
Updating Boot record ...
The read-only test run ended successfully.

Narzędzie ntfsresize operuje na podstawie potęgi 10 zamiast 2 -- 10G i 10GiB to nie jest to samo. Można również zauważyć, że będzie potrzeba przenieść 98MB zanim system plików zostanie zmniejszony. W przypadku większych partycji, naturalnie będzie to sporo więcej danych. Jeśli nie będzie żadnych błędów, wydajemy polecenie bez opcji -n :

# ntfsresize -f -s 10G /dev/sdb1
ntfsresize v2013.1.13AR.1 (libntfs-3g)
Device name        : /dev/sdb1
NTFS volume version: 3.1
Cluster size       : 4096 bytes
Current volume size: 31457276416 bytes (31458 MB)
Current device size: 31457280000 bytes (31458 MB)
New volume size    : 9999995392 bytes (10000 MB)
Checking filesystem consistency ...
100.00 percent completed
Accounting clusters ...
Space in use       : 538 MB (1.7%)
Collecting resizing constraints ...
Needed relocations : 23717 (98 MB)
WARNING: Every sanity check passed and only the dangerous operations left.
Make sure that important data has been backed up! Power outage or computer
crash may result major data loss!
Are you sure you want to proceed (y/[n])? y
Schedule chkdsk for NTFS consistency check at Windows boot time ...
Resetting $LogFile ... (this might take a while)
Relocating needed data ...
100.00 percent completed
Updating $BadClust file ...
Updating $Bitmap file ...
Updating Boot record ...
Syncing device ...
Successfully resized NTFS on device '/dev/sdb1'.
You can go on to shrink the device for example with Linux fdisk.
IMPORTANT: When recreating the partition, make sure that you
  1)  create it at the same disk sector (use sector as the unit!)
  2)  create it with the same partition type (usually 7, HPFS/NTFS)
  3)  do not make it smaller than the new NTFS filesystem size
  4)  set the bootable flag for the partition if it existed before
Otherwise you won't be able to access NTFS or can't boot from the disk!
If you make a mistake and don't have a partition table backup then you
can recover the partition table by TestDisk or Parted's rescue mode.

Zmniejszyliśmy właśnie system plików. By się przekonać czy faktycznie jego rozmiar uległ zmianie, wydajemy poniższe polecenie:

# ntfsresize -i -f /dev/sdb1
ntfsresize v2013.1.13AR.1 (libntfs-3g)
Device name        : /dev/sdb1
NTFS volume version: 3.1
Cluster size       : 4096 bytes
Current volume size: 9999995392 bytes (10000 MB)
Current device size: 31457280000 bytes (31458 MB)
Checking filesystem consistency ...
100.00 percent completed
Accounting clusters ...
Space in use       : 538 MB (5.4%)
Collecting resizing constraints ...
You might resize at 537047040 bytes or 538 MB (freeing 9462 MB).
Please make a test run using both the -n and -s options before real resizing!

Current volume size i Current device size różnią się. Teraz jeszcze trzeba zmniejszyć rozmiar partycji. By tego dokonać potrzebny nam fdisk. W fdisku możemy precyzować rozmiar używając bajtów lub sektorów, z tym, że fdisk używa podstawy potęgi 2. Jak widać wyżej, niby wpisaliśmy 10G ale wyszła liczba 9999995392, która nijak się dzieli przez 1024 ale dzieli się za to znośnie przez 512, a że 512 to rozmiar sektora to możemy sobie wyliczyć rozmiar nowej partycji w sektorach. Można też bez problemu podać rozmiar w bajtach. Jeśli jednak ktoś preferuje sektory, to będzie to 9999995392/512=19531241 sektorów. Odpalamy zatem fdiska, kasujemy zmienianą partycję i na jej miejsce tworzymy nową. Musi ona się zaczynać w miejscu starej, jedynie co, to zmieni się położenie końca, no i w drugim parametrze (ostatni sektor) podajemy +19531241 (jeśli ktoś ma problemy ze zrozumieniem wydawanych poleceń niech wpisze m):

# fdisk /dev/sdb
Command (m for help): d
Partition number (1-4): 1

Command (m for help): n
Partition type:
   p   primary (1 primary, 0 extended, 3 free)
   e   extended
Select (default p): p
Partition number (1-4, default 1):
Using default value 1
First sector (2048-156299374, default 2048):
Using default value 2048
Last sector, +sectors or +size{K,M,G} (2048-61442047, default 61442047): +19531241

Domyślnie w fdisku zostanie stworzona partycja o kodzie 83 (linux), musimy to zmienić na kod 7 (ntfs). Możemy sobie wylistować typy partycji w fdisku przy pomocy opcji L :

Hex code (type L to list codes): L

 0  Empty           24  NEC DOS         81  Minix / old Lin bf  Solaris
 1  FAT12           27  Hidden NTFS Win 82  Linux swap / So c1  DRDOS/sec (FAT-
 2  XENIX root      39  Plan 9          83  Linux           c4  DRDOS/sec (FAT-
 3  XENIX usr       3c  PartitionMagic  84  OS/2 hidden C:  c6  DRDOS/sec (FAT-
 4  FAT16           40  Venix 80286     85  Linux extended  c7  Syrinx
 5  Extended        41  PPC PReP Boot   86  NTFS volume set da  Non-FS data
 6  FAT16           42  SFS             87  NTFS volume set db  CP/M / CTOS / .
 7  HPFS/NTFS/exFAT 4d  QNX4.x          88  Linux plaintext de  Dell Utility
 8  AIX             4e  QNX4.x 2nd part 8e  Linux LVM       df  BootIt
 9  AIX bootable    4f  QNX4.x 3rd part 93  Amoeba          e1  DOS access
 a  OS/2 Boot Manag 50  OnTrack DM      94  Amoeba BBT      e3  DOS R/O
 b  W95 FAT32       51  OnTrack DM6 Aux 9f  BSD/OS          e4  SpeedStor
 c  W95 FAT32 (LBA) 52  CP/M            a0  IBM Thinkpad hi eb  BeOS fs
 e  W95 FAT16 (LBA) 53  OnTrack DM6 Aux a5  FreeBSD         ee  GPT
 f  W95 Ext'd (LBA) 54  OnTrackDM6      a6  OpenBSD         ef  EFI (FAT-12/16/
10  OPUS            55  EZ-Drive        a7  NeXTSTEP        f0  Linux/PA-RISC b
11  Hidden FAT12    56  Golden Bow      a8  Darwin UFS      f1  SpeedStor
12  Compaq diagnost 5c  Priam Edisk     a9  NetBSD          f4  SpeedStor
14  Hidden FAT16    61  SpeedStor       ab  Darwin boot     f2  DOS secondary
16  Hidden FAT16    63  GNU HURD or Sys af  HFS / HFS+      fb  VMware VMFS
17  Hidden HPFS/NTF 64  Novell Netware  b7  BSDI fs         fc  VMware VMKCORE
18  AST SmartSleep  65  Novell Netware  b8  BSDI swap       fd  Linux raid auto
1b  Hidden W95 FAT3 70  DiskSecure Mult bb  Boot Wizard hid fe  LANstep
1c  Hidden W95 FAT3 75  PC/IX           be  Solaris boot    ff  BBT
1e  Hidden W95 FAT1 80  Old Minix

Wybieramy zatem partycję i ustawiamy jej pożądany typ:

Command (m for help): t
Partition number (1-4): 1

Hex code (type L to list codes): 7
Changed system type of partition 1 to 7 (HPFS/NTFS/exFAT)

Sprawdzamy czy wszystko się zgadza i jeśli jesteśmy zadowoleni z wyniku, zapisujemy układ partycji:

Command (m for help): p

Disk /dev/sdb: 80.0 GB, 80025280000 bytes
255 heads, 63 sectors/track, 9729 cylinders, total 156299375 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000c741d

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1            2048    19533289     9765621    7  HPFS/NTFS/exFAT
/dev/sdb2        61442048   156299263    47428608   83  Linux

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

Jeszcze by mieć absolutną pewność, że nic nie popsuliśmy, rzućmy okiem na to co nam powie ntfsresize:

# ntfsresize -i -f /dev/sdb1
ntfsresize v2013.1.13AR.1 (libntfs-3g)
Device name        : /dev/sdb1
NTFS volume version: 3.1
Cluster size       : 4096 bytes
Current volume size: 9999995392 bytes (10000 MB)
Current device size: 9999995904 bytes (10000 MB)
Checking filesystem consistency ...
100.00 percent completed
Accounting clusters ...
Space in use       : 538 MB (5.4%)
Collecting resizing constraints ...
You might resize at 537047040 bytes or 538 MB (freeing 9462 MB).
Please make a test run using both the -n and -s options before real resizing!

Ja u siebie jeszcze na wszelki wypadek sprawdziłem czy nowa partycja sprawia jakiś kłopot w gparted ale nawet on nie zwraca żadnych problemów. Dane na dysku również są i można je odczytać. Także wszystko przebiegło bez większych problemów.

1.2. Zwiększanie rozmiaru partycji ntfs

Skoro istnieje potrzeba by skurczyć czasem partycję, to na pewno ktoś będzie potrzebował partycję rozciągnąć. W przypadku powiększania partycji, postępujemy odwrotnie jak w przypadku jej zmniejszania -- Najpierw rozciągamy partycję, a następnie system plików. Odpalamy zatem fdiska, kasujemy starą partycję i na jej miejsce tworzymy nową:

Command (m for help): d
Partition number (1-4): 1

Command (m for help): n
Partition type:
   p   primary (1 primary, 0 extended, 3 free)
   e   extended
Select (default p): p
Partition number (1-4, default 1): 1
First sector (2048-156299374, default 2048):
Using default value 2048
Last sector, +sectors or +size{K,M,G} (2048-61442047, default 61442047): +20G

Command (m for help): t
Partition number (1-4): 1
Hex code (type L to list codes): 7
Changed system type of partition 1 to 7 (HPFS/NTFS/exFAT)

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

W przypadku gdybyśmy próbowali rozciągnąć system plików bez uprzedniego zwiększenia rozmiaru partycji, dostalibyśmy poniższy komunikat:

ERROR: New size can't be bigger than the device size.

Mając już powiększoną partycję, zmieniamy rozmiar jej systemu plików -- pierw oczywiście test w trybie tylko do odczytu:

# ntfsresize -s 20G -f -n  /dev/sdb1
ntfsresize v2013.1.13AR.1 (libntfs-3g)
Device name        : /dev/sdb1
NTFS volume version: 3.1
Cluster size       : 4096 bytes
Current volume size: 9999995392 bytes (10000 MB)
Current device size: 21474836480 bytes (21475 MB)
New volume size    : 19999994368 bytes (20000 MB)
Checking filesystem consistency ...
100.00 percent completed
Accounting clusters ...
Space in use       : 538 MB (5.4%)
Collecting resizing constraints ...
Schedule chkdsk for NTFS consistency check at Windows boot time ...
Resetting $LogFile ... (this might take a while)
Updating $BadClust file ...
Updating $Bitmap file ...
Updating Boot record ...
The read-only test run ended successfully.

Prędzej piekło zamarznie niż 20G będzie oznaczać to samo w każdym programie. :] Fdisk bez problemu policzył 20*1024*1024*1024=21474836480 , a ten ntfsresize próbował 20*1000*1000*1000, a że komputery działają w oparciu o podstawę potęgi 2, a nie 10, to w życiu nie uzyskamy okrągłego wyniku i temu mamy 19999994368 zamiast okrągłego 20000000000. W każdym razie zamiast -s 20G można sprecyzować -s 21474836480 :

# ntfsresize -s 21474836480 -f -n  /dev/sdb1
ntfsresize v2013.1.13AR.1 (libntfs-3g)
Device name        : /dev/sdb1
NTFS volume version: 3.1
Cluster size       : 4096 bytes
Current volume size: 9999995392 bytes (10000 MB)
Current device size: 21474836480 bytes (21475 MB)
New volume size    : 21474832896 bytes (21475 MB)
Checking filesystem consistency ...
100.00 percent completed
Accounting clusters ...
Space in use       : 538 MB (5.4%)
Collecting resizing constraints ...
Schedule chkdsk for NTFS consistency check at Windows boot time ...
Resetting $LogFile ... (this might take a while)
Updating $BadClust file ...
Updating $Bitmap file ...
Updating Boot record ...
The read-only test run ended successfully.

Jak już jesteśmy pewni co do swoich czynów i ustawiliśmy wszystko jak trzeba, usuwamy opcję -n :

# ntfsresize -s 21474836480 -f /dev/sdb1
ntfsresize v2013.1.13AR.1 (libntfs-3g)
Device name        : /dev/sdb1
NTFS volume version: 3.1
Cluster size       : 4096 bytes
Current volume size: 9999995392 bytes (10000 MB)
Current device size: 21474836480 bytes (21475 MB)
New volume size    : 21474832896 bytes (21475 MB)
Checking filesystem consistency ...
100.00 percent completed
Accounting clusters ...
Space in use       : 538 MB (5.4%)
Collecting resizing constraints ...
WARNING: Every sanity check passed and only the dangerous operations left.
Make sure that important data has been backed up! Power outage or computer
crash may result major data loss!
Are you sure you want to proceed (y/[n])? y
Schedule chkdsk for NTFS consistency check at Windows boot time ...
Resetting $LogFile ... (this might take a while)
Updating $BadClust file ...
Updating $Bitmap file ...
Updating Boot record ...
Syncing device ...
Successfully resized NTFS on device '/dev/sdb1'.

I jeszcze dla pewności sprawdzamy czy aby wszystko jest w porządku:

# ntfsresize -i -f /dev/sdb1
ntfsresize v2013.1.13AR.1 (libntfs-3g)
Device name        : /dev/sdb1
NTFS volume version: 3.1
Cluster size       : 4096 bytes
Current volume size: 21474832896 bytes (21475 MB)
Current device size: 21474836480 bytes (21475 MB)
Checking filesystem consistency ...
100.00 percent completed
Accounting clusters ...
Space in use       : 538 MB (2.5%)
Collecting resizing constraints ...
You might resize at 537395200 bytes or 538 MB (freeing 20937 MB).
Please make a test run using both the -n and -s options before real resizing!

Rozmiary partycji i systemu plików są z grubsza takie same no i żaden program nie zwraca błędów, zatem wszystko musi być w porządku.

2. Zmiana rozmiaru partycji ext4

Bawienie się rozmiarem partycji w przypadku ext4 niczym się nie różni w stosunku do partycji ntfs, no może poza użyciem do tego celu innych narzędzi. Zaczynamy jak zwykle od sprawdzenia integralności danych na partycji (jeśli ktoś ma problemy ze zrozumieniem opcji, niech skorzysta z --help):

# fsck.ext4 -f -v /dev/sdb2
e2fsck 1.42.9 (28-Dec-2013)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information

        4246 inodes used (0.19%, out of 2240224)
           3 non-contiguous files (0.1%)
           0 non-contiguous directories (0.0%)
             # of inodes with ind/dind/tind blocks: 0/0/0
             Extent depth histogram: 4233
      299646 blocks used (3.35%, out of 8948224)
           0 bad blocks
           1 large file

        3841 regular files
         391 directories
           0 character device files
           0 block device files
           0 fifos
           0 links
           5 symbolic links (5 fast symbolic links)
           0 sockets
------------
        4237 files

By móc skorzystać z opcji zmiany rozmiaru systemu plików ext4 trzeba mieć zainstalowany pakiet e2fsprogs .

2.1. Zmniejszanie rozmiaru partycji ext4

Jeśli chcemy skurczyć system plików do możliwe małego, możemy użyć opcji -M , by zobaczyć jaki jest najmniejszy możliwy rozmiar systemu plików, korzystamy z opcji -P. My jednak ustawimy określony rozmiar:

# resize2fs -p /dev/sdb2 10G
resize2fs 1.42.9 (28-Dec-2013)
Resizing the filesystem on /dev/sdb2 to 2621440 (4k) blocks.
Begin pass 2 (max = 85252)
Relocating blocks             XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Begin pass 3 (max = 274)
Scanning inode table          XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Begin pass 4 (max = 430)
Updating inode references     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
The filesystem on /dev/sdb2 is now 2621440 blocks long.

Cóż to jest te 2621440 bloków? 2621440*4096/1024/1024/1024=10GiB , przy czym rozmiar bloku (4096) może być inny, a sprawdzimy go przez:

# tune2fs -l /dev/sdb2 | grep -i "block size"
Block size:               4096

Ten rozmiar bloku to nie jest to samo co fdisk ma wpisane pod pozycją block. Dla fdiska rozmiar tamtego bloku jest równy 1024 (przynajmniej u mnie), także nie możemy kierować się powyższym 2621440 , trzeba przyjąć liczbę 4 krotnie wyższą czyli 10485760 , tylko, że to są bloki. Trzeba je przeliczyć na sektory -- (10485760*2)-1=20971519 albo sprecyzować wielkość partycji przez +10G, bo w obu przypadkach (resize2fs i fdisk) używana jest 2 jako podstawa potęgi. Odpalamy fdiska, kasujemy partycję i robimy nową. Z tym, że trzeba uważać. U mnie partycja druga nie zaczyna się zaraz po pierwszej. Zawsze dobrze jest sprawdzić i spisać sobie początek zmienianej partycji:

# fdisk /dev/sdb

Command (m for help): p

Disk /dev/sdb: 80.0 GB, 80025280000 bytes
255 heads, 63 sectors/track, 9729 cylinders, total 156299375 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000c741d

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1            2048    41945087    20971520    7  HPFS/NTFS/exFAT
/dev/sdb2        84713472   156299263    35792896   83  Linux

Liczbę 84713472 trzeba będzie wpisać jako pierwszy sektor przy tworzeniu nowej partycji. Kasujemy partycję i tworzymy nową podając, albo +10G, albo +20971519 jako ostatni sektor:

Command (m for help): d
Partition number (1-4): 2

Command (m for help): n
Partition type:
   p   primary (1 primary, 0 extended, 3 free)
   e   extended
Select (default p): p
Partition number (1-4, default 2): 2
First sector (41945088-156299374, default 41945088): 84713472
Last sector, +sectors or +size{K,M,G} (84713472-156299374, default 156299374): +20971519

Command (m for help): t
Partition number (1-4): 2
Hex code (type L to list codes): 83

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

I to wszystko jeśli chodzi o kurczenie rozmiaru partycji ext4.

2.2. Zwiększanie rozmiaru partycji ext4

Po sprawdzeniu systemu plików w poszukiwaniu błędów, odpalamy fdiska i kasujemy odpowiednią partycję:

# fdisk /dev/sdb

Command (m for help): p

Disk /dev/sdb: 80.0 GB, 80025280000 bytes
255 heads, 63 sectors/track, 9729 cylinders, total 156299375 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000c741d

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1            2048    41945087    20971520    7  HPFS/NTFS/exFAT
/dev/sdb2        84713472   105684991    10485760   83  Linux

Command (m for help): d
Partition number (1-4): 2

Command (m for help): n
Partition type:
   p   primary (1 primary, 0 extended, 3 free)
   e   extended
Select (default p): p
Partition number (1-4, default 2): 2
First sector (41945088-156299374, default 41945088): 84713472
Last sector, +sectors or +size{K,M,G} (84713472-156299374, default 156299374): +15G

Command (m for help): t
Partition number (1-4): 2
Hex code (type L to list codes): 83

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

By powiększyć system plików, korzystamy z resize2fs:

# resize2fs -p /dev/sdb2 
resize2fs 1.42.9 (28-Dec-2013)
Resizing the filesystem on /dev/sdb2 to 3932160 (4k) blocks.
The filesystem on /dev/sdb2 is now 3932160 blocks long.

Można sprecyzować oczywiście i rozmiar ale gdy w grę wchodzi powiększanie partycji, tak by wypełniła całą dostępną przestrzeń, można ominąć ten parametr, a system będzie wiedział, że ma rozciągnąć system plików jak tylko się da.

3. Zmiana rozmiaru partycji fat32

Podobnie jak i w przypadku dwóch poprzedników zaczynamy od sprawdzenia systemu plików:

# dosfsck -v -a -w /dev/sdb3
dosfsck 3.0.16 (01 Mar 2013)
dosfsck 3.0.16, 01 Mar 2013, FAT32, LFN
Checking we can access the last sector of the filesystem
Boot sector contents:
System ID "mkdosfs"
Media byte 0xf8 (hard disk)
       512 bytes per logical sector
     16384 bytes per cluster
        32 reserved sectors
First FAT starts at byte 16384 (sector 32)
         2 FATs, 32 bit entries
   5029888 bytes per FAT (= 9824 sectors)
Root directory start at cluster 2 (arbitrary size)
Data area starts at byte 10076160 (sector 19680)
   1253401 data clusters (20535721984 bytes)
63 sectors/track, 255 heads
         0 hidden sectors
  40128512 sectors total

Reclaiming unconnected clusters.
Checking free cluster summary.
/dev/sdb3: 20757 files, 72885/1253401 clusters

Jeśli chodzi o zmianę rozmiaru partycji fat32, to nie znalazłem narzędzia, które by zmieniało tylko rozmiar systemu plików. Istnieje co prawda narzędzie fatresize ale ono robi wszystko za nas. Poniżej będzie krótki opis jak go używać. Ale jeśli nie fatresize, to w takim razie co? No trzeba będzie zaciągnąć do pomocy parted, on obsługuje partycje fat bez problemu.

3.1. Wykorzystanie fatresize do zmiany rozmiaru partycji fat32

Fatresize to typowy automat, grunt, że dostępny jest spod konsoli. Możemy przy jego pomocy zbadać urządzenie i ustalić jaki nowy rozmiar może mieć zmieniana partycja. By to sprawdzić, wydajemy poniższe polecenie:

# fatresize -v -i /dev/sdb3
fatresize 1.0.2 (04/23/10)
FAT: fat32
Size: 20545798144
Min size: 1320769536
Max size: 80025280000

Powyższe wartości są w bajtach, a sam program obsługuje zarówno podstawę potęgi 2 jak i 10. Zmieńmy zatem rozmiar z 20GiB na 10GiB:

# fatresize -v -p -s 10Gi /dev/sdb3
fatresize 1.0.2 (04/23/10)
.Resizing file system.
.........................................Done.
Committing changes.

Wszystko sprowadza się do ustawienia nowego rozmiaru. Nie da się jednak skorzystać z tego narzędzia gdy w grę wchodzi zaszyfrowany kontener posiadający system plików fat.

3.2. Wykorzystanie parted do zmiany rozmiaru partycji fat32

Parted umożliwia nieco bardziej swobodny obrót partycjami, przynajmniej tymi, które są przez niego obsługiwane. Dysk się obecnie prezentuje jak poniżej:

# parted /dev/sdb
GNU Parted 2.3
Using /dev/sdb
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) unit
Unit?  [compact]? s
(parted) print free
Model: WDC WD80 0JB-00JJA0 (scsi)
Disk /dev/sdb: 156299375s
Sector size (logical/physical): 512B/512B
Partition Table: msdos

Number  Start       End         Size       Type     File system  Flags
        63s         2047s       1985s               Free Space
 1      2048s       41945087s   41943040s  primary  ntfs
        41945088s   84713471s   42768384s           Free Space
 2      84713472s   116170751s  31457280s  primary  ext4
 3      116170752s  137109375s  20938624s  primary  fat32
        137109376s  156299374s  19189999s           Free Space

Wybieramy pożądaną partycję oraz ustawiamy jej odpowiedni rozmiar. Jeśli komuś przeszkadzają sektory jako jednostki, może to z powodzeniem zmienić przez wpisanie unitdo parted. Ustawmy zatem nowy rozmiar dla trzeciej partycji:

(parted) resize 3
WARNING: you are attempting to use parted to operate on (resize) a file system.
parted's file system manipulation code is not as robust as what you'll find in
dedicated, file-system-specific packages like e2fsprogs.  We recommend
you use parted only to manipulate partition tables, whenever possible.
Support for performing most operations on most types of file systems
will be removed in an upcoming release.
Start?  [116170752s]?
End?  [137109375s]? 156290000s
moving data... 46%      (time left 00:29)

I sprawdzamy czy partycja ma inny rozmiar:

(parted) print free
Model: WDC WD80 0JB-00JJA0 (scsi)
Disk /dev/sdb: 156299375s
Sector size (logical/physical): 512B/512B
Partition Table: msdos

Number  Start       End         Size       Type     File system  Flags
        63s         2047s       1985s               Free Space
 1      2048s       41945087s   41943040s  primary  ntfs
        41945088s   84713471s   42768384s           Free Space
 2      84713472s   116170751s  31457280s  primary  ext4
 3      116170752s  156290000s  40119249s  primary  fat32
        156290001s  156299374s  9374s               Free Space

Lepiej zawsze zostawić trochę miejsca na końcu dysku, być może kiedyś będziemy potrzebować przekonwertować tablicę partycji z ms-dos na gpt.

W przypadku systemu plików ext również możemy korzystać z parted w celu zautomatyzowania i przyśpieszenia całej pracy. Nie ma on jednak zaimplementowanej obsługi ntfs, dodatkowo, jak możemy wyczytać z ostrzeżenia, parted zostanie pozbawiony możliwości operowania na danych w przyszłych wydaniach.

Wszystkie czynności opisane powyżej można także wykonać w gparted. Jednak żadne z tych narzędzi nie przyda się gdy w grę wejdzie LVM i/lub LUKS . Jeśli system nie widzi nowych partycji, być może pomocne okaże się wydanie poniższego polecenia:

# partprobe

4. Zmiana rozmiaru zaszyfrowanego kontenera LUKS

Tutaj już zaczynają się schody, bo w grę wchodzi wiele czynników, które trzeba uwzględnić przy próbie zmiany rozmiaru zaszyfrowanego kontenera. Dodatkowo rozmiar trzeba zmieniać przy otwartym kontenerze. Odblokujmy kontener:

# cryptsetup luksOpen /dev/sdb1 sdb1
Enter passphrase for /dev/sdb1:

# lsblk /dev/sdb
NAME             MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT
sdb                8:16   0  74.5G  0 disk
└─sdb1             8:17   0  37.3G  0 part
  └─sdb1 (dm-10) 254:10   0  37.3G  0 crypt

W zależności od tego jaki system plików posiadamy w kontenerze, trzeba skorzystać z odpowiedniego narzędzia do sprawdzenia integralności danych. W ty przypadku, w kontenerze znajduje się system plików ext4, zatem korzystamy z fsck.ext4, podając ścieżkę do odszyfrowanego systemu plików zlokalizowanego w /dev/mapper/ :

# fsck.ext4 -f -v -f /dev/mapper/sdb1
e2fsck 1.42.9 (28-Dec-2013)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information

        8119 inodes used (0.33%, out of 2449408)
           3 non-contiguous files (0.0%)
           1 non-contiguous directory (0.0%)
             # of inodes with ind/dind/tind blocks: 0/0/0
             Extent depth histogram: 8108
      309143 blocks used (3.16%, out of 9778688)
           0 bad blocks
           1 large file

        7226 regular files
         881 directories
           0 character device files
           0 block device files
           0 fifos
           0 links
           0 symbolic links (0 fast symbolic links)
           3 sockets
------------
        8110 files

4.1. Zmniejszanie LUKSa

Jeśli stworzyliśmy kiedyś zaszyfrowaną partycję, z której rozmiaru obecnie nie jesteśmy zadowoleni i chcielibyśmy ją zmniejszyć, to nic nie stoi na przeszkodzie by to zrobić. Kolejność działań jest taka sama jak w przypadku zmiany rozmiaru zwykłej partycji -- najpierw zmieniamy rozmiar systemu plików, a potem... no właśnie co potem? Trzeba będzie zmniejszyć rozmiar voluminu oraz partycji. Zatem do dzieła, zmieniamy rozmiar systemu plików ext4 z 37GiB na 10GiB:

# resize2fs -p /dev/mapper/sdb1 10G
resize2fs 1.42.9 (28-Dec-2013)
Resizing the filesystem on /dev/mapper/sdb1 to 2621440 (4k) blocks.
Begin pass 2 (max = 78514)
Relocating blocks             XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Begin pass 3 (max = 299)
Scanning inode table          XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Begin pass 4 (max = 915)
Updating inode references     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
The filesystem on /dev/mapper/sdb1 is now 2621440 blocks long.

Mając ciągle otwarty kontener ale niepodmontowany zasób, zmieniamy jego rozmiar przez cryptsetup resize , przy czym ten parametr przyjmuje wartości w sektorach. A zgodnie z tym co napisałem wcześniej, nie możemy skorzystać z rozmiaru bloku 2621440, który widnieje powyżej. Trzeba go pomnożyć przez 4. Czyli liczba bloków wynosi 10485760 , a po przeliczeniu tego na sektory to jest: (10485760*2)-1=20971519 .

Tylko tutaj ważna uwaga -- ta liczba bloków nie uwzględnia nagłówka zaszyfrowanej partycji, jest to tylko rozmiar systemu plików. Jeśli nie wiemy ile zajmuje nagłówek naszej partycji, możemy to sprawdzić przez:

# cryptsetup status sdb1
/dev/mapper/sdb1 is active.
  type:    LUKS1
  cipher:  aes-xts-plain64
  keysize: 512 bits
  device:  /dev/sdb1
  offset:  4096 sectors
  size:    78229504 sectors
  mode:    read/write

Jest to 4096 sektorów 512 bajtówych, co daje 2097152 bajtów, 2097152/1024/1024=2MiB . Jeśli teraz byśmy nie uwzględnili w wyliczeniach tego nagłówka i próbowali dostosować partycję obcinając te dodatkowe bloki, przy próbie montowania dostaniemy błąd:

# mount /dev/mapper/sdb1 /mnt
mount: wrong fs type, bad option, bad superblock on /dev/mapper/sdb1,
       missing codepage or helper program, or other error
       In some cases useful info is found in syslog - try
       dmesg | tail  or so

A w syslogu poniższy komunikat:

kernel: [40192.322415] EXT4-fs (dm-10): bad geometry: block count 2621440 exceeds size of device (2620928 blocks)

Sama partycja otworzy się bez problemu, bo obcięliśmy kawałek z tyłu partycji. Jeśli rozpatrzymy powyższy błąd -- 2621440-2620928=512 . Jest to 512 bloków, każdy z bloków ma 4096 bajtów, co daje 512*4096=2097152, a to z kolei jest 2097152/1024/1024=2MiB -- tyle samo co w przypadku ustalania wielkości nagłówka zaszyfrowanego dysku. Trzeba pamiętać by do faktycznego rozmiaru bloków wskazanego przez resize2fs (2621440) dodać 512 bloków i dopiero w oparciu o te bloki -- ((2621440+512)*4)*2-1= 20975615 -- zmieniać rozmiar partycji w fdisku. Nie ma się co stresować i jeśli źle coś policzymy, po prostu trzeba poprawić wpis w fdisku w oparciu o nowe obliczenia.

W przypadku voluminu stosujemy sektory bez offsetu -- ((2621440*4)*2)-1=20971519 :

# cryptsetup resize sdb1 --size 20971519

# lsblk /dev/sdb
NAME             MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT
sdb                8:16   0  74.5G  0 disk
└─sdb1             8:17   0  37.3G  0 part
  └─sdb1 (dm-10) 254:10   0    10G  0 crypt

Rozmiar voluminu sdb1 uległ zmianie. Ale partycja nadal ma 37GiB. By zmienić rozmiar partycji, zamykamy kontener i wchodzimy do fdiska.

# fdisk /dev/sdb

Command (m for help): p

Disk /dev/sdb: 80.0 GB, 80025280000 bytes
255 heads, 63 sectors/track, 9729 cylinders, total 156299375 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000c741d

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1            2048    78235647    39116800   83  Linux

Command (m for help): d
Selected partition 1

Command (m for help): n
Partition type:
   p   primary (0 primary, 0 extended, 4 free)
   e   extended
Select (default p): p
Partition number (1-4, default 1): 1
First sector (2048-156299374, default 2048):
Using default value 2048
Last sector, +sectors or +size{K,M,G} (2048-156299374, default 156299374): +20975615

Command (m for help): t
Selected partition 1
Hex code (type L to list codes): 83
Changed system type of partition 1 to 83 (Linux)

Command (m for help): p

Disk /dev/sdb: 80.0 GB, 80025280000 bytes
255 heads, 63 sectors/track, 9729 cylinders, total 156299375 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000c741d

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1            2048    20977663    10487808   83  Linux

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

No to teraz by sprawdzić czy wszystko działa, otwieramy kontener:

# cryptsetup luksOpen /dev/sdb1 sdb1
Enter passphrase for /dev/sdb1:

# lsblk /dev/sdb
NAME             MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT
sdb                8:16   0  74.5G  0 disk
└─sdb1             8:17   0    10G  0 part
  └─sdb1 (dm-10) 254:10   0    10G  0 crypt

Rozmiar partycji sdb1 uległ zmniejszeniu. Montujemy system plików i sprawdźmy czy zawarte w nim dane są możliwe do odczytania:

# mount /dev/mapper/sdb1 /mnt
# ls -al /mnt
total 28K
drwxr-xr-x  4 root root 4.0K Jan 13 20:51 ./
drwxr-xr-x 28 root root 4.0K Jan 13 20:54 ../
drwx------  2 root root  16K Jan 13 20:50 lost+found/
drwxr-xr-x 41 root root 4.0K Jan 13 20:52 morfik/

Nie ma błędów, katalog morfik wraz z cała zawartością siedzi nietknięty. Znaczy to nic innego jak tylko to, że proces zmniejszenia rozmiaru zaszyfrowanej partycji zakończył się sukcesem.

4.2. Powiększanie LUKSa

No to tak jeszcze by w pełni wyczerpać temat zmiany rozmiaru zaszyfrowanej partycji, trzeba rozpatrzyć drugi wariant, czyli zwiększenie rozmiaru kontenera LUKS.

Tak obecnie wygląda ułożenie partycji na dysku:

# lsblk /dev/sdb
NAME             MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT
sdb                8:16   0  74.5G  0 disk
└─sdb1             8:17   0    10G  0 part
  └─sdb1 (dm-10) 254:10   0    10G  0 crypt

Zamykamy kontener i przechodzimy do fdiska:

# cryptsetup luksClose sdb1

Kasujemy starą partycję i tworzymy nową, powiedzmy +15G, czyli nowy rozmiar kontenera to 25G:

# fdisk /dev/sdb

Command (m for help): p

Disk /dev/sdb: 80.0 GB, 80025280000 bytes
139 heads, 49 sectors/track, 22948 cylinders, total 156299375 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000c741d

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1            2048    20973567    10485760   83  Linux

Command (m for help): d
Selected partition 1

Command (m for help): n
Partition type:
   p   primary (0 primary, 0 extended, 4 free)
   e   extended
Select (default p): p
Partition number (1-4, default 1):
Using default value 1
First sector (2048-156299374, default 2048):
Using default value 2048
Last sector, +sectors or +size{K,M,G} (2048-156299374, default 156299374): +25G

Command (m for help): t
Selected partition 1
Hex code (type L to list codes): 83

Command (m for help): p

Disk /dev/sdb: 80.0 GB, 80025280000 bytes
139 heads, 49 sectors/track, 22948 cylinders, total 156299375 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000c741d

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1            2048    52430847    26214400   83  Linux

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

Otwieramy kontener:

# cryptsetup luksOpen /dev/sdb1 sdb1
Enter passphrase for /dev/sdb1:

# lsblk /dev/sdb
NAME             MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT
sdb                8:16   0  74.5G  0 disk
└─sdb1             8:17   0    25G  0 part
  └─sdb1 (dm-10) 254:10   0    25G  0 crypt

Rozmiar partycji i voluminu uległ zmianie. Trzeba jeszcze rozszerzyć system plików. Tylko tutaj jest problem związany z nagłówkami. W fdisku ustawiliśmy 25G -- jest to 25*1024*1024*1024=26843545600 bajtów, 26843545600/512=52428800 sektorów. Z kolei zaś 52428800/2=26214400 bloków (tych w fdisku). 26214400/4=6553600 bloków (tych w resize2fs). Jeśli byśmy spróbowali ustawić 25G jako rozmiar, dostaniemy błąd:

# resize2fs -p /dev/mapper/sdb1 25G
resize2fs 1.42.9 (28-Dec-2013)
The containing partition (or device) is only 6553088 (4k) blocks.
You requested a new size of 6553600 blocks.

Oczywiście można by pójść na łatwiznę i wpisać jeszcze raz rozmiar, tym razem używając liczby 6553088 wypisanej powyżej. Ale my to policzymy. By system plików miał odpowiedni rozmiar trzeba odjąć rozmiar nagłówków, a to jest 512 bloków 4096 bajtowych -- 512*4096=2097152 . Czyli rozmiar nowego systemu plików wynieść powinien 26843545600-2097152=26841448448 bajtów. Ale resize2fs nie przyjmie rozmiaru w bajtach (tylko w przypadku K,M,G). Za to przyjmuje rozmiar w sektorach. Zatem nowy rozmiar powinien wynieść 26841448448/512=52424704 sektorów. Jeśli chcielibyśmy operować na blokach: 6553600−512=6553088 bloków, 6553088*4096=26841448448 bajtów, 26841448448/512=52424704 sektorów, 52424704/8=6553088 bloków 4096 bajtowych (4096=8*512) -- dokładnie tyle samo ile zasugerował resize2fs.

Sprawdźmy zatem czy resize2fs przyjmie rozmiar 52424704s :

# resize2fs -p /dev/mapper/sdb1 52424704s
resize2fs 1.42.9 (28-Dec-2013)
Resizing the filesystem on /dev/mapper/sdb1 to 6553088 (4k) blocks.
The filesystem on /dev/mapper/sdb1 is now 6553088 blocks long.

Weszło. W przypadku gdyby pojawił się poniższy komunikat:

# resize2fs -p /dev/mapper/sdb1 52424704s
resize2fs 1.42.9 (28-Dec-2013)
Please run 'e2fsck -f /dev/mapper/sdb1' first.

Trzeba przeskanować system plików i ponowić żądanie zmiany rozmiaru. Montujemy jeszcze system plików i sprawdzamy czy są w nim wcześniej stworzone pliki:

# mount /dev/mapper/sdb1 /mnt
# ls -al /mnt
total 28K
drwxr-xr-x  4 root root 4.0K Jan 13 20:51 ./
drwxr-xr-x 28 root root 4.0K Jan 13 20:54 ../
drwx------  2 root root  16K Jan 13 20:50 lost+found/
drwxr-xr-x 41 root root 4.0K Jan 13 20:52 morfik/

I to wszystko co się tyczy zmiany rozmiaru zaszyfrowanego kontenera.

5. Zmiana rozmiaru LVM

No to teraz przyszła pora na zmianę rozmiaru voluminów LVM. Tak obecnie prezentuje się mój dysk:

# fdisk -l /dev/sdb

Disk /dev/sdb: 80.0 GB, 80025280000 bytes
255 heads, 63 sectors/track, 9729 cylinders, total 156299375 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000c741d

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1            2048    81922047    40960000   83  Linux

I w postaci zamontowanej:

# lsblk /dev/sdb
NAME                       MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sdb                          8:16   0  74,5G  0 disk 
└─sdb1                       8:17   0  39,1G  0 part 
  ├─grupa1-volumin1 (dm-1) 254:1    0     5G  0 lvm  /media/1
  ├─grupa1-volumin2 (dm-2) 254:2    0     7G  0 lvm  /media/2
  ├─grupa1-volumin3 (dm-3) 254:3    0     9G  0 lvm  /media/3
  ├─grupa1-volumin4 (dm-4) 254:4    0    11G  0 lvm  /media/4
  └─grupa1-volumin5 (dm-5) 254:5    0   7,1G  0 lvm  /media/5

By zacząć cokolwiek robić z kontenerem LVM, musimy pierw uzyskać stosowne informacje:

# pvscan 
  PV /dev/sdb1   VG grupa1   lvm2 [39,06 GiB / 0    free]
  Total: 1 [39,06 GiB] / in use: 1 [39,06 GiB] / in no VG: 0 [0   ]

# pvs -v --segments
    Scanning for physical volume names
  PV         VG     Fmt  Attr PSize  PFree Start SSize LV       Start Type   PE Ranges          
  /dev/sdb1  grupa1 lvm2 a--  39,06g    0      0  1280 volumin1     0 linear /dev/sdb1:0-1279   
  /dev/sdb1  grupa1 lvm2 a--  39,06g    0   1280  1792 volumin2     0 linear /dev/sdb1:1280-3071
  /dev/sdb1  grupa1 lvm2 a--  39,06g    0   3072  2304 volumin3     0 linear /dev/sdb1:3072-5375
  /dev/sdb1  grupa1 lvm2 a--  39,06g    0   5376  2816 volumin4     0 linear /dev/sdb1:5376-8191
  /dev/sdb1  grupa1 lvm2 a--  39,06g    0   8192  1807 volumin5     0 linear /dev/sdb1:8192-9998

# lvs -v --segments
    Finding all logical volumes
  LV       VG     Attr      Start SSize  #Str Type   Stripe Chunk
  volumin1 grupa1 -wc-ao---    0   5,00g    1 linear     0     0 
  volumin2 grupa1 -wc-ao---    0   7,00g    1 linear     0     0 
  volumin3 grupa1 -wc-ao---    0   9,00g    1 linear     0     0 
  volumin4 grupa1 -wc-ao---    0  11,00g    1 linear     0     0 
  volumin5 grupa1 -wc-ao---    0   7,06g    1 linear     0     0

Jeśli ktoś preferuje sektory nad bajtami, wystarczy sprecyzować jednostkę przy pomocy --units s :

# pvs -v --units s
    Scanning for physical volume names
  PV         VG     Fmt  Attr PSize     PFree DevSize   PV UUID                               
  /dev/sdb1  grupa1 lvm2 a--  81911808S    0S 81920000S xMddCU-5h1X-ZZL4-GFfO-ea4L-PqW8-YCGLte

# lvs -v --segments --units s
    Finding all logical volumes
  LV       VG     Attr      Start SSize     #Str Type   Stripe Chunk
  volumin1 grupa1 -wc-ao---    0S 10485760S    1 linear     0S    0S
  volumin2 grupa1 -wc-ao---    0S 14680064S    1 linear     0S    0S
  volumin3 grupa1 -wc-ao---    0S 18874368S    1 linear     0S    0S
  volumin4 grupa1 -wc-ao---    0S 23068672S    1 linear     0S    0S
  volumin5 grupa1 -wc-ao---    0S 14802944S    1 linear     0S    0S

Jak widać z powyższych informacji, mamy 1 kontener 39GiB, na którym znajduje się 5 voluminów logicznych. Każdy z nich ma strukturę ciągłą, tzn. że zakresy bloków występują jeden po drugim. Wiąże się z tym problem zmiany rozmiaru dysków -- zachowują się jak zwykłe partycje i limitowane tym co leży obok nich. W tym przypadku można by rozciągnąć i skurczyć bez problemu tylko ostatni dysk. W przypadku gdy dyski nie mają struktury ciągłej, można bez problemu obracać nimi i nie ma znaczenia gdzie one są, byle by tylko miejsca w kontenerze wystarczyło.

Ogólne info na temat voluminów LVM można uzyskać też przez dmsetup:

# dmsetup info --columns
Name             Maj Min Stat Open Targ Event  UUID                                                                
grupa1-volumin5  254   5 L--w    1    1      0 LVM-Yas25yA36PmWfMQNJ17UWf48Uat1Wd4MAkxiRDJ1HSjRhwAdfvQsvfaSKD3dqJ3J
grupa1-volumin4  254   4 L--w    1    1      0 LVM-Yas25yA36PmWfMQNJ17UWf48Uat1Wd4MVLPNyLV6edfQ5F1Whn2cekmQzuHEiU2a
grupa1-volumin3  254   3 L--w    1    1      0 LVM-Yas25yA36PmWfMQNJ17UWf48Uat1Wd4MXOe2Txojibc6XiGCLk5RPKxjEOJ9gRxk
grupa1-volumin2  254   2 L--w    1    1      0 LVM-Yas25yA36PmWfMQNJ17UWf48Uat1Wd4MTUAwlgfkbmodBL5MSAb9Xt2yoNpNj9o8                
grupa1-volumin1  254   1 L--w    1    1      0 LVM-Yas25yA36PmWfMQNJ17UWf48Uat1Wd4MYaU6fBv6UC4XBJPOmeCJ1lrlqk0FA5cU

Atrybuty: (L)ive, (I)nactive, (s)uspended, (r)ead-only, read-(w)rite

Jeśli potrzebujemy bardziej szczegółowych informacji na temat któregoś z voluminów:

# lvdisplay /dev/mapper/grupa1-volumin1
  --- Logical volume ---
  LV Path                /dev/grupa1/volumin1
  LV Name                volumin1
  VG Name                grupa1
  LV UUID                YaU6fB-v6UC-4XBJ-POme-CJ1l-rlqk-0FA5cU
  LV Write Access        read/write
  LV Creation host, time livemor, 2014-01-15 09:46:44 +0100
  LV Status              available
  # open                 1
  LV Size                5,00 GiB
  Current LE             1280
  Segments               1
  Allocation             contiguous
  Read ahead sectors     auto
  - currently set to     256
  Block device           254:1

5.1. Powiększanie LVM

Spróbujmy teraz rozszerzyć partycję LVM i 2 voluminy w niej zawarte. Zgodnie w info o pv (polecenie pvs) rozmiar fizycznego voluminu (pv) to 81911808 sektorów, za to rozmiar urządzenia, na którym znajduje się LVM to 81920000 sektorów. Jak widać te dwie pozycje różnią się o 8192 sektory (4MiB). W fdisku rozmiar wyjściowy to rozmiar partycji LVM -- 81920000 , do tej wartości trzeba dodać 10GiB -- (10*1024*1024*1024)/512=20971520 sektorów. Rozmiar nowej partycji wynosić będzie zatem 81920000+20971520-1=102891519 sektorów. Wchodzimy do fdiska i dodajemy +10GiB miejsca:

# fdisk /dev/sdb

Command (m for help): p

Disk /dev/sdb: 80.0 GB, 80025280000 bytes
255 heads, 63 sectors/track, 9729 cylinders, total 156299375 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000c741d

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1            2048    81922047    40960000   83  Linux

Command (m for help): d 
Selected partition 1

Command (m for help): n
Partition type:
   p   primary (0 primary, 0 extended, 4 free)
   e   extended
Select (default p): 
Using default response p
Partition number (1-4, default 1): 
Using default value 1
First sector (2048-156299374, default 2048): 
Using default value 2048
Last sector, +sectors or +size{K,M,G} (2048-156299374, default 156299374): +102891519

Command (m for help): t
Selected partition 1
Hex code (type L to list codes): 8e
Changed system type of partition 1 to 8e (Linux LVM)

Command (m for help): p

Disk /dev/sdb: 80.0 GB, 80025280000 bytes
255 heads, 63 sectors/track, 9729 cylinders, total 156299375 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000c741d

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1            2048   102893567    51445760   8e  Linux LVM

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.

Sprawdzamy czy rozmiar partycji pod LVM się zmienił:

# lsblk /dev/sdb
NAME                       MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sdb                          8:16   0  74,5G  0 disk 
└─sdb1                       8:17   0  49,1G  0 part 
  ├─grupa1-volumin1 (dm-1) 254:1    0     5G  0 lvm  /media/1
  ├─grupa1-volumin2 (dm-2) 254:2    0     7G  0 lvm  /media/2
  ├─grupa1-volumin3 (dm-3) 254:3    0     9G  0 lvm  /media/3
  ├─grupa1-volumin4 (dm-4) 254:4    0    11G  0 lvm  /media/4
  └─grupa1-volumin5 (dm-5) 254:5    0   7,1G  0 lvm  /media/5

Jest +10GiB. Teraz trzeba jeszcze rozszerzyć kontener LVM

# pvscan 
  PV /dev/sdb1   VG grupa1   lvm2 [39,06 GiB / 0    free]
  Total: 1 [39,06 GiB] / in use: 1 [39,06 GiB] / in no VG: 0 [0   ]

# pvresize /dev/sdb1 
  Physical volume "/dev/sdb1" changed
  1 physical volume(s) resized / 0 physical volume(s) not resized

# pvscan
  PV /dev/sdb1   VG grupa1   lvm2 [49,06 GiB / 10,00 GiB free]
  Total: 1 [49,06 GiB] / in use: 1 [49,06 GiB] / in no VG: 0 [0   ]

Wolne miejsce wskazuje, że 10GiB dodanych wewnątrz LVM zostało uwzględnione. Rozszerzmy zatem 2 voluminy, powiedzmy 2 i 5, dodając im po 5GiB. Z piątym, jako, że jest ostatni, nie będzie problemu:

# lvresize -L +5G /dev/mapper/grupa1-volumin5 
  Extending logical volume volumin5 to 12,06 GiB
  Logical volume volumin5 successfully resized

Ale gdy spróbujemy dodać +5GiB do drugiego logicznego dysku, dostaniemy poniższy komunikat:

# lvresize -L +5G /dev/mapper/grupa1-volumin2
  Extending logical volume volumin2 to 12,00 GiB
  Insufficient suitable contiguous allocatable extents for logical volume volumin2: 1280 more required

Co w takim przypadku zrobić? Wyjścia są dwa, albo usunąć volumin i stworzyć nowy -- tym razem bez opcji -C y , albo zmienić strukturę tego voluminu, tak by przestała być ciągła. Jeśli nie uśmiecha nam się kasowanie danych, możemy skorzystać z drugiego rozwiązania:

# lvchange -C n /dev/mapper/grupa1-volumin2 
  Logical volume "volumin2" changed

I sprawdzamy czy volumin stracił ciągłość:

# lvscan
  ACTIVE            '/dev/grupa1/volumin1' [5,00 GiB] contiguous
  ACTIVE            '/dev/grupa1/volumin2' [7,00 GiB] inherit
  ACTIVE            '/dev/grupa1/volumin3' [9,00 GiB] contiguous
  ACTIVE            '/dev/grupa1/volumin4' [11,00 GiB] contiguous
  ACTIVE            '/dev/grupa1/volumin5' [12,06 GiB] contiguous

Rozszerzamy go o +5GiB:

# lvresize -L +5G /dev/mapper/grupa1-volumin2 
  Extending logical volume volumin2 to 12,00 GiB
  Logical volume volumin2 successfully resized

I już teraz poszło wszystko bez problemu. Sprawdźmy jeszcze jak wygląda struktura LVM:

# pvs -v --segments
    Scanning for physical volume names
  PV         VG     Fmt  Attr PSize  PFree Start SSize LV       Start Type   PE Ranges            
  /dev/sdb1  grupa1 lvm2 a--  49,06g    0      0  1280 volumin1     0 linear /dev/sdb1:0-1279     
  /dev/sdb1  grupa1 lvm2 a--  49,06g    0   1280  1792 volumin2     0 linear /dev/sdb1:1280-3071  
  /dev/sdb1  grupa1 lvm2 a--  49,06g    0   3072  2304 volumin3     0 linear /dev/sdb1:3072-5375  
  /dev/sdb1  grupa1 lvm2 a--  49,06g    0   5376  2816 volumin4     0 linear /dev/sdb1:5376-8191  
  /dev/sdb1  grupa1 lvm2 a--  49,06g    0   8192  3087 volumin5     0 linear /dev/sdb1:8192-11278 
  /dev/sdb1  grupa1 lvm2 a--  49,06g    0  11279  1280 volumin2  1792 linear /dev/sdb1:11279-12558

Wszystko wygląda dobrze, tylko taka uwaga -- wszystkie powyższe operacje były przeprowadzane przy podmontowanych voluminach. Do tej pory nie było potrzeby by te voluminy były odmontowane, niemniej jednak, teraz trzeba rozciągnąć ich system plików, tak by wypełniał całą przestrzeń dostępną na logicznych dyskach.

# umount /media/1
# umount /media/2
# umount /media/3
# umount /media/4
# umount /media/5

# lsblk /dev/sdb
NAME                       MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sdb                          8:16   0  74,5G  0 disk 
└─sdb1                       8:17   0  49,1G  0 part 
  ├─grupa1-volumin1 (dm-1) 254:1    0     5G  0 lvm  
  ├─grupa1-volumin2 (dm-2) 254:2    0    12G  0 lvm  
  ├─grupa1-volumin3 (dm-3) 254:3    0     9G  0 lvm  
  ├─grupa1-volumin4 (dm-4) 254:4    0    11G  0 lvm  
  └─grupa1-volumin5 (dm-5) 254:5    0  12,1G  0 lvm

W tym przypadku wszystkie voluminy mają system plików ext4. Przed zmianą rozmiaru trzeba przeskanować voluminy przy pomocy fsck. Rozmiar zostanie zmieniony w przypadku dwóch, także skanujemy tylko te dwa:

# e2fsck -f /dev/mapper/grupa1-volumin2
e2fsck 1.42.8 (20-Jun-2013)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/mapper/grupa1-volumin2: 11/458752 files (0.0% non-contiguous), 65599/1835008 blocks

# e2fsck -f /dev/mapper/grupa1-volumin5
e2fsck 1.42.8 (20-Jun-2013)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/mapper/grupa1-volumin5: 11/463296 files (0.0% non-contiguous), 65921/1850368 blocks

I rozszerzamy ich system plików przy pomocy resize2fs. W przypadku niepodania argumentu rozmiaru, system plików zostanie rozciągnięty na całą dostępną przestrzeń w voluminie:

# resize2fs -p /dev/mapper/grupa1-volumin2
resize2fs 1.42.8 (20-Jun-2013)
Resizing the filesystem on /dev/mapper/grupa1-volumin2 to 3145728 (4k) blocks.
The filesystem on /dev/mapper/grupa1-volumin2 is now 3145728 blocks long.

# resize2fs -p /dev/mapper/grupa1-volumin5
resize2fs 1.42.8 (20-Jun-2013)
Resizing the filesystem on /dev/mapper/grupa1-volumin5 to 3161088 (4k) blocks.
The filesystem on /dev/mapper/grupa1-volumin5 is now 3161088 blocks long.

Teraz już lsblk powinien zauważyć nowe rozmiary dysków:

# lsblk /dev/sdb
NAME                       MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sdb                          8:16   0  74,5G  0 disk 
└─sdb1                       8:17   0  49,1G  0 part 
  ├─grupa1-volumin1 (dm-1) 254:1    0     5G  0 lvm  
  ├─grupa1-volumin2 (dm-2) 254:2    0    12G  0 lvm  
  ├─grupa1-volumin3 (dm-3) 254:3    0     9G  0 lvm  
  ├─grupa1-volumin4 (dm-4) 254:4    0    11G  0 lvm  
  └─grupa1-volumin5 (dm-5) 254:5    0  12,1G  0 lvm

I tak faktycznie się dzieje. By sprawdzić czy wszystko działa jak należy, reaktywujemy grupę voluminów i montujemy dyski logiczne:

# vgchange -a n grupa1
  0 logical volume(s) in volume group "grupa1" now active
# vgchange -a y grupa1
  5 logical volume(s) in volume group "grupa1" now active
# mount /dev/mapper/grupa1-volumin1 /media/1
# mount /dev/mapper/grupa1-volumin2 /media/2
# mount /dev/mapper/grupa1-volumin3 /media/3
# mount /dev/mapper/grupa1-volumin4 /media/4
# mount /dev/mapper/grupa1-volumin5 /media/5

Nie ma żadnych problemów, co oznacza, że dyski logiczne, jak i sam kontener LVM, zostały z powodzeniem rozciągnięte.

5.2. Zmniejszanie LVM

Połowa drogi za nami, teraz jeszcze trzeba zmniejszyć jakoś ten kontener LVM. Obecnie dysk posiada 49GiB:

# pvscan 
  PV /dev/sdb1   VG grupa1   lvm2 [49,06 GiB / 0    free]
  Total: 1 [49,06 GiB] / in use: 1 [49,06 GiB] / in no VG: 0 [0   ]

# lvscan
  ACTIVE            '/dev/grupa1/volumin1' [5,00 GiB] contiguous
  ACTIVE            '/dev/grupa1/volumin2' [12,00 GiB] inherit
  ACTIVE            '/dev/grupa1/volumin3' [9,00 GiB] contiguous
  ACTIVE            '/dev/grupa1/volumin4' [11,00 GiB] contiguous
  ACTIVE            '/dev/grupa1/volumin5' [12,06 GiB] contiguous

Potrzeba jest by skurczyć partycję o 30GiB. Załóżmy, że mamy dwa zbędne voluminy -- 2 i 4. Da nam to tylko 23GiB, dodatkowo volumin3 ma sporo wolnego miejsca i nadaje się do skurczenia. Odmontowujemy wszystkie voluminy i usuwamy volumin2 oraz volumin4:

# umount /media/1
# umount /media/2
# umount /media/3
# umount /media/4
# umount /media/5

# lsblk /dev/sdb
NAME                       MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sdb                          8:16   0  74,5G  0 disk 
└─sdb1                       8:17   0  49,1G  0 part 
  ├─grupa1-volumin1 (dm-1) 254:1    0     5G  0 lvm  
  ├─grupa1-volumin2 (dm-2) 254:2    0    12G  0 lvm  
  ├─grupa1-volumin3 (dm-3) 254:3    0     9G  0 lvm  
  ├─grupa1-volumin4 (dm-4) 254:4    0    11G  0 lvm  
  └─grupa1-volumin5 (dm-5) 254:5    0  12,1G  0 lvm
# lvremove /dev/mapper/grupa1-volumin2
Do you really want to remove active logical volume volumin2? [y/n]: y
  Logical volume "volumin2" successfully removed

# lvremove /dev/mapper/grupa1-volumin4
Do you really want to remove active logical volume volumin4? [y/n]: y
  Logical volume "volumin4" successfully removed

Zmieniamy także rozmiar logicznego dysku numer 3. Musimy pierw skurczyć system plików przy pomocy resize2fs:

# e2fsck -f /dev/mapper/grupa1-volumin3
e2fsck 1.42.8 (20-Jun-2013)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/mapper/grupa1-volumin3: 11/589824 files (0.0% non-contiguous), 74975/2359296 bloków

# resize2fs -p /dev/mapper/grupa1-volumin3 2G
resize2fs 1.42.8 (20-Jun-2013)
Resizing the filesystem on /dev/mapper/grupa1-volumin3 to 524288 (4k) block.
Begin pass 3 (max = 24)
Scanning inode table XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
The filesystem on /dev/mapper/grupa1-volumin3 is now 524288 blocks long.

Zmieniamy teraz rozmiar voluminu, tak by pasował do rozmiaru systemu plików. Ci którzy nie ufają rozmiarom definiowanym w bajtach (K,M,G), mogą oczywiście przeliczyć rozmiar na sektory. W tym celu bierzemy bloki wypisane przez resize2fs -- 524288*8=4194304 sektorów 512 bajtowych. Jeśli chcemy definiować rozmiar po sektorach, trzeba odjąć 1 od tej wartości -- 4194304-1=4194303 .

# lvresize -t -L 4194303s /dev/mapper/grupa1-volumin3 
TEST MODE: Metadata will NOT be updated and volumes will not be (de)activated.
Rounding size to boundary between physical extents: 2,00 GiB
WARNING: Reducing active and open logical volume to 2,00 GiB

Jeśli nie chce nam się bawić w przeliczanie, możemy po prostu ustawić 2G:

# lvresize -t -L 2G /dev/mapper/grupa1-volumin3
TEST MODE: Metadata will NOT be updated and volumes will not be (de)activated.
WARNING: Reducing active and open logical volume to 2,00 GiB
THIS MAY DESTROY YOUR DATA (filesystem etc.)

Jak widać na powyższym teście, w obu przypadkach nowy rozmiar to 2GiB. Wybieramy jeden z powyższych i zmieniamy wielkość voluminu na 2GiB:

# lvresize -L 2G /dev/mapper/grupa1-volumin3 
  WARNING: Reducing active and open logical volume to 2,00 GiB
  THIS MAY DESTROY YOUR DATA (filesystem etc.)
Do you really want to reduce volumin3? [y/n]: y
  Reducing logical volume volumin3 to 2,00 GiB
  Logical volume volumin3 successfully resized

Sprawdzamy czy udało się odzyskać 30GiB:

# pvscan
  PV /dev/sdb1   VG grupa1   lvm2 [49,06 GiB / 30,00 GiB free]
  Total: 1 [49,06 GiB] / in use: 1 [49,06 GiB] / in no VG: 0 [0   ]

Mamy 30GiB wolnego miejsca, więc wszystko zgodnie z planem. Sprawdźmy jeszcze czy wszystkie 3 voluminy się montują bez problemu:

# vgchange -a n grupa1
  0 logical volume(s) in volume group "grupa1" now active
# vgchange -a y grupa1
  3 logical volume(s) in volume group "grupa1" now active
# mount /dev/mapper/grupa1-volumin1 /media/1
# mount /dev/mapper/grupa1-volumin3 /media/3
# mount /dev/mapper/grupa1-volumin5 /media/5

# lsblk /dev/sdb
NAME                       MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sdb                          8:16   0  74,5G  0 disk 
└─sdb1                       8:17   0  49,1G  0 part 
  ├─grupa1-volumin1 (dm-1) 254:1    0     5G  0 lvm  /media/1
  ├─grupa1-volumin3 (dm-2) 254:2    0     2G  0 lvm  /media/3
  └─grupa1-volumin5 (dm-3) 254:3    0  12,1G  0 lvm  /media/5

Nie ma żadnych błędów, co oznacza, że wszystko jest w porządku. Ostatni krok to zmniejszenie partycji LVM ale tu już nie będzie tak łatwo. Jeśli spojrzymy na to jak wygląda obecnie struktura kontenera LVM, zobaczymy dziury:

# pvs -v --segments
    Scanning for physical volume names
  PV         VG     Fmt  Attr PSize  PFree  Start SSize LV       Start Type   PE Ranges           
  /dev/sdb1  grupa1 lvm2 a--  49,06g 30,00g     0  1280 volumin1     0 linear /dev/sdb1:0-1279    
  /dev/sdb1  grupa1 lvm2 a--  49,06g 30,00g  1280  1792              0 free                       
  /dev/sdb1  grupa1 lvm2 a--  49,06g 30,00g  3072   512 volumin3     0 linear /dev/sdb1:3072-3583 
  /dev/sdb1  grupa1 lvm2 a--  49,06g 30,00g  3584  4608              0 free                       
  /dev/sdb1  grupa1 lvm2 a--  49,06g 30,00g  8192  3087 volumin5     0 linear /dev/sdb1:8192-11278
  /dev/sdb1  grupa1 lvm2 a--  49,06g 30,00g 11279  1280              0 free

Jeśli próbowalibyśmy zmniejszyć rozmiar partycji o 30GiB, dostalibyśmy poniższy komunikat:

# pvresize --setphysicalvolumesize 29,06G /dev/sdb1 
  /dev/sdb1: cannot resize to 7439 extents as later ones are allocated.
  0 physical volume(s) resized / 1 physical volume(s) not resized

Dzieje się tak dlatego, że za ostatnim voluminem jest dostępnych 1280*4MiB=5GiB wolnego miejsca. I w tej chwili możemy zmniejszyć kontener LVM, jak i samą partycję, jedynie o 5GiB z pożądanych 30GiB. Jeśli policzymy sobie pozostałe przestrzenie, tj. 4608*4MiB=18GiB oraz 1792*4MiB=7GiB, to da nam to 5+18+7=30GiB. Czemu mnożymy przez 4MiB? To jest blok LVM, można go odczytać z:

# vgdisplay 
  --- Volume group ---
  VG Name               grupa1
  System ID             
  Format                lvm2
  Metadata Areas        1
  Metadata Sequence No  13
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                3
  Open LV               3
  Max PV                0
  Cur PV                1
  Act PV                1
  VG Size               49,06 GiB
  PE Size               4,00 MiB
  Total PE              12559
  Alloc PE / Size       4879 / 19,06 GiB
  Free  PE / Size       7680 / 30,00 GiB
  VG UUID               Yas25y-A36P-mWfM-QNJ1-7UWf-48Ua-t1Wd4M

Co zrobić by usunąć wolne miejsce z kontenera? Trzeba poprzenosić logiczne voluminy i upakować je blisko siebie ale trzeba zwracać uwagę na wolne miejsce, bo nie da rady wpakować większego voluminu do mniejszej dziury, podobnie jest z przesuwaniem voluminu -- jeśli dziura przed voluminem ma 2GiB, a sam volumin 3GiB, nie damy rady przesunąć voluminu, trzeba będzie go skopiować gdzieś by uwolnić pierw miejsce, tak by dziura miała minimum 3GiB.

W tym przypadku akurat sprawa wygląda prosto: volumin3 ma rozmiar 512bloków i się zmieści w dziurę przed nim, a potem tylko dokleimy volumin5 za voluminem3. Zatem do dzieła. Każdy logiczny volumin jest reprezentowany przez dwie wartości -- przez początek dysku i jego rozmiar. Rozpatrując przeniesienie voluminu3, jego rozmiar to 512 bloków i musi zostać przeniesiony na pozycję 1280. Zatem nowe parametry będą wynosić 1280-1791 -- trzeba pamiętać o odjęciu 1 od końcowego bloku. Przenosimy volumin na tym samym fizycznym nośniku zatem linijka będzie miała postać:

# pvmove --alloc anywhere -i 30 /dev/sdb1:3072-3583  /dev/sdb1:1280-1791
  /dev/sdb1: Moved: 0,0%
  /dev/sdb1: Moved: 15,0%
  /dev/sdb1: Moved: 30,3%

Zobaczmy co się dzieje wewnątrz kontenera LVM podczas przenoszenia voluminów:

# pvs -v --segments
    Scanning for physical volume names
  PV         VG     Fmt  Attr PSize  PFree  Start SSize LV        Start Type   PE Ranges                              
  /dev/sdb1  grupa1 lvm2 a--  49,06g 28,00g     0  1280 volumin1      0 linear /dev/sdb1:0-1279                       
  /dev/sdb1  grupa1 lvm2 a--  49,06g 28,00g  1280   512 [pvmove0]     0 mirror /dev/sdb1:3072-3583 /dev/sdb1:1280-1791
  /dev/sdb1  grupa1 lvm2 a--  49,06g 28,00g  1792  1280               0 free                                          
  /dev/sdb1  grupa1 lvm2 a--  49,06g 28,00g  3072   512 [pvmove0]     0 mirror /dev/sdb1:3072-3583 /dev/sdb1:1280-1791
  /dev/sdb1  grupa1 lvm2 a--  49,06g 28,00g  3584  4608               0 free                                          
  /dev/sdb1  grupa1 lvm2 a--  49,06g 28,00g  8192  3087 volumin5      0 linear /dev/sdb1:8192-11278                   
  /dev/sdb1  grupa1 lvm2 a--  49,06g 28,00g 11279  1280               0 free

Mamy tam nowy volumin -- pvmove0 . Jest on tworzony tylko na czas przenoszenia danych. Po pomyślnym zakończeniu, stary volumin zostanie usunięty.

Gdy proces dobiegnie końca, przenosimy volumin5. Sprawdzamy pierw jak prezentuje się układ LVM:

# pvs -v --segments
    Scanning for physical volume names
  PV         VG     Fmt  Attr PSize  PFree  Start SSize LV       Start Type   PE Ranges           
  /dev/sdb1  grupa1 lvm2 a--  49,06g 30,00g     0  1280 volumin1     0 linear /dev/sdb1:0-1279    
  /dev/sdb1  grupa1 lvm2 a--  49,06g 30,00g  1280   512 volumin3     0 linear /dev/sdb1:1280-1791 
  /dev/sdb1  grupa1 lvm2 a--  49,06g 30,00g  1792  6400              0 free                       
  /dev/sdb1  grupa1 lvm2 a--  49,06g 30,00g  8192  3087 volumin5     0 linear /dev/sdb1:8192-11278
  /dev/sdb1  grupa1 lvm2 a--  49,06g 30,00g 11279  1280              0 free 

I przenosimy przy pomocy:

# pvmove --alloc anywhere -i 30 /dev/sdb1:8129-11278  /dev/sdb1:1792-4878

Jeśli się pomyliliśmy lub z jakiegoś powodu chcemy przerwać proces przenoszenia voluminu, to nic nam nie da wciśnięcie ctrl+c -- proces dalej będzie działał. Trzeba w konsoli wpisać pvmove --abort . Wtedy proces przenoszenia voluminu zostanie przerwany. Żadne zmiany nie zostaną poczynione w stosunku do starego voluminu.

Po skończonej pracy, powinniśmy uzyskać wynik podobny do tego poniżej:

# pvs -v --segments
    Scanning for physical volume names
  PV         VG     Fmt  Attr PSize  PFree  Start SSize LV       Start Type   PE Ranges          
  /dev/sdb1  grupa1 lvm2 a--  49,06g 30,00g     0  1280 volumin1     0 linear /dev/sdb1:0-1279   
  /dev/sdb1  grupa1 lvm2 a--  49,06g 30,00g  1280   512 volumin3     0 linear /dev/sdb1:1280-1791
  /dev/sdb1  grupa1 lvm2 a--  49,06g 30,00g  1792  3087 volumin5     0 linear /dev/sdb1:1792-4878
  /dev/sdb1  grupa1 lvm2 a--  49,06g 30,00g  4879  7680              0 free  

# lvs -v --segments
    Finding all logical volumes
  LV       VG     Attr      Start SSize  #Str Type   Stripe Chunk
  volumin1 grupa1 -wc-ao---    0   5,00g    1 linear     0     0 
  volumin3 grupa1 -wc-ao---    0   2,00g    1 linear     0     0 
  volumin5 grupa1 -wc-ao---    0  12,06g    1 linear     0     0

Czas zmniejszyć kontener LVM . Jeśli spróbujemy skurczyć kontener za bardzo, dostaniemy błąd:

# pvresize -v /dev/sdb1 --setphysicalvolumesize 19G
    Using physical volume(s) on command line
    Archiving volume group "grupa1" metadata (seqno 21).
    /dev/sdb1: Pretending size is 39845888 not 102884229 sectors.
    Resizing volume "/dev/sdb1" to 102884229 sectors.
    Resizing physical volume /dev/sdb1 from 0 to 4863 extents.
  /dev/sdb1: cannot resize to 4863 extents as 4879 are allocated.
  0 physical volume(s) resized / 1 physical volume(s) not resized

Powyżej mamy wypisaną wartość jakiej powinniśmy użyć -- 4879. 4879*4+1=19517M

# pvresize -v /dev/sdb1 --setphysicalvolumesize 19517M
    Using physical volume(s) on command line
    Archiving volume group "grupa1" metadata (seqno 21).
    /dev/sdb1: Pretending size is 39970816 not 102884229 sectors.
    Resizing volume "/dev/sdb1" to 102884229 sectors.
    Resizing physical volume /dev/sdb1 from 0 to 4879 extents.
    Updating physical volume "/dev/sdb1"
    Creating volume group backup "/etc/lvm/backup/grupa1" (seqno 22).
  Physical volume "/dev/sdb1" changed
  1 physical volume(s) resized / 0 physical volume(s) not resized

Sprawdzamy czy rzeczywiście rozmiar kontenera uległ zmianie:

# pvscan
  PV /dev/sdb1   VG grupa1   lvm2 [19,06 GiB / 0    free]
  Total: 1 [19,06 GiB] / in use: 1 [19,06 GiB] / in no VG: 0 [0   ]

Rozmiar 19,06GiB i 0 wolnego miejsca.

Ostatni krok to zmniejszenie partycji via fdisk. Jakiego rozmiaru potrzebujemy? Sprawdzamy rozmiar kontenera w sektorach:

# pvs -v --unit s
    Scanning for physical volume names
  PV         VG     Fmt  Attr PSize     PFree DevSize    PV UUID                               
  /dev/sdb1  grupa1 lvm2 a--  39968768S    0S 102891520S xMddCU-5h1X-ZZL4-GFfO-ea4L-PqW8-YCGLte

Rozmiar partycji powinien być większy o 8192 sektory w stosunku do wielkości kontenera LVM. W tym przypadku kontener ma 39968768 sektorów. Zatem rozmiar partycji wyniesie: 39968768+8192-1=39976959 sektorów. Nie należy brać pod uwagę wpisu w DevSize, on ciągle ma starą wartość.

# fdisk /dev/sdb

Command (m for help): d
Selected partition 1

Command (m for help): n
Partition type:
   p   primary (0 primary, 0 extended, 4 free)
   e   extended
Select (default p): 
Using default response p
Partition number (1-4, default 1): 
Using default value 1
First sector (2048-156299374, default 2048): 
Using default value 2048
Last sector, +sectors or +size{K,M,G} (2048-156299374, default 156299374): +39976959

Command (m for help): t
Selected partition 1
Hex code (type L to list codes): 8e
Changed system type of partition 1 to 8e (Linux LVM)

Command (m for help): p

Disk /dev/sdb: 80.0 GB, 80025280000 bytes
100 heads, 3 sectors/track, 520997 cylinders, total 156299375 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000c741d

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1            2048    39979007    19988480   8e  Linux LVM

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

Być może też czasem dostaniemy poniższy komunikat:

WARNING: Re-reading the partition table failed with error 16: Device or resource busy.
The kernel still uses the old table. The new table will be used at
the next reboot or after you run partprobe(8) or kpartx(8)

Może się on pojawić nawet przy odmontowanych voluminach. Jest to zasługą aktywnej grupy. Można ją, albo deaktywować na czas zmian tablicy partycji, albo zaktualizować wpisy przy pomocy partprobe -- nie ma potrzeby resetowania systemu by nowe wartości zaczęły obowiązywać.

Sprawdzamy, czy wszystko się montuje bez problemu:

# vgchange -a n grupa1
  0 logical volume(s) in volume group "grupa1" now active
# lsblk /dev/sdb
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sdb      8:16   0  74,5G  0 disk 
└─sdb1   8:17   0  19,1G  0 part 
# vgchange -a y grupa1
  3 logical volume(s) in volume group "grupa1" now active
# lsblk /dev/sdb
NAME                       MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sdb                          8:16   0  74,5G  0 disk 
└─sdb1                       8:17   0  19,1G  0 part 
  ├─grupa1-volumin1 (dm-1) 254:1    0     5G  0 lvm  
  ├─grupa1-volumin3 (dm-2) 254:2    0     2G  0 lvm  
  └─grupa1-volumin5 (dm-3) 254:3    0  12,1G  0 lvm  
# mount /dev/mapper/grupa1-volumin1 /media/1
# mount /dev/mapper/grupa1-volumin3 /media/3
# mount /dev/mapper/grupa1-volumin5 /media/5

Wychodzi na to, że wszystko gra.

6. Objawy przy złym przycięciu partycji

Jeśli zmniejszymy za bardzo partycję, np. w wyniku złych obliczeń i obetniemy jej trochę systemu plików, dostaniemy errora -- inny w zależności od tego jaki to będzie system plików.

W przypadku systemu plików ntfs:

# ntfsresize -i -f /dev/sdb1
ntfsresize v2013.1.13AR.1 (libntfs-3g)
Failed to read last sector (19531240): Invalid argument
HINTS: Either the volume is a RAID/LDM but it wasn't setup yet,
   or it was not setup correctly (e.g. by not using mdadm --build ...),
   or a wrong device is tried to be mounted,
   or the partition table is corrupt (partition is smaller than NTFS),
   or the NTFS boot sector is corrupt (NTFS size is not valid).
ERROR(22): Opening '/dev/sdb1' as NTFS failed: Invalid argument
The device '/dev/sdb1' doesn't have a valid NTFS.
Maybe you selected the wrong partition? Or the whole disk instead of a
partition (e.g. /dev/hda, not /dev/hda1)? This error might also occur
if the disk was incorrectly repartitioned (see the ntfsresize FAQ).

W przypadku systemu plików ext4:

# fsck.ext4 -fv /dev/sdb1
e2fsck 1.42.9 (28-Dec-2013)
The filesystem size (according to the superblock) is 1280000 blocks
The physical size of the device is 786432 blocks
Either the superblock or the partition table is likely to be corrupt!
Abort? yes

W przypadku systemu plików fat32:

# dosfsck -v /dev/sdb1
dosfsck 3.0.16 (01 Mar 2013)
dosfsck 3.0.16, 01 Mar 2013, FAT32, LFN
Checking we can access the last sector of the filesystem
Seek to 5242879488:Invalid argument

W przypadku gdybyśmy nieco przycięli partycję z kontenerem LVM w fdisku, dostaniemy taki komunikat:

# pvscan
  /dev/grupa1/volumin5: read failed after 0 of 4096 at 12947750912: Błąd wejścia/wyjścia
  /dev/grupa1/volumin5: read failed after 0 of 4096 at 12947808256: Błąd wejścia/wyjścia
  PV /dev/sdb1   VG grupa1   lvm2 [19,06 GiB / 0    free]
  Total: 1 [19,06 GiB] / in use: 1 [19,06 GiB] / in no VG: 0 [0   ]

Nie da rady oczywiście w takich przypadkach zamontować żadnej przyciętej partycji, a przy próbie zamontowania takiego zasobu zostanie wyrzucony poniższy komunikat:

mount: wrong fs type, bad option, bad superblock on /dev/sdb1,
       missing codepage or helper program, or other error
       In some cases useful info is found in syslog - try
       dmesg | tail  or so

Oczywiście bez obaw, trzeba po prostu znów odpalić fdiska i zrobić partycję nieco większą. Żadnych danych w ten sposób nie stracimy, gdyż operujemy jedynie na tablicy partycji, a ta ma w swojej strukturze parę pozycji, z których tylko 3 są brane pod uwagę, przynajmniej w linuxie. Są to sektor początkowy partycji, rozmiar w sektorach, oraz typ partycji. Możemy dowolnie się tymi parametrami bawić bez utraty danych, tylko lepiej pamiętać pozycję wyjściową.

7. Ryzyko utraty danych

Ryzyko utraty danych zawsze istnieje, zwłaszcza gdy się obchodzi z systemem plików bardzo nieumiejętnie ale wystarczy odrobina rozsądku i kalkulator aby to ryzyko całkowicie wyeliminować. Poniżej kilka wskazówek na temat tego jak robić backup wrażliwych danych.

7.1. Backup wpisów tablicy partycji ms-dos

Zanim się zaczniemy bawić z tablicą partycji, która jest zlokalizowana w MBR (przynajmniej jej część), najlepiej jest wykonać kopię zapasową tego sektora i zachować ją w bezpiecznym miejscu. Jeśli posiadamy partycję rozszerzoną, przydałoby się również zrobić kopię każdego EBR, a ich lokalizacja zależy od faktycznego rozkładu dysków logicznych, przykładowo:

Device Boot      Start         End      Blocks   Id  System
/dev/sdb1            2048    45641727    22819840   83  Linux
/dev/sdb2        45641728    80166911    17262592   83  Linux
/dev/sdb3        80166912   104224767    12028928   83  Linux
/dev/sdb4       104224768   156299263    26037248    5  Extended
/dev/sdb5       104226816   119328767     7550976   83  Linux
/dev/sdb6       119330816   128720895     4695040   83  Linux
/dev/sdb7       128722944   156299263    13788160   83  Linux

Są tutaj 3 EBR, a lokalizacja każdego z nich znajduje się zawsze w pierwszym sektorze logicznego dysku. W przypadku pierwszego dysku logicznego jest to parametr "start" partycji rozszerzonej widziany powyżej ale w przypadku pozostałych dysków sprawa ma się nieco inaczej -- jest to sektor zaraz za końcem poprzedniej partycji. Między tymi dyskami logicznymi jest trochę wolnego miejsca, w przypadku równania do 1MiB jest tam 2048 sektorów, w tym 1 sektor na EBR. Jeśli byśmy wykonali kopię tej pozycji co jest w parametrze "start", skopiujemy pierwszy sektor systemu plików, a nie EBR, i przywrócenie tego sektora nic nam nie da.

Kopię MBR za to możemy wykonać bardzo łatwo, bo MBR zawsze znajduje się na tej samej pozycji -- pierwszy sektor dysku:

# dd if=/dev/sdb of=./mbr bs=512 count=1

W razie problemów by przywrócić podstawową tablicę partycji możemy wgrać 64 bajty do MBR z uprzednio zrobionej kopi zapasowej:

# dd if=./mbr of=/dev/sdb bs=1 count=64 skip=446 seek=446

Kopie EBR robimy w ten sam sposób podając tylko odpowiednie adresy sektorów.

Zamiast jednak się bawić w robienie kopi MBR i EBR, możemy zrobić kopię wpisów w tablicy partycji:

# sfdisk -d /dev/sdb > sdb_table
# sfdisk /dev/sda < sdb_table

Tak wygląda przykładowa tablica partycji:

# partition table of /dev/sdb
unit: sectors

/dev/sdb1 : start=     2048, size= 45639680, Id=83
/dev/sdb2 : start= 45641728, size= 34525184, Id=83
/dev/sdb3 : start= 80166912, size= 24057856, Id=83
/dev/sdb4 : start=104224768, size= 52074496, Id= 5
/dev/sdb5 : start=104226816, size= 15101952, Id=83
/dev/sdb6 : start=119330816, size=  9390080, Id=83
/dev/sdb7 : start=128722944, size= 27576320, Id=83

Jak coś nawali, zawsze możemy ręcznie wpisywać wartości z tej tabelki do fdiska.

7.2. Backup wpisów tablicy partycji gpt

Jeśli ktoś używa tablicy partycji gpt to nie może kierować się powyższymi wskazówkami co do backupu struktury tablicy partycji, bo ta w przypadku gpt jest inna. Bez problemu możemy zrobić jej backup i zachować go jako plik przy pomocy gdiska lub sgdiska:

root:~# gdisk /dev/sdb
GPT fdisk (gdisk) version 0.8.8

Partition table scan:
  MBR: protective
  BSD: not present
  APM: not present
  GPT: present

Found valid GPT with protective MBR; using GPT.

Command (? for help): b
Enter backup filename to save: backup_gpt_file
The operation has completed successfully.

Problem ze stworzonym w ten sposób plikiem jest taki, że nie jest on w postaci czytelnej dla człowieka i trzeba przywracać całą kopię partycji, zamiast jedynie pojedynczych wpisów.

7.3. Backup nagłówków zaszyfrowanych partycji

Jeśli chodzi o zaszyfrowane kontenery, to trzeba pamiętać, że by się dostać do tego co jest w środku, musimy podać odpowiedni klucz/hasło, a te są przechowywane w nagłówku partycji. Taki nagłówek to zwykle 2MiB danych. Możemy kopię takiego nagłówka zrobić ręcznie przy pomocy dd albo też posłużyć się w tym celu LUKSowymi narzędziami.

Jeśli zdecydujemy się na ręczny backup nagłówka LUKS, musimy pierw uzyskać informacje na temat tego ile taki nagłówek faktycznie zajmuje:

# cryptsetup status sdb1
/dev/mapper/sdb1 is active.
  type:    LUKS1
  cipher:  aes-xts-plain64
  keysize: 512 bits
  device:  /dev/sdb1
  offset:  4096 sectors
  size:    78229504 sectors
  mode:    read/write

W tym przypadku jest to 4096 sektorów, z których każdy ma 512 bajtów. Zatem wklepujemy parametry do dd:

dd if=/dev/sdb1 of=./backup_header_sdb1 bs=512 count=4096

Ręczne przywracanie kopi nagłówka LUKS:

dd if=./backup_header_sdb1 of=/dev/sdb1 bs=512 count=4096

Tworzenie kopi zapasowej nagłówka LUKS przy pomocy luksHeaderBackup :

# cryptsetup luksHeaderBackup /dev/sdb1  --header-backup-file ./backup_header_sdb1

Przywracanie kopi zapasowej nagłówka LUKS przy pomocy luksHeaderRestore :

# cryptsetup luksHeaderRestore /dev/sdb1 --header-backup-file ./backup_header_sdb1

7.4. Backup struktury LVM

LVM posiada narzędzia umożliwiające backup struktury kontenera i zapisanie jej w czytelnej formie do pliku. By zrobić kopię wpisujemy do terminala poniższą komendę:

# vgcfgbackup 
  Volume group "grupa1" successfully backed up.

Zostanie w ten sposób utworzony plik /etc/lvm/backup/grupa1 . Przykładowy plik ze strukturą LVM:

# Generated by LVM2 version 2.02.98(2) (2012-10-15): Wed Jan 15 14:20:20 2014

contents = "Text Format Volume Group"
version = 1

description = "Created *after* executing 'vgcfgbackup'"

creation_host = "livemor"   # Linux livemor 3.11-2-amd64 #1 SMP Debian 3.11.10-1 (2013-12-04) x86_64
creation_time = 1389792020  # Wed Jan 15 14:20:20 2014

grupa1 {
    id = "Yas25y-A36P-mWfM-QNJ1-7UWf-48Ua-t1Wd4M"
    seqno = 24
    format = "lvm2" # informational
    status = ["RESIZEABLE", "READ", "WRITE"]
    flags = []
    extent_size = 8192      # 4 Megabytes
    max_lv = 0
    max_pv = 0
    metadata_copies = 0

    physical_volumes {

        pv0 {
            id = "xMddCU-5h1X-ZZL4-GFfO-ea4L-PqW8-YCGLte"
            device = "/dev/sdb1"    # Hint only

            status = ["ALLOCATABLE"]
            flags = []
            dev_size = 39968768 # 19,0586 Gigabytes
            pe_start = 2048
            pe_count = 4879 # 19,0586 Gigabytes
        }
    }

    logical_volumes {

        volumin1 {
            id = "YaU6fB-v6UC-4XBJ-POme-CJ1l-rlqk-0FA5cU"
            status = ["READ", "WRITE", "VISIBLE"]
            flags = []
            creation_host = "livemor"
            creation_time = 1389775604  # 2014-01-15 09:46:44 +0100
            allocation_policy = "contiguous"
            segment_count = 1

            segment1 {
                start_extent = 0
                extent_count = 1280 # 5 Gigabytes

                type = "striped"
                stripe_count = 1    # linear

                stripes = [
                    "pv0", 0
                ]
            }
        }

        volumin3 {
            id = "XOe2Tx-ojib-c6Xi-GCLk-5RPK-xjEO-J9gRxk"
            status = ["READ", "WRITE", "VISIBLE"]
            flags = []
            creation_host = "livemor"
            creation_time = 1389775623  # 2014-01-15 09:47:03 +0100
            allocation_policy = "contiguous"
            segment_count = 1

            segment1 {
                start_extent = 0
                extent_count = 512  # 2 Gigabytes

                type = "striped"
                stripe_count = 1    # linear

                stripes = [
                    "pv0", 1280
                ]
            }
        }

        volumin5 {
            id = "AkxiRD-J1HS-jRhw-Adfv-Qsvf-aSKD-3dqJ3J"
            status = ["READ", "WRITE", "VISIBLE"]
            flags = []
            creation_host = "livemor"
            creation_time = 1389775657  # 2014-01-15 09:47:37 +0100
            allocation_policy = "contiguous"
            segment_count = 1

            segment1 {
                start_extent = 0
                extent_count = 3087 # 12,0586 Gigabytes

                type = "striped"
                stripe_count = 1    # linear

                stripes = [
                    "pv0", 1792
                ]
            }
        }
    }
}

8. Uszkadzanie struktury dysku

Może i zmiana rozmiaru LVM, LUKS i zwykłych partycji przebiegła bez najmniejszych problemów ale w życiu czasem różnie bywa i niekiedy struktura danych zawartych na dysku może zostać rozbita. Pomyślmy sobie co się stanie jak badsector uderzy w MBR w miejsce gdzie siedzą wpisy tablicy partycji, albo co się stanie gdy trafi na nagłówki zaszyfrowanych partycji. Wyżej został opisany co prawda sposób backupu danych i wgrywania ich w przypadku problemów ale to trochę takie bezpłciowe. Poniżej sprawdzimy czy faktyczne uszkodzenie struktury dysku spowoduje utratę rzeczywistych danych.

8.1. Uszkodzenie zwykłej partycji

W przypadku zwyczajnych partycji przeprowadzaliśmy już szereg zabiegów ich psucia przez zmianę wpisów w tablicy partycji (usuwanie/tworzenie w fdisku). To co może jeszcze ulec awarii to MBR. W MBR poza kodem bootloadera mamy 4*16=64 bajtów na tablicę partycji. Dobrze jest zrobić kopię całego MBR, a potem ewentualnie przywracać jego części. MBR może przechować maksymalnie 4 wpisy odpowiadające 4 partycjom. Nie przechowuje jednak wpisów, które są na partycji rozszerzonej.

Partycję rozszerzoną można traktować jako dysk zagnieżdżony w innym dysku. Posiada swój MBR z tym, że nieco inny. EBR ma taką samą strukturę co MBR ale jest pozbawiony kodu bootloadera i wykorzystuje dwa wpisy na partycje z czterech dostępnych. Jeden z nich opisuje partycję (start partycji, bez offsetu, oraz długość partycji), a drugi linkuje do kolejnego EBR (start w miejscu nowego EBR, rozmiar całej partycji począwszy od EBR). W przypadku ostatniej partycji w łańcuchu EBR, ten drugi wpis ma 0 bajtów.

Co się zatem mogłoby stać? Mógłby zostać uszkodzony wpis podstawowej partycji w MBR, w takim przypadku stracilibyśmy jedną partycję. Mógłby zostać też trafiony wpis rozszerzony, w wyniku takiego zdarzenia stracilibyśmy wszystkie partycje w łańcuchu EBR. Jeśli mamy 4 dyski logiczne na rozszerzonej partycji i uszkodzeniu uległby drugi EBR, stracilibyśmy nie tylko 2 dysk logiczny ale również 3 i 4.

Tak wygląda przykładowy dysk, ma 3 partycje podstawowe i 3 rozszerzone:

root:~# fdisk /dev/sdb

Command (m for help): p

Disk /dev/sdb: 80.0 GB, 80025280000 bytes
255 heads, 63 sectors/track, 9729 cylinders, total 156299375 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000c741d

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1            2048    45641727    22819840   83  Linux
/dev/sdb2        45641728    80166911    17262592   83  Linux
/dev/sdb3        80166912   104224767    12028928   83  Linux
/dev/sdb4       104224768   156299263    26037248    5  Extended
/dev/sdb5       104226816   119328767     7550976   83  Linux
/dev/sdb6       119330816   128720895     4695040   83  Linux
/dev/sdb7       128722944   156299263    13788160   83  Linux

Skopiujmy teraz całą tablicę partycji:

root:~# sfdisk -d /dev/sdb > ./sdb_table
Warning: extended partition does not start at a cylinder boundary.
DOS and Linux will interpret the contents differently.
# cat sdb_table
# partition table of /dev/sdb
unit: sectors

/dev/sdb1 : start=     2048, size= 45639680, Id=83
/dev/sdb2 : start= 45641728, size= 34525184, Id=83
/dev/sdb3 : start= 80166912, size= 24057856, Id=83
/dev/sdb4 : start=104224768, size= 52074496, Id= 5
/dev/sdb5 : start=104226816, size= 15101952, Id=83
/dev/sdb6 : start=119330816, size=  9390080, Id=83
/dev/sdb7 : start=128722944, size= 27576320, Id=83

W przypadku gdy zniknie nam jeden wpis, możemy odtworzyć go ręcznie, przywracając tylko ten, którego brakuje. Czas nabroić trochę. Skoro tablica partycji to 64 bajty po 446 bajtach, uszkodzimy drugą partycję przez zapisanie 5 bajtów z tych 16 opisujących tą partycję. Zatem 446+16=462 , czyli na 462 zaczyna się drugi wpis, jako, że numerowanie zaczyna się od 0, a nie od 1:

# dd if=/dev/zero of=/dev/sdb bs=1 seek=462 count=5
5+0 records in
5+0 records out
5 bytes (5 B) copied, 0.00636016 s, 0.8 kB/s
# partprobe

I patrzymy cośmy uczynili:

# fdisk /dev/sdb

Command (m for help): p

Disk /dev/sdb: 80.0 GB, 80025280000 bytes
255 heads, 63 sectors/track, 9729 cylinders, total 156299375 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000c741d

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1            2048    45641727    22819840   83  Linux
/dev/sdb2        45641728    80166911    17262592    0  Empty
/dev/sdb3        80166912   104224767    12028928   83  Linux
/dev/sdb4       104224768   156299263    26037248    5  Extended
/dev/sdb5       104226816   119328767     7550976   83  Linux
/dev/sdb6       119330816   128720895     4695040   83  Linux
/dev/sdb7       128722944   156299263    13788160   83  Linux

No ładnie druga partycja zniszczona -- oznaczona jako "empty", nie jest to co prawda "free space" ale dane są pozornie utracone. Wpis partycji ma szereg bajtów opisujących jej strukturę i w tym przypadku nadpisaliśmy tylko typ partycji ale w realiach może się zdarzyć, że nieczytelne będą inne bajty opisujące np. początek partycji. Jak zatem naprawić szkody, które spowodowaliśmy? W tym przypadku wystarczy na nowo ustawić typ partycji:

# fdisk /dev/sdb

Command (m for help): t
Partition number (1-7): 2
Hex code (type L to list codes): 83
Changed system type of partition 2 to 83 (Linux)

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

# mount /dev/sdb2 /mnt
# cat /mnt/test_morfika
Nic się nie dzieje, wszystko gra.

A w innych przypadkach? Można oczywiście usunąć cały wpis w tablicy partycji i stworzyć go na nowo.

Command (m for help): d
Partition number (1-7): 2
Warning: partition 2 has empty type
Command (m for help): n
Partition type:
   p   primary (2 primary, 1 extended, 1 free)
   l   logical (numbered from 5)
Select (default p): p
Selected partition 2
First sector (45641728-156299374, default 45641728):
Using default value 45641728
Last sector, +sectors or +size{K,M,G} (45641728-80166911, default 80166911):
Using default value 80166911

Command (m for help): t
Partition number (1-7): 2
Hex code (type L to list codes): 83
Command (m for help): p

Disk /dev/sdb: 80.0 GB, 80025280000 bytes
255 heads, 63 sectors/track, 9729 cylinders, total 156299375 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000c741d

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1            2048    45641727    22819840   83  Linux
/dev/sdb2        45641728    80166911    17262592   83  Linux
/dev/sdb3        80166912   104224767    12028928   83  Linux
/dev/sdb4       104224768   156299263    26037248    5  Extended
/dev/sdb5       104226816   119328767     7550976   83  Linux
/dev/sdb6       119330816   128720895     4695040   83  Linux
/dev/sdb7       128722944   156299263    13788160   83  Linux

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

Scenariusz drugi, czyli uszkodzenie partycji rozszerzonej.

# dd if=/dev/zero of=/dev/sdb bs=1 seek=494 count=5
5+0 records in
5+0 records out
5 bytes (5 B) copied, 0.00958093 s, 0.5 kB/s
# partprobe

W tym przypadku partycja rozszerzona będzie pokazywana jako partycja podstawowa i nie da rady zmienić jej typu na 5 (partycja rozszerzona). Spróbujemy przywrócić cały wpis. Jeśli nie wiemy jaki powinien być rozmiar partycji rozszerzonej, możemy to wyliczyć z backupu stworzonego przez sfdisk:

/dev/sdb4 : start=104224768, size= 52074496, Id= 5

Początkowy sektor mamy -- 104224768, a rozmiar to 52074496-1=52074495 sektorów.

root:~# fdisk /dev/sdb
Command (m for help): p

Disk /dev/sdb: 80.0 GB, 80025280000 bytes
255 heads, 63 sectors/track, 9729 cylinders, total 156299375 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000c741d

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1            2048    45641727    22819840   83  Linux
/dev/sdb2        45641728    80166911    17262592   83  Linux
/dev/sdb3        80166912   104224767    12028928   83  Linux
/dev/sdb4       104224768   156299263    26037248    0  Empty

Command (m for help): d
Partition number (1-5): 4

Command (m for help): n
Partition type:
   p   primary (3 primary, 0 extended, 1 free)
   e   extended
Select (default e): e
Selected partition 4
First sector (104224768-156299374, default 104224768): 104224768
Last sector, +sectors or +size{K,M,G} (104224768-156299374, default 156299374): +52074495

Command (m for help): p

Disk /dev/sdb: 80.0 GB, 80025280000 bytes
255 heads, 63 sectors/track, 9729 cylinders, total 156299375 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000c741d

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1            2048    45641727    22819840   83  Linux
/dev/sdb2        45641728    80166911    17262592   83  Linux
/dev/sdb3        80166912   104224767    12028928   83  Linux
/dev/sdb4       104224768   156299263    26037248    5  Extended

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

Jak widać stworzenie nowej partycji rozszerzonej nie przywróciło dysków logicznych. Jak je przywrócić? Trzeba ręcznie przepisać wpisy z backupu sfdiska:

Command (m for help): p

Disk /dev/sdb: 80.0 GB, 80025280000 bytes
255 heads, 63 sectors/track, 9729 cylinders, total 156299375 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000c741d

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1            2048    45641727    22819840   83  Linux
/dev/sdb2        45641728    80166911    17262592   83  Linux
/dev/sdb3        80166912   104224767    12028928   83  Linux
/dev/sdb4       104224768   156299263    26037248    5  Extended

Command (m for help): n
All primary partitions are in use
Adding logical partition 5
First sector (104226816-156299263, default 104226816): 104226816
Last sector, +sectors or +size{K,M,G} (104226816-156299263, default 156299263): +15101951

Command (m for help): n
All primary partitions are in use
Adding logical partition 6
First sector (119330816-156299263, default 119330816): 119330816
Last sector, +sectors or +size{K,M,G} (119330816-156299263, default 156299263): +9390079

Command (m for help): n
All primary partitions are in use
Adding logical partition 7
First sector (128722944-156299263, default 128722944): 128722944
Last sector, +sectors or +size{K,M,G} (128722944-156299263, default 156299263): +27576319

Command (m for help): p

Disk /dev/sdb: 80.0 GB, 80025280000 bytes
255 heads, 63 sectors/track, 9729 cylinders, total 156299375 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000c741d

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1            2048    45641727    22819840   83  Linux
/dev/sdb2        45641728    80166911    17262592   83  Linux
/dev/sdb3        80166912   104224767    12028928   83  Linux
/dev/sdb4       104224768   156299263    26037248    5  Extended
/dev/sdb5       104226816   119328767     7550976   83  Linux
/dev/sdb6       119330816   128720895     4695040   83  Linux
/dev/sdb7       128722944   156299263    13788160   83  Linux

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

Jeszcze tylko sprawdźmy czy damy radę odczytać plik na 6 partycji:

# mount /dev/sdb6 /mnt
# cat /mnt/test_morfika
Nic się nie dzieje, wszystko gra.

Można również wgrać pierwszy EBR, jego pozycja znajduje się zawsze na początku partycji rozszerzonej, a przy tworzeniu nowej rozszerzonej partycji ten sektor jest nadpisywany -- to dlatego nie ma dysków logicznych. Jego kopię w tym przypadku można by sporządzić przez:

# dd if=/dev/sdb bs=512 skip=104224768 count=1 of=./ebr

I jeśli stracimy rozszerzony wpis w MBR, tworzymy go na nowo w fdisku:

root:~# fdisk /dev/sdb

Command (m for help): d
Partition number (1-7): 4
Command (m for help): n
Partition type:
   p   primary (3 primary, 0 extended, 1 free)
   e   extended
Select (default e): e
Selected partition 4
First sector (104224768-156299374, default 104224768): 104224768
Last sector, +sectors or +size{K,M,G} (104224768-156299374, default 156299374): +52074495

Command (m for help): p

Disk /dev/sdb: 80.0 GB, 80025280000 bytes
255 heads, 63 sectors/track, 9729 cylinders, total 156299375 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000c741d

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1            2048    45641727    22819840   83  Linux
/dev/sdb2        45641728    80166911    17262592   83  Linux
/dev/sdb3        80166912   104224767    12028928   83  Linux
/dev/sdb4       104224768   156299263    26037248    5  Extended

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.

I wgrywamy EBR:

# dd if=./ebr bs=512 seek=104224768 count=1 of=/dev/sdb
1+0 records in
1+0 records out
512 bytes (512 B) copied, 0.000119726 s, 4.3 MB/s
# partprobe

I co widzimy w fdisku?

root:~# fdisk /dev/sdb

Command (m for help): p

Disk /dev/sdb: 80.0 GB, 80025280000 bytes
255 heads, 63 sectors/track, 9729 cylinders, total 156299375 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000c741d

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1            2048    45641727    22819840   83  Linux
/dev/sdb2        45641728    80166911    17262592   83  Linux
/dev/sdb3        80166912   104224767    12028928   83  Linux
/dev/sdb4       104224768   156299263    26037248    5  Extended
/dev/sdb5       104226816   119328767     7550976   83  Linux
/dev/sdb6       119330816   128720895     4695040   83  Linux
/dev/sdb7       128722944   156299263    13788160   83  Linux

Logiczne dyski wróciły na swoje miejsce. Sprawdźmy jeszcze czy da radę odczytać plik testowy:

# mount /dev/sdb6 /mnt
# cat /mnt/test_morfika
Nic się nie dzieje, wszystko gra.

Ostatnie uszkodzenie będzie polegać na nadpisaniu EBR poprzedzającego partycję sdb6. Tylko tutaj taka uwaga, nie możemy nadpisywać sektora 119330816 (start sda6), bo tutaj jest uwzględniony offset. EBR tej partycji znajduje się zaraz za końcem partycji poprzedzającej czyli: 119328767+1=119328768 i to ten sektor należy uszkodzić.

# dd if=/dev/zero bs=512 seek=119328768 of=/dev/sdb count=1
1+0 records in
1+0 records out
512 bytes (512 B) copied, 0.00091464 s, 560 kB/s
# partprobe

I sprawdźmy:

# fdisk /dev/sdb
omitting empty partition (6)

Command (m for help): p

Disk /dev/sdb: 80.0 GB, 80025280000 bytes
255 heads, 63 sectors/track, 9729 cylinders, total 156299375 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000c741d

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1            2048    45641727    22819840   83  Linux
/dev/sdb2        45641728    80166911    17262592   83  Linux
/dev/sdb3        80166912   104224767    12028928   83  Linux
/dev/sdb4       104224768   156299263    26037248    5  Extended
/dev/sdb5       104226816   119328767     7550976   83  Linux

Tak jak można było się spodziewać, zniknęły dwie partycje -- ta, której EBR nadpisaliśmy oraz następne w łańcuchu EBR, a że była tylko jedna to w sumie zniknęły dwie. Oczywiście w tym przypadku sprawa wygląda podobnie, trzeba przywrócić EBR. A co jeśli nie mamy EBR? Można by skorzystać z kopi sfdiska. W sumie to sfdisk rozwiązuje wszystkie problemy. Zatem wchodzimy do fdiska i przywracamy dwa zagubione wpisy:

root:~# fdisk /dev/sdb
omitting empty partition (6)

Command (m for help): n
All primary partitions are in use
Adding logical partition 6
First sector (119330816-156299263, default 119330816): 119330816
Last sector, +sectors or +size{K,M,G} (119330816-156299263, default 156299263): +9390079

Command (m for help): n
All primary partitions are in use
Adding logical partition 7
First sector (128722944-156299263, default 128722944): 128722944
Last sector, +sectors or +size{K,M,G} (128722944-156299263, default 156299263): +27576319

Command (m for help): p

Disk /dev/sdb: 80.0 GB, 80025280000 bytes
255 heads, 63 sectors/track, 9729 cylinders, total 156299375 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000c741d

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1            2048    45641727    22819840   83  Linux
/dev/sdb2        45641728    80166911    17262592   83  Linux
/dev/sdb3        80166912   104224767    12028928   83  Linux
/dev/sdb4       104224768   156299263    26037248    5  Extended
/dev/sdb5       104226816   119328767     7550976   83  Linux
/dev/sdb6       119330816   128720895     4695040   83  Linux
/dev/sdb7       128722944   156299263    13788160   83  Linux

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

Montujemy i sprawdzamy czy da radę odczytać plik testowy:

root:~# mount /dev/sdb6 /mnt
root:~# cat /mnt/test_morfika
Nic się nie dzieje, wszystko gra.

Także kopia pełnej tablicy partycji uchroni nas przed utratą danych wynikającą z jej uszkodzenia.

8.2. Uszkodzenie LVM

Przetestujmy zatem czy posiadanie zapasowej kopi pliku backupu kontenera LVM uchroni nas przed czymś. Popsujmy celowo cały kontener LVM:

# vgremove grupa1 
Do you really want to remove volume group "grupa1" containing 3 logical volumes? [y/n]: y
Do you really want to remove active logical volume volumin1? [y/n]: y
  Logical volume "volumin1" successfully removed
Do you really want to remove active logical volume volumin3? [y/n]: y
  Logical volume "volumin3" successfully removed
Do you really want to remove active logical volume volumin5? [y/n]: y 
  Logical volume "volumin5" successfully removed
  Volume group "grupa1" successfully removed

# pvremove /dev/sdb1 
  Labels on physical volume "/dev/sdb1" successfully wiped

# lsblk /dev/sdb
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sdb      8:16   0  74,5G  0 disk 
└─sdb1   8:17   0  19,1G  0 part

No to ładnie namieszaliśmy. Spróbujmy to teraz przywrócić:

# vgcfgrestore -v grupa1 -f /home/user/grupa1
  Couldn't find device with uuid xMddCU-5h1X-ZZL4-GFfO-ea4L-PqW8-YCGLte.
  Cannot restore Volume Group grupa1 with 1 PVs marked as missing.
  Restore failed.

# pvcreate --uuid xMddCU-5h1X-ZZL4-GFfO-ea4L-PqW8-YCGLte --restorefile /home/user/grupa1 /dev/sdb1
  Couldn't find device with uuid xMddCU-5h1X-ZZL4-GFfO-ea4L-PqW8-YCGLte.
  Physical volume "/dev/sdb1" successfully created

#  vgcfgrestore -vv -f /home/user/grupa1 grupa1
      Setting activation/monitoring to 0
      Setting global/locking_type to 1
      Setting global/wait_for_locks to 1
      File-based locking selected.
      Setting global/locking_dir to /run/lock/lvm
      Setting global/prioritise_write_locks to 1
      Locking /run/lock/lvm/V_grupa1 WB
      Locking /run/lock/lvm/P_orphans WB
      /dev/sdb: size is 156299375 sectors
      /dev/sdb1: size is 39976960 sectors
      /dev/sdb1: size is 39976960 sectors
      /dev/sdb1: lvm2 label detected at sector 1
  Restored volume group grupa1
      Unlocking /run/lock/lvm/P_orphans
      Unlocking /run/lock/lvm/V_grupa1

Sprawdzamy czy coś to dało:

# pvs -v --segments
    Scanning for physical volume names
  PV         VG     Fmt  Attr PSize  PFree Start SSize LV       Start Type   PE Ranges          
  /dev/sdb1  grupa1 lvm2 a--  19,06g    0      0  1280 volumin1     0 linear /dev/sdb1:0-1279   
  /dev/sdb1  grupa1 lvm2 a--  19,06g    0   1280   512 volumin3     0 linear /dev/sdb1:1280-1791
  /dev/sdb1  grupa1 lvm2 a--  19,06g    0   1792  3087 volumin5     0 linear /dev/sdb1:1792-4878

# lvs -v --segments
    Finding all logical volumes
  LV       VG     Attr      Start SSize  #Str Type   Stripe Chunk
  volumin1 grupa1 -wc------    0   5,00g    1 linear     0     0 
  volumin3 grupa1 -wc------    0   2,00g    1 linear     0     0 
  volumin5 grupa1 -wc------    0  12,06g    1 linear     0     0

Podmontujmy jeszcze voluminy:

# vgchange -a y grupa1 
  3 logical volume(s) in volume group "grupa1" now active
# mount /dev/mapper/grupa1-volumin1 /media/1
# mount /dev/mapper/grupa1-volumin3 /media/3
# mount /dev/mapper/grupa1-volumin5 /media/5

# lsblk /dev/sdb
NAME                       MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sdb                          8:16   0  74,5G  0 disk 
└─sdb1                       8:17   0  19,1G  0 part 
  ├─grupa1-volumin1 (dm-1) 254:1    0     5G  0 lvm  /media/1
  ├─grupa1-volumin3 (dm-2) 254:2    0     2G  0 lvm  /media/3
  └─grupa1-volumin5 (dm-3) 254:3    0  12,1G  0 lvm  /media/5

Wszystko działa jak trzeba, także, jeśli kontener się spieprzy, a mamy backup metadanych w postaci pliku, możemy być spokojni. Co ciekawe, wszelkie zmiany struktury kontenera LVM są odnotowywane i zapisywane w /etc/lvm/archive/ . Są tam po prostu wszystkie przeszłe konfiguracje kontenerów LVM. Jeśli manipulujemy rozmiarem kontenera LVM najlepiej backupować folder /etc/lvm/ i trzymać go na osobnym dysku.

8.3. Uszkodzenie zaszyfrowanego kontenera LUKS

W tym przypadku mogą ulec uszkodzeniu nagłówki partycji uniemożliwiając nam dostęp do zaszyfrowanych danych. Robimy zatem backup nagłówków:

# cryptsetup luksHeaderBackup /dev/sdb1 --header-backup-file ./backup_header_sdb1
# ls -al backup_header_sdb1
-r-------- 1 root root 2.0M Jan 16 16:51 backup_header_sdb1

Nadpiszmy zatem nagłówki przy pomocy 20 sektorów 512 bajtowych:

# dd if=/dev/zero of=/dev/sdb1 bs=512 count=20 seek=100
20+0 records in
20+0 records out
10240 bytes (10 kB) copied, 0.00268263 s, 3.8 MB/s

Spróbujmy otworzyć kontener:

 # cryptsetup luksOpen /dev/sdb1 sdb1
Enter passphrase for /dev/sdb1:
No key available with this passphrase.
Enter passphrase for /dev/sdb1:
No key available with this passphrase.
Enter passphrase for /dev/sdb1:
No key available with this passphrase.

No to chyba najgorszy nasz sen się spełnił, albo nam żona zmieniła hasło do zaszyfrowanego kontenera. :] Jeśli nie otworzymy kontenera, nie da rady dostać się do danych, a to źle. Jeśli sprawdzimy nagłówek, zobaczymy, że jakieś hasło tam jest przechowywane:

# cryptsetup luksDump /dev/sdb1
LUKS header information for /dev/sdb1

Version:        1
Cipher name:    aes
Cipher mode:    xts-plain64
Hash spec:      sha512
Payload offset: 4096
MK bits:        512
MK digest:      1e 6b c3 90 8f 4d ae 35 0c 08 38 16 5f 81 97 e2 a5 34 d0 ec
MK salt:        da 47 d9 88 8f ef 97 79 99 96 cb 9d ca cd 4d 56
                73 a1 5f 76 5b 44 a8 76 3d a4 a9 93 35 e1 7c fd
MK iterations:  46875
UUID:           88ddc490-8904-4fad-b072-39686730977b

Key Slot 0: ENABLED
        Iterations:             185180
        Salt:                   01 88 98 93 3d 96 8c 31 5e ea d2 f4 d9 d8 52 9b
                                66 a2 40 19 72 cb 46 c7 7f a4 1c 97 c2 d8 40 45
        Key material offset:    8
        AF stripes:             4000
Key Slot 1: DISABLED
Key Slot 2: DISABLED
Key Slot 3: DISABLED
Key Slot 4: DISABLED
Key Slot 5: DISABLED
Key Slot 6: DISABLED
Key Slot 7: DISABLED

Ale jakież to hasło? Tego raczej nie zgadniemy. Przywróćmy zatem kopię nagłówków:

# cryptsetup luksHeaderRestore /dev/sdb1 --header-backup-file ./backup_header_sdb1

WARNING!
========
Device /dev/sdb1 already contains LUKS header. Replacing header will destroy existing keyslots.

Are you sure? (Type uppercase yes): YES

No to jeszcze sprawdźmy czy pliki w kontenerze są i da radę je odczytać:

# cryptsetup luksOpen /dev/sdb1 sdb1
Enter passphrase for /dev/sdb1:
# mount /dev/mapper/sdb1 /mnt
# cat /mnt/test_morfika
Nic się nie dzieje, wszystko gra.

Także posiadanie kopi zapasowej nagłówków zaszyfrowanych partycji jest iście obowiązkowe.

Jak widać w pokazanym przeze mnie doświadczeniu nie ma się co bać przy ustawianiu i zmienianiu konfiguracji, oczywiście gdy ma się porobione backupy i kalkulator pod ręką.

Cały tekst powstał w oparciu o manuale dostępne na stronie debiana -- każde polecenie użyte w tym artykule posiada mniej lub bardziej rozbudowany manual, do którego warto zajrzeć.

OSnews Wykop Blip Flaker Kciuk Śledzik Facebook Identi.ca Twitter del.icio.us Google Bookmarks