null

FreeBSD: swap на zvol

Существует большое количество различных how-to по использованию в качестве области страничного обмена на FreeBSD томов на ZFS. В большинстве из них рекомендуют отключать контрольные суммы. Но далеко не везде вспоминают про другие свойства тома, такие как размер блока и настройка кэширования.

С одной стороны, при создании тома ZFS по умолчанию устанавливается размер блока 8КБ, а на архитектурах i386 и amd64 обычно используется размер страницы равный 4КБ, что может отрицательно повлиять на производительность подсистемы страничного обмена.

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

Правильная команда для создания тома для области страничного обмена должна быть примерно такой:

zfs create -o org.freebsd:swap=on \
  -o volblocksize=4K \
  -o checksum=off \
  -o primarycache=metadata \
  -V 4G rpool/swap

Небольшой комментарий по поводу свойства org.freebsd:swap, про которое везде говорят, но не объясняют почему оно именно такое. В ZFS изначально не предусмотрено никаких специальных свойств для обозначения тома как области страничного обмена, и в Solaris она подключается используя традиционный /etc/vfstab. Разработчики FreeBSD вполне логично посчитали, что это не всегда удобно и было бы удобнее перенести это в свойства тома. ZFS предоставляет возможность создания определённых пользователем свойств, имена которых состоят из имени модуля и имени свойства, разделённых двоеточием. Именно пользовательские свойства и задействовали разрабочики FreeBSD, с одной стороны не внося изменений в сам ZFS и сохранив совместимость реализаций, с другой стороны избавив пользователя от необходимости указывать область обмена в /etc/fstab. Для подключения областей подкачки выполняется загрузочный скрипт /etc/rc.d/zvol, который ищет тома включенным свойством org.freebsd:swap, и выполняет для них swapon.

К сожалению ZFS не позволяет изменять размер блока у уже созданного тома. Если в системе уже создана и подключена область обмена с неправильным размером блока, можно пересоздать том следующим скриптом:

OPTS="-o org.freebsd:swap=on
  -o volblocksize=4K
  -o checksum=off
  -o primarycache=metadata"
DEV=/dev/zvol/

swapinfo | grep "^$DEV" | cut -d ' ' -f 1 | while read swap
do
  swapoff $swap
  zvol=`echo $swap | sed "s@^$DEV@@"`
  size=`zfs get -H -o value volsize $zvol`
  zfs destroy $zvol
  zfs create $OPTS -V $size $zvol
  swapon $swap
done

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

PS. Примечательно, что установщик Solaris при создании области страничного обмена всё делает правильно.

Коротко о себе:

Работаю в компании Tune-IT и тьютором кафедры Вычислительной техники в СПбГУИТМО.

Очень люблю команду cat, core solaris и IPv6.