0

Виртуальная файловая система linux

Виртуальная файловая система (англ. virtual file system — VFS) или виртуальный коммутатор файловой системы (англ. virtual filesystem switch ) — уровень абстракции поверх конкретной реализации файловой системы. Целью VFS является обеспечение единообразного доступа клиентских приложений к различным типам файловых систем. VFS может быть использована для доступа к локальным устройствам и файлам (fat32, ext4, ntfs), сетевым устройствам и файлам на них (nfs), а также к устройствам, не предназначенным для хранения данных (procfs [1] ). VFS декларирует программный интерфейс между ядром и драйвером конкретной файловой системой, таким образом, для добавления поддержки новой файловой системы не требуется вносить изменений в ядро операционной системы.

Содержание

История развития [ править | править код ]

Одна из первых виртуальных файловых систем в Unix-подобных ОС была реализована Sun Microsystems в SunOS 2.0 в 1985 году. Это позволило системным вызовам Unix получить прозрачный доступ к локальной UFS и удалённой NFS. По этой причине вендоры Unix-систем, получившие лицензию на код NFS, часто копировали дизайн VFS от Sun. Другие файловые системы могут быть подключены так же: появилась реализация файловой системы MS-DOS FAT, разработанная в Sun, использовавшая SunOS VFS, хотя она не поставлялась в качестве продукта до SunOS 4.1. Реализация SunOS лежит в основе механизма VFS в System V Release 4.

Джон Хейдеманн ( John Heidemann ) разработал стековую VFS под SunOS 4.0 для экспериментальной файловой системы Ficus . Этот проект предусматривал повторное использование кода в файловых системах с различной, но похожей семантикой (например, шифрованная файловая система может использовать систему имён и код для хранения данных нешифрованной файловой системы). В своей диссертации Хейдеманн адаптировал эту работу для использования в 4.4BSD. Наследники этого кода лежат в основе реализаций современных файловых систем в операционных системах, производных от BSD, включая Mac OS X.

Устройство VFS [ править | править код ]

Как было указано ранее, основное предназначение современных VFS — организация единого интерфейса доступа пользователя к различным файловым системам, драйвера которых загружены в память компьютера. Для реализации этой цели от ядра операционной системы требуется создание единого программного интерфейса внутренних вызовов ядра. Данный интерфейс должен быть достаточно широким в плане функциональности, поскольку он будет использоваться для доступа к очень большому числу различных (в плане свойств и функционала) файловых систем. Помимо стандартных для файлов вызовов на открытие/закрытие и чтение/запись от VFS требуется иметь интерфейс для ревалидации (от англ. revalidation ) данных, работы с кэшами, посылки специальных запросов (IOCTL — Input/Output Control ), а также для организации текущей сессии работы с открытым файлом.

Для работы с VFS драйверу файловой системы необходимо реализовать обозначенные программные вызовы с учётом специфики работы данной файловой системы. Драйвер может поддерживать лишь часть вызовов API VFS, в этом случае ядро ОС должно корректно «заглушить» соответствующие необрабатываемые запросы от пользователя.

Фактически, интерфейс VFS, предоставляемый драйверам файловых систем, может является определением к самому понятию файловой системы. Любой драйвер, реализующий функционал API VFS и загруженный в ядро правильным образом, становится драйвером файловой системы, безотносительно того, используется ли он для доступа к файлам или нет. Более того, сама функциональность файловой системы может быть даже не в драйвере, а в пространстве пользователя. Ярким примером такого подхода является файловая система в пользовательском пространстве ( Filesystem in Userspace — FUSE).

Применение в современных ОС [ править | править код ]

В OS/2 и Microsoft Windows механизм виртуальной файловой системы называется устанавливаемой файловой системой ( Installable File System ).

В Linux механизм VFS, как и весь код ядра, является открытым. Это позволяет разработчикам файловых систем писать их драйвера максимально эффективно. Как результат — Linux поддерживает монтирование подавляющего большинства современных файловых систем.

В Unix файловые системы включают File System Switch в System V Release 3 и в Ultrix.

Операционная система Windows может быть установлена только на файловую систему NTFS, поэтому обычно у пользователей не возникает вопросов какую ФС лучше использовать. Но Linux очень сильно отличается, здесь в ядро системы встроены и могут использоваться несколько файловых систем, каждая из которых оптимизирована для решения определенных задач и лучше подходит именно для них.

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

Жесткий диск и разделы

Обычно в компьютере используется один жесткий диск, но для удобства все доступное пространство разделяется на разделы, в Windows они известны как диски, в Linux же их принято называть разделами. Чтобы операционная система знала сколько разделов есть на диске и их физические границы используется таблица разделов. Она может быть двух типов – GPT или MBR. В этой статье мы не будем рассматривать ее подробно. Скажу только, что там находится метка раздела, его порядковый номер и адрес начала и конца на жестком диске.

Что такое файловая система?

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

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

Типы файловых систем Linux

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

Основные файловые системы

Каждый дистрибутив Linux позволяет использовать одну из этих файловых систем, каждая из них имеет свои преимущества и недостатки:

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

Ext2, Ext3, Ext4 или Extended Filesystem – это стандартная файловая система для Linux. Она была разработана еще для Minix. Она самая стабильная из всех существующих, кодовая база изменяется очень редко и эта файловая система содержит больше всего функций. Версия ext2 была разработана уже именно для Linux и получила много улучшений.

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

Читайте также:  Заработок ютуберов статистика сайт

JFS или Journaled File System была разработана в IBM для AIX UNIX и использовалась в качестве альтернативы для файловых систем ext. Сейчас она используется там, где необходима высокая стабильность и минимальное потребление ресурсов. При разработке файловой системы ставилась цель создать максимально эффективную файловую систему для многопроцессорных компьютеров. Также как и ext, это журналируемая файловая система, но в журнале хранятся только метаданные, что может привести к использованию старых версий файлов после сбоев.

ReiserFS – была разработана намного позже, в качестве альтернативы ext3 с улучшенной производительностью и расширенными возможностями. Она была разработана под руководством Ганса Райзера и поддерживает только Linux. Из особенностей можно отметить динамический размер блока, что позволяет упаковывать несколько небольших файлов в один блок, что предотвращает фрагментацию и улучшает работу с небольшими файлами.

Еще одно преимущество – в возможности изменять размеры разделов на лету. Но минус в некоторой нестабильности и риске потери данных при отключении энергии. Раньше ReiserFS применялась по умолчанию в SUSE Linux, но сейчас разработчики перешли на Btrfs.

XFS – это высокопроизводительная файловая система, разработанная в Silicon Graphics для собственной операционной системы еще в 2001 году. Она изначально была рассчитана на файлы большого размера, и поддерживала диски до 2 Терабайт. Из преимуществ файловой системы можно отметить высокую скорость работы с большими файлами, отложенное выделение места, увеличение разделов на лету и незначительный размер служебной информации.

XFS – журналируемая файловая система, однако в отличие от ext, в журнал записываются только изменения метаданных. Она используется по умолчанию в дистрибутивах на основе Red Hat. Из недостатков – это невозможность уменьшения размера, сложность восстановления данных и риск потери файлов при записи, если будет неожиданное отключение питания, поскольку большинство данных находится в памяти.

Btrfs или B-Tree File System – это совершенно новая файловая система, которая сосредоточена на отказоустойчивости, легкости администрирования и восстановления данных. Файловая система объединяет в себе очень много новых интересных возможностей, таких как размещение на нескольких разделах, поддержка подтомов, изменение размера не лету, создание мгновенных снимков, а также высокая производительность. Но многими пользователями файловая система Btrfs считается нестабильной. Тем не менее, она уже используется как файловая система по умолчанию в OpenSUSE и SUSE Linux.

Другие файловые системы, такие как NTFS, FAT, HFS могут использоваться в Linux, но корневая файловая система linux на них не устанавливается, поскольку они для этого не предназначены.

Специальные файловые системы

Ядро Linux использует специальные файловые системы, чтобы предоставить доступ пользователю и программам к своим настройкам и информации. Наиболее часто вы будете сталкиваться с такими вариантами:

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

procfs – по умолчанию смонтирована в папку proc и содержит всю информацию о запущенных в системе процессах, а также самом ядре.

sysfs – с помощью этой файловой системы вы можете задавать различные настройки ядра во время выполнения.

Виртуальные файловые системы

Не все файловые системы нужны в ядре. Существуют некоторые решения, которые можно реализовать и в пространстве пользователя. Разработчики ядра создали модуль FUSE ( filesystem in userspace), который позволяет создавать файловые системы в пространстве пользователя. К виртуальным файловым системам можно отнести ФС для шифрования и сетевые файловые системы.

EncFS – файловая система, которая шифрует все файлы и сохраняет их в зашифрованном виде в нужную директорию. Получить доступ к расшифрованным данным можно только примонтировав файловую систему.

Aufs (AnotherUnionFS) – позволяет объединять несколько файловых систем (папок) в одну общую.

NFS (Network Filesystem) – позволяет примонтировать файловую систему удаленного компьютера по сети.

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

Выводы

В этой статье мы рассмотрели типы файловых систем Linux. Как видите, здесь все намного запутаннее чем в Windows. Но на самом деле все просто. Если вам нужна максимально стабильная файловая система linux – то лучшим решением будет ext4, хотите новых технологий – btrfs, для маленьких файлов – raiser4, для больших – XFS. А какие файловые системы linux предпочитаете вы? Напишите в комментариях!

На завершение видео о том, что такое файловая система и ее структура в linux:

Оригинал: Virtual filesystems in Linux: Why we need them and how they work
Автор: Alison Chaiken
Дата публикации: 8 марта 2019 года
Перевод: А. Кривошей
Дата перевода: май 2019 г.

Что такое файловая система? По словам Роберта Лава , «файловая система – это иерархическое хранилище данных, привязанных к определенной структуре». Однако это описание одинаково хорошо применимо к VFAT (виртуальная таблица размещения файлов), Git и Cassandra (база данных NoSQL). Так что же отличает файловую систему?

Основы файловых систем

Ядро Linux требует, чтобы сущность, которая считается файловой системой, должна реализовывать методы open(), read() и write() для постоянных объектов, имеющих название. С точки зрения объектно-ориентированного программирования ядро рассматривает общую файловую систему как абстрактный интерфейс, и эти три главные функции являются «виртуальными», без определения по умолчанию. Соответственно, стандартная реализация файловой системы ядра называется виртуальной файловой системой (VFS).

VFS лежит в основе известного наблюдения, что в Unix-подобных системах «все является файлом». Подумайте, как странно, что крошечное демо с символьным устройством /dev/console на самом деле работает. Изображение показывает интерактивный сеанс Bash по виртуальному телетайпу (tty). При отправке строки в устройство виртуальной консоли она появляется на виртуальном экране. VFS имеет другие, даже более странные свойства. Например, в ней можно производить поиск.

Все известные файловые системы, такие как ext4, NFS и /proc, предоставляют определения функций большой тройки в структуре данных на языке C, называемой file_operations. Кроме того, некоторые файловые системы расширяют и переопределяют функции VFS в рамках объектно-ориентированного подхода. Как указывает Роберт Лав, абстракция VFS позволяет пользователям Linux безболезненно копировать файлы в и из сторонних операционных систем или абстрактных объектов, таких как каналы, не беспокоясь о внутреннем формате данных. От имени пользовательского пространства с помощью системного вызова процесс может копировать из файла в структуры данных ядра с помощью метода read() одной файловой системы, а затем использовать метод write() другого типа файловой системы для вывода данных.

Определения функций, которые принадлежат самому базовому типу VFS, находятся в файлах fs/*.c в исходном коде ядра, а подкаталоги fs/ содержат определенные файловые системы. Ядро также содержит объекты, подобные файловой системе, такие как cgroups, /dev и tmpfs, которые необходимы на ранних этапах процесса загрузки и поэтому определяются в подкаталоге init/ ядра. Обратите внимание, что cgroups, /dev и tmpfs не вызывают три главные функции file_operations, а вместо этого непосредственно читают и записывают в память.

Диаграмма ниже примерно иллюстрирует, как пользовательское пространство обращается к различным типам файловых систем, обычно монтируемых в системах Linux. Не показаны такие конструкции, как pipe, dmesg и часы POSIX, которые также реализуют struct file_operations и доступ к которым, следовательно, происходит через уровень VFS.

Читайте также:  Инструкция по прошивке xiaomi

VFS – это "слой прокладки" между системными вызовами и разработчиками определенных файловых систем, таких как ext4 и procfs. Затем функции file_operations могут взаимодействовать либо с драйверами, специфичными для устройства, либо с аксессорами памяти. tmpfs, devtmpfs и cgroups не используют file_operations, но имеют прямой доступ к памяти.

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

/tmp: простой совет

Простой способ выяснить, какие VFS присутствуют в системе, набрать команду mount | grep -v sd | grep -v :/, которая выводит все смонтированные файловые системы, которые не находятся на диске и не являются NFS на большинстве компьютеров. Одной из перечисленных точек монитирования VFS наверняка будет /tmp, верно?

Все знают, что хранение /tmp на физическом носителе – это безумие!

Почему хранить /tmp на носителе нецелесообразно? Потому что файлы в /tmp являются временными (!), а устройства хранения данных работают медленнее, чем оперативная память, где создается tmpfs. Кроме того, физические устройства более подвержены износу при частой записи. Наконец, файлы в /tmp могут содержать конфиденциальную информацию, поэтому возможность их исчезновения при каждой перезагрузке – это преимущество.

К сожалению, установочные скрипты для некоторых дистрибутивов Linux по умолчанию создают /tmp на жестком диске. Не отчаивайтесь, если это произойдет с вашей системой. Следуйте простым инструкциям в великолепной Arch Wiki, чтобы решить эту проблему, помня, что память, выделенная для tmpfs, не доступна для других целей. Другими словами, система с гигантскими tmpfs с большими файлами в ней может исчерпать доступную память и зависнуть. Другой совет: при редактировании файла /etc/fstab обязательно заканчивайте его новой строкой, иначе ваша система не загрузится.

/proc и /sys

Помимо /tmp, VFS, с которыми большинство пользователей Linux лучше всего знакомы, это /proc и /sys. (/dev полагается на разделяемую память и не использует файловых операций). Почему две файловые системы? Давайте посмотрим их более подробно.

Procfs предлагает моментальный снимок состояния ядра и процессов, которые оно контролирует для пользовательского пространства. В /proc ядро публикует информацию о предоставляемых им средствах, таких как прерывания, виртуальная память и планировщик. Кроме того, /proc/sys – это место, где параметры, которые можно настроить с помощью команды sysctl, доступны для пользователя. Состояние и статистика по отдельным процессам указываются в каталогах /proc/

/proc /meminfo – это пустой файл, который, тем не менее, содержит ценную информацию.

Поведение файлов в /proc показывает, насколько VFS может отличаться от файловых систем на диске. С одной стороны, /proc/meminfo содержит информацию, представленную командой free. С другой стороны, он также пустой! Как это может быть? Ситуация напоминает известную статью, написанную физиком Корнелльского университета Н. Дэвидом Мермином в 1985 году, под названием «Есть ли луна там, куда никто не смотрит? Реальность и квантовая теория». Правда в том, что ядро собирает статистику о памяти, когда процесс запрашивает его, из /proc, и в файлах /proc фактически ничего нет, когда никто не просматривает их. Как сказал Мермин, «фундаментом квантовой доктрины является то, что измерение, как правило, не выявляет ранее существовавшее значение измеряемого свойства».

Файлы в /proc пустые, когда к ним не обращается ни один процесс (источник).

Кажущаяся пустота procfs имеет смысл, поскольку доступная там информация динамична. Ситуация с sysfs другая. Давайте сравним, сколько файлов размером не менее одного байта существует в /proc и /sys.

Procfs имеет именно одну, а именно экспортированную конфигурацию ядра, что является исключением, поскольку его нужно генерировать только один раз при загрузке. С другой стороны, /sys имеет много файлов большего размера, большинство из которых составляют одну страницу памяти. Как правило, файлы sysfs содержат ровно одно число или строку, в отличие от таблиц информации, создаваемой чтением таких файлов, как /proc/meminfo.

Цель sysfs – предоставить доступ для чтения и записи свойств того, что ядро называет "kobjects", в пространстве пользователя. Единственная цель kobjects – подсчет ссылок: когда последняя ссылка на kobject удаляется, система возвращает связанные с ним ресурсы. Тем не менее, /sys представляет собой большую часть знаменитого «stable ABI to userspace» ядра, которое никто и ни при каких обстоятельствах не может «сломать». Это не означает, что файлы в sysfs являются статическими, что противоречило бы подсчету ссылок изменчивых объектов.

Вместо этого стабильный ABI ядра ограничивает то, что может появиться в /sys, а не то, что действительно присутствует там в данный момент. Перечисление разрешений для файлов в sysfs дает представление о том, как настраиваемые параметры устройств, модулей, файловых систем и т. д., могут быть заданы или прочитаны. Логика заставляет прийти к заключению, что procfs также является частью стабильного ABI ядра, хотя в документации ядра это не указано явно.

Файлы в sysfs описывают ровно одно свойство каждого объекта и могут быть читаемыми, записываемыми или все это вместе. «0» в файле показывает, что SSD не является съемным.

Отслеживание VFS с помощью утилит eBPF и bcc

Самый простой способ узнать, как ядро управляет файлами sysfs, – это посмотреть его в действии, а самый простой способ посмотреть это на ARM64 или x86_64 – использовать eBPF. eBPF (extended Berkeley Packet Filter) состоит из виртуальной машины, работающей внутри ядра, которую привилегированные пользователи могут запрашивать из командной строки. Код ядра сообщает читателю, что может сделать ядро; запуск инструментов eBPF в загруженной системе показывает, что фактически делает ядро.

К счастью, начать работу с eBPF довольно просто с помощью утилит bcc, которые доступны в виде пакетов из основных дистрибутивов Linux и подробно документированы Бренданом Греггом. Утилиты bcc – это скрипты Python с небольшими встроенными фрагментами C, поэтому любой, кто знаком с любым языком, может легко их изменить. На этот счет в bcc/tools есть 80 скриптов Python, поэтому весьма вероятно, что системный администратор или разработчик найдет соответствующий его потребностям.

Чтобы получить очень общее представление о том, какую работу выполняют VFS в работающей системе, попробуйте скрипты vfscount или vfsstat, которые показывают, что каждую секунду происходят десятки вызовов vfs_open() и подобных ему.

vfsstat.py – это скрипт Python со встроенным фрагментом C, который просто считает вызовы функций VFS.

Для менее тривиального примера давайте посмотрим, что происходит в sysfs, когда в работающую систему вставлена USB-флешка.

Посмотрите с помощью eBPF, что происходит в /sys, когда вставлена флешка.

В первом простом примере, приведенном выше, скрипт trace.py выводит сообщение всякий раз, когда запускается команда sysfs_create_files(). Мы видим, что sysfs_create_files() была запущена потоком kworker в ответ на вставку USB-накопителя, но какой файл при этом был создан? Второй пример иллюстрирует полную мощь eBPF. Здесь trace.py выводит обратную трассировку ядра (опция -K) плюс имя файла, созданного sysfs_create_files(). Фрагмент внутри одинарных кавычек представляет собой некоторый исходный код на C, включая легко распознаваемую строку format, которая побуждает компилятор LLVM на лету компилировать и выполнять код внутри виртуальной машины в ядре. Полная сигнатура функции sysfs_create_files() должна быть воспроизведена во второй команде, чтобы строка format могла ссылаться на один из параметров. Ошибки в этом фрагменте C приводят к распознаваемым ошибкам компилятора C. Например, если опущен параметр -I, результатом будет «Failed to compile BPF text». Разработчики, знакомые с C или Python, найдут, что утилиты bcc легко расширять и модифицировать.

Читайте также:  Вытяжка с угольным фильтром без отвода отзывы

Когда вставлен USB-накопитель, появляется обратная трассировка ядра, показывающая, что PID 7711 является потоком kworker, который создал файл с именем «events» в sysfs. Соответствующий вызов sysfs_remove_files() показывает, что удаление флешки приводит к удалению файла events в соответствии с идеей подсчета ссылок. Просмотр sysfs_create_link() с помощью eBPF во время вставки USB-накопителя (не показан) показывает, что создано не менее 48 символических ссылок.

В любом случае, какова цель файла events? Использование cscope для поиска function __device_add_disk() показывает, что она вызывает disk_add_events(), и либо «media_change», либо «eject_request» могут быть записаны в файл events. Здесь блочный уровень ядра информирует пространство пользователя о появлении и исчезновении «диска». Подумайте, насколько быстро этот метод исследует, как работает вставка USB-накопителя, в сравнении с попыткой изучить этот процесс исключительно из источников.

Доступные только для чтения корневые файловые системы делают возможными встроенные устройства.

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

Тем не менее, многие слышали, что большинство IoT и встроенных устройств, такие как маршрутизаторы, термостаты и автомобили, теперь работают под управлением Linux. У многих из этих устройств почти полностью отсутствует пользовательский интерфейс, и нет способа их «чистой» перезагрузки. Подумайте о запуске автомобиля с разряженной батареей, когда питание бортового компьютера под управлением Linux скачет. Как получается, что система загружается без длинного fsck, когда двигатель наконец запускается? Ответ заключается в том, что встроенные устройства используют корневую файловую систему только для чтения (для краткости ro-rootfs).

ro-rootfs – это то, почему встраиваемые системы часто не нуждаются в fsck.

Ro-rootfs предлагают множество преимуществ, которые менее очевидны, чем неубиваемость. Одно из них заключается в том, что вредоносные программы не могут писать в /usr или /lib, как и ни один процесс Linux. Другое заключается в том, что неизменяемая файловая система в значительной степени имеет решающее значение для полевой поддержки удаленных устройств, поскольку вспомогательный персонал обладает локальными системами, которые номинально идентичны системам на местах. Возможно, самое важное (но также и самое тонкое) преимущество заключается в том, что ro-rootfs заставляет разработчиков решать на этапе разработки проекта, какие системные объекты будут неизменными. Работа с ro-rootfs часто может быть неудобной или даже болезненной, как это часто бывает с константами в языках программирования, но преимущества легко окупают дополнительные издержки.

Создание rootfs только для чтения требует дополнительных усилий для разработчиков встраиваемых систем, и именно здесь на помощь приходит VFS. Linux требует, чтобы файлы в /var были доступны для записи, и, кроме того, многие популярные приложения, которые запускаются встраиваемыми системами, будут пытаться создать конфигурационные файлы в $HOME. Одно из решений для конфигурационных файлов в домашнем каталоге, как правило, состоит в том, чтобы сгенерировать их предварительно и встроить в rootfs. Для /var один из подходов заключается в монтировании его в отдельный доступный для записи раздел, а / – только для чтения. Использование монтирования с привязкой и наложением (bind and overlay mounts) является еще одной популярной альтернативой.

Монтирования с привязкой и наложением, и их использование в контейнерах

Запуск man mount – лучшее место для изучения монтирования с привязкой и наложением, которое позволяет разработчикам встроенных систем и системным администраторам создавать файловую систему в одном месте, а затем предоставлять ее приложениям в другом. Для встроенных систем это означает, что можно сохранять файлы в /var на неперезаписываемом флэш-устройстве, но накладывать или привязывать-монтировать путь в tmpfs на путь /var при загрузке, чтобы приложения могли просматривать их у себя. При следующем включении изменения в /var исчезнут. Оверлейные монтирования обеспечивают объединение между tmpfs и базовой файловой системой и позволяют вносить видимые изменения в существующий файл в ro-rootfs, в то время как монтирования с привязкой делает так, чтобы новые пустые каталоги tmpfs отображались как доступные для записи в путях ro-rootfs. Хотя overlayfs является подходящим типом файловой системы, монтирование с привязкой осуществляется с помощью средств пространства имен VFS.

Основываясь на описании оверлеев и связываний, никто не удивится, что контейнеры Linux активно их используют. Давайте посмотрим, что происходит, когда мы используем systemd-nspawn для запуска контейнера, запустив утилиту bcc mountsnoop:

Вызов system-nspawn запускает контейнер во время работы mountsnoop.py.

И посмотрим, что случилось:

Запуск mountsnoop во время «загрузки» контейнера показывает, что среда выполнения контейнера сильно зависит от привязки монтирования (отображается только начало длинного вывода).

Здесь systemd-nspawn предоставляет выбранные файлы в procfs и sysfs хоста контейнеру по путям в его rootfs. Помимо флага MS_BIND, который устанавливает привязку-монтирование, некоторые другие флаги, которые вызывает системный вызов mount, определяют взаимосвязь между изменениями в пространстве имен хоста и в контейнере. Например, bind-mount может либо распространять изменения в /proc и /sys на контейнер, либо скрывать их, в зависимости от вызова.

Заключение

Понимание внутренних возможностей Linux может показаться невыполнимой задачей, поскольку само ядро ​​содержит гигантский объем кода, даже оставляя в стороне приложения пользовательского пространства Linux и интерфейс системных вызовов в библиотеках C, таких как glibc. Один из способов добиться прогресса – это прочитать исходный код одной подсистемы ядра с акцентом на понимание системных вызовов и заголовков, обращенных к пользовательскому пространству, а также основных внутренних интерфейсов ядра, примером которых является таблица file_operations. Файловые операции – это то, что заставляет работать принцип "все – это файл", поэтому особенно полезно получить управление ими. Исходные файлы ядра C в каталоге / верхнего уровня представляют собой реализацию виртуальных файловых систем, которые представляют собой слой, обеспечивающий широкую и относительно прямую совместимость популярных файловых систем и устройств хранения. Монтирование с привязкой и наложением через пространства имен Linux – это магия VFS, которая делает возможными контейнеры и корневые файловые системы только для чтения. В сочетании с изучением исходного кода, набор утилит eBPF и его интерфейс bcc делают исследование ядра более простым, чем когда-либо прежде.

admin

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *