Активация discard (TRIM) на Linux для SSD

Современные накопители данных такие как SSD нуждаются в команде TRIM интерфейса ATA и для этого в ОС построенных на базе ядра Linux предусмотрено два метода управления на уровне файловых систем:


  • discard — устанавливается как опция монтировании файловой системы. Позволяет ядру Linux сразу отправлять команду TRIM на устройство, как только об этом сообщит файловая система.
  • fstrim — утилита которая запускается вручную или по расписанию как сервис ОС, отправляет список удаленных блоков с ФС для зачистки их на устройстве.

Для включения fstrim достаточно активировать сервис fstrim.service в systemd, но лучше вместо сервиса, который будет висеть в памяти, использовать таймер fstrim.timer который будет запускать еженедельный TRIM.


Пример включения сервиса:


# Включение, старт и вывод статуса сервиса:
systemctl enable fstrim.service && \
systemctl start fstrim.service && \
systemctl status fstrim.service

Но этих мер недостаточно, если у вас файловые системы располагаются на томах LVM, а LVM в LUKS игла в яйце, яйцо в утке, утка в зайце:




Первое что нужно сделать, это проверить, что контроллер SATA работает в режиме AHCI, а не IDE, иначе TRIM работать не будет:


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

Ключевое слово здесь это TRIM supported, значит контроллер SATA работает в режиме AHCI и вам не нужно ничего менять в BIOS или UEFI.


Итак, опция discard может устанавливаться:


  • в суперблоке ФС (как опция монтирования по умолчанию)
  • в конфигурации монтирования ФС — /etc/fstab
  • в конфигурации cryptsetup — /etc/crypttab
  • в конфигурации LVM — /etc/lvm/lvm.conf
  • в конфигурации загрузчика — /boot/grub/grub.cfg

Мы рассмотрим все эти варианты. Примеры будут даны для дистрибутива Arch Linux и его производных, но я думаю вас не затруднит адаптировать тему к любому другому дистрибутиву Linux.


discard в суперблоке EXT4


Если в /etc/fstab для файловой системы опция discard не указана или в опциях монтирования указана опция defaults, то система будет использовать опции монтирования прописанные в суперблоке файловой системы. Это актуально для файловой системы EXT4. Запись опций монтирования в суперблоке ФС может быть выгодна тем, что если у вас съёмное устройство которое подключается по SATA к разным машинам в которых вы не можете по каким-то причинам вносить изменения в /etc/fstab.


Добавляем опцию монтирования discard по умолчанию в суперблок файловой системы EXT4. У меня это три раздела:


sudo tune2fs -o discard /dev/mapper/vg1-lvroot
sudo tune2fs -o discard /dev/mapper/vg1-lvhome
sudo tune2fs -o discard /dev/mapper/vg1-lvvar

Убедиться в установленной опции можно через tune2fs. Здесь /dev/mapper/vg1-lvroot это устройство, раздел с файловой системой EXT4 в томе LVM:


sudo tune2fs -l /dev/mapper/vg1-lvroot | grep options

discard в fstab


Если это единственная система куда разделы SSD будут монтироваться, то мы можем прописать опцию discard явно в /etc/fstab для автомонтирования разделов, но устанавливать опцию необязательно для EXT4, если она уже была ранее задана в суперблоке.


Также, опцию discard следует добавить для swap раздела:


# /dev/mapper/vg1-lvroot
UUID=e86ab458-341d-4f59-8344-0271d2c363e8    /            ext4    rw,noatime,discard   0 0
# /dev/mapper/vg1-lvvar
UUID=44b31816-1193-4dc1-9f58-f70df2250e1a    /var         ext4    rw,noatime,discard   0 0
# /dev/mapper/vg1-lvhome
UUID=372bc9ae-b581-49a4-abed-ca9f3b67edb6    /home        ext4    rw,noatime,discard   0 0
# /dev/sda1
UUID=0BE5-60FB                               /boot/efi    vfat    rw,relatime,discard,...,errors=remount-ro   0 0
# /dev/mapper/vg1-lvswap
UUID=cf67ae1e-3a17-4e5e-ac58-ef23725d2359    none         swap    defaults,discard,pri=-2   0 0

discard на LVM


В конфигурационном файле /etc/lvm/lvm.conf устанавливаем значение опции issue_discards в значение равное 1:


devices {
  issue_discards = 1
}

Важно отметить, что включение этой опции не пересылает команду TRIM с файловых систем когда на них производятся команды удаления файлов, эта опция посылает команду TRIM только когда производятся манипуляции изменения логического тома, например, через такие команды как lvremove, lvreduce и т.д.


discard для зашифрованного root-раздела


Прежде, чем вы решите включить discard на зашифрованных томах, необходимо оценить риск безопасности утечки метаданных (тип файловой системы, используемое пространство и т. д.) которые могут быть извлечены из физического устройства при его завладении нежелательными лицами, об этом говорит предупреждение в мануале crypttab:


WARNING: This command can have a negative security impact because it can make filesystem-level operations visible on the physical device. For example, information leaking filesystem type, used space, etc. may be extractable from the physical device if the discarded blocks can be located later. If in doubt, do not use it.

Если вы Джеймс Бонд или секретный агент который занимается незаконными делами или работаете с гостайной и рискуете потерять жизнь, то эту опцию нежелательно использовать. В иных случаях, для простого пользователя, который шифрует разделы на устройстве с целью защиты информации от посторонних глаз, защиты себя и своих близких от шантажа неким домашним хакером в случае кражи ноута или устройства, то возможно ли расшифровать данные, если злой хакер получит метаданные файловой системы? Каким уровнем знаний должен обладать этот хакер, чтобы справится с расшифровкой данных? Какова цена? Предлагаю обсудить это в комментариях :)




В приведенной выше схеме разметки таблицы разделов на накопителе, некоторые разделы являются зашифрованными и "заперты" в криптоконтейнере LUKS. Чтобы TRIM был разрешен для этих разделов, корневой раздел должен быть открыт cryptsetup'ом с аргументом --allow-discards или опция должна быть прописана в /etc/crypttab для нужного раздела, но проблема заключается в том, что мы не можем прописать опцию в /etc/crypttab, так как root-раздел в нашей схеме изначально зашифрован и система не может прочитать его до того как откроет криптоконтейнер.


Решением этой проблемы является указать опцию при открытии криптоконтейнера на раннем этапе загрузки в initramfs, а передать эту опцию в initramfs поможет опция в конфигурации загрузчика grub для ядра Linux.


Добавляем значение allow-discards в конфигурационный файл /etc/default/grub для параметра cryptdevice в параметре для ядра GRUB_CMDLINE_LINUX.


Меняем эту строчку:


GRUB_CMDLINE_LINUX="cryptdevice=UUID=3c121aac-ead9-4d57-88be-c1199acf72f0:cryptlvm"

на эту:


GRUB_CMDLINE_LINUX="cryptdevice=UUID=3c121aac-ead9-4d57-88be-c1199acf72f0:cryptlvm:allow-discards"

Затем необходимо сгенерировать "правильный" конфиг grub'а:


sudo grub-mkconfig -o /boot/grub/grub.cfg

Также проверьте, что у вас образ initramfs скомпилирован с хуком encrypt который позволяет открывать криптоконтейнеры с помощью cryptsetup и он расположен до хука lvm2:


cat /etc/mkinitcpio.conf | grep ^HOOKS

HOOKS=(base udev autodetect keyboard keymap consolefont modconf block encrypt lvm2 resume filesystems)

После внесения изменений в grub систему следует перезагрузить для применения изменений.


discard для других зашифрованных разделов устройства




В приведенной выше схеме разметки, раздел /home не является корневым и находится в контейнере LUKS. В этом случае, следует прописать опцию монтирования discard в конфигурационном файле /etc/crypttab который зачитывается системой до зачитывания и выполнения /etc/fstab.


Формат записи опции в конфигурационном файле вы найдете в мануале: man crypttab


Проверка TRIM


Выполните следующую команду:


lsblk --discard

NAME             DISC-ALN DISC-GRAN DISC-MAX DISC-ZERO
sda                     0      512B       2G         0
├─sda1                  0      512B       2G         0
└─sda2                  0      512B       2G         0
  └─cryptlvm            0        0B       0B         0
      ├─vg1-lvroot      0        0B       0B         0
      ├─vg1-lvvar       0        0B       0B         0
      ├─vg1-lvswap      0        0B       0B         0
      └─vg1-lvhome      0        0B       0B         0

Если вы видите нулевые значения в колонках DISC-GRAN (discard granularity) и DISC-MAX (discard max bytes), значит TRIM не работает.


Проверить еще можно командой ручного вызова TRIM:


sudo fstrim -v /

/: 7,4 GiB (7906193408 bytes) trimmed

Если вы видите положительный результат, значит TRIM работает. При полной поддержке TRIM значения должны быть на всех разделах:


lsblk --discard

NAME             DISC-ALN DISC-GRAN DISC-MAX DISC-ZERO
sda                     0      512B       2G         0
├─sda1                  0      512B       2G         0
└─sda2                  0      512B       2G         0
  └─cryptlvm            0      512B       2G         0
    ├─vg1-lvroot        0      512B       2G         0
    ├─vg1-lvvar         0      512B       2G         0
    ├─vg1-lvswap        0      512B       2G         0
    └─vg1-lvhome        0      512B       2G         0

Здесь DISC-GRAN равен 512B потому что размер сектора на моём SSD равен 512 bytes. Операционная система посылает команду TRIM контроллеру накопителя с указанием номеров секторов, которые могут быть очищены. Размер вашего сектора можно узнать из следующих команд:


sudo cryptsetup status cryptlvm

/dev/mapper/cryptlvm is active and is in use.
type:    LUKS1
cipher:  aes-xts-plain64
keysize: 512 bits
key location: dm-crypt
device:  /dev/sda2
sector size:  512
offset:  4096 sectors
size:    487806976 sectors
mode:    read/write

sudo hdparm -I /dev/sda | grep -i "sector size"

      Logical  Sector size:                   512 bytes
      Physical Sector size:                   512 bytes

sudo smartctl -a /dev/sda | grep -i "sector size"

Sector Size:      512 bytes logical/physical

На этом всё!




UPDATE 14.04.2020 14:20: Добавил предупреждение использования опции на зашифрованных томах. Спасибо AAngstrom который отметил в комментариях это упущение.
UPDATE 23.04.2020 22:00: Подправил текст, убрал слово "диск" из текста, так как оно не соответствует описываемому в статье устройству. Спасибо vitaliy2

AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 15

    0
    А у меня такой вопрос — если дёргать fstrim раз в сутки по крону, будут какие-то негативные последствия?
      0
      1. Если контроллёр диска "тупой", то он может заблокировать или снизить приоритет чтения/записи, так как будет стремится очистить все блоки за сутки — их может быть очень много, всё зависит от интенсивности записи/удаления и самого контроллера.
      2. Контроллёр может нагреваться если нет хорошего охлаждения и внутренние алгоритмы, чтобы его остудить будут приостанавливать те или иные процессы, на выбор контроллёра.

      discard в этом плане распределенный по времени механизм, без волнообразного эффекта в случае с fstrim

      +1

      В целом, очень хорошая и детальная инструкция. Но есть пара НО.


      По поводу discard на зашифрованных дисках стоит добавить, что это может снизить защищённость. Например, man crypttab содержит такое предупреждение по поводу опции discard:


      WARNING: Assess the specific security risks carefully before enabling this option. For example, allowing discards on encrypted devices may lead to the leak of information about the ciphertext device (filesystem type, used space etc.) if the discarded blocks can be located easily on the device later.

      И в целом, включать discard от балды не рекомендуется (не зная, как именно работает контроллер Вашего диска), потому что на некоторых типах дисков это может приводить к замедлению работы. По этой причине, например, в Debian (и в Ubuntu), начиная с какого-то времени, по умолчанию используется периодический TRIM вместо discard.

        0

        Спасибо за уточнение. В man crypttab я не обнаружил предупредждения для зашифрованных не корневых разделов, однако оно имеет место быть в man crypsetup. Вот оригинальный текст:


        --allow-discards
                Allow the use of discard (TRIM) requests for the device.  This option is only relevant for open action.  This is also not supported for LUKS2 devices with data integrity protection.
        
                WARNING: This command can have a negative security impact because it can make filesystem-level operations visible on the physical device. For example, information leaking filesystem type, used space, etc. may be extractable from the physical device if the discarded blocks can be located later. If in doubt, do not use it.

        Это предупреждение было в планах добавить в статью, но при публикации я это упустил. Сейчас статью обновил и добавил эту информацию.

        0
        Подскажите, как можно активировать TRIM на дисках (Samsung 850PRO, когда-то они попадали в blacklist ядра на выполнение TRIM), подключенных через контроллер SAS2008? В одно время заметили, что они значительно быстрее других моделей деградируют — и очень вероятно на это влияет отсутсвие TRIM и заполнение данными выше 85-90%. Переключить на SATA не вариант, большое количество дисков в jbod-массиве
          0
          Я не включил TRIM. Мне это упростит восстановление данных при сбое? Может лучше пожертвовать скоростью?
            +1

            Бэкап… Надо делать бэкап, а не шаманить восстанавливая данные.

              +1
              Если кратко, нет, вряд ли упростит.
              Современные контроллеры SSD умеют справляться и без TRIM. Отсюда, я так подозреваю, что они перетасовывают данные в любом случае, а это снижает вероятность успешного восстановления удалённых данных (я так понимаю, вас интересует именно такое восстановление).
                0

                Это смотря на каком уровне рассматривать восстановление. Если на уровне ячеек памяти — да, без разницы. А вот на уровне ФС — есть подозрение, что TRIM все-таки усложнит.

              0
              по sata ssd понятно, а что по NVMe ssd?
              нужен TRIM или нет?
              wiki.archlinux.org/index.php/Solid_state_drive/NVMe#Discards
              в арчвики пишут мол дискард не нужен, можно иногда делать fstrim но это советовал из всех только intel
                0
                Все то же самое, только в NVMe используется не SATA TRIM команда, а эквивалент «Deallocate». en.wikipedia.org/wiki/Trim_(computing)#NVM_Express
                0
                (deleted)
                  0
                  Отличная практическая статья, спасибо.
                    0
                    В Ubuntu автоматически включено через fstrim.timer.
                      +1
                      Спасибо за статью.

                      Немного дополню.
                      У меня Proxmox VE.
                      Для вкл. TRIM на ВМ:
                      — тип контроллера — Virtio-scsi\Virtio-scsi single;
                      — тип диска — scsi;
                      — в настройках диска ВМ стоит галка на Discard (+ галка на Эмуляция SSD, если диск ВМ располагается на SSD).

                      Эти настройки обязательны для любых ВМ и независимо от того на SSD или HDD «живут» ВМ-ы. Иначе блоки удаленных данных не будут очищаться и размер диска ВМ будет увеличиваться.

                      Only users with full accounts can post comments. Log in, please.