UnionFS

Материал из Национальной библиотеки им. Н. Э. Баумана
Последнее изменение этой страницы: 19:07, 20 июля 2016.
Unionfs
Полное название Unification File System
Features
Разрешения файловой системы POSIX
Прозрачное сжатие No
Транспорантное шифрование No (but can be provided at the block device level)
Другие
Операционная система Linux, FreeBSD and NetBSD

UnionFS — вспомогательная файловая система для Linux и FreeBSD, которая объединяет различные файловые системы в единое пространство имён, чтобы они воспринимались как одно целое. Работа UnionFS заключается в том, что она определённым образом накладывает один каталог на другой, делая возможным одновременное использование файлов и подкаталогов как в одном, так и в другом. То есть, в отличие от других ФС, unionfs не перекрывает при монтировании старые объекты, размещаемые в каталоге, объявленном как точка монтирования, а осуществляет объединение этих каталогов.

Реализация UnionFS для FreeBSD

В реализации FreeBSD unionfs «накладывает» один каталог на другой, руководствуясь следующими принципами:

  • один из каталогов становится каталогом верхнего уровня, второй – каталогом нижнего уровня;
  • пользователю объекты каталогов доступны «сверху вниз», т.е. если запрошенный объект есть в «верхнем» каталоге, возвращается он, независимо от наличия объекта с таким именем в «нижнем» каталоге; иначе возвращается объект «нижнего» каталога; если запрошенного объекта нет ни там, ни там, возвращается ошибка «Нет такого файла или каталога»;
  • рабочим каталогом является «верхний», то есть все действия пользователя по изменению данных отражаются только на каталоге верхнего уровня, не влияя на содержимое «нижнего» каталога.

Последний пункт означает, что все каталоги, кроме каталога верхнего уровня, фактически можно рассматривать как подключенные «только для чтения». Однако для пользователя это остаётся незаметным: при попытке редактировать файл из «нижнего» каталога он копируется в «верхний», перекрывая оригинальный файл (так называемое «копирование при записи»). В результате пользователь может безограничений работать с этим файлом, в то время как в первоначальном месте он остаётся неизменным .

Здесь выплывают два интересных момента. Допустим, файл f3 есть в обоих каталогах. Пользователь будет видеть «верхний». А если пользователь этот файл удалит? Согласно изложенному выше, при запросе f3 пользователю должен быть возвращён «нижний» файл. Но тогда получается нестыковка со здравым смыслом – ведь пользователь только что этот файл удалил, и было бы нелогично увидеть его снова! Точнее, даже не «его», а, вполне вероятно, совершенно другой файл, просто с таким же именем.

Этот случай unionfs должна обрабатывать особым образом – в «верхнем» каталоге создаётся особый элемент-заглушка (называемый элементом whiteout), и как только он будет найден по запросу на поиск объекта, сразу возвращается ошибка «Нет такого файла или каталога», без обращений к нижележащим уровням. Если файл с данным именем в дальнейшем будет создан, то он заменит собой элемент whiteout, и уже он будет перекрывать файл, размещённый на нижнем уровне

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

Ещё более интересный случай – удаление и последующее восстановление каталога, имя которого присутствует на обоих уровнях. С удалением всё просто – так же, как и для файла, достаточно в «верхнем» каталоге создать элемент whiteout. Но вот если каталог после этого создать, то в нём сразу станут доступны файлы, хранящиеся в одноимённом каталоге нижнего уровня. Чтобы этого избежать, unionfs должна обрабатывать такие воссозданные каталоги особым образом – без передачи запросов на нижние уровни. То есть они должны вести себя так, как при обычном монтировании, когда верхний слой полностью перекрывает объекты нижележащего.

Реализация UnionFS для Linux

Существует две версии UnionFS для Linux. Версия 1.x является изолированной, которая может быть собрана в виде модуля. Версия 2.x новее, реконструированная. В Январе 2007, UnionFS была включена в ветку Linux -mm tree, которую поддерживает Andrew Morton, означая дальнейшее полное включение в основную ветку ядра Linux. Версия 2.x является мельчайшей реализацией каскадно-объединённого монтирования для Linux, она была тщательно проверена и исследована многими разработчиками ядра, к тому же является самой эффективной.

Aufs — альтернативная версия UnionFS для Linux, которая позволяет собрать итоговую файловую систему как слоеный пирог.

  • В качестве слоя может быть squashfs модуль, файл с файловой системой внутри (например, сохраненка), раздел файловой системы, RAM_drive
  • Любой из перечисленных объектов может быть в любое время подключен выше (файлы «слоя» заместят повторяющиеся файлы «пирога») или ниже
  • Количество возможных слоев выбирается при компиляции ядра. Дефолтное значение 128. Увеличение может привести к замедлению работы
  • Возможно и отключение слоя (если его файлы не заняты)
  • Как правило, во всех системах (Puppy), использующих AUFS, в самый верхний слой подключается «сохраненка». Слой допускающий не только чтение но и запись и сохраняющий изменения после рестарта. В качестве «сохраненки» можно использовать RAM_drive, но тогда изменения пропадут после рестарта

Монтирование unionfs во FreeBSD

Во FreeBSD монтирование файловой системы unionfs выполняется с помощью утилиты mount_unionfs (если вам это кажется удобнее, можно использовать mount -t unionfs). Параметров немного – помимо «-o», позволяющего задавать стандартные опции монтирования, есть ещё два ключа:

  • -r – заставляет при монтировании полностью скрыть объекты нижнего уровня, в результате чего поведение unionfs становится идентично работе файловой системы nullfs;
  • -b – инвертирует верхний и нижний уровни таким образом, что видимая пользователю точка монтирования становится верхним уровнем, т.е. рабочим каталогом.

Например:

# mount_unionfs /usr/home/src /usr/src
# mount -t unionfs -b /usr/home/src /usr/src

Первая команда смонтирует каталог /usr/home/src поверх /usr/src, и всё это будет доступно пользователю в точке монтирования /usr/src, причём рабочим каталогом (каталогом верхнего уровня, в котором будут происходить все изменения) будет /usr/home/src.

Вторая команда отличается от первой ключом -b, так что результирующий каталог будет смонтирован в /usr/home/src, который и станет «верхним». То есть ключ -b фактически изменяет точку монтирования.

Если монтирование не выполняется, завершаясь ошибкой «Operation not supported by device», то первое, в чём следует убедиться, – это в том, что подгружается модуль unionfs.ko:

Применение на практике

Возникает вопрос: а зачем она вообще нужна?

Первое, что приходит в голову, – монтирование пользовательского каталога поверх точки монтирования CD-диска. Раз нижний слой всё равно не изменяем, то доступность CD только для чтения никакой роли в данном случае не сыграет. Зато монтирование доступного на запись каталога верхнего уровня позволит, например, выполнять сборку и установку программ или системы «прямо с CD» – все временные файлы будут создаваться в пользовательском каталоге:

# mount_unionfs /usr/home/cdrom /mnt/cdrom

Теперь в каталоге /mnt/cdrom можно выполнять любые изменения файлов – на самом деле они будут выполняться в /usr/home/cdrom. Кстати, так можно не только обходить явный запрет на запись, но и избегать записи там, где она нежелательна. Например, примонтировав пользовательский каталог поверх каталога с исходниками, можно смело экспериментировать с наложением патчей и сборкой, не боясь испортить «оригинал» или замусорить дерево исходных кодов временными файлами.

Можно зайти ещё дальше – использовать в качестве каталога верхнего уровня файловую систему, размещаемую в памяти (во FreeBSD она реализуется с помощью mdmfs). В результате и скорость работы должна возрасти, и «мусор» за собой убирать вручную не придётся. Главное, чтобы выделение памяти под md-раздел было не в ущерб доступной для операций сборки:

# mount_mfs -s 50m md /tmp/md1
# mount_unionfs /tmp/md1 /usr/ports/www/apache22

Ещё один близкий по духу пример: использование unionfs для целей обучения. Понятно, что если в университете каждого студента пускать «админить» реальную систему, то довольно часто придётся заниматься аварийно-восстановительными мероприятиями. Решений у этой проблемы много – и LiveCD, и заранее сохранённые «образы» системы, с которых можно легко восстановить исходное состояние. Здесь же можно применить и UnionFS – примонтировать пользовательский каталог поверх реального /etc, сохранив тем самым первозданную чистоту оригинального каталога.

Наконец, UnionFS будет крайне полезна для построения jail-систем. В Solaris «зоны» используют похожую технологию – при создании зоны она наследует файлы основной системы, но если какой-то из них изменяется, то эти изменения отражаются только внутри данной зоны. Это позволяет значительно экономить дисковое пространство, выделяя его лишь «по требованию», что особенно заметно, если выполняется построение множества однотипных зон. Так же и с jail – создавая виртуальную среду, например, для хостинга или тестирования ПО, можно не копировать в неё полностью все системные файлы, а использовать каталоги основной системы, поверх которых монтировать пользовательские каталоги в unionfs (фрагмент /etc/fstab).

Список литературы

Ссылки