Обріжте LVM та dm-склеп


21

Я спробував налаштувати TRIM за допомогою LVM та dm-crypt на ubuntu 13.04, дотримуючись цього підручника:

http://blog.neutrino.es/2013/howto-properly-activate-trim-for-your-ssd-on-linux-fstrim-lvm-and-dmcrypt/

Дивіться примітки про мою конфігурацію та мою процедуру тестування нижче.

Запитання

  1. Чи є надійний тест, якщо TRIM працює належним чином?

  2. Неправильний мій тест чи мій TRIM не працює?

  3. Якщо це не працює: що не так з моїм налаштуванням?

  4. Як я можу налагодити TRIM для мого налаштування та змусити TRIM працювати?

Конфігурація

Ось моя конфігурація:

cat /etc/crypttab

sda3_crypt UUID=[...] none luks,discard

і

cat /etc/lvm/lvm.conf

# [...]
devices  {
      # [ ... ]
      issue_discards = 1
      # [ ... ]
   }
# [...]

SSD - це Samsung 840 Pro.

Ось моя тестова процедура

Щоб перевірити налаштування, я щойно зробив, в sudo fstrim -v /результаті чого

/: [...] bytes were trimmed

Знову ж таки це призвело до того, /: 0 bytes were trimmedщо, здається, має сенс і вказує на те, що TRIM, здається, працює.

Однак тоді я зробив цей тест:

dd if=/dev/urandom of=tempfile count=100 bs=512k oflag=direct

sudo hdparm --fibmap tempfile                                 

tempfile:
 filesystem blocksize 4096, begins at LBA 0; assuming 512 byte sectors.
 byte_offset  begin_LBA    end_LBA    sectors
           0    5520384    5521407       1024
      524288    5528576    5529599       1024
     1048576    5523456    5525503       2048
     2097152    5607424    5619711      12288
     8388608    5570560    5603327      32768
    25165824    5963776    5980159      16384
    33554432    6012928    6029311      16384
    41943040    6275072    6291455      16384
    50331648    6635520    6639615       4096

sync

sudo hdparm --read-sector 5520384 /dev/sda                    

/dev/sda:
reading sector 5520384: succeeded
7746 4e11 bf42 0c93 25d3 2825 19fd 8eda
bd93 8ec6 9942 bb98 ed55 87eb 53e1 01d5
c61a 3f52 19a1 0ae5 0798 c6e2 39d9 771a
b89f 3fc5 e786 9b1d 3452 d5d7 9479 a80d
114a 7528 a79f f475 57dc aeaf 25f4 998c
3dd5 b44d 23bf 77f3 0ad9 8688 6518 28ee
81db 1473 08b5 befe 8f2e 5b86 c84e c7d2
1bdd 1065 6a23 fd0f 2951 d879 e823 021b
fa84 b9c1 eadd 9154 c9f4 2ebe cd70 64ec
75a8 4d93 c8fa 3174 7277 1ffb e858 5eca
7586 8b2e 9dbc ab12 40ab eb17 8187 e67d
5e0d 0005 5867 b924 5cfd 6723 9e4a 6f5f
99a4 a3b0 eeac 454a 83b6 c528 1106 6682
ca77 4edf 2180 bf0c b175 fabb 3d4b 37e2
b834 9e3e 82f2 2fdd 2c6a c6ca 873f e71e
f979 160f 5778 356f 2aea 6176 46b6 72b9
f76e ee51 979c 326b 1436 7cfe f677 bfcd
4c3c 9e11 4747 45c1 4bb2 4137 03a1 e4c8
e9dd 43b4 a3b4 ce1b d218 4161 bf64 727b
75d8 dcc2 e14c ebec 2126 25da 0300 12bd
6b1a 28b3 824f 3911 c960 527d 97cd de1b
9f08 9a8e dcdc e65f 1875 58ca be65 82bf
e844 50b8 cc1b 7466 58b8 e708 bd3d c01f
64fb 9317 a77a e43b 671f e1fb e328 93a9
c9c7 291c 56e0 c6c1 f011 b94d 9dc7 71e6
c8b1 5720 b8c9 b1a6 14f1 7299 9122 912b
312a 0f2f a31a 8bf9 9f8c 54e6 96f3 60b8
04a7 7dc9 3caa db0a a837 e5d7 2752 b477
c22d 7598 44e1 84e9 25d4 5db5 9f19 f73b
85a0 c656 373a ec34 55fb e1fc 124e 4674
1ba8 1a84 6aa4 7cb5 455e f416 adc6 a125
c4d4 8323 4eee 2493 2920 4e38 524c 1981

sudo rm tempfile

sync

sudo fstrim /

sync

sudo hdparm --read-sector 5520384 /dev/sda

/dev/sda:
reading sector 5520384: succeeded
7746 4e11 bf42 0c93 25d3 2825 19fd 8eda
bd93 8ec6 9942 bb98 ed55 87eb 53e1 01d5
c61a 3f52 19a1 0ae5 0798 c6e2 39d9 771a
b89f 3fc5 e786 9b1d 3452 d5d7 9479 a80d
114a 7528 a79f f475 57dc aeaf 25f4 998c
3dd5 b44d 23bf 77f3 0ad9 8688 6518 28ee
81db 1473 08b5 befe 8f2e 5b86 c84e c7d2
1bdd 1065 6a23 fd0f 2951 d879 e823 021b
fa84 b9c1 eadd 9154 c9f4 2ebe cd70 64ec
75a8 4d93 c8fa 3174 7277 1ffb e858 5eca
7586 8b2e 9dbc ab12 40ab eb17 8187 e67d
5e0d 0005 5867 b924 5cfd 6723 9e4a 6f5f
99a4 a3b0 eeac 454a 83b6 c528 1106 6682
ca77 4edf 2180 bf0c b175 fabb 3d4b 37e2
b834 9e3e 82f2 2fdd 2c6a c6ca 873f e71e
f979 160f 5778 356f 2aea 6176 46b6 72b9
f76e ee51 979c 326b 1436 7cfe f677 bfcd
4c3c 9e11 4747 45c1 4bb2 4137 03a1 e4c8
e9dd 43b4 a3b4 ce1b d218 4161 bf64 727b
75d8 dcc2 e14c ebec 2126 25da 0300 12bd
6b1a 28b3 824f 3911 c960 527d 97cd de1b
9f08 9a8e dcdc e65f 1875 58ca be65 82bf
e844 50b8 cc1b 7466 58b8 e708 bd3d c01f
64fb 9317 a77a e43b 671f e1fb e328 93a9
c9c7 291c 56e0 c6c1 f011 b94d 9dc7 71e6
c8b1 5720 b8c9 b1a6 14f1 7299 9122 912b
312a 0f2f a31a 8bf9 9f8c 54e6 96f3 60b8
04a7 7dc9 3caa db0a a837 e5d7 2752 b477
c22d 7598 44e1 84e9 25d4 5db5 9f19 f73b
85a0 c656 373a ec34 55fb e1fc 124e 4674
1ba8 1a84 6aa4 7cb5 455e f416 adc6 a125
c4d4 8323 4eee 2493 2920 4e38 524c 1981

Це, мабуть, вказує на те, що TRIM не працює. З тих пір

sudo hdparm -I /dev/sda | grep -i TRIM                        
       *    Data Set Management TRIM supported (limit 8 blocks)
       *    Deterministic read ZEROs after TRIM

Редагувати

Ось вихід sudo dmsetup table

lubuntu--vg-root: 0 465903616 linear 252:0 2048
lubuntu--vg-swap_1: 0 33308672 linear 252:0 465905664
sda3_crypt: 0 499222528 crypt aes-xts-plain64 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0 8:3 4096 1 allow_discards

Ось мій /etc/fstab:

# <file system> <mount point>   <type>  <options>       <dump>  <pass>
/dev/mapper/lubuntu--vg-root /               ext4    errors=remount-ro 0       1
# /boot was on /dev/sda2 during installation
UUID=f700d855-96d0-495e-a480-81f52b965bda /boot           ext2    defaults        0       2
# /boot/efi was on /dev/sda1 during installation
UUID=2296-2E49  /boot/efi       vfat    defaults        0       1
/dev/mapper/lubuntu--vg-swap_1 none            swap    sw              0       0
# tmp
tmpfs /tmp tmpfs nodev,nosuid,noexec,mode=1777          0       0 

Редагувати:

Нарешті я повідомив про це як про помилку в https://bugs.launchpad.net/ubuntu/+source/lvm2/+bug/1213631

Сподіваюся, що хтось знайде там рішення або хоча б перевірить налаштування та перевірить помилку.

Оновлення

Тепер це працює, дивіться прийняту відповідь.


LVM , здається, відсутня викид риби, повинен бути issue_discardsНЕ , issue discardsякщо це не помилка. allow_discardsмає відображатися в таблиці dmsetup для розділів LVM.
frostschutz

Вибачте, це була помилка друку. У мене є issue_discards = 1конфігураційний файл.
студент

Якби я був ти, я б спробував використати ціль iSCSI і перевірити це за допомогою tcpdump / wireshark, щоб перевірити, чи працює інсталяція, хоча я не знаю, підтримує ціль iSCSI Linux обробка чи ні. Я вважаю, що dm-crypt не повинен очищати блоки на фізичному диску, тому що це полегшує ігнорування вільного місця на пристрої при спробі грубої сили (не знаю, чи робить це чи ні, хоча ). Крім того, SSD-диски не вимагають повернення нулів після блокування, оскільки знос-нівелювання може перенаправляти зчитування на інший блок, ніж на блокований.
Діді Коен

1
За повідомленнями bugzilla.redhat.com/show_bug.cgi?id=958096 я неправильно зрозумів issue_discards = 1.
frostschutz

Відповіді:


23

Я пропоную використовувати інший метод тестування. hdparmтрохи дивніше, оскільки він надає адреси пристроїв, а не адреси файлової системи, і не говорить про те, до якого пристрою відносяться ці адреси (наприклад, він вирішує розділи, але не цілі для деваймування пристрою тощо). Набагато простіше використовувати те, що стикається з адресами файлової системи, таким чином, це послідовно (можливо, за винятком нетрадиційних файлових систем, таких як zfs / btrfs).

Створіть тестовий файл: (не випадково за призначенням)

# yes | dd iflag=fullblock bs=1M count=1 of=trim.test 

Отримайте адресу, довжину та розмір блоку: (точна команда залежить від filefragверсії)

# filefrag -s -v trim.test
File size of trim.test is 1048576 (256 blocks, blocksize 4096)
 ext logical physical expected length flags
   0       0    34048             256 eof
trim.test: 1 extent found

Отримайте пристрій та точку кріплення:

# df trim.test
/dev/mapper/something  32896880 11722824  20838512   37% /mount/point

За допомогою цього налаштування у вас є файл, trim.testзаповнений yes-pattern на /dev/mapper/somethingадресу 34048з довжиною 256блоків 4096байтів.

Читаючи, що з пристрою безпосередньо слід виробляти yes-матеріал:

# dd bs=4096 skip=34048 count=256 if=/dev/mapper/something | hexdump -C
00000000  79 0a 79 0a 79 0a 79 0a  79 0a 79 0a 79 0a 79 0a  |y.y.y.y.y.y.y.y.|
*
00100000

Якщо TRIM увімкнено, ця модель повинна змінюватися, коли ви видаляєте файл. Зауважте, що кеші також потрібно скинути, інакше дані ddне будуть перечитані з диска.

# rm trim.test
# sync
# fstrim -v /mount/point/ # when not using 'discard' mount option
# echo 1 > /proc/sys/vm/drop_caches
# dd bs=4096 skip=34048 count=256 if=/dev/mapper/something | hexdump -C

На більшості SSD, що призведе до нульової картини:

00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00100000

Якщо задіяно шифрування, ви побачите замість нього випадковий зразок:

00000000  1f c9 55 7d 07 15 00 d1  4a 1c 41 1a 43 84 15 c0  |..U}....J.A.C...|
00000010  24 35 37 fe 05 f7 43 93  1e f4 3c cc d8 83 44 ad  |$57...C...<...D.|
00000020  46 80 c2 26 13 06 dc 20  7e 22 e4 94 21 7c 8b 2c  |F..&... ~"..!|.,|

Це тому, що фізично оброблений, криптошар зчитує нулі та розшифровує ці нулі до "випадкових" даних.

Якщо yesпатерн зберігається, швидше за все, обрізки не проводили.


1
@student: Мені шкода, що не помічав цього раніше, редагував відповідь на те, щоб кинути кеші раніше hexdump.
frostschutz

1
Дякую, це було відсутнім моментом. Тепер, здається, працює!
студент

2
Я все ще не впевнений, що ядро ​​не повинно скидати кеші самостійно, коли воно щось обробляє на SSD. Кеші не повинні повертати неправильні дані. Це також марна трапляння на кеш-пам'ять, якщо її займає щось, чого вже немає ... о, добре.
frostschutz

1
@frostschutz Дякую за чудове рішення. Я склав сценарій для автоматизації процесу, якщо сюди приїде якийсь ледачий чоловік.
десгуа

1
Новачки , зауважте, що команда TRIM не завжди одразу «заповнює» нулі блоки. Дивіться тут , тут і тут . Хоча у випадку з ОП це повинно бути, оскільки його hdparm -Iрезультат вказує на "Детерміновані читання ZERO після TRIM".
Марк.2377

3

Ваш тестовий розпорядок невірний - ви отримуєте номери секторів щодо блокового пристрою, на якому сидить файлова система - що в цьому випадку є логічним обсягом. Логічний об'єм, звичайно, не починається з першого сектора фізичного об'єму (і може навіть не бути суміжним).

Навіть якщо логічний об'єм розпочався з сектора 0 фізичного об'єму (якого він не має), то фізичний об'єм є насправді іншим цільовим пристроєм-картографом, цим для шифрування. І, мабуть, попереду є заголовок ЛУКС, тож цифри секторів також не збігаються.

Якщо ви хочете працювати над відображенням номера сектора на базовий диск, dmsetup tablesдамо вам необхідну інформацію. Якщо ви вставите його сюди, переконайтеся, що ваша версія - це версія, яка не відображає ключ у висновку (він повинен показувати всі 0 замість цього)! ( Відкриття ключа немає відновлення - його неможливо змінити - це набагато гірше, ніж розкриття пароля).

Я пропоную для налагодження (як тільки ви складете картографічне розроблення сектору), ви починаєте з найнижчого рівня і підтверджуєте, що він працює там. TRIM файлову систему безпосередньо на / dev / sdaX і переконайтеся, що вона працює (цілком можливо, що пристрій лежить, а обробка не читає нулі назад). Тоді dm-crypt поверх цього, і обріжте файлову систему на цьому, і переконайтеся, що вона працює. Нарешті, поставте LVM зверху та перевірте, чи працює він.


@student Добре, тоді це неправильний сектор (перші два абзаци моєї відповіді). Я відредагую свою відповідь, щоб видалити це речення про сектор 6575104, оскільки воно вже не актуальне.
дероберт

Я не впевнений, який пристрій я повинен взяти dmsetup. Я щойно зробив: sudo dmsetup table /dev/mapper/lubuntu--vg-rootщо дає0 465903616 linear 252:0 2048
студент

@student Це означає, що сектор 0 знаходиться в секторі 2048 на пристрої 252: 0. Вам доведеться розібратися, що таке 252: 0, я думаю, його крипто-пристрій dm (це головне і другорядне число, відображатиметься в / dev, наприклад). І вам потрібно буде переглянути таблицю для цього пристрою, щоб продовжувати переслідувати його до блоку на базовому пристрої.
дероберт

3

Це просто сценарій, яким я хотів би поділитися, якщо сюди приїде якийсь ледачий чоловік. Це було зроблено з прийнятої відповіді від frostschutz .

#! / бін / баш
#
# Цей сценарій надається "як є" без будь-яких гарантій, явних або явних, включаючи, але не обмежуючись цим, маються на увазі гарантії товарності, придатності для певної мети або не порушень.
#
# Ліцензія GPL2
#
# від desgua 2014/04/29

функція CLEAN {
cd "$ макаронні вироби"
[-f test-trim-by-desgua] && rm test-trim-by-desgua && echo "Темп-файл видалено"
відлуння "До побачення"
вихід 0
}

пастка 'відлуння; відлуння "Аборт". ; ЧИСТИТИ; відлуння; вихід 0 'INT HUP

if [["$ (echo $ USER)"! = "корінь"]]; потім

прочитати -n 1 -p 'Стати корінь? [Y / n] 'a
    якщо [[$ a == "Y" || $ a == "y" || $ a == ""]]; потім
        судо $ 0 $ 1
        вихід 0
    ще
        відлуння "
        Цей скрипт потребує root права.
        "
        вихід 1

    фі

фі


name = $ (відлуння $ 0 | sed 's /.*\///')
якщо [$ # -ne 1]; потім

відлуння "
Використання: $ name / папка / to / test /

"
вихід 1
фі

макаронні вироби = 1 долар

read -n 1 -p 'Використовувати fstrim? [у / Н] 'а
якщо [[$ a == "Y" || $ a == "y"]]; потім
    fs = 1
фі

метод =
while [["$ method"! = "1" && "$ method"! = "2"]]; робити
read -n 1 -s -p 'Оберіть метод:
[1] hdparm (вийде з ладу в LUKS на LVM)
[2] filefrag (попередження: можливо, вам доведеться змусити вийти - закрити термінал - у деяких випадках успішного обрізання, якщо ви бачите вихід, який ніколи не закінчується) 
'метод
зроблено

функція SDATEST {
диск = $ (fdisk -l | grep / dev / sda)
if ["$ disk" == ""]; потім
відлуння "
fdisk не знайдено / dev / sda 
"
вихід 1
фі
}

функція TEST {
відлуння "Вхід /"; відлуння
cd $ макаронні вироби
ехо "Створення файлу test-trim-by-desgua у $ pasta"; відлуння
dd, якщо = / dev / urandom of = тест-обробка по-десгуа = 10 bs = 512k
відлуння "Синхронізація та сну 2 секунди". ; відлуння
синхронізація
сон 2

hdparm - fibmap test-trim-by-desgua
lbab = $ (hdparm - fibmap test-trim-by-desgua | tail -n1 | awk '{print $ 2}')

echo "Як ви бачите, файл був створений і його LBA починається з $ lbab"; відлуння

відлуння "Синхронізація та сну 2 секунди". ; відлуння
синхронізація
сон 2

відлуння "Видалення файлу тест-обробка-по-десгуа"; відлуння
rm тест-обробка по десгуа

пастка 'відлуння; відлуння; відлуння "Аборт". ; відлуння; вихід 0 'INT
відлуння "Синхронізація та сну 2 секунди". ; відлуння
синхронізація
сон 2

if [["$ fs" == "1"]]; потім
    ехо "fstrim $ паста && сон 2"; відлуння
    fstrim $ макаронні вироби
    сон 2
фі

echo "Це читається з сектору $ lbab:"
hdparm - читає сектор $ lbab / dev / sda

pass = $ (hdparm - прочитаний сектор $ lbab / dev / sda | grep "0000 0000 0000 0000")

якщо [[$ pass == ""]]; потім
    відлуння "
Обрізка не вдалася ... 
Ви повинні бачити лише 0000 0000 0000 0000 ...
"
ще
    відлуння "Успіх !!!"
фі
вихід 0

}

функція LUKSTEST {
# Довідка: /unix/85865/trim-with-lvm-and-dm-crypt#
echo 1> / proc / sys / vm / drop_caches
cd $ макаронні вироби
echo "Створення файлу \" так \ "."
так | dd iflag = fullblock bs = 1M count = 1 of = test-trim-by-desgua

# position = `filefrag -s -v тест-обробка-по-desgua | grep "eof" | awk '{print $ 3}' `
position = `filefrag -s -v тест-обробка-по-desgua | grep "eof" | sed 's | || г; s |. * 255: || ; s | \. \ .. * || '`
[["$ position" == ""]] && echo "Не вдалося знайти позицію файлу. Ви знаходитесь на LUKS у LVM?" && CLEAN;

device = `df test-trim-by-desgua | grep "dev /" | awk '{print $ 1}' `

так = `dd bs = 4096 пропустити = $ count count = 256 if = $ device | гексдумп -С`

відлуння "У наступному рядку ви повинні побачити такий зразок: 
00000000 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a | yyyyyyyy |
$ так
"

if [["` echo "$ yes" | grep "yyy" `" == ""]]; потім
    відлуння "Шаблон неможливо перевірити. Щось пішло не так. Вихід".
    ЧИСТИТИ;
ще
    ехо "Візерунок підтверджений."
фі

ехо "Видалення тимчасового файлу." 
rm тест-обробка по десгуа

відлуння "Синхронізація".
синхронізація
сон 1

if [["$ fs" == "1"]]; потім
    ехо "fstrim -v $ макаронні вироби & сон 2"; відлуння
    fstrim -v $ макаронні вироби
    сон 2
фі

# Скинути кеш
echo 1> / proc / sys / vm / drop_caches

відлуння "У наступному рядку ви повинні ** НЕ ** бачити шаблон так: 
00000000 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a | yyyyyyyy | 
Якщо ви бачите, обробка не працює:
`dd bs = 4096 пропустити = $ count count = 256 if = $ device | hexdump -C` "

так = `dd bs = 4096 пропустити = $ count count = 256 if = $ device | гексдумп -С`
if [["` echo "$ yes" | grep "yyy" `"! = ""]]; потім
    ехо "TRIM не працює".
ще
    ехо "TRIM працює!"
фі
ЧИСТИТИ;
}

if [["$ метод" == "1"]]; потім
    SDATEST;
    ТЕСТ;
elif [["$ метод" == "2"]]; потім
    ЛУКСТЕСТ;
фі
вихід 0

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.