<?xml version="1.0" encoding="utf-8"?> 
<rss version="2.0"
  xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
  xmlns:atom="http://www.w3.org/2005/Atom">

<channel>

<title>M9K blog: заметки с тегом ZFS</title>
<link>https://blog.m9k.space/tags/zfs/</link>
<description>Заметки обо всём: devops, lifestyle, культура.</description>
<author>M</author>
<language>ru</language>
<generator>E2 (v3877; Aegea)</generator>

<itunes:owner>
<itunes:name>M</itunes:name>
<itunes:email></itunes:email>
</itunes:owner>
<itunes:subtitle>Заметки обо всём: devops, lifestyle, культура.</itunes:subtitle>
<itunes:image href="" />
<itunes:explicit></itunes:explicit>

<item>
<title>Как временно расширить ZFS-пул с помощью zvol из другого пула</title>
<guid isPermaLink="false">228</guid>
<link>https://blog.m9k.space/all/kak-vremenno-rasshirit-zfs-pul-s-pomoschyu-zvol-iz-drugogo-pula/</link>
<pubDate>Tue, 21 Jul 2026 09:36:32 +0000</pubDate>
<author>M</author>
<comments>https://blog.m9k.space/all/kak-vremenno-rasshirit-zfs-pul-s-pomoschyu-zvol-iz-drugogo-pula/</comments>
<description>
&lt;p&gt;Иногда ZFS-пул оказывается заполнен почти полностью, но переносить данные на другой файловый раздел неудобно или слишком долго.&lt;/p&gt;
&lt;p&gt;Было два независимых пула:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;zpool list

NAME    SIZE  ALLOC   FREE  FRAG  CAP  HEALTH
db     11.7T  8.99T  2.71T   18%  76%  ONLINE
limon  79.5G  77.0G  2.46G   90%  96%  ONLINE&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Пул limon закончился, а в пуле db оставалось несколько терабайт свободного пространства.&lt;/p&gt;
&lt;p&gt;Требовалось временно дать пулу limon около 10 ГБ, очистить логи и затем вернуть конфигурацию в исходное состояние.&lt;/p&gt;
&lt;h3&gt;Почему нельзя просто передать свободное место?&lt;/h3&gt;
&lt;p&gt;Свободное пространство принадлежит конкретному ZFS-пулу. Датасет одного пула не может непосредственно использовать место из другого пула.&lt;/p&gt;
&lt;h3&gt;Топология исходного пула&lt;/h3&gt;
&lt;p&gt;Пул limon состоял из одного раздела:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;zpool status limon

pool: limon
state: ONLINE
config:

    NAME        STATE     READ WRITE CKSUM
    limon       ONLINE       0     0     0
      sdd1      ONLINE       0     0     0&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Для последующего удаления временного vdev необходимо проверить поддержку функции device_removal:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;zpool get feature@device_removal limon&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;В моём случае функция была включена:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;NAME   PROPERTY                VALUE    SOURCE
limon  feature@device_removal  enabled  local&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Также необходимо определить фактическое значение ashift существующего vdev.&lt;/p&gt;
&lt;p&gt;Команда:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;zpool get ashift limon&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;может показать:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;limon  ashift  0  default&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Значение 0 означает автоматический выбор для новых устройств и не показывает фактический ashift уже существующего vdev.&lt;/p&gt;
&lt;p&gt;Реальное значение можно получить через zdb:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;zdb -C limon | grep -E 'path|ashift'&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Результат:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;path: '/dev/sdd1'
phys_path: 'acpi-VMBUS:01-vmbus-3d4511ba2bac43a19298b9d3bddf7b27-lun-2'
ashift: 12&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Таким образом, временный vdev тоже нужно добавлять с ashift=12.&lt;/p&gt;
&lt;h3&gt;Важное предупреждение&lt;/h3&gt;
&lt;p&gt;Описанный способ создаёт зависимость одного ZFS-пула от другого.&lt;/p&gt;
&lt;p&gt;Пока временный zvol входит в пул limon:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;пул db нельзя экспортировать;&lt;/li&gt;
&lt;li&gt;zvol нельзя удалить;&lt;/li&gt;
&lt;li&gt;сервер нельзя загружать без доступного пула db;&lt;/li&gt;
&lt;li&gt;потеря пула db может привести к потере всего пула limon&lt;br /&gt;
Это аварийная временная мера, а не постоянная архитектура хранения.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Создание временного zvol&lt;/h3&gt;
&lt;p&gt;Чтобы не повторять изменяемые значения в командах, зададим переменные:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;POOL_SOURCE=&amp;quot;db&amp;quot;
POOL_TARGET=&amp;quot;limon&amp;quot;
ZVOL_NAME=&amp;quot;limon-temp-vdev&amp;quot;
ZVOL_SIZE=&amp;quot;10G&amp;quot;
ZVOL_DATASET=&amp;quot;${POOL_SOURCE}/${ZVOL_NAME}&amp;quot;
ZVOL_DEVICE=&amp;quot;/dev/zvol/${ZVOL_DATASET}&amp;quot;
ASHIFT=&amp;quot;12&amp;quot;
VOLBLOCKSIZE=&amp;quot;16K&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Создаём обычный, неразреженный zvol:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;zfs create -V &amp;quot;${ZVOL_SIZE}&amp;quot; -b &amp;quot;${VOLBLOCKSIZE}&amp;quot; -o compression=off &amp;quot;${ZVOL_DATASET}&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Проверяем созданный zvol:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;zfs get volsize,volblocksize,refreservation,compression &amp;quot;${ZVOL_DATASET}&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Проверяем наличие блочного устройства:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;udevadm settle
ls -l &amp;quot;${ZVOL_DEVICE}&amp;quot;
blockdev --getsize64 &amp;quot;${ZVOL_DEVICE}&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;У обычного zvol параметр refreservation должен быть примерно равен его размеру. Это гарантирует, что необходимые 10 ГБ действительно зарезервированы в пуле db.&lt;/p&gt;
&lt;h3&gt;Проверка добавления без изменения пула&lt;/h3&gt;
&lt;p&gt;Сначала выполняем пробный запуск:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;zpool add -n -o ashift=&amp;quot;${ASHIFT}&amp;quot; &amp;quot;${POOL_TARGET}&amp;quot; &amp;quot;${ZVOL_DEVICE}&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;В предполагаемой конфигурации исходный диск и временный zvol должны находиться на одном уровне:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;limon
sdd1
/dev/zvol/db/limon-temp-vdev&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Добавление временного пространства&lt;/h3&gt;
&lt;p&gt;Если пробная проверка не показывает ошибок, добавляем zvol:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;zpool add -o ashift=&amp;quot;${ASHIFT}&amp;quot; &amp;quot;${POOL_TARGET}&amp;quot; &amp;quot;${ZVOL_DEVICE}&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;После этого проверяем состояние:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;zpool status -P &amp;quot;${POOL_TARGET}&amp;quot;zpool list &amp;quot;${POOL_TARGET}&amp;quot;
zfs list &amp;quot;${POOL_TARGET}&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Дополнительно проверяем ashift обоих vdev:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;zdb -C &amp;quot;${POOL_TARGET}&amp;quot; | grep -E 'path|ashift'&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Оба top-level vdev должны иметь ashift=12. Разный ashift может помешать последующему удалению временного устройства.&lt;/p&gt;
&lt;p&gt;После добавления zvol пул limon получит немного меньше 10 ГБ полезного пространства из-за внутренних накладных расходов ZFS.&lt;/p&gt;
&lt;h3&gt;Удаление временного vdev&lt;/h3&gt;
&lt;p&gt;Сначала проверяем возможность удаления:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;zpool remove -n &amp;quot;${POOL_TARGET}&amp;quot; &amp;quot;${ZVOL_DEVICE}&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Параметр -n не выполняет полноценную симуляцию переноса данных. Он используется для оценки параметров операции, включая необходимый объём памяти для таблиц перенаправления.&lt;/p&gt;
&lt;p&gt;Если ошибок нет, запускаем удаление с ожиданием завершения:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;zpool remove -w &amp;quot;${POOL_TARGET}&amp;quot; &amp;quot;${ZVOL_DEVICE}&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Во время удаления ZFS переносит блоки с временного zvol обратно на исходный диск sdd1.&lt;/p&gt;
&lt;p&gt;За процессом можно наблюдать в другом терминале:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;watch -n 5 &amp;quot;zpool status ${POOL_TARGET}; zpool list ${POOL_TARGET}&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;До полного завершения операции нельзя:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;уничтожать zvol;&lt;/li&gt;
&lt;li&gt;экспортировать пул db;&lt;/li&gt;
&lt;li&gt;отключать устройство;&lt;/li&gt;
&lt;li&gt;перезагружать систему без необходимости.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;После успешного удаления проверяем, что в пуле остался только исходный vdev:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;zpool status -P &amp;quot;${POOL_TARGET}&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;В конфигурации должен снова отображаться только sdd1.&lt;/p&gt;
&lt;h3&gt;Удаление временного zvol&lt;/h3&gt;
&lt;p&gt;Только после успешного завершения zpool remove можно уничтожить zvol:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;zfs destroy &amp;quot;${ZVOL_DATASET}&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Финальная проверка:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;zpool status &amp;quot;${POOL_TARGET}&amp;quot;
zpool list &amp;quot;${POOL_TARGET}&amp;quot;
zfs list &amp;quot;${POOL_SOURCE}&amp;quot; &amp;quot;${POOL_TARGET}&amp;quot;&lt;/code&gt;&lt;/pre&gt;</description>
</item>

<item>
<title>ZFS на Oracle Linux 8.10</title>
<guid isPermaLink="false">181</guid>
<link>https://blog.m9k.space/all/zfs-na-oracle-linux-8-10/</link>
<pubDate>Thu, 06 Mar 2025 10:29:29 +0000</pubDate>
<author>M</author>
<comments>https://blog.m9k.space/all/zfs-na-oracle-linux-8-10/</comments>
<description>
&lt;p&gt;При установке ZFS на Oracle Linux 8.10 по официальной &lt;a href="https://openzfs.github.io/openzfs-docs/Getting%20Started/RHEL-based%20distro/index.html"&gt;доке&lt;/a&gt; столкнулся с неочевидной ошибкой:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;checking for kernel config option compatibility... done&lt;br /&gt;
checking whether CONFIG_MODULES is defined... no&lt;br /&gt;
configure: error:&lt;br /&gt;
		*** This kernel does not include the required loadable module&lt;br /&gt;
		*** support!&lt;br /&gt;
		***&lt;br /&gt;
		*** To build OpenZFS as a loadable Linux kernel module&lt;br /&gt;
		*** enable loadable module support by setting&lt;br /&gt;
		*** `CONFIG_MODULES=y` in the kernel configuration and run&lt;br /&gt;
		*** `make modules_prepare` in the Linux source tree.&lt;br /&gt;
		***&lt;br /&gt;
		*** If you don’t intend to enable loadable kernel module&lt;br /&gt;
		*** support, please compile OpenZFS as a Linux kernel built-in.&lt;br /&gt;
		***&lt;br /&gt;
		*** Prepare the Linux source tree by running `make prepare`,&lt;br /&gt;
		*** use the OpenZFS `—enable-linux-builtin` configure option,&lt;br /&gt;
		*** copy the OpenZFS sources into the Linux source tree using&lt;br /&gt;
		*** `./copy-builtin &lt;linux source directory&gt;`,&lt;br /&gt;
		*** set `CONFIG_ZFS=y` in the kernel configuration and compile&lt;br /&gt;
		*** kernel as usual.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Объяснение и решение проблемы нашёл &lt;a href="https://run.tournament.org.il/build-zfs-on-oel-with-uek7/"&gt;тут&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The root of the problem is with the GCC toolset used to build UEK7 kernel, which is different from the one used to build Redhat compatible version. RH kernel is built (using the default) GCC.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Решение:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;dnf install -y gcc-toolset-11-annobin-plugin-gcc
. /opt/rh/gcc-toolset-11/enable
dkms install zfs/$VERSION&lt;/code&gt;&lt;/pre&gt;</description>
</item>


</channel>
</rss>