Дополнение B, Архитектура программного обеспечения Stratis: Версия 2.0.0

Это дополнение является переводом с последними изменениями от 01/10/2020 из Документации Stratis.

Содержание

Дополнение B, Архитектура программного обеспечения Stratis
Часть I. Предпосылки
Постановка задачи
Цель: предоставить пользователям современные функции в более простой форме
План: реализовать гибридную Файловую систему управления томами
Требования
Часть II. Обзор решения
Введение
Stratis и стек хранения Linux
Концептуальная модель
Блочные устройства, пулы и файловые системы
Атрибуты и функциональные возможности пула
Вопросы масштабируемости и производительности
Часть III. Реализация
Компоненты программного обеспечения
Практика пользователей
Известные недостатки
Программный API D-Bus
Обзор
Управление доступом D-Bus
Политика безопасности
Предотвращение подделок
Запросы состояния stratisd через D-Bus
Внутреннее устройство
Требования Уровня Данных
Уровень Данных
Блочные устройства
Целостность (опционально)
Избыточность (опционально)
Гибкость
Динамичное выделение
Тонкие тома
Файловая система
Метаданные Уровня Данных
Требования
Соглашения
Обзор архитектуры
BlockDev Data Area (BDA)
Metadata Area (MDA)
Metadata Volume (MDV)
MDA и Очень большие пулы
Метаданные и восстановление
Уровень Кэширования
Требования
Методанные Уровня Кэширования
Шифрование
Подробности реализации
Инструментарий командной строки ’stratis’
stratisd
Имена device-mapper
Требования соглашения именования
Соглашения именования
Определения именования по уровням
Минимальная версия Имён device-mapper
Интеграция с ОС: Запуск и initrd
Интеграция с ОС: udev
Интеграция с ОС: записи /dev
Частичная активация пула
Моментальные снимки
Внутреннее устройство лежащего в основе хранилища
Выделения на основании потребности
API Общего уровня
Рабочие состояния
Состояния пула
Состояния расширения пула
Состояния пространства пула
Лицензирование
Часть IV. Дополнительные материалы
Первоначальные варианты адаптации существующих решений
Расширение имеющегося проекта
SSM
LVM2
Сборка поверх имеющегося проекта
XFS
device-mapper
LVM2
Выводы
Подробности реализации шифрования
Формат на диске
Формат маркера LUKS2
Формат метаданных шифрованного Stratis
Создание шифрованного диска
Обнаружение шифрованного диска
Активация шифрованного диска
Уничтожение шифрованного диска
Согласованность ключей для шифрованных пулов
Управление ключами

Обращение с вопросами и внесение изменений

Этот документ можно найти в репозитории stratis-docs, написанном с применением LYX 2.3.3. По любым вопросам и возникающим проблемам, будьте любезны обращаться на GitHub при помощи списка рассылки stratis-devel@lists.fedorahosted.org.

Основные положения

Stratis это новый инструментарий, который (среди прочих) отвечает потребностям пользователей Red Hat Enterprise Linux (RHEL), требующих просто настраиваемого, плотно интегрированного решения для хранения, которое работает в рамках имеющегося стека управления хранением Linux. Для достижения этого Stratis приоритетно уделяет внимание простой практике командной строки, богатому API и полностью автоматизированному, непрозрачному для внешних пользователей подходу к управлению хранением. Он с максимальной возможностью опирается на элементы уже существующего стека хранения для обеспечения доставки в 1- 2 года. В частности, изначально Stratis планирует применение device-mapper и файловой системы XFS, однако может включать в себя и прочие технологии.

Часть I. Предпосылки

Постановка задачи

За последние годы в Linux появилось большое число относящихся к хранению функциональных возможностей, на каждая из них требовала от самого пользователя управление настройкой таких возможностей многоуровневым манером путём добавлений. Подлинно новые и полезные свойства, такие как динамическое выделение, RAID и множественность путей для достижения окончательного результата зависят от правильной настройки множества разнообразных уровней через различные инструменты. Более того, поскольку инструмент настройки каждого уровня обладает лишь интерфейсом командной строки (CLI), всякий инструментарий управления верхнего уровня обязан выстраивать ввод и выполнять синтаксический разбор ориентированного на пользователя вывода для каждого из CLI таких уровней. Это приводит к пустой трате усилий и возможности ошибок, ибо всякий инструментарий верхнего уровня выстраивает свой собственный API для своих функциональных возможностей поверх CLI инструментов нижнего уровня.

Цель: предоставить пользователям современные функции в более простой форме

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

Однако в действительности имеется единственная конфигурация, способная работать в большинстве вариантов применения. Исходя из фиксированной многоуровневости функциональных возможностей хранения (причём, некоторые, возможно, не обязательны), мы предоставляем возможность действенного управления ими от имени самого пользователя программному обеспечению.

Тем самым, автоматическое управление снижает нагрузку администрирования на своего пользователя. Этот пользователь всё ещё определяет ресурсы, желаемые им функциональные свойства, а также результаты - какие аппаратные ресурсы применять, какие возможности включать, как должно представляться логически хранилище - применяя меньшее число понятий с хорошо определёнными взаимоотношениями. Программное обеспечение управляет всем остальным и обрабатывает бо́льшую часть проблем времени выполнения без вовлечения пользователя.

План: реализовать гибридную Файловую систему управления томами

За последний десяток лет VMF (volume-managing filesystems, файловые системы управления томами), например вошли в моду и приобрели почитателей такие как ZFS и Btrfs, после того как они были доступными лишь в прочих операционных системах на основе Unix. Они объединяют в неком едином инструментарии то, что могло бы обрабатываться множеством инструментов в традиционных Linux. Избыточность, динамическое выделение, управление томами и файловыми системами становятся функциональными возможностями в единой комплексной и согласованной системе конфигурации. В то время как традиционный стек хранения Linux выставляет самому пользователю возможность управления блочными устройствами, VMF скрывают всё это в неком пуле. Его пользователь помещает сырое устройство хранения в такой пул, в то время как VMF управляет своим хранилищем в этом пуле, предоставляя те функциональные возможности, которые пожелает сам пользователь и делает возможным для своего пользователя создавать файловые системы из общего пула не входя в детали реализации.

К сожалению, существующие VMF не так просто применять в корпоративных дистрибутивах Linux, подобных RHEL. ZFS не является вариантом, который может взять себе на борт RHEL по причине лицензирования, в отличии от Ubuntu. Btrfs не имеет проблем с лицензированием, однако сопровождение современной поддержки в ядрах корпоративного уровня создаёт сложности.

Исходя из многих лет усилий разработчиков, вложенных в эти два проекта, мы можем видеть, что написание VMF это трудоёмкая задача, отнимающая много времени. Мы также слышим запрос своих пользователей на такие функциональные возможности и простоту их применения.

Вместо написания с нуля новой VMF, Stratis предоставляет удовлетворение подобным VMF требованиям путём управления от имени пользователя уже существующими технологиями с тем, чтобы пользователи были способны управлять своими хранилищами при помощи понятий верхнего уровня, таких как "пул" и "файловая система" и при этом продолжая оставаться без забот относительно более сложных деталей под капотом.

Это к тому же возможность узнать о преимуществах и недостатках имеющихся решений. Нам не следует просто копировать ZFS. ZFS теперь исполнилось пятнадцать лет и сам ландшафт хранения изменился с момента её проектирования. Мы стремимся удовлетворить те же потребности, что и ZFS, но к тому же более тесно интегрируемся в современные решения управления хранения со всё возрастающей автоматизацией, которые охватывают как центр обработки данных, так и локальную машину. Это стало возможным благодаря гибридному подходу, основанном на пространстве пользователя.

Требования

  1. Упрощение функциональных возможностей для применения их в сочетании друг с другом: динамического выделения, целостности, избыточности, множественности путей, шифрования, перенастройки оборудования, мониторинга и некого уровня кэширования.

  2. Простой и выразительный интерфейс командной строки

    1. Простой

      1. Единственный способ выполнения необходимого

      2. Без выставления вовне подробностей внутренней реализации. Предоставление Stratis больше свободы реализации, причём с меньшей стоимостью, так как внутренний компоненты чересчур сложны для практичного выполнения вручную восстановления

      3. Как правило, не применяется пользователем на ежедневной основе

        1. Непротиворечивые команды, которые может представить себе пользователь, скорее всего, окажутся верными

        2. Требование в явном виде от своего пользователя операций в явном виде для тех, которые потенциально приводят к утрате данных, например, задание параметра "force"

    2. Всеобъемлемость

      1. Пользователь обязан быть господином лишь одного инструмента

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

  3. Нейтральный к языкам программирования программный API для интеграции инструмента управления верхнего уровня

    1. Ясный последующий шаг для пользователей после того как они столкнутся с ограничениями в написании сценариев CLI

    2. Поощрение тесной интеграции и применения всех функциональных возможностей инструментарием верхнего уровня

  4. Движимые событиями мониторинг и предупреждения

    1. Простые понятия, выраженные в видимых пользователю терминах Stratis сообщения мониторинга и предупреждений вместо подробностей реализации

    2. Низкие накладные расходы ЦПУ/ памяти для мониторинга

    3. Всего лишь предупреждение в случае необходимости действия

    4. В случае оставленных без внимания предупреждений аккуратное завершение работы

  5. Устранение изменения вручную размера файловых систем

    1. Большое число отчётов о проблемах на протяжении многих лет указывает что изменение размера файловых систем это некая область, в которой пользователи испытывают беспокойство по причине потенциальной потери данных в случае совершения ошибки. Нет вообще реальной причины требовать самого пользователя выполнять это.

    2. Это упрощает жизнь DevOps

    3. Превращает хранилище в "выделяемое по запросу", аналогично виртуальной памяти. Современные технологии делают для нас возможным управлять ростом или снижением (динамичное выделение) реального потребления файловой системы.

  6. Совместимость с Initrd

    1. Допускает для использования Stratis root fs, всех прочих файловых систем за исключением /boot. Это необходимо для простоты применения

    2. Ограниченная среда - никаких Python или DBus - однако может применять device-mapper

  7. Готовая к запуску системы (планируется - см ??)

    1. Когда для запуска не требуется никакая вторичная файловая система, ощущается как "настоящая" файловая система

    2. Делает возможным применение образом системы функциональных возможностей Stratis, т.е. запуск из моментального снимка и допуская рост /boot

    3. Требует поддержки в явном виде от начального загрузчика (Grub2)

    4. device-mapper не доступен

  8. Приспособление к появляющимся технологиям хранения

    1. Энергонезависимая память

      1. Stratis способен применять pmem с блочным отображением

      2. Байт- адресуемый pmem см. ??

  9. Реализуется за 1- 2 года

    1. Мы уже отстали - ждать 10 лет - не вариант

Часть II. Обзор решения

Введение

Stratis это решение локального хранения, которое делает возможным множеству логических файловых систем совместно использовать некий пул хранения, который выделяется из одного или более блочных устройств. Вместо подхода целиком из ядра, подобного ZFS или Btrfs, Stratis применяет гибридный подход пространства пользователя/ ядра, который собирается поверх имеющихся блочных возможностей, таких как device-mapper, существующие возможности файловых систем, таких как XFS, а также демона пространства пользователя для мониторинга и управления.

Основная цель Stratis состоит в предоставлении собственно понятийной простоты файловых систем управления томами и обгон их в таких областях как мониторинг и уведомления, автоматическая перенастройка и интеграция с инфраструктурами управления хранением верхнего уровня.

Stratis и стек хранения Linux

Stratis упрощает многие стороны предоставления и настройки локального хранилища. Это, совместно с его API, позволило бы намного упростить проекты, зависящие от настройки локального хранилища.

Например, установку необходимой ОС в пул Stratis при помощи Anaconda. После выбора необходимых дисков для использования в таком пуле, самым первым преимуществом имелась бы возможность пропуска всего сложного потока относительно изменения размера файловых систем. Затем, поскольку Stratis обладает неким API, Anaconda способна применять его напрямую, вместо потребности в работе с Blivet для построения некого API поверх инструментов командной строки.

Прочие инструменты управления, такие как Cockpit, продукты виртуализации подобные RHEV или контейнерные продукты навроде Atomic обнаружат его более простым и менее подверженным ошибкам для использования хранилища и моментальных снимков при помощи Stratis, причём для тех же самых причин: нет нужды беспокоиться относительно установления размеров по файловым системам (только того что сам пул обладает достаточным "лежащим в основе хранилище"); а также имеющегося API, который делает возможной интеграцию между инструментами, нежели использования программирования CLI.

 

Рисунок B-1


Будущее положение Stratis в стеке управления хранилищами Linux

Существуют библиотеки, которые обрабатывают интерфейс командной строки к API как для Anaconda, так и для Cockpit. Они могут быть расширены или нет для поддержки Stratis.

Концептуальная модель

Блочные устройства, пулы и файловые системы

Концептуальная модель Stratis составлена из блочных устройств, пулов и файловых систем. Некий пул создаётся из одного или более блочных устройств (blockdevs), а далее из полученного пула создаются файловые системы. Файловые системы это монтируемые иерархические собрания файлов, которым по мере необходимости выделяется лежащее в основе хранилище из пула. Основное ключевое отличие между файловой системы Stratis и обыкновенной файловой системой Unix состоит в том, что изменение размера и сопровождение файловой системы Stratis не управляется её пользователем, а вместо этого самой Stratis.

 

Рисунок B-2


Архитектура Stratis

Атрибуты и функциональные возможности пула

Некий пул создаётся при помощи некого первоначального набора из одного или более блочных устройств. Блочные устройства также могут добавляться и после создания такого пула. Со временем блочные устройства также могут удаляться из пул если выполнены определённые приготовления и условия. Такой пул первичной коллекции блочных устройств носит название уровня данных (data tier).

Как вариант, пул также обладает уровнем кэширования (cache tier), который применяет отдельный набор более быстрых блочных устройств для улучшения производительности вместо увеличения ёмкости общего пула.

Оба пула обладают своим собственным независимым уровнем избыточности данных, которыми могут быть none, raid1, raid5, raid6 или raid10 (значение по умолчанию none).

Поскольку отдельная система может обладать множеством пулов, каждый пул имеет некое название, как это сделано и у каждой файловой системы внутри пула. Они оба назначаются самим пользователем. Блочные устройства, пулы и файловые системы также обладают UUID, которые не устанавливаются их пользователем.

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

Некая новая файловая система это либо некая новая пустая файловая система или моментальный снимок какой- то имеющейся файловой системы внутри пула. В настоящее время Stratis не различает моментальные снимки и файловые системы (это может измениться.)

Вопросы масштабируемости и производительности

Stratis не оптимизирует производительность внутри своего уровня данных, вместо уделяет внимание гибкости и целостности. Улучшение производительности является заданием для уровня кэширования или, возможно, сборки пула с применением блочных устройств с более высокими IOPS, например, SSD.

Часть III. Реализация

Компоненты программного обеспечения

Startis составлен из инструмента командной строки, stratis и службы, stratisd.

stratis реализует интерфейс командной строки и преобразует команды в вызовы API D-Bus в stratisd

stratisd реализует необходимый интерфейс D-Bus, а также выполняет управлением и мониторингом блочных устройств внутреннего пула Stratis, как это описывается ниже. Он запускается самой системой и продолжает выполняться пока пулы Stratis или блочные устройства представлены в его системе.

stratisd включает в себя некий механизм эмуляции. Этот механизм симулятора полностью вычислительный, однако не оказывает воздействия на свою среду, хотя он выполняет взаимодействие поверх D-Bus.

Рисунок 2 отображает базовую архитектуру Stratis.

Практика пользователей

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

Для получения самого последнего состояния архитектуры CLI обращайтесь к https://github.com/stratis-storage/stratis-cli.

Этот компонент не требует его установки в тех ситуациях, когда имелось некое приложение верхнего уровня, например, Cockpit или Ansible применяющие напрямую API D-Bus.

Известные недостатки

Цель Stratis состоит в сокрытии имеющейся сложности его реализации от своего пользователя, а вместо этого применя подход повторного применения/ множества уровней для своей реализации, будут иметься места, куда можно заглянуть относительно подробностей реализации Stratis. Это способно вызывать путаницу у пользователя, а также ставить под угрозу целостность Stratisпри внесении изменений его пользователем.

  • Для файловых систем Stratis 'df' будет выдавать в отчёте значения размеров используемого и свободного пространств, как они наблюдаются и выдаются в отчёте XFS. Это не является полезными сведениями, потому как значение реального использования его файловой системы будет меньше по причине динамического выделения, а также по причине того, что Stratis будет автоматически наращивать файловую систему по мере приближения к текущему размеру ёмкости XFS.

  • Пользователям не следует предпринимать попытки повторного форматирования или повторной настройки файловых систем XFS, которыми управляет Stratis. Stratis не обладает возможностями принудительного применения этого или выдавать предупреждения об избежании таких действий, кроме как указывать на это в своей документации.

  • Stratis будет применять большое число устройств device-mapper, которые будут перечисляться в списке 'dmsetup' и в /proc/partitions. Аналогично, вывод 'lsblk' в системе Stratis бужет отражать внутренние исполнения и уровни Stratis.

  • Stratis требует некого демона пространства пользователя, который обязан оставаться запущенным всё время для надлежащего мониторинга и сопровождения пула.

Программный API D-Bus

Устанавливаемый процесс службы Stratis выставляет некий интерфейс D-Bus для интеграции поддержки Stratis со стороны прочих программ. Он рассматривается как первичный интерфейс Stratis. Имеющийся инструмент командной строки применяет этот API D-Bus.

Обзор

API D-Bus выступает частью stratisd. Это некий тонкий уровень, который получает сообщения по имеющейся шине D-Bus, обрабатывает их, передаёт их в установленный механизм Stratis, получать результаты от такого механизма и возвращать эти результаты вызывающей стороне данного API. При обработке вызовов метода, его ответственность ограничена:

  • Получением параметров и проверки того что они удовлетворяют значению подписи вызывавшего метода.

  • Передаёт параметры метода, полученные в установленной D-Bus в аргументы соответствующего типа для передачи в методы механизма.

  • Преобразует кортежи параметров, применяемых для представления не обязательных параметров в значения, которые наполняют тип Rust Option.

  • Вызывает соответствующие методы механизма и перехватывает их внутренние значения.

  • Выстраивает соответствующие возвращённые значения для размещения в имеющейся D-Bus совместно с кодом возврата и сообщением.

  • Добавлять или удалять объекты из дерева D-Bus.

API D-Bus реализуется при помощи библиотеки dbus-rs. Описание соответствующего API содержится в D-Bus API Reference Manual Stratisd.

Управление доступом D-Bus

 

Политика безопасности

Большинство методов D-Bus stratisd требуют полномочий root. Тем не менее, это не касается перечисления действий; оно может выполняться пользователем без привилегий. Значения устанавливаемых по умолчанию полномочий определяются в соответствующем файле политик, stratisd.conf, включённом в дистрибутив stratisd. Эти значения по умолчанию допускают любые действия пользователями root, но ограничивают пользователей без привилегий действиями только на чтение. Системные администраторы имеют возможность регулировать полномочия изменяя соответствующие файлы политик D-Bus stratisd.

 

Предотвращение подделок

 

Запросы состояния stratisd через D-Bus

stratisd выставляет интерфейс отчётов, который позволяет пользователям опрашивать значение состояния внутренних структур данных stratisd для составления отчётов об отладке и ошибках. Такой запрос D-Bus возвращает некую строку JSON, с которой можно провести синтаксический разбор для выявления состояния программным образом; тем не менее, имеющийся интерфейс отчётов не стабилен, а вследствие этого значения предоставляемых отчётами имён и схем не следуют семантическим правилам управления версиями, которым соответствуют остальной API stratisd.

Внутреннее устройство

Внутреннее устройство Stratis обязано быть непрозрачным его пользователю. Это делает возможным для его реализации выполнять всё что необходимо Stratis версии 1, а также выполнять расширения в последующих версиях без нарушения каких бы то ни было ожиданий пользователей.

Требования уровня данных

Уровень данных Stratis обязан управлять блочными устройствами от имени соответствующего пользователя для предоставления следующего:

  1. Управление файловыми системами, которые потребляют лишь столько пространства, сколько содержат их файлы.

  2. Быстрые моментальные снимки имеющихся файловых систем.

  3. Возможность добавления (и в конечном счёте удаления) индивидуальных блочных устройств для роста размера доступного для файловых систем доступного пространства.

  4. Выбираемый пользователем уровень избыточности (с грануляцией на уровне пулов) {в последующих версиях}

  5. Проверка целостности {в последующих версиях}

  6. Шифрование

Уровень Данных

Собственно уровень данных достигает этих требований выстраиванием уровней устройств device-mapper (DM) поверх имеющихся блочных устройств пула. Самый верхний уровень состоит из тонких устройств, выделяемых из тонкого пула. Stratis инициализирует такие тонкие устройства с некой файловой системой и управляет устройствами DM и файловыми системами для удовлетворения вышеупомянутым требованиям.

 

Блочные устройства

Этот уровень отвечает за обнаружение имеющихся в пуле блочных устройств, инициализации и однозначного выставлении меток новых блочных устройств в качестве части пула, установки всех относящихся к диску параметров и хранения метаданных пула для каждого блочного устройства. В качестве минимального блочного устройства Stratis принимается 1GiB. Блочные устройства могут подвергаться шифрованию и дешифрации. Относительно реализации шифрования обратитесь к разделу Шифрование.

 

Целостность (опционально) {в последующих версиях}

Данный уровень применяет соответствующую цель целостности DM для включения выявления неверных данных, которые он считывает при помощи дополнительного пространства для записи соответствующих результатов функций контрольных сумм/ кэширования в своих блоках данных с последующим сопоставлением получаемых результатов от тех блочных устройств, которые они возвращают Это сделает возможным для Sratis выявлять разрушение данных при отсутствии избыточности пула и восстанавливать такое разрушение в случае присутствия избыточности пула. В случае когда такие сведения присутствуют, должно быть также возможным их получение при помощи DF.

 

Избыточность (опционально) {в последующих версиях}

Пул Stratis может быть в случае необходимости настроен на разброс данных по множеству физических дисков с тем, чтобы факт утраты каждого из дисков не приводил к утрате данных. Startis применяет обычные RAID технологии (1, 5, 6, 10, 1E - доп. сведения), как они и предписаны, а также преобразовывает блочные устройства 0 Уровня в некое число хранилищ с меньшим размером с заданными свойствами raid.

Поскольку Stratis поддерживает бо́льшее число блочных устройств, нежели на это способны устройства RAID (как правило, наилучшим для набора raid числом является не более 8 - DM поддерживает и бо́льшее число блочных устройств, однако слишком большое их число увеличивает вероятность индивидуальных отказов), причём с блочными устройствами различного размера, и при этом пул Startis способен содержать множество наборов raid (все с одним и тем же глобальным типом). В зависимости от схемы в блочных устройствах пула может иметься некий объём пространства, который не может применяться, ибо он не способен использоваться в наборе RAID. Stratis интенсивно управляет наборами raid, расширяя их на вновь добавляемые блочные устройства или создавая новые наборы raid; а также выполняя обработку удаляемых блочных устройств {в последующих версиях}. Stratis способен, когда это возможно, пользоваться способностями изменения формы dm raid, хотя это изменяет размеры полос и может вызывать проблемы.

Stratis не поддерживает избыточность для единственного диска, однако у нас имеется возможность резервирования небольшого пространства для метаданных raid и прочего применения даже в пулах Stratis с единственным диском. Это позволит соответствующему пулу быть выполненым с избыточностью (в той версии, которая поддерживает это) не сталкиваясь с уродливыми крайними ситуациями.

 

Гибкость

Будут ли блочные устройства частью набора raid или применяться напрямую, пулы обязаны справляться с их добавлением или удалением {в последующих версиях}.

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

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

Пометка некого вновь добавляемого диска в качестве ‘spare’ (запасного) оставит его в резерве с тем, чтобы имелась возможность немедленного удаления и замены отказавшего диска без возможного превышения общего размера пула на это время.

Уровень гибкости содержит четыре линейных устройства DM, выполненных из сегментов устройств нижнего уровня. Первые два устройства будут применяться Уровнем 4 (Динамичного выделения) в качестве устройств метаданных и данных. Этот уровень гибкости будет отслеживать из каких устройств нижнего уровня выполнены эти выделения и делает возможным рост этих двух устройств по мере необходимости.

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

Четвёртое, и последнее линейное устройство DM используется под Том метаданных (MDV, Metadata Volume) этот том применяется для хранения метаданных о верхних уровнях, уровне 5 и выше.

Все устройства на этом уровне могут собираться из устройств L0, L1, L2, в зависимости от конфигурации.

Значения первоначальных размеров всех устройств уровня гибкости следует выбирать с тем, чтобы позволять пулу целиком умещаться внутри отдельного блочного устройства минимального размера (1 GiB).

 

Динамичное выделение

Под некое устройство DM тонкого пула в качестве устройств метаданных и данных используются два соответствующих целевых из L3. Такие устройства тонкого пула реализуют алгоритм копирования записью (CoW, copy-on-write) с тем, чтобы блоки в этом блочном устройстве выделялись только по мере необходимости под основу своих динамично выделяемых томов из своего тонкого пула.

Stratis управляет своими устройствами тонкого пула расширяя имеющиеся два подустройства L3 когда какое- то из них исчерпывает доступные блоки. Когда пул приближается к тому моменту, когда он более не обладает пустым пространством нижнего уровня для расширения, Stratis выдаёт предупреждение своему пользователю и предпринимает действия для предупреждения разрушений. Действия могут включать в себя переключение файловых систем в режим доступа исключительно на чтение, запуск fstrim или прогрессивного дросселирования записи.

 

Тонкие тома

Stratis создаёт тонкие тома из своего тонкого пула (пула динамичного выделения). Он будет автоматически предоставлять некий новый том с установленными по умолчанию размером, форматированной в нём файловой системой и делая его доступным для соответствующего пользователя.

Stratis также допускает создание некого нового тома в качестве моментального снимка какого- то имеющегося тома для чтения/ записи. Хотя лежащая в основе реализация не требует поддержки первичного соотнесения между моментальным снимком и его оригиналом, Startis записывает в своих метаданных это соотнесение. Такая связь может использоваться пользователями которые способны, к примеру, применять моментальные снимки для резервного копирования и могут пользоваться значением первоначальных сведений для идентификации определённой резервной копии моментального снимка под восстановление с него.

 

Файловая система

Startis отслеживает все использования файловых систем на предмет их ёмкости и автоматически расширяет их вреальном масштабе времени без вмешательства пользователя. Расширение включает в себя изменение значения логического размера тонкого устройства с последующим применением подобного xfs_growfs инструмента для роста его файловой системы. Startis также периодически запускает fstrim для возврата не используемого пространства с некой периодичностью. Периоды простоя будут обнаруживаться на основании текущих и исторических уровней активности системного ввода/ вывода.

Метаданные Уровня Данных

Stratis должен отслеживать свои блочные устройства, которые составляют собственно уровень данных его пула (L0), параметры целостности (L1), имеющиеся наборы raid, которые созданы из его блочных устройств данных (L2), установленное дерево линейных целей, которое разбросано по соответствующим устройствам L2 (L3), выставленные устройства тонкого пула - пула динамичного выделения (L4), а также значения атрибутов его тонких устройств (L5) и созданных из этого пула динамичного выделения файловых систем (L7).

 

Требования

  1. Уникальность идентификации блочных устройств по мере их применения Stratis, того, участниками какого пула они выступают и параметров, которые требуются для повторного создания всех уровней

  2. Выявление неполных и нарушенных метаданных и восстановление через вторичную копию

  3. Сделать возможным расширение блочных устройств под Stratis

  4. Избыточность в каждом блочном устройстве для невосприимчивости к не считываемым секторам (Также рассматривалась возможность восстановления случайного перекрытия записей начала блочного устройства через размещение второй копии в конце самого блочного устройства, но это приводило к иным проблемам, которые перевешивали получаемые преимущества)

  5. Избыточность по блочным устройствам для отработки утраченных или разрушившихся участников. Способна предоставлять метаданные утраченных блочных устройств

  6. Обработку тысячи и более блочных устройств в пуле

  7. Обработку миллиона и более файловых систем в пуле и обновление без записи в каждое блочное устройство

  8. Расширяемый/ обновляемый формат метаданных

 

Соглашения

Секторы составляют в длину 512 байт (Исторически, это минимальная единица хранения на жёстком диске. Многие API Linux предполагают, что это значение является постоянным - что предполагается и в данном документе - а также применяют иной термин, например 'размер блока' для работы в той ситуации, когда зачение минимального элемента хранения отличается от него)

Все UUID записываются как ASCII кодированные без дефисов в их шестнадцатеричном представлении в нижнем регистре (UUID являют собой 128- битные значения, а потому для их числового представления требуется лишь 16 байт. Однако, поскольку всякое значение ASCII требует байт, получаемое шестнадцатеричное представление некого 128- битного значения требует 32 шестнадцатеричных цифр, следовательно, выбранный способ кодирования требует 32 байт.)

 

Обзор архитектуры

Метаданные Stratis находятся в трёх местах:

  1. Области данных блочного устройства (BDA, Blockdev Data Area)

    1. Блок подписи внутри Статического заголовка

    2. Область метаданных (MDA, Metadata Area)

  2. Том метаданных (MDV, Metadata Volume)

(Особенные цели DM, такие как raid, целостность и пул динамичного выделения - тонкий пул также помещают на диск свои собственные метаданные)

Сведения на уровнях 0 - 4 дублируются по всем блочным устройствам в рамках некоторого формата метаданных на диске под названием BDA (Blockdev Data Area, Область данных блочного устройства). Такая BDA составляется из двоичного Блока подписи и соответствующей MDA (Metadata Area, Области метаданных), которая хранит сведения в текстовом формате JSON. И двоичная, и основанная на тексте части самой BDA определяют измерения избыточности и проверки целостности.

Соответствующий MDV (Metadata Volume, Том метаданных) хранит метаданные 5 Уровня и выше в обычном блочном устройстве и файловой системе, которые выступают частью Уровня гибкости. Выбор расщепления общего хранилища метаданных на две схемы делает возможным более верхним уровням освобождаться от ограничений, которые применялись бы при использовании единой схемы. Например, форматам метаданных на диском трудно поддерживать расширение размера времени исполнения, они способны хранить избыточные копии для обеспечения надёжности и активно проверять наличие повреждений. Это может хорошо работать при малых объёмах данных, которые изменяются не часто, однако по мере роста данных возникают проблемы или же мы пожелаем выполнять изменения по месту хранения.

Метаданные верхнего уровня способны достигать избыточности и целостности опираясь на соответствующих предварительно имеющиеся нижние уровни и работать с более слабыми ограничениями в отношении обновлений по месту хранения и значения общего размера, до которого они способны увеличиваться. Они могут повторно применять имеющиеся, хорошо проверенные подходы для решения организации данных и задач хранения - файловых систем общего назначения.

 

BlockDev Data Area (BDA)

 

Рисунок B-3


Формат BDA

Собственно Области данных блочного устройства (BDA, BlockDev Data Area) составлена из шестнадцати секторов Статичного заголовка фиксированной длины, содержащего две копии значения Блока подписи (Signature Block), а также Области метаданных (MDA, metadata area), длина которой определяется в его Блоке подписи. Она записана в самом начале своего блочного устройства, как это описывается ниже.

Startis резервирует первые 16 секторов каждого блочного устройства под такой Статический заголовок. При инициализации или изменении Блока подписи по местоположениям 1 и 2 записываются идентичные данные.

Таблица B-1. Статичный заголовок
смещение сектора длина (в секторах) содержимое

0

1

Не используется

1

1

Место Блока подписи 1

2

7

Не используется

9

1

Место Блока подписи 2

10

6

Не используется

Таблица B-2. Блок подписи
байт смещения длина (в байтах) описание

0

4

CRC32C IEEE Блока подписи (байты со смещения 4 длиной 508 байт)

4

16

Подпись Stratis: ’!Stra0tis\x86\xff\x02^\x41rh’

20

8

Размер устройства в 512-байтных секторах (u64) {232768}

28

1

Версия Блока подписи (u8) (значение = 1)

29

3

Не используется

32

32

UUID самого пула Stratis

64

32

UUID этого блочного устройства

96

8

длина сектора области метаданных блочного устройства (MDA) (u64)

104

8

длина сектора резервного пространства (u64)

112

8

флаги (u64)

120

8

время инициализации: метка времени UNIX (секунды, исчисленные от 1 января 1970) с применением UTC (u64)

128

384

Не используется

  • Никакие флаги пока не определены, а потому поле флагов (’flags’) заполнено нулями.

  • Все не используемые поля (’unused’) заполнены нулями и зарезервированы под дальнейшее использование.

  • Когда область метаданных (MDA) блочного устройства не нулевая, её длина (по смещению 96) должна быть числом, кратным четырём и по крайней мере 2032.

  • Значение BDA непосредственно следует за зарезервированным пространством, размер которого определяется в Блоке подписи (по смещению 104).

  • Минимальная длина BDA (статический заголовок MDA) плюс Зарезервированное пространство составляют 2048 секторов (1 MiB).

  • Когда блочное устройство удаляется из пула, или имеется разрушенной часть пула, Stratis затирает Статический заголовок.

  • Основная цель неиспользуемых секторов состоит в удвоении. Прежде всего, помещение места надлежащей копии Блока подписи в двух отдельных 4k блоков способствует предотвращению одной неверной операции в дисках с 4k блоками от разрушения обеих копий. Далее, использование отдельного сектора под Блок подписи помогает минимизировать значение вероятности разрушений на дисках с блоками в 512 байт.

  • Всякий раз, когда Stratis производит запись в одно или оба места Блока подписи, он также заполняет нулями все остающиеся не используемыми секторы, которые совместно используют тот же самый блок 4k.

Сама MDA делится на четыре зоны (region) одинакового размера с номерами 0-3. При обновлении метаданных, идентичные данные записываются либо в нечётные (1 и 3), либо в чётные (0 и 2) зоны, которые выбираются по опросу значения временной метки и перезаписываются значением более старых пар.

Обновление каждой зоны составляется из Заголовка зоны MDA фиксированной длины, за которым следуют JSON данные переменной длины.

Таблица B-3. Заголовок зоны MDA
байт смещения длина (в байтах) описание

0

4

CRC32C IEEE, покрывающий остаток заголовка MDA

4

4

CRC32C IEEE, покрывающий данные JSON

8

8

Длина данных JSON в байтах (u64)

16

8

Временная метка UNIX (секунды, отсчитываемые с 1 января 1970) с применением UTC (u64)

24

4

наносекунды

28

1

Версия Заголовка зоны (u8) (значение = 1)

29

1

Версия Метаданных переменной длины (u8) (значение = 1)

30

2

Не используется

32

изменяемая

данные JSON

  • Обновления метаданных записываются в более старую из нечётной или чётной зон MDA. Это определяется наименьшей временной меткой и далее наименьшими наносекундами, когда временные метки равны.

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

  • Сама процедура для обновления метаданных следующая:

    1. Определить какие именно зоны в имеющейся MDA (нечётные или чётные) использовать, как это предписано выше.

    2. Записать заголовок MDA и данные JSON в первую зону MDA (0 или 1).

    3. Выполнить Flush/FUA.

    4. Выполнить запись заголовка MDA и данных JSON во вторую зону MDA (2 или 3).

    5. Выполнить Flush/FUA.

    6. Повторить для дополнительных блочных устройств. Также изучите раздел MDA и Очень большие пулы.

  • Подлежащие обновлению множество блочных устройств с одними и теми же метаданными должны записывать идентичные данные во все зоны MDA, однако какие зоны (нечётные или чётные) применяются, может разниться когда сами блочные устройства получают со временем отличающиеся числа обновлений метаданных.

 

Metadata Area (MDA)

Собственно MDA содержит объект JSON, которая представляет общую конфигурацию своего пула с L0 по L4.

Таблица B-4. Объекты верхнего уровня:
ключ тип JSON необходим описание

name

string

да

значение название представляемого пула

backstore

object

да

конкретные блочные устройства в этом пуле

flex_devs

object

да

схема всех линейных устройств данных и метаданных

thinpool_dev

object

да

параметры имеющихся устройств пула динамического размещения

Таблица B-5. backstore: описывающий уровень данных и уровень кэша объект
ключ тип JSON необходим описание

data_tier

object

да

конкретные блочные устройства в этом уровне данных

cap

object

да

заглавное устройство, из которого сегменты выделяются в соответствующий гибкий уровень

cache_tier

object

нет

конкретные блочные устройства в имеющемся уровне кэширования

Таблица B-6. data_tier: описывающий уровень данных объект
ключ тип JSON необходим описание

blockdev

object

да

настройки и соответствия, описывающие составвляющие данный уровень блочные устройства

integrity

object

нет

настройки и соответствия TBD, относящиеся к поддержке целостности

raid

object

нет

настройки и соответствия TBD, относящиеся к поддержке избыточности (RAID)

vdo

object

нет

настройки и соответствия TBD, связанные с VDO

Таблица B-7. blockdev: описывающий составляющие соответствующий уровень физические блочные устройства объект
ключ тип JSON необходим описание

devs

array

да

массив объектов base_block_dev

base_block_dev

array

да

массив массивов объектов base_dev

Таблица B-8. base_dev: описывающий размещения их блочного устройства объект
ключ тип JSON необходим описание

parent

string

да

UUID устройства, из которого создаётся данный сегмент

start

integer

да

смещение стартового сектора внутри его родительского устройства

length

integer

да

длина в секторах данного сегмента

Таблица B-9. base_block_dev: описывающий на самом нижнем уровне блочное устройство объект
ключ тип JSON необходим описание

uuid

string

да

UUID данного блочного устройства, как он записан в Блоке подписи

user_info

string

нет

предоставляемые пользователем сведения для отслеживания этого устройства

hardware_info

string

нет

уникальные идентификационные сведения для данного блочного устройства, например, SCSI VPD83 или серийный номер

Таблица B-10. integrity: настройки и соответствия (TBD), относящиеся к поддержке целостности
raid: настройки и соответствия (TBD), относящиеся к поддержке RAID
vdo: настройки и соответствия (TBD), связанные с VDO.
cap: описывающий представление линейного устройства верхнего уровня объект, предоставляемый лежащим в основе хранилищем в уровень гибкости
ключ тип JSON необходим описание

allocs

array

да

массив пар целых, представляющих смещения старта и длины размещения в секторах

Таблица B-11. cache_tier: Описывающий уровень кэширования объект. Идентичен формату data_tier, за исключением того, что уровень VDO не поддерживается
flex_devs: объект с четырьмя ключами, который задаёт те линейные сегменты, которе составляют всякое устройство на уровне гибкости
ключ тип JSON необходим описание

meta_dev

array

да

массив пар целых, представляющих смещения старта и длины размещения в секторах, которые составляют соответствующий том метаданных (MDV)

thin_meta_dev

array

да

массив пар целых, представляющих смещения старта и длины размещения в секторах, которые составляют соответствующее тонкое устройство метаданных

thin_meta_dev_spare

array

да

массив пар целых, представляющих смещения старта и длины размещения в секторах, которые составляют соответствующее запасное тонкое устройство метаданных

thin_data_dev

array

да

массив пар целых, представляющих смещения старта и длины размещения в секторах, которые составляют соответствующее тонкое устройство данных

Таблица B-12. thinpool_dev: Объект, определяющий свойства соответствующего устройства динамично выделяемого пула
ключ тип JSON необходим описание

data_block_size

integer

да

Значение размера в секторах соответствующего блока данных линамично выделяемого пула

 

Metadata Volume (MDV)

Тома метаданных форматируются с файловой системой XFS, которая используется Stratis для хранения сведений создаваемых пользователем динамично выделяемых (тонких) файловых систем (L5 - L7). Эти сведения хранятся в самой файловой системе в неком формате TBD, причём, может быть в некой индивидуальной схеме на основе файлов, или базы данных SQLite.

 

MDA и Очень большие пулы

Пулы Stratis с очень большим числом блочных устройств будут испытывать две проблемы. Во- первых, обновление имеющихся метаданных во всех блочных устройствах в их пуле способно преарвтиться в узкое место. Во- вторых, значение установленного по умолчанию размера MDA может превратиться неудовлетворительное для содержания необходимых сведений.

Для решения первой из проблем Stratis ограничивает общее число тех блочных устройств, которые получают обновляемые сведения метаданных. Разумное ограничение для такого числа может располагаться в диапазоне от 6 до 10 и следует распространять обновления по блочным устройствам с независимыми путями, когда их можно обнаружить, либо случайным образом. Это ограничивает чрезмерное число операций ввода/ вывода при добавлении или удалении блочных устройств в пул или из него, но и максимизирует вероятность того, что в случае сбоя будут получены обновлённые метаданные.

Для решения второй задачи Stratis отслеживает насколько велики его самые последние последовательные обновления метаданных и увеличивает значение размера областей MDA во вновь добавляемых устройствах когда достигается довольно низкий порог - 50% - по сравнению с размером доступной области MDA. Это гарантирует, что к тому времени, когда в пул будет добавлено достаточно блочных устройств для достижения слишком больших последовательных данных JSON, будет иметься достаточно блочных устройств с увеличенным пространством MDA, которые могут быть применены для записи MDA.

 

Метаданные и восстановление

Плохие вещи происходят.

Для восстановления диска после сбоев Stratis применяет CRC для критически важных метаданных L0 - L4 и записывает дублирующие копии в отдельное блочное устройство, также как и по множеству блочных устройств, когда это возможно. Применяется именно такой подход - копий - вместо того механизма, который способен сделать возможным чстичное восстановление повреждённых метаданных по трём причинам:

  1. Эти метаданные относительно малы - они относятся к дискам и наборам raid, из которых в пуле будет лишь небольшое число, а потому присутствие нескольких копий не является жутко расточительным.

  2. Частично восстановленные сведения обладают ограниченной ценностью.Это обусловлено многоуровневой природой Stratis. Недостаточно знать некоторые подмножества уровней сопоставления устройств. Поскольку они обладают многоуровневым характером, восстановление, скажем, схем L0 - L2 не сделают возможным восстановление сведений без знания также того, как L3 и L4 соотносятся сверху, и наоборот.

  3. Метаданные L0 - L4 должны требовать относительно небольшого количества обновлений в день, поскольку отражаемые ими изменения будут добавляться/ удаляться из своего пула или из данных устройств расширений пула динамичного расширения. Редкие обновления снижают вероятность повреждений. (требуется цитирование?)

L5-L7 хранятся в Томе метаданных в файловой системе XFS. Имеется возможность частичного восстановления этих данных.

Дополнительно к относящимся к Stratis метаданным, все такие уровни device-mapper, как кэширование, raid, как и сами файловые системы XFS, все они обладают своими собственными метаданными. В случае когда они сообщают об ошибках, Stratis будет полагаться на запуск инструментов специфичных для каждого из них/ fsck.

Уровень Кэширования

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

 

Требования

  1. Кэширование может настраиваться с избыточностью или без применения избыточности.

  2. Кэширование может настраиваться с режимами обратной записи и сквозной записи.

  3. Stratis соединяет все кэши блочных устройств и применяет получаемое в результате устройство для кэширования своего устройства пула динамичного обновления (L4). Это позволяет всем файловым системам получать преимущества от такого кэширования.

  4. Размер блока кэширования обязан соответствовать размеру блока данных пула динамичного выделения.

  5. Удаление уровня кэширования сопровождается удара по производительности и получением этапа "разогрева".

  6. Для кэширования обратной записью Уровень кэширования обязан быть избыточным когда Уровень данных избыточный.

 

Метаданные Уровня Кэширования

Требования Метаданных уровня кэширования

  1. Идентификации всех блочных устройств, которые составляют часть своего пула Уровня кэширования, настроенного уровня избыточности и прочих относящихся к кэшированию параметров настройки (например, WT/WB, размера блока, политики кэширования)

  2. Уровень кэширования поддерживает до 8 устройств

Шифрование

stratisd выполняет шифрование блочных устройств на уровне своих блочных устройств. Когда устройства Stratis зашифрованы, будут выполнены следующие условия:

  • Каждое устройство будет зашифровано при помощи отличающегося и вырабатываемого случайным образом MEK (Media Encryption Key)/

  • Все устройства в пуле будут зашифрованы или все устройсва в пуле не будут шифроваться. Stratis будет поддерживать смешанное применение пулов, когда некоторые пулы шифруются, а иные нет.

  • Для каждого из пулов будут поддерживаться отличающиеся фразы идентификации (passphrase, применяемые для выработки KEK, или Key Encryption Key), хотя и остаётся возможность применения одной и той же фразы идентификации для всех пулов в случае такого пожелания.

  • В момент создания пула у пользователя будет требоваться определение того будет или нет шифроваться пул и ему надлежит указать свой выбор дополнительным параметром в соответствующей команде CLI "pool create". Не поддерживается шифрование уже существующего пула.

  • Изначально не рассматривается шифрование с новыми параметрами; такая функциональная возможность будет рассмотрена и добавлена на следующем этапе.

  • Когда некий пул был зашифрован при создании, тогда все добавляемые в его уровень данных блочные устройства будут автоматически шифроваться со случайно вырабатываемыми MEK и имеющимся выработанным KEK пула.

  • Во всех зашифрованных блочных устройствах соответствующие метаданные Startis сами по себе; они не будут доступны пока не будет открыто его зашифрованное блочное устройство.

  • Применение уровня кэширования и шифрование взаимно исключающие. Когда пул зашифрован, попытка добавления блочного устройства в имеющийся Уровень кэширования будет отвергнута.

  • для шифрования всех зашифрованных устройств шифр по умолчанию определяется cryptsetup 2.1, aes-xts-plain64. MEK состоит из 512 бит.

Перечисленные выше условия требуют реализации, в которой применяется заголовок LUK52. В частности, для дешифрации блочного устройства при помощи специфичного для него KEK, будет необходимо включать в заголовок сведения, которые позволяют идентифицировать устройство как принадлежащее определённому пулу Stratis. Такой заголовок LUKS2 включает в себя поддержку маркеров LUKS, что делает возможным для stratisd идентифицировать тот пул, к которому относится это устройство: заголовок LUKS1 не поддерживается.

Подробности реализации

Инструментарий командной строки ’stratis’

Инструмент командной строки stratis написан на Python. Поскольку он применяется только после того как его система загружена системным администратором, природа Python и накладные расходы не принимаются в расчёт.

stratisd

Stratisd требует реализации на компилируемом языке чтобы отвечать требованию своей работы в среде предварительно загрузки. Также важен небольшой отпечаток в памяти времени исполнения.

stratisd написан на Rust. Основные ключевые свойства Rust, которые превращают его в хороший выбор для stratisd это:

  • Компилируется с минимальным временем исполнения (никакого GC)

  • Безопасность памяти, скорость и одновременность работы

  • Сильная stdlib, включая наборы

  • Обработка ошибок

  • Доступные для DBus, device-mapper, последовательностей JSON и CRC библиотеки

  • В случае необходимости библиотеки FFI на C

  • Будет доступен в RHEL 8 на момент его поставки; в настоящий момент поставляется в комплекте Fedora

Другими рассматриваемыми альтернативами являлись C и C++. Rust был выбран как более предпочтительный по сравнению с ними по причинам безопасности памяти и производительности.

Имена device-mapper

Если stratisd непредсказуемо завершается и стартует повторно, ему необходимо перестроить свои сведения по запущенной системе. Это включает не только повторную нумерацию блочных устройств для выявления участников Stratis, но также и определение текущего состояния тех целей device-mapper, которые составляют пулы. Перезапуск stratisd необходим для обработки, когда отсутствуют или присутствуют некоторые или все ожидаемые устройства DM и если присутствующие устройства DM не работают должным образом или при некотором состоянии ошибки.

При таких завершениях Stratis применяет непротиворечивые имена для целей device-mapper. Это делает возможным для stratisd более простым способом определять что устройства DM уже имеются и избегать утечки старых соответствий DM.

 

Требования соглашения именования

  • Глобальная уникальность

  • Максимум в 12 символов

  • Отличие между Stratis и прочими устройствами DM

  • Совместимость на будущее для возможности обновления Stratisd

  • Читаемость персоналом

  • Простой синтаксический разбор

 

Соглашения именования

Таблица B-13. DM имена stratis состоят из пяти обязательных и двух опциональных частей, разделяемых ’-’
часть название максимальная длина необходим описание

1

stratis-id

7

да

Универсальный отличитель DM: ’stratis’

2

format-version

1

да

Версия согласования именования: 1

3

private

7

нет

Необязательный индикатор: ’private’

4

pool-id

32

да

Шестнадцатеричный ASCII UUID рассматриваемого пула

5

layer-name

16

да

Название того уровня Stratis, в котором предывает это устройство

4

layer-role

16

да

Название той роли, к которой относится данное цстройство внутри своего уровня

7

role-unique-id

40

нет

Уникальный специфичный для роли отличитель между множеством устройств внутри конкретного уровня с одной и той же ролью

  • Значение максимальной длины (включая 6 ’-’ в качестве сепараторов) составляет 125 для того чтобы оставаться в пределах имени DM в 127 символов.

  • “private” включается в имена устройств DM, которые должны быть внутренними и подлежат исключению из сканирования такими инструментами как blkid.

  • Символы для каждой из частей выбираются исключительно из классов символов ’[a-z]’ и ’[0-9]’, за исключением части 7, которая также может использовать символ ’-’. Эти ограничения соответствуют требованиям D-Bus и udev (дополнительные сведения см. в коде lvm2 libdm/libdm-common.c _is_whitelisted_char().)

 

Определения именования по уровням

  • Layer 0: Blockdev

    нет необходимости

  • Layer 1: Integrity

    TBD

  • Layer 2: Redundancy

    TBD

  • Таблица B-14. Layer 3: Flex
    private layer-name layer-role role-unique-id описание

    y

    flex

    thinmeta

    нет

    Линейное устройство для метаданных thinpool

    y

    flex

    thindata

    нет

    Линейное устройство для данных thinpool

    y

    flex

    mdv

    нет

    Линейное устройство для MDV (mdv)

    Образец:

    stratis-1-private-2836fca3047bba22938475638abcd840-flex-thinmeta

  • Таблица B-15. Layer 4: Thinpool
    private layer-name layer-role role-unique-id описание

    y

    thinpool

    pool

    нет

    Устройство thinpool

    Образец:

    stratis-1-private-2836fca3047bba22938475638abcd840-thinpool-pool

  • Таблица B-16. Layer 5: Thin volume
    private layer-name layer-role role-unique-id описание

    y

    thin

    fs

    32 шестнадцатеричных символов ASCII UUID fs

    Том thin

    Образец:

    stratis-1-2836fca3047bba22938475638abcd840-thin-fs-ca7efca3047bba22938475638abc3141

  • Layer 6: Encryption

    TBD

Минимальная версия Имён device-mapper

Для поддержки событий poll() DM и поддержки event_nr в list_devices ioctl младшая версия 37 device-mapper stratisd или выше.

Интеграция с ОС: Запуск и initrd

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

В такой предваряющей запуск среде нет возможности применять D-Bus. Тем самым, Stratis обязан быть терпимым к её отсутствию.

Наиболее вероятная реализация этого требования состоит в режиме "“boot-init”" для Stratis, в котором он обнаруживает блочные устройства и активирует пулы, но не подключается к D-Bus и далее выполняет выход. Затем, как часть основной фазы своей системы, Stratis запускается снова и остаётся в рабочем состоянии для обработки отслеживания пула и команд через D-Bus обычным образом.

Интеграция с ОС: udev

Библиотека udev “libudev” делает возможным доступ к базе данных собственно устройств udev. Это позволяет пользователям библиотеки перенумеровывать блочные устройства в своей системе и включать атрибуты, описывающие их контекст, такие которые были выявлены подписью файловой системы или диспетчера томов. (Для этого libudev пользуется libblkid, в которую недавно была добавлена поддержка подписи Stratis.) Первичное преимущество этого состоит в выполнении временеёмкого сканирования блочных устройств лишь раз и облегчает пользователям возможность интерпретации содержимого блочного устройства.

При запуске Stratis применяет libudev для перенумерации в своей системе блочных устройств Stratis, считывает с каждого из них необходимые метаданные Stratis и активирует пулы для которых она завершена. Позднее, в процессе фазы основного исполнения системы Stratis отслеживает события udev на предмет вновь добавляемых блочных устройств с тем, чтобы когда Stratis пропустил участников пула, подключённых к завершённому пулу, такой пул был бы способен выполнить активацию и готов к применению.

Интеграция с ОС: записи /dev

Stratis позволяет пользователям создавать файловые системы, которые далее могут монтироваться и применяться через mount(8) и fstab(5). Stratisd создаёт каталог /stratis. Он создаёт /stratis/<poolname> для каждого имеющегося в своей системе пула и /stratis/<poolname>/<filesystemname> для каждой файловой системы в таком пуле. Такие изменения, как создание, удаление и переименование отражаются в имеющихся под /stratis записях. Эти записи снабжают пользователя хорошо знакомыми путями к устройствам под применение для монтирования файловой системы Stratis. Файловые системы также могут быть перечислены в /etc/fstab при помощи XFS UUID.

Частичная активация пула

Stratis обязан обрабатывать случаи, при которых составляющие некий пул устройства отсутствуют. Его изначальная политика состоит в том, чтобы не активировать пул до тех пор, пока не будут присутствовать все его участники. Тем не менее, имеются ситуации, при которых это не требуется в строгом соблюдении, например, когда некое блочное устройство не имеет никаких выделений Уровня гибкости для него, или (в Stratis 2.0) когда избыточность имеющегося уровня RAID позволяет функционирование в деградировавшем состоянии. Для учёта таких ситуаций, скорее всего, первоначальная политика будет изменена.

Моментальные снимки

Текущая реализация моментальных снимков Stratis характеризуется несколькими особенностями:

  • Моментальный снимок и его первоисточник не связаны при их работе, т.е. файловая система моментального снимка может существовать дольше чем та файловая система, из которой она создана.

  • Моментальный снимок фаловой системы это другая файловая система.

  • С файловой системы можно выполнять моментальный снимок при её монтировании и размонтировании.

  • Всякий моментальный снимок использует около половины гигабайта реального лежащего в основе хранилища, которое требуется для ведения журнала файловой системы XFS.

В данльнейшем это может измениться.

Внутреннее устройство лежащего в основе хранилища

Собственно лежащее в основе хранилище делится на два слоя: его уровень данных и не обязательный уровень кэша. Каждый из уровней обладает собственным набором физических блочных устройств. Основная цель каждого слоя состоит в предоставлении линейного устройства, поверх которого может быть запросто собран Уровень гибкости (или иной уровень).

Некий слой создаётся с определённым набором функциональных возможностей, что в результате предоставляет внутреннюю многоуровневость устройств, как того требуется от таких функциональных возможностей. Такие свойства как избыточность, целостность и дедупликация/ сжатие. Такие поддерживаемые функциональные возможности фиксируются в момент создания уровня. Тем не менее, сами составляющие этот уровень блочные устройства могут меняться. Блочное устройство может увеличиваться в размере или же могут добавляться новые блочные устройства.

Вот что требуется поддерживать каждому уровню:

  • Сейчас

    • add_blockdev (добавить новое блочное устройство в этот уровень)

    • blockdevs (перечислить/ выполнить итерации)

  • Грядущие функциональные возможности

    • extend_blockdev (начать применять добавленное пространство в блочном устройстве, которое стало больше)

  • Последующие функциональные возможности

    • prepare_to_remove_blockdev ( переместить данные с блочного устройства при его подготовке к удалению, когда ещё где- то имеется пространство)

    • remove_blockdev (удалить блочное устройство, на котором нет данных)

Все уровни содержат в себе не обязательную внутреннюю поддержку для множества функциональных возможностей, которые также могут реализовываться при помощи устройств DM.

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

Каждый уровень получает список блочных устройств и преобразовывает его в список "лучших" блочных устройств, чей общий размер,вероятно, отличается (Integrity и raid будут меньшего размера, vdo представляет одно блочное устройство гораздо большего размера и т.д.)

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

Порядок уровней (снизу вверх) следующий:

  1. blockdev

    Блочное устройство поддерживает доступное своему уровню пространство. Блочные устройства могут расти, например, когда им случается быть виртуальными поверх некого приложения хранения, Amazon EBS или блочного хранилища Ceph.

  2. integrity

    Когда integrity = true, используемому пространству каждого блочного устройства ставится в соответствие надлежащая цель целостности DM, которая слегка снижает используемое пространство и вызывает воздействие на производительность при выявлении искажений при считывании. Предполагается, что целостные устройства не способны изменять размер. Тем самым, расширение блочного устройства может потребовать создание второго устройства целостности DM.

  3. raid

    При raid = true для создания программного RAID поверх представленных ему устройств Stratis применяет цель dm-raid (это могут быть "сырые" блочные устройства или блочные устройства с включённой целостностью). Для максимизации гибкости Stratis создаёт множество наборов raid определяя максимальный размер каждого участника raid, а также общее число участников в наборе raid. Он также способен выбирать меньший максимального размер участника raid для обеспечения создания 4 - 8 наборов raid.

    Когда делаются доступными дополнительные блочные ресурсы, уровень raid строит дополнительные наборы raid.

  4. vdo

    Если vdo = true, создаваемый уровень vdo объединяет все приданные ему блочные устройства (если это потребуется) любого из ранее упомянутых типов и создаёт отдельное устройство VDO. Этот уровень должен управлять расширением как логического размера (вершина) как отклик на запросы пространства свыше, а также запрашивать дополнительное пространство у своих нижних уровней для расширения своего физического размера (низ), если это необходимо.

  5. cap

    При наличии более одного блочного устройства или же такого блочного устройства, которое обладает ненулевым смещением, данный уровень "cap" обеспечит что данный уровень представляет некое единое блочное устройство с соглаоованным соответствие для его применения поверх своего уровня через создание Линейного устройства, которое никогда не переназначает предварительно поставленные в соответствие диапазоны блоков.

 

Выделения на основании потребности

Уровням не следует потреблять всё доступное пространство ими целиком при построении устройств, а вместо этого надлежит наращивать имеющееся поставленное в соответствие им выделение (либо создавать новые), по мере того как создаются общие потребности более верхних слоёв к большему росту. Это более предпочтительно нежели "прожорливая" стратегия, ибо любое созданное содержащее данное сопоставление обязано поддерживаться на протяжении всего срока службы пулов. Не существует хорошего способа сообщать о том, что установленные в соответствие в имеющемся устройстве блоки становятся задействованными. Когда мы начинаем с небольшого, а затем наращиваем выделение, это предоставляет каждому уровню некий способ отслеживания зон, которые имеют при необходимости возможность утилизации. В конечном итоге это упростит поддержку удаления блочного устройства.

Другая причина состоит в том, что требования пространства могут расширяться или усекаться по мере передачи запроса вниз к соответствующему уровню. Например, VDO способны удовлетворять запросу на дополнительное логическое пространство без потребности в каком бы то ни было дополнительном пространстве нижнего уровня. Тем не менее, когда уже имеющийся уровень заполнен, некий небольшой запрос к уровню RAID может потребовать построение какого- то совершенно нового набора raid с большим минимальным размером из незадействованного пространства.

 

API Общего уровня

TBD

Внутреннее устройство лежащего в основе хранилища

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

Stratis обладает состояниями операций для своих пулов, расширений метаданных и данных, а также для блочных устройств (перечисляемых далее).

 

Состояния пула

Дополнительно к основным состояниям, в которых может пребывать пул, Запущенный (Running) пул может также быть Совершенным (Complete) или Неполным (Incomplete), а Остановленный (Stopped) пул может обладать одним из нескольких моментов, препятствующих его исполнению.

Таблица B-17. Состояния пула
состояние описание переходит в

Initializing

Пул в процессе запуска

Running, OutOfDataSpace, ReadOnly, Failed

Running

Пул в процессе чтения/ записи - нормальное рабочее состояния

OutOfDataSpace, ReadOnly, Failed, Stopping

OutOfDataSpace

Метаданные могут изменяться - под новые данные не может выполняться выделение. Данные устройства лишь обновляются.

Running, ReadOnly, Failed, Stopping

ReadOnly

Метаданные не могут изменяться - данные доступны только на считывание

Running, OutOfDataSpace, Failed, Stopping

Failed

Все операции ввода/ вывода завершаются отказом

Running, OutOfDataSpace, ReadOnly, Stopping

Stopping

Пул пребывает в демонтированном виде

 

 

Состояния расширения пула

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

Таблица B-18. Состояния расширения пула
состояние описание переходит в

Initializing

Пул в процессе запуска

Good, DataFailed, MetaFailed, MetaAndDataFailed

Good

Нормальное рабочее состояния

DataFailed, MetaFailed, MetaAndDataFailed

DataFailed

Отказ в расширении данного устройства данных пула

Good, MetaAndDataFailed

MetaFailed

Отказ в расширении данного устройства метаданных пула

Good, MetaAndDataFailed

MetaAndDataFailed

Отказ в расширении как устройства метаданных, так и устройства данных этого пула

Good, DataFailed, MetaFailed

 

Состояния пространства пула

Пространство пула также обладает некоторыми состояниями, в котором оно способно пребывать. Определённый пул свободно может переходить между ними. Пребывание в состоянии Критического (critical) может иметь результатом переход состояния пула в Остановленный/ ИсчерпавшийПространство (Stopped/ OutOfSpace).

Таблица B-19. Состояния пространства пула
состояние описание действие

Good

Доступное пространство превышает Низшее пороговое значение

нет<

Low

Доступное пространство меньше Низшего порогового значения

Предупреждение пользователю, запуск сопроводительных операций<

Critical

Доступное пространство меньше Критического порогового значения

Предупреждение пользователю о критическом состоянии, запуск сопроводительных операций<

Лицензирование

В настоящее время stratisd и все включённые в организацию хранилища stratis библиотеки Rust, предназначенные для stratisd лицензируются как MPLv2. Такое заключение было сделано по тщательному рассмотрению совместимости с прочими лицензиями в экосистеме открытого исходного кода. MPLv2 делает возможными некоторые основные преимущества:

  1. Он совместим с обладающими большими разрешениями лицензиями для экосистем с открытым исходным кодом, такими как лицензии BSD и MIT. С учётом обладающих бо́льшими разрешениями лицензий в экосистеме Rust это важное соображение.

  2. Это совместимо с кодом GPL. Что позволяет stratisd включать в свой состав код GPL и превращаться в действенный GPL без какого бы то ни было изменения лицензии MPLv2.

  3. Когда код GPL несовместим с добавленной позже лицензией зависимости, MPLv2 делает возможным удаление кода GPL с миграцией этого кода GPL в отдельную службу чтобы разрешить добавление конфликтующей зависимости. Всё это может быть осуществлено без повторного лицензирования.

После оценки возможных вариантов MPLv2 показалась самой гибкой лицензией, которая всё ещё удовлетворяет требованиям данного проекта.

Ссылки

[1]

[2] Mario Sáenz Espinoza, Jose Goncalves, Paulo Leitao, Jose Luis Gonzalez Sanchez, and Alberto Herreros. Inverse kinematics of a 10 dof modular hyper-redundant robot resorting to exhaustive and error-optimization methods: A comparative study. In Robotics Symposium and Latin American Robotics Symposium (SBR-LARS), 2012 Brazilian, pages 125–130. IEEE, 2012.

[3] Mario Sáenz Espinoza, Ana I Pereira, and José Gonçalves. Optimization methods for hyperredundant robots’ inverse kinematics in biomedical applications. In AIP Conference Proceedings, volume 1479, page 818, 2012.

[4] Ming Tham. Writing research theses or dissertations, May 2001. University of Newcastle Upon Tyne.

Часть IV. Дополнительные материалы

Первоначальные варианты адаптации существующих решений

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

Расширение имеющегося проекта

 

SSM

System Storage Manager (SSM) предоставляет интерфейс командной строки для управления хранилищем в существующих технологиях. Наш интерес к SSM был определён на случай если бы он был неким существующим проектом, который мы бы были способны расширить для удовлетворения своих потребностей.

SSM предоставляет единообразный интерфейс для трёх различных "основ": LVM, Btrfs и crypto. Тем не менее, когда мы желаем предоставлять простую, унифицированную практику, наш первый шаг скорее всего будет состоять в подхвате имеющихся основ и сборки вокруг их возможностей. Это исключает сложность CLI - пользователю нет нужды выбирать серверную часть или сталкиваться с командами, которые могут и не работать в зависимости от выбранного сервера, но при этом избавляется от большинства моментов SSM.

SSM не предоставляет программируемого API. Внутри себя он содержит "ssmlib", которая может быть расширена и выставлена, но будет доступна лишь в Python. ssmlib также собрана вокруг инструментария командной строки, что может создавать проблемы.

SSM не является демоном. Нам потребуется изменить SSM для работы в модели демона. Для мониторинга сбоев, а также для автоматической работы файловой системы и расширений динамически выделяемого пула требуется постоянное присутствие.

SSM в настоящее время не поддерживает RAID5/6, динамичное выделение и настройку уровня кэширования.

SSM написан на Python, что ограничивало бы возможность применения в средах раннего запуска.

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

Вывод

Расширенный SSM не удовлетворяет нашим требованиям.

 

LVM2

Logical Volume Manager (LVM2) почти универсально применяемый диспетчер томов в Linux. Он предоставляет соответствующую "политику", которая управляет device-mapper. Он добавляет:

  • Формат метаданных на диске для сохранения и восстановления конфигурации между запусками

  • Модель применения построена на понятиях Physical Volume, Volume Group и Logical Volume (PV, VG, LV)

  • Выразительный набор инструментов командной строки для настройки возможностей линейного, raid, динамично выделяемого, кэшируемого и прочего для device-mapper

  • Мониторинг, обработка ошибок и восстановление

  • Изменение размера LV; PV способен добавляться и удаляться в/ из VG

  • Моментальные снимки и динамически предоставляемые моментальные снимки

  • Выбор руководимого пользователем или автоматического выделения/ построения схемы внутри соответствующей VG

Заключение

Добавление возможности управления файловыми системами в LVM2 не была чем- то что рассматривалось всерьёз. Расширение LVM2 очень затруднит достижение простоты взаимодействия, учитывая противоречивость требования сопровождения обратной совместимости с тем, что LVM предоставляет сейчас.

Сборка поверх имеющегося проекта

 

XFS

XFS это весьма уважаемая файловая система без управления томами. Для достижения цели исключения изменения пользователем вручную размера файловой системы Stratis требует чтобы применяемая файловая система обладала способностью изменения размера в реальном масштабе времени (или по крайней мере роста в реальном времени), чем располагает XFS. В отсутствии сжатия в реальном времени Stratis будет полагаться на обрезку для освобождения пространства от увеличенной, но в основном пустой файловой системы и возвращать его в свой ул динамичного выделения для применения прочими файловыми системами.

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

Заключение

XFS удовлетворяет требованиям и в настоящий момент кажется наилучшим выбором.

 

device-mapper

device-mapper это предоставляемая самим ядром Linux инфраструктура для создания расширенной функциональности блочных устройств поверх физических блочных устройств. Такие новые устройства могут добавлять поддержку RAID, динамичное выделение, шифрование, устройства со множеством путей, устройства кэширования и многое иное. Эта инфраструктура предоставляет собственно возможность настройки и выстраивания уровней таких функций, однако не имеется средств для сохранения или восстановления некой конфигурации. device-mapper предоставляет механизм, но не политики.

Заключение

Непосредственное применение device-mapper потребует от верхнего уровня реализацию его собственного формата метаданных на диске и обработки некоторых задач аналогичным LVM2 образом.

 

LVM2

Для описания возможностей LVM2 обратитесь к разделу LVM2.

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

Проблемы со сборкой поверх LVM2

Замечание: Предполагается та реализация, которая описана в Части III.

Замечание: Команда lvm-team выразила возражения против данного перечня.

  • Противопоставления Политики+ Механизм с Политка+ Политика+ Механизм: LVM2 настраивается, однако имеет ограничения. Например, мы можем пожелать позволять пользователю определять некое блочное устройство как применяемое исключительно для подмены в неком наборе raid отказавшего устройства. Тем не менее, raid_fault_policy=”allocate” LVM будет применять любой свободный PV, а не только один зарезервированный в явном виде.

  • Хороший API требует способности передачи для их интерпретации значимых и последовательных ошибок прочим приложениям. Командная строка lvm применяет стратегию простого кода выхода. Значение причины ошибки встраивается в stderr в виде свободного текста, которые меняется без каких бы то ни было уведомлений. Тем самым, практически невозможно для любой оболочки командной строки lvm предоставлять значимые и непротиворечивые коды ошибок, отличающиеся от успеха или неудачи. Отметим: в последнее время lvm добавил вывод JSON, который содержит определённую возможность добавления более значимых и полезных кодов ошибок, однако данная функциональность не реализована и не тривиальна в плане завершённости.

  • Нет возможности применения lvm-dbus по причине того, что это потребует Python и D-Bus,, причём ни тот, ни другой не доступны в initrd

  • Управляемые Stratis LVM2 устройства будут отображаться в перечнях устройств и томов LVM2, что может запутывать пользователей

  • Использование LVM2 для отслеживания метаданных это неплохо, но только пока никакие вышележащие слои не требуют для собственных нужд хранилища метаданных. Как быть с тегами? Теги не могут хранить объекты JSON, ибо ’[]{},"’ не допускаются в тегах.

  • Формат метаданных LVM2 препятствует новым схемам метаданных, например, отслеживанию динамично предоставляемых томов отдельно от метаданных PV или метаданные резервной копии также не пребывают в хвосте самого блочного устройства

  • Использование новых функциональных возможностей device-mapper сдерживаются реализацией LVM2 и циклом выпуска

  • Одним из крупнейших аргументов сторонников LVM2 является то, что LVM2 это крупный проект с длительным временем жизни, который многому научился на собственном горьком опыте и было бы глупо отказываться от всего этого и начинать всё заново.

    • Следует ли нам применять его код или же мы можем извлечь уроки разработчиков LVM2 и внедрять это независимо? Возможно, подправит некоторые моменты, которые невозможно поправить в LVM2 из- за обратной совместимости?

    • Большие части его кодовой основы не дают преимуществ Stratis:

      • Блокировка на основе файлов и настроек: не требуется, так как все упорядочивается через stratisd

      • Демоны /* содержат clvmd

      • Udev: stratisd предполагает udev и listens для событий udev

      • Filter/global_filter

      • Кэширование: не требуется, властвует демон

      • Профили

      • Предпочтительное упорядочение имён

      • Отображение настроек lvm.conf: не требуется или обрабатывается через библиотеки

      • dev_manager: Уровни Stratis предопределены, что намного проще

      • config_tree

      • report: выходит за рамки Stratis

      • Синтаксический разбор параметров, инструментов командной строуи: обрабатывается в cli, уменьшен в сфере

      • lib/misc/*: не требуется или обрабатывается через библиотеки

      • Поддержка формата множественных метаданных

    • Из чего Stratis способен извлечь преимущества?

      • формат метаданных на диске

      • Наилучшие политики для дублированных/ отсутствующих/ разрушенных блочных устройств

      • устойчивость к отказам/ восстановление

      • мониторинг пула/ моментального снимка

Заключение

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

Выводы

Исходя из доступных строительных блоков, наилучшим вариантом является сборка Stratis в качестве нового проекта, который изначально применяет в своей реализации XFS и device-mapper при реализации необходимых расширений. Это позволяет Stratis без промедления перейти к тому моменту, когда он может быть передан в руки потенциальных пользователей для начала получения обратной связи и позволит Stratis в конечном счёте применять LVM2 и избежать дублирования уже предоставляемой функциональности LVM2.

Подробности реализации шифрования

Для добавления каждого блочного устройства в зашифрованный пул Stratis применяет libcryptsetup с целью управления FDE (full disk encryption, шифрование всего диска.

Формат на диске

В качестве основы для реализации своего шифрования Stratis применяет формат шифрования LUKS2. Для идентификации устройства в качестве шифрованного устройства Stratis могут применяться сведения, содержащиеся в заголовке LUKS2.

 

Формат маркера LUKS2

Маркеры LUKS2 содержат все необходимые сведения для описания того как разблокировать его устройства. В таких маркерах не содержится никакие частные сведения. Stratis пользуется двумя маркерами, один это стандартный маркер криптонастройки (cryptsetup token), который позволяет активировать своё устройство при помощи идентификационной фразы, хранимой в кольце ключей ядра, а другой это определяемый Stratis маркер, который содержит необходимый Stratis сведения активации. Идентификаторы маркера статически выделяются для каждого маркера по ряду причин:

  • При использовании статического идентификаторов stratisd не приходится выполнять сканирование всех имеющихся маркеров, за чем следуют эвристические правила для распознавания маркеров. Вместо этого он выбирает соответствующий статический идентификатор и, когда его формат не соответствует ожидаемому, он не трактуется как шифрованное устройство Stratis.

  • По мере добавления прочих методов активации, стимуляция пула может определять один идентификатор маркера для применения в активации всех устройств в этом пуле и ожидается что они будут разблокированы при помощи одного и того жк механизма.

  • Новые маркеры могут добавляться без прерывающих изменений во все назначения имеющихся идентификаторов маркеров.

Маркер Stratis имеет идентификатор 0, в то время как маркер кольца ключей LUKS2обладает идентификатором 1.

Маркер кольца ключей LUKS2

Маркер кольца ключей самого ядра содержат сведения для интеграции LUKS2 с ключами в самом кольце ключей. Этот маркер является стандартным маркером, поддерживаемым activation, а детали этого формата можно найти в документации самого cryptsetup. Взаимодействие с этим маркером обрабатывается стандартными методами API libcryptsetup.

Маркер Stratis

Маркер Stratis используется для идентификации и активации устройства и его значения устанавливаются непосредственно Stratis. Формат спецификации следующий:


{
		"type": "stratis",
		"keyslots": [],
		"activation_name": <DEVICEMAPPER_NAME>,
		"pool_uuid": <POOL_UUID>,
		"device_uuid": <DEVICE_UUID>
}
 	   

Ниже приводятся пояснения для каждого значения JSON:

<DEVICEMAPPER_NAME>

Именно это управляемое имя будет отображаться в device-mapper при активации данного устройства при помощи libcryptsetup. В то время как это имя может отслеживаться в самой системе через запросы device-mapper, управляемые шифрованные устройства Stratis не поддерживаются вне Stratis, поэтому оно рассматривается как внутреннее имя.

<POOL_UUID>

Этот UUID относится к тому пулу Stratis, который владеет данным блочным устройством. Значение UUID пула в данном маркере соответствует значению UUID пула в соответствующих зашифрованных метаданных Stratis.

<DEVICE_UUID>

Данный UUID относится к значению UUID устройства для данного конкретного блочного устройства. Значение UUID устройства в этом маркере соответствует значению UUID устройства в соответствующих зашифрованных метаданных Stratis.

 

Формат метаданных шифрованного Stratis

После того как том LUKS2 разблокирован, соответствующие шифрованные метаданные Stratis должны быть доступными через своё расшифрованное логическое устройство device-mapperв точности так же как и некое не зашифрованное устройство Stratis.

Создание шифрованного диска

Stratis не зачищает своё устройство перед его инициализацией заголовком LUKS2. Это означает, что некий злоумышленник способен вывести следующее при опросе инициализированного без предварительной подготовки при помощи Stratis диска:

  • Значение объёма хранящихся в настоящий момент на диске сведения, которые не зашифрованы. Например, когда диск обладает секторами, которые были заполнены нулями или содержат не зашифрованные сведения, ранее хранившиеся на этом диске в самом конце некого шифрованного сегмента, это может предоставить внутренние сведения о том сколько в этом устройстве хранится зашифрованных блоков. Для предотвращения этого данное устройство надлежит затереть случайными данными перед его предоставлением пулу Stratis.

  • Собственно содержимое не зашифрованных сведений, которые ранее хранились на данном диске перед его инициализацией Stratis. Реализация LUKS2 cryptsetup по умолчанию не перекрывает все эти сведения на данном диске, поэтому без предварительной подготовки все те сектора, которые не были перекрыты зашифрованными данными всё ещё будут содержать предварительно сохранённые на этом диске сведения. Чтобы предотвратить это данный диск надлежит заполнить нулями или затереть случайными данными.

Обнаружение шифрованного диска

Stratis идентифицирует относящиеся к нему зашифрованные устройства по своему маркеру Stratis. Он не пытается активировать любое устройство пока он не получит некую команду D-Bus для активации всех устройств. Когда такая команда получена, stratisd предпринимает попытку разблокировать надлежащие устройства при помощи маркера кольца ключей LUKS2, предварительно настроенного stratisd. Когда активация устройств выдаёт некий набор устройств, которые способны формировать пул целиком, этот пул устанавливается.

Активация шифрованного диска

Устройства активируются при помощи имени активации из соответствующего маркера Stratis. Для пояснения маркера Stratis обратитесь к разделу Формат маркера LUKS2. Активация устройства имеет результатом некий новый активированный путь устройства с надлежащим каноническим именем пути


/dev /mapper/<activation_name>
 	   

по которому можно выполнять доступ к не зашифрованным данным. По причине архитектуры и применения libcryptsetup зашифрованные устройства также могут активироваться вне Stratis при помощи libcryptsetup или CLI cryptsetup пока необходимая фраза идентификации пребывает в соответствующем кольце ключей ядра.

Уничтожение шифрованного диска

Уничтожение некоторого зашифрованного устройства Stratis не вычищает всё это устройство целиком, ибо стоимость такой операции линейно пропорциональна ожидаемому размеру диска. Вместо этого Stratis пользуется libcryptsetup для уничтожения всех имеющихся слотов ключей, зачисткой всех зашифрованных сведений MEK (media encryption key) в каждом из слотов ключей. Затем он получает значение размера установленных метаданных LUKS2 в этом устройстве и выполняет дополнительную зачистку всех остающихся метаданных LUKS2. Это предоставляет следующие свойства устройства в уничтоженном пуле:

  • Все сведения MEK уничтожены, поэтому сохранённые в этом устройстве сведения не будут подлежать восстановлению.

  • Если данное устройство применяется позднее при создании другого пула, Stratis будет иметь возможность повторно инициализировать его и будет рассматривать данное устройство как не обладающее владельцем по причине зачистки всех метаданных LUKS2.

  • Все зашифрованные сведения останутся в этом устройстве, но будут недоступны по причине уничтожения их ключа.

Обнуляя этот диск или перекрывая его случайными данными с применением внешних инструментов можно достичь дополнительной безопасности.

Согласованность ключей для шифрованных пулов

Stratis предпринимает шаги для гарантии того, что та же самая идентификационная фраза применяется в процессе первоначального создания соответствующего пула что и идентификационная фраза, которая применялась для добавления зашифрованных блочных устройств позднее. Перед добавлением блочных устройств в шифрованный пул stratisd запускает проверку для того чтобы убедиться что данная идентификационная фраза в имеющемся кольце ключей ядра со своим описанием ключа, записанном в метаданных LUKS2 способна разблокировать те блочные устройства, которые уже были зашифрованы и добавлены в этот пул. Это препятствует случайному или намеренному изменению сведений идентификационной фразы, связанной с описанием ключа между созданием пула и добавлением зашифрованных блочных устройств, что привело бы в результате к некому неприемлемому пулу и утрате данных при ситуации, когда этот пул следует настроить в следующий раз.

Управление ключами

Stratis предоставляет возможности управления ключами. Собственно кольцо ключей ядра используется в качестве хранилища под те ключи, которые предоставляются через API D-Bus чтобы выполнять надлежащий контроль за идентификационными фразами. Сама архитектура ввода ключа была тщательно разработана чтобы избегать оставления ключей в памяти после того как они больше не используются. Сам ключ не отправляется напрямую через D-Bus; обмен D-Bus не шифруются, а потому это было бы утечкой в открытом тексте идентификационной фразы. Вместо этого сама сторона клиента предоставляет своей стороне сервера некий файловый дескриптор из которого считывается необходимая идентификационная фраза с тем, чтобы никакие данные даже и не выставлялись бы в соответствующем вызове метода D-Bus. Когда какой- то пользователь предоставляет некий ключ при помощи интерактивного режима в своём CLI или API D-Bus, на стороне клиента отключается буферизация ввода с тем, чтобы ключ никогда не сохранялся бы в памяти пространства пользователя. На стороне соответствующего сервера stratisd считывает это ключ в управляемый libcryptsetup блок памяти с тем, чтобы как только эта память более не используется, libcryptsetup зачистит эту память при помощи метода, который не будет оптимизироваться его компилятором. Всё это гарантирует что значения данных ключа будут доступны лишь в одном местоположении в памяти при его использовании и что эта память будет безопасно зачищена после использования.