Naprawa badblocków na partycji z systemem plików JFS

Dyski twarde mają to do siebie, że lubią ulegać awarii. Z tego powodu zalecane jest monitorowanie dysku za pomocą S.M.A.R.T. i okresowe uruchamianie testów short / long.

W wypadku, gdy dysk nie przejdzie testu powstaje pytanie czy nadaje się on już do wymiany? W sieci można znaleźć wiele poradników dotyczących tzw. badblocków. Punktem wyjściowym powinien być poradnik na stronie narzędzia smartmontools.

Jeżeli problem wystąpi w przestrzeni dysku zajmowanej przez partycje typu ext2, ext3, ext4 to nie powinno być problemu, gdyż doskonała większość poradników odnosi się właśnie do takiego przypadku.
Co jednak w przypadku partycji JFS? Jako, że spotkałem się właśnie z takim problemem postaram sie opisać procedurę próby naprawienia badbloków na partycji z systemem plików JFS.

W pierwszej kolejności powinniśmy sprawdzić stan podejrzanego dysku z użyciem smartctl. W moim wypadku problematyczny był dysk sdb.

$ sudo smartctl -a /dev/sdb

<-- output omitted -->

SMART Attributes Data Structure revision number: 16
Vendor Specific SMART Attributes with Thresholds:
ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
  1 Raw_Read_Error_Rate     0x000b   100   100   016    Pre-fail  Always       -       0
  2 Throughput_Performance  0x0005   135   135   054    Pre-fail  Offline      -       96
  3 Spin_Up_Time            0x0007   117   117   024    Pre-fail  Always       -       198
  4 Start_Stop_Count        0x0012   100   100   000    Old_age   Always       -       1165
  5 Reallocated_Sector_Ct   0x0033   100   100   005    Pre-fail  Always       -       1
  7 Seek_Error_Rate         0x000b   100   100   067    Pre-fail  Always       -       0
  8 Seek_Time_Performance   0x0005   140   140   020    Pre-fail  Offline      -       30
  9 Power_On_Hours          0x0012   100   100   000    Old_age   Always       -       5781
10 Spin_Retry_Count        0x0013   100   100   060    Pre-fail  Always       -       0
12 Power_Cycle_Count       0x0032   100   100   000    Old_age   Always       -       1164
192 Power-Off_Retract_Count 0x0032   100   100   000    Old_age   Always       -       1165
193 Load_Cycle_Count        0x0012   100   100   000    Old_age   Always       -       1165
194 Temperature_Celsius     0x0002   200   200   000    Old_age   Always       -       30
196 Reallocated_Event_Count 0x0032   100   100   000    Old_age   Always       -       1
197 Current_Pending_Sector  0x0022   100   100   000    Old_age   Always       -       6
198 Offline_Uncorrectable   0x0008   100   100   000    Old_age   Offline      -       0
199 UDMA_CRC_Error_Count    0x000a   200   200   000    Old_age   Always       -       0

SMART Error Log Version: 0
No Errors Logged

SMART Self-test log structure revision number 1
Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
# 1  Extended offline    Completed: read failure       90%      5748         30465321
# 2  Short offline       Completed without error       00%      1259         -
# 3  Short offline       Completed without error       00%        59         -

<-- output omitted -->

Jak widać dysk ma 6 sektorów oczekujących na relokacje. Ponadto ostatni test extended (long) nie powiódł się. smartctl podał miejsce, na którym napotkał błąd. To będzie nasz punkt zaczepny.

Następnym krokiem jest określenie na jakiej partycji znajduje się kłopotliwy sektor.

$ sudo fdisk -lu /dev/sdb

Dysk /dev/sdb: 465,8 GiB, bajtów: 500107862016, sektorów: 976773168
Jednostki: sektorów, czyli 1 * 512 = 512 bajtów
Rozmiar sektora (logiczny/fizyczny) w bajtach: 512 / 512
Rozmiar we/wy (minimalny/optymalny) w bajtach: 512 / 512
Typ etykiety dysku: dos
Identyfikator dysku: 0x0008642f

Device     Boot     Start       End   Sectors   Size Id Type
/dev/sdb1  *         2048   1050623   1048576   512M 83 Linux
/dev/sdb2         1050624   5244927   4194304     2G 82 Linux swap / Solaris
/dev/sdb3         5246974 976773119 971526146 463,3G  5 Extended
/dev/sdb5         5246976 214962175 209715200   100G 83 Linux
/dev/sdb6       214964224 634394623 419430400   200G 83 Linux
/dev/sdb7       634396672 976773119 342376448 163,3G 83 Linux

Jako, że smartctl używa LBA do określenia miejsca wystąpienia problemu, jak również fdisk korzysta z założenia ze sektor równy jest 512 bajtom to nie musimy dokonywać żadnej konwersji, aby określić właściwą partycję. Po spojrzeniu czy nasz sektor mieści się pomiędzy wartościami start i end możemy śmiało powiedzieć, że kłopot jest na partycji /dev/sdb5.

Warto sprawdzić, jeżeli nie pamiętamy, jaki punkt montowania ma wskazana partycja.

$ mount | grep /dev/sdb5
/dev/sdb5 on / type jfs (rw,relatime)

W moim przypadku partycja jest podmontowana jako główna partycja systemowa.

W następnej kolejności musimy odnaleźć rozmiar pojedyńczego bloku dla partycji /dev/sdb5. Jako, że partycja jest typu JFS nie możemy skorzystać z narzędzia tune2fs, a użyć komendy przedstawionej poniżej.

$ sudo jfs_tune -l /dev/sdb5

jfs_tune version 1.1.15, 04-Mar-2011

JFS filesystem superblock:

JFS magic number: 'JFS1'
JFS version: 1
JFS state: mounted
JFS flags: JFS_LINUX  JFS_COMMIT  JFS_GROUPCOMMIT  JFS_INLINELOG 
Aggregate block size: 4096 bytes
Aggregate size: 209446256 blocks
Physical block size: 512 bytes
Allocation group size: 262144 aggregate blocks
Log device number: 0x815
Filesystem creation: Sun May 25 14:30:43 2014
Volume label: ''

Jak widać pojedyńczy blok systemu plików na partycji /dev/sdb5 ma 4096 bajtów. W celu określenia miejsca, w którym występuje problem należy skorzystać z wzoru:

(numer_sektora_LBA_smartctl - numer_pierwszego_sektora_partycji) * (fizyczny_rozmiar_sektora / rozmiar_sektora_systemu_plików)

(30465321 - 5246976) * (512/4096) = 3152293,125

Jako, że sektorów do relokacji mamy aż 6 ta metoda jest czasochłonna i wymaga dodatkowych przeliczeń. Dużo szybciej i pewniej jest skorzystać z narzędzia badblocks. UWAGA! Zalecane jest, aby używać tego narzędzia na odmontowanych partycjach.

$ sudo badblocks -b 4096 -v /dev/sdb5
Sprawdzanie bloków od 0 do 26214399
Poszukiwanie wadliwych bloków (tylko odczyt): 3152293
3152294

Narzędzie zwróciło dwa blocki 4096 bajtowe, które pokrywają się z powyższymi obliczeniami. Jako, że każdy blok zawiera osiem 512 bajtowych sektorów stąd w tych dwóch blokach może zmieścić się 6 sektorów do relokacji.

Jako, że próba naprawy badblocków jest destrukcyjna, gdyż będziemy wykorzystywać zerowanie to zalecane jest sprawdzenie co znajduje się w tym obszarze parycji /dev/sdb5.

$ sudo jfs_debugfs /dev/sdb5
jfs_debugfs version 1.1.15, 04-Mar-2011

Aggregate Block Size: 4096

> d 3152293 0 i
ujfs_rw_diskblocks: read 0 of 4096 bytes at offset 12911792128
display: ujfs_rw_diskblocks failed

> d 3152294 0 i
ujfs_rw_diskblocks: read 0 of 4096 bytes at offset 12911796224
display: ujfs_rw_diskblocks failed

> q

Błędy świadczą, że przestrzeń nie jest używana. W wypadku gdyby była używana to powinniśmy otrzymać numer inode'a, który trzeba sprawdzić. W moim przypadku mogę śmiało nadpisać dwa wskazane bloki.

$ sudo dd if=/dev/zero of=/dev/sdb5 bs=4096 count=1 seek=3152293
1+0 przeczytanych recordów
1+0 zapisanych recordów
skopiowane 4096 bajtów (4,1 kB), 0,00156196 s, 2,6 MB/s

$ sudo dd if=/dev/zero of=/dev/sdb5 bs=4096 count=1 seek=3152294
1+0 przeczytanych recordów
1+0 zapisanych recordów
skopiowane 4096 bajtów (4,1 kB), 0,00390099 s, 1,0 MB/s

Bloki zostały nadpisane. Możemy teraz sprawdzić czy ilość sektorów oczekujących na relokację się zmniejszyła.

$ sudo smartctl -a /dev/sdb

<-- output omitted -->

ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
  1 Raw_Read_Error_Rate     0x000b   100   100   016    Pre-fail  Always       -       0
  2 Throughput_Performance  0x0005   135   135   054    Pre-fail  Offline      -       96
  3 Spin_Up_Time            0x0007   117   117   024    Pre-fail  Always       -       198
  4 Start_Stop_Count        0x0012   100   100   000    Old_age   Always       -       1165
  5 Reallocated_Sector_Ct   0x0033   100   100   005    Pre-fail  Always       -       1
  7 Seek_Error_Rate         0x000b   100   100   067    Pre-fail  Always       -       0
  8 Seek_Time_Performance   0x0005   140   140   020    Pre-fail  Offline      -       30
  9 Power_On_Hours          0x0012   100   100   000    Old_age   Always       -       5783
10 Spin_Retry_Count        0x0013   100   100   060    Pre-fail  Always       -       0
12 Power_Cycle_Count       0x0032   100   100   000    Old_age   Always       -       1164
192 Power-Off_Retract_Count 0x0032   100   100   000    Old_age   Always       -       1165
193 Load_Cycle_Count        0x0012   100   100   000    Old_age   Always       -       1165
194 Temperature_Celsius     0x0002   193   193   000    Old_age   Always       -       31
196 Reallocated_Event_Count 0x0032   100   100   000    Old_age   Always       -       1
197 Current_Pending_Sector  0x0022   100   100   000    Old_age   Always       -       0
198 Offline_Uncorrectable   0x0008   100   100   000    Old_age   Offline      -       0
199 UDMA_CRC_Error_Count    0x000a   200   200   000    Old_age   Always       -       0

Parametr 197 spadł do 0, tak więc operacja powiodła się. Dla pewności zalecane jest ponowne uruchomienie testu long oraz wymuszenie fsck dla tej partycji.

Brak dostępnych komentarzy.

Dodaj komentarz

Filtered HTML

  • Adresy internetowe są automatycznie zamieniane w odnośniki, które można kliknąć.
  • To post pieces of code, surround them with <code>...</code> tags. For PHP code, you can use <?php ... ?>, which will also colour it based on syntax.
  • Dozwolone znaczniki HTML: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Znaki końca linii i akapitu dodawane są automatycznie.

Plain text

  • Znaczniki HTML niedozwolone.
  • Adresy internetowe są automatycznie zamieniane w odnośniki, które można kliknąć.
  • Znaki końca linii i akapitu dodawane są automatycznie.
CAPTCHA
Ten tekst ma na celu określenie czy jesteś człowiekiem. Ma to zapobiec mechanizmom rozpowszechniającym SPAM.
Image CAPTCHA
Enter the characters shown in the image.